Blender V2.61 - r43446

multires.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software  Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2007 by Nicholas Bishop
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Contributor(s): none yet.
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00033 #include "MEM_guardedalloc.h"
00034 
00035 /* for reading old multires */
00036 #define DNA_DEPRECATED_ALLOW
00037 
00038 #include "DNA_mesh_types.h"
00039 #include "DNA_meshdata_types.h"
00040 #include "DNA_object_types.h"
00041 #include "DNA_scene_types.h"
00042 
00043 #include "BLI_blenlib.h"
00044 #include "BLI_math.h"
00045 #include "BLI_pbvh.h"
00046 #include "BLI_editVert.h"
00047 #include "BLI_utildefines.h"
00048 
00049 #include "BKE_cdderivedmesh.h"
00050 #include "BKE_mesh.h"
00051 #include "BKE_modifier.h"
00052 #include "BKE_multires.h"
00053 #include "BKE_paint.h"
00054 #include "BKE_scene.h"
00055 #include "BKE_subsurf.h"
00056 
00057 #include "BKE_object.h"
00058 
00059 #include "CCGSubSurf.h"
00060 
00061 #include <math.h>
00062 #include <string.h>
00063 
00064 /* MULTIRES MODIFIER */
00065 static const int multires_max_levels = 13;
00066 static const int multires_grid_tot[] = {0, 4, 9, 25, 81, 289, 1089, 4225, 16641, 66049, 263169, 1050625, 4198401, 16785409};
00067 static const int multires_side_tot[] = {0, 2, 3, 5,  9,  17,  33,   65,   129,   257,   513,    1025,    2049,    4097};
00068 
00069 static void multires_mvert_to_ss(DerivedMesh *dm, MVert *mvert);
00070 static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, int invert, int add, DMGridData **oldGridData, int totlvl);
00071 
00072 DerivedMesh *get_multires_dm(Scene *scene, MultiresModifierData *mmd, Object *ob)
00073 {
00074     ModifierData *md= (ModifierData *)mmd;
00075     ModifierTypeInfo *mti = modifierType_getInfo(md->type);
00076     DerivedMesh *tdm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
00077     DerivedMesh *dm;
00078 
00079     dm = mti->applyModifier(md, ob, tdm, 0, 1);
00080     if (dm == tdm) {
00081         dm = CDDM_copy(tdm);
00082     }
00083 
00084     return dm;
00085 }
00086 
00087 MultiresModifierData *find_multires_modifier_before(Scene *scene, ModifierData *lastmd)
00088 {
00089     ModifierData *md;
00090 
00091     for(md = lastmd; md; md = md->prev) {
00092         if(md->type == eModifierType_Multires) {
00093             if (modifier_isEnabled(scene, md, eModifierMode_Realtime))
00094                 return (MultiresModifierData*)md;
00095         }
00096     }
00097 
00098     return NULL;
00099 }
00100 
00101 /* used for applying scale on mdisps layer and syncing subdivide levels when joining objects
00102    use_first - return first multires modifier if all multires'es are disabled
00103 */
00104 MultiresModifierData *get_multires_modifier(Scene *scene, Object *ob, int use_first)
00105 {
00106     ModifierData *md;
00107     MultiresModifierData *mmd= NULL, *firstmmd= NULL;
00108 
00109     /* find first active multires modifier */
00110     for(md = ob->modifiers.first; md; md = md->next) {
00111         if(md->type == eModifierType_Multires) {
00112             if(!firstmmd)
00113                 firstmmd= (MultiresModifierData*)md;
00114 
00115             if (modifier_isEnabled(scene, md, eModifierMode_Realtime)) {
00116                 mmd= (MultiresModifierData*)md;
00117                 break;
00118             }
00119         }
00120     }
00121 
00122     if(!mmd && use_first) {
00123         /* active multires have not been found
00124            try to use first one */
00125         return firstmmd;
00126     }
00127 
00128     return mmd;
00129 }
00130 
00131 static int multires_get_level(Object *ob, MultiresModifierData *mmd, int render)
00132 {
00133     if(render)
00134         return (mmd->modifier.scene)? get_render_subsurf_level(&mmd->modifier.scene->r, mmd->renderlvl): mmd->renderlvl;
00135     else if(ob->mode == OB_MODE_SCULPT)
00136         return mmd->sculptlvl;
00137     else
00138         return (mmd->modifier.scene)? get_render_subsurf_level(&mmd->modifier.scene->r, mmd->lvl): mmd->lvl;
00139 }
00140 
00141 static void multires_set_tot_level(Object *ob, MultiresModifierData *mmd, int lvl)
00142 {
00143     mmd->totlvl = lvl;
00144 
00145     if(ob->mode != OB_MODE_SCULPT)
00146         mmd->lvl = CLAMPIS(MAX2(mmd->lvl, lvl), 0, mmd->totlvl);
00147 
00148     mmd->sculptlvl = CLAMPIS(MAX2(mmd->sculptlvl, lvl), 0, mmd->totlvl);
00149     mmd->renderlvl = CLAMPIS(MAX2(mmd->renderlvl, lvl), 0, mmd->totlvl);
00150 }
00151 
00152 static void multires_dm_mark_as_modified(DerivedMesh *dm)
00153 {
00154     CCGDerivedMesh *ccgdm = (CCGDerivedMesh*)dm;
00155     ccgdm->multires.modified = 1;
00156 }
00157 
00158 void multires_mark_as_modified(Object *ob)
00159 {
00160     if(ob && ob->derivedFinal)
00161         multires_dm_mark_as_modified(ob->derivedFinal);
00162 }
00163 
00164 void multires_force_update(Object *ob)
00165 {
00166     if(ob) {
00167         if(ob->derivedFinal) {
00168             ob->derivedFinal->needsFree =1;
00169             ob->derivedFinal->release(ob->derivedFinal);
00170             ob->derivedFinal = NULL;
00171         }
00172         if(ob->sculpt && ob->sculpt->pbvh) {
00173             BLI_pbvh_free(ob->sculpt->pbvh);
00174             ob->sculpt->pbvh= NULL;
00175         }
00176     }
00177 }
00178 
00179 void multires_force_external_reload(Object *ob)
00180 {
00181     Mesh *me = get_mesh(ob);
00182 
00183     CustomData_external_reload(&me->fdata, &me->id, CD_MASK_MDISPS, me->totface);
00184     multires_force_update(ob);
00185 }
00186 
00187 void multires_force_render_update(Object *ob)
00188 {
00189     if(ob && (ob->mode & OB_MODE_SCULPT) && modifiers_findByType(ob, eModifierType_Multires))
00190         multires_force_update(ob);
00191 }
00192 
00193 int multiresModifier_reshapeFromDM(Scene *scene, MultiresModifierData *mmd,
00194                 Object *ob, DerivedMesh *srcdm)
00195 {
00196     DerivedMesh *mrdm = get_multires_dm (scene, mmd, ob);
00197 
00198     if(mrdm && srcdm && mrdm->getNumVerts(mrdm) == srcdm->getNumVerts(srcdm)) {
00199         multires_mvert_to_ss(mrdm, srcdm->getVertArray(srcdm));
00200 
00201         multires_dm_mark_as_modified(mrdm);
00202         multires_force_update(ob);
00203 
00204         mrdm->release(mrdm);
00205 
00206         return 1;
00207     }
00208 
00209     if(mrdm) mrdm->release(mrdm);
00210 
00211     return 0;
00212 }
00213 
00214 /* Returns 1 on success, 0 if the src's totvert doesn't match */
00215 int multiresModifier_reshape(Scene *scene, MultiresModifierData *mmd, Object *dst, Object *src)
00216 {
00217     DerivedMesh *srcdm = mesh_get_derived_final(scene, src, CD_MASK_BAREMESH);
00218     return multiresModifier_reshapeFromDM(scene, mmd, dst, srcdm);
00219 }
00220 
00221 int multiresModifier_reshapeFromDeformMod(Scene *scene, MultiresModifierData *mmd,
00222                 Object *ob, ModifierData *md)
00223 {
00224     ModifierTypeInfo *mti = modifierType_getInfo(md->type);
00225     DerivedMesh *dm, *ndm;
00226     int numVerts, result;
00227     float (*deformedVerts)[3];
00228 
00229     if(multires_get_level(ob, mmd, 0) == 0)
00230         return 0;
00231 
00232     /* Create DerivedMesh for deformation modifier */
00233     dm = get_multires_dm(scene, mmd, ob);
00234     numVerts= dm->getNumVerts(dm);
00235     deformedVerts= MEM_callocN(sizeof(float)*numVerts*3, "multiresReshape_deformVerts");
00236 
00237     dm->getVertCos(dm, deformedVerts);
00238     mti->deformVerts(md, ob, dm, deformedVerts, numVerts, 0, 0);
00239 
00240     ndm= CDDM_copy(dm);
00241     CDDM_apply_vert_coords(ndm, deformedVerts);
00242 
00243     MEM_freeN(deformedVerts);
00244     dm->release(dm);
00245 
00246     /* Reshaping */
00247     result= multiresModifier_reshapeFromDM(scene, mmd, ob, ndm);
00248 
00249     /* Cleanup */
00250     ndm->release(ndm);
00251 
00252     return result;
00253 }
00254 
00255 /* reset the multires levels to match the number of mdisps */
00256 static int get_levels_from_disps(Object *ob)
00257 {
00258     Mesh *me = ob->data;
00259     MDisps *mdisp;
00260     int i, totlvl= 0;
00261 
00262     mdisp = CustomData_get_layer(&me->fdata, CD_MDISPS);
00263 
00264     for(i = 0; i < me->totface; ++i, ++mdisp) {
00265         int S = me->mface[i].v4 ? 4 : 3;
00266 
00267         if(mdisp->totdisp == 0) continue;
00268 
00269         while(1) {
00270             int side = (1 << (totlvl-1)) + 1;
00271             int lvl_totdisp = side*side*S;
00272             if(mdisp->totdisp == lvl_totdisp)
00273                 break;
00274             else if(mdisp->totdisp < lvl_totdisp)
00275                 --totlvl;
00276             else
00277                 ++totlvl;
00278 
00279         }
00280     }
00281 
00282     return totlvl;
00283 }
00284 
00285 /* reset the multires levels to match the number of mdisps */
00286 void multiresModifier_set_levels_from_disps(MultiresModifierData *mmd, Object *ob)
00287 {
00288     Mesh *me = ob->data;
00289     MDisps *mdisp;
00290 
00291     if(me->edit_mesh)
00292         mdisp = CustomData_get_layer(&me->edit_mesh->fdata, CD_MDISPS);
00293     else
00294         mdisp = CustomData_get_layer(&me->fdata, CD_MDISPS);
00295 
00296     if(mdisp) {
00297         mmd->totlvl = get_levels_from_disps(ob);
00298         mmd->lvl = MIN2(mmd->sculptlvl, mmd->totlvl);
00299         mmd->sculptlvl = MIN2(mmd->sculptlvl, mmd->totlvl);
00300         mmd->renderlvl = MIN2(mmd->renderlvl, mmd->totlvl);
00301     }
00302 }
00303 
00304 static void multires_set_tot_mdisps(Mesh *me, int lvl)
00305 {
00306     MDisps *mdisps= CustomData_get_layer(&me->fdata, CD_MDISPS);
00307     int i;
00308 
00309     if(mdisps) {
00310         for(i = 0; i < me->totface; i++) {
00311             if(mdisps[i].totdisp == 0) {
00312                 int nvert = (me->mface[i].v4)? 4: 3;
00313                 mdisps[i].totdisp = multires_grid_tot[lvl]*nvert;
00314             }
00315         }
00316     }
00317 }
00318 
00319 static void multires_reallocate_mdisps(Mesh *me, MDisps *mdisps, int lvl)
00320 {
00321     int i;
00322 
00323     /* reallocate displacements to be filled in */
00324     for(i = 0; i < me->totface; ++i) {
00325         int nvert = (me->mface[i].v4)? 4: 3;
00326         int totdisp = multires_grid_tot[lvl]*nvert;
00327         float (*disps)[3] = MEM_callocN(sizeof(float) * 3 * totdisp, "multires disps");
00328 
00329         if(mdisps[i].disps)
00330             MEM_freeN(mdisps[i].disps);
00331 
00332         mdisps[i].disps = disps;
00333         mdisps[i].totdisp = totdisp;
00334     }
00335 }
00336 
00337 static void column_vectors_to_mat3(float mat[][3], float v1[3], float v2[3], float v3[3])
00338 {
00339     copy_v3_v3(mat[0], v1);
00340     copy_v3_v3(mat[1], v2);
00341     copy_v3_v3(mat[2], v3);
00342 }
00343 
00344 static void multires_copy_grid(float (*gridA)[3], float (*gridB)[3], int sizeA, int sizeB)
00345 {
00346     int x, y, j, skip;
00347 
00348     if(sizeA > sizeB) {
00349         skip = (sizeA-1)/(sizeB-1);
00350 
00351         for(j = 0, y = 0; y < sizeB; y++)
00352             for(x = 0; x < sizeB; x++, j++)
00353                 copy_v3_v3(gridA[y*skip*sizeA + x*skip], gridB[j]);
00354     }
00355     else {
00356         skip = (sizeB-1)/(sizeA-1);
00357 
00358         for(j = 0, y = 0; y < sizeA; y++)
00359             for(x = 0; x < sizeA; x++, j++)
00360                 copy_v3_v3(gridA[j], gridB[y*skip*sizeB + x*skip]);
00361     }
00362 }
00363 
00364 static void multires_copy_dm_grid(DMGridData *gridA, DMGridData *gridB, int sizeA, int sizeB)
00365 {
00366     int x, y, j, skip;
00367 
00368     if(sizeA > sizeB) {
00369         skip = (sizeA-1)/(sizeB-1);
00370 
00371         for(j = 0, y = 0; y < sizeB; y++)
00372             for(x = 0; x < sizeB; x++, j++)
00373                 copy_v3_v3(gridA[y*skip*sizeA + x*skip].co, gridB[j].co);
00374     }
00375     else {
00376         skip = (sizeB-1)/(sizeA-1);
00377 
00378         for(j = 0, y = 0; y < sizeA; y++)
00379             for(x = 0; x < sizeA; x++, j++)
00380                 copy_v3_v3(gridA[j].co, gridB[y*skip*sizeB + x*skip].co);
00381     }
00382 }
00383 
00384 static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl)
00385 {
00386     Mesh *me = (Mesh*)ob->data;
00387     int levels = mmd->totlvl - lvl;
00388     MDisps *mdisps;
00389 
00390     multires_set_tot_mdisps(me, mmd->totlvl);
00391     CustomData_external_read(&me->fdata, &me->id, CD_MASK_MDISPS, me->totface);
00392     mdisps= CustomData_get_layer(&me->fdata, CD_MDISPS);
00393 
00394     multires_force_update(ob);
00395 
00396     if(mdisps && levels > 0) {
00397         if(lvl > 0) {
00398             int nsize = multires_side_tot[lvl];
00399             int hsize = multires_side_tot[mmd->totlvl];
00400             int i;
00401 
00402             for(i = 0; i < me->totface; ++i) {
00403                 MDisps *mdisp= &mdisps[i];
00404                 float (*disps)[3], (*ndisps)[3], (*hdisps)[3];
00405                 int nvert = (me->mface[i].v4)? 4: 3;
00406                 int totdisp = multires_grid_tot[lvl]*nvert;
00407                 int S;
00408 
00409                 disps = MEM_callocN(sizeof(float) * 3 * totdisp, "multires disps");
00410 
00411                 ndisps = disps;
00412                 hdisps = mdisp->disps;
00413 
00414                 for(S = 0; S < nvert; S++) {
00415                     multires_copy_grid(ndisps, hdisps, nsize, hsize);
00416 
00417                     ndisps += nsize*nsize;
00418                     hdisps += hsize*hsize;
00419                 }
00420 
00421                 MEM_freeN(mdisp->disps);
00422                 mdisp->disps = disps;
00423                 mdisp->totdisp = totdisp;
00424             }
00425         }
00426         else {
00427             CustomData_external_remove(&me->fdata, &me->id, CD_MDISPS, me->totface);
00428             CustomData_free_layer_active(&me->fdata, CD_MDISPS, me->totface);
00429         }
00430     }
00431 
00432     multires_set_tot_level(ob, mmd, lvl);
00433 }
00434 
00435 /* direction=1 for delete higher, direction=0 for lower (not implemented yet) */
00436 void multiresModifier_del_levels(MultiresModifierData *mmd, Object *ob, int direction)
00437 {
00438     Mesh *me = get_mesh(ob);
00439     int lvl = multires_get_level(ob, mmd, 0);
00440     int levels = mmd->totlvl - lvl;
00441     MDisps *mdisps;
00442 
00443     multires_set_tot_mdisps(me, mmd->totlvl);
00444     CustomData_external_read(&me->fdata, &me->id, CD_MASK_MDISPS, me->totface);
00445     mdisps= CustomData_get_layer(&me->fdata, CD_MDISPS);
00446 
00447     multires_force_update(ob);
00448 
00449     if(mdisps && levels > 0 && direction == 1) {
00450         multires_del_higher(mmd, ob, lvl);
00451     }
00452 
00453     multires_set_tot_level(ob, mmd, lvl);
00454 }
00455 
00456 static DerivedMesh *multires_dm_create_local(Object *ob, DerivedMesh *dm, int lvl, int totlvl, int simple)
00457 {
00458     MultiresModifierData mmd= {{NULL}};
00459 
00460     mmd.lvl = lvl;
00461     mmd.sculptlvl = lvl;
00462     mmd.renderlvl = lvl;
00463     mmd.totlvl = totlvl;
00464     mmd.simple = simple;
00465 
00466     return multires_dm_create_from_derived(&mmd, 1, dm, ob, 0, 0);
00467 }
00468 
00469 static DerivedMesh *subsurf_dm_create_local(Object *ob, DerivedMesh *dm, int lvl, int simple, int optimal, int plain_uv)
00470 {
00471     SubsurfModifierData smd= {{NULL}};
00472 
00473     smd.levels = smd.renderLevels = lvl;
00474     if(!plain_uv)
00475         smd.flags |= eSubsurfModifierFlag_SubsurfUv;
00476     if(simple)
00477         smd.subdivType = ME_SIMPLE_SUBSURF;
00478     if(optimal)
00479         smd.flags |= eSubsurfModifierFlag_ControlEdges;
00480 
00481     return subsurf_make_derived_from_derived(dm, &smd, 0, NULL, 0, 0, (ob->mode & OB_MODE_EDIT));
00482 }
00483 
00484 
00485 
00486 /* assumes no is normalized; return value's sign is negative if v is on
00487    the other side of the plane */
00488 static float v3_dist_from_plane(float v[3], float center[3], float no[3])
00489 {
00490     float s[3];
00491     sub_v3_v3v3(s, v, center);
00492     return dot_v3v3(s, no);
00493 }
00494 
00495 void multiresModifier_base_apply(MultiresModifierData *mmd, Object *ob)
00496 {
00497     DerivedMesh *cddm, *dispdm, *origdm;
00498     Mesh *me;
00499     ListBase *fmap;
00500     float (*origco)[3];
00501     int i, j, offset, totlvl;
00502 
00503     multires_force_update(ob);
00504 
00505     me = get_mesh(ob);
00506     totlvl = mmd->totlvl;
00507 
00508     /* nothing to do */
00509     if(!totlvl)
00510         return;
00511 
00512     /* XXX - probably not necessary to regenerate the cddm so much? */
00513 
00514     /* generate highest level with displacements */
00515     cddm = CDDM_from_mesh(me, NULL);
00516     DM_set_only_copy(cddm, CD_MASK_BAREMESH);
00517     dispdm = multires_dm_create_local(ob, cddm, totlvl, totlvl, 0);
00518     cddm->release(cddm);
00519 
00520     /* copy the new locations of the base verts into the mesh */
00521     offset = dispdm->getNumVerts(dispdm) - me->totvert;
00522     for(i = 0; i < me->totvert; ++i) {
00523         dispdm->getVertCo(dispdm, offset + i, me->mvert[i].co);
00524     }
00525 
00526     /* heuristic to produce a better-fitting base mesh */
00527 
00528     cddm = CDDM_from_mesh(me, NULL);
00529     fmap = cddm->getFaceMap(ob, cddm);
00530     origco = MEM_callocN(sizeof(float)*3*me->totvert, "multires apply base origco");
00531     for(i = 0; i < me->totvert ;++i)
00532         copy_v3_v3(origco[i], me->mvert[i].co);
00533 
00534     for(i = 0; i < me->totvert; ++i) {
00535         IndexNode *n;
00536         float avg_no[3] = {0,0,0}, center[3] = {0,0,0}, push[3];
00537         float dist;
00538         int tot;
00539 
00540         /* don't adjust verts not used by at least one face */
00541         if(!fmap[i].first)
00542             continue;
00543 
00544         /* find center */
00545         for(n = fmap[i].first, tot = 0; n; n = n->next) {
00546             MFace *f = &me->mface[n->index];
00547             int S = f->v4 ? 4 : 3;
00548             
00549             /* this double counts, not sure if that's bad or good */
00550             for(j = 0; j < S; ++j) {
00551                 int vndx = (&f->v1)[j];
00552                 if(vndx != i) {
00553                     add_v3_v3(center, origco[vndx]);
00554                     ++tot;
00555                 }
00556             }
00557         }
00558         mul_v3_fl(center, 1.0f / tot);
00559 
00560         /* find normal */
00561         for(n = fmap[i].first; n; n = n->next) {
00562             MFace *f = &me->mface[n->index];
00563             int S = f->v4 ? 4 : 3;
00564             float v[4][3], no[3];
00565             
00566             for(j = 0; j < S; ++j) {
00567                 int vndx = (&f->v1)[j];
00568                 if(vndx == i)
00569                     copy_v3_v3(v[j], center);
00570                 else
00571                     copy_v3_v3(v[j], origco[vndx]);
00572             }
00573             
00574             if(S == 4)
00575                 normal_quad_v3(no, v[0], v[1], v[2], v[3]);
00576             else
00577                 normal_tri_v3(no, v[0], v[1], v[2]);
00578             add_v3_v3(avg_no, no);
00579         }
00580         normalize_v3(avg_no);
00581 
00582         /* push vertex away from the plane */
00583         dist = v3_dist_from_plane(me->mvert[i].co, center, avg_no);
00584         copy_v3_v3(push, avg_no);
00585         mul_v3_fl(push, dist);
00586         add_v3_v3(me->mvert[i].co, push);
00587         
00588     }
00589 
00590     MEM_freeN(origco);
00591     cddm->release(cddm);
00592 
00593     /* subdivide the mesh to highest level without displacements */
00594     cddm = CDDM_from_mesh(me, NULL);
00595     DM_set_only_copy(cddm, CD_MASK_BAREMESH);
00596     origdm = subsurf_dm_create_local(ob, cddm, totlvl, 0, 0, mmd->flags & eMultiresModifierFlag_PlainUv);
00597     cddm->release(cddm);
00598 
00599     /* calc disps */
00600     multiresModifier_disp_run(dispdm, me, 1, 0, origdm->getGridData(origdm), totlvl);
00601 
00602     origdm->release(origdm);
00603     dispdm->release(dispdm);
00604 }
00605 
00606 static void multires_subdivide(MultiresModifierData *mmd, Object *ob, int totlvl, int updateblock, int simple)
00607 {
00608     Mesh *me = ob->data;
00609     MDisps *mdisps;
00610     int lvl= mmd->totlvl;
00611 
00612     if(totlvl > multires_max_levels)
00613         return;
00614 
00615     multires_force_update(ob);
00616 
00617     mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS);
00618     if(!mdisps)
00619         mdisps = CustomData_add_layer(&me->fdata, CD_MDISPS, CD_DEFAULT, NULL, me->totface);
00620 
00621     if(mdisps->disps && !updateblock && totlvl > 1) {
00622         /* upsample */
00623         DerivedMesh *lowdm, *cddm, *highdm;
00624         DMGridData **highGridData, **lowGridData, **subGridData;
00625         CCGSubSurf *ss;
00626         int i, numGrids, highGridSize, lowGridSize;
00627 
00628         /* create subsurf DM from original mesh at high level */
00629         cddm = CDDM_from_mesh(me, NULL);
00630         DM_set_only_copy(cddm, CD_MASK_BAREMESH);
00631         highdm = subsurf_dm_create_local(ob, cddm, totlvl, simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv);
00632 
00633         /* create multires DM from original mesh at low level */
00634         lowdm = multires_dm_create_local(ob, cddm, lvl, lvl, simple);
00635         cddm->release(cddm);
00636 
00637         /* copy subsurf grids and replace them with low displaced grids */
00638         numGrids = highdm->getNumGrids(highdm);
00639         highGridSize = highdm->getGridSize(highdm);
00640         highGridData = highdm->getGridData(highdm);
00641         lowGridSize = lowdm->getGridSize(lowdm);
00642         lowGridData = lowdm->getGridData(lowdm);
00643 
00644         subGridData = MEM_callocN(sizeof(float*)*numGrids, "subGridData*");
00645 
00646         for(i = 0; i < numGrids; ++i) {
00647             /* backup subsurf grids */
00648             subGridData[i] = MEM_callocN(sizeof(DMGridData)*highGridSize*highGridSize, "subGridData");
00649             memcpy(subGridData[i], highGridData[i], sizeof(DMGridData)*highGridSize*highGridSize);
00650 
00651             /* overwrite with current displaced grids */
00652             multires_copy_dm_grid(highGridData[i], lowGridData[i], highGridSize, lowGridSize);
00653         }
00654 
00655         /* low lower level dm no longer needed at this point */
00656         lowdm->release(lowdm);
00657 
00658         /* subsurf higher levels again with displaced data */
00659         ss= ((CCGDerivedMesh*)highdm)->ss;
00660         ccgSubSurf_updateFromFaces(ss, lvl, NULL, 0);
00661         ccgSubSurf_updateLevels(ss, lvl, NULL, 0);
00662 
00663         /* reallocate displacements */
00664         multires_reallocate_mdisps(me, mdisps, totlvl); 
00665 
00666         /* compute displacements */
00667         multiresModifier_disp_run(highdm, me, 1, 0, subGridData, totlvl);
00668 
00669         /* free */
00670         highdm->release(highdm);
00671         for(i = 0; i < numGrids; ++i)
00672             MEM_freeN(subGridData[i]);
00673         MEM_freeN(subGridData);
00674     }
00675     else {
00676         /* only reallocate, nothing to upsample */
00677         multires_reallocate_mdisps(me, mdisps, totlvl); 
00678     }
00679 
00680     multires_set_tot_level(ob, mmd, totlvl);
00681 }
00682 
00683 void multiresModifier_subdivide(MultiresModifierData *mmd, Object *ob, int updateblock, int simple)
00684 {
00685     multires_subdivide(mmd, ob, mmd->totlvl+1, updateblock, simple);
00686 }
00687 
00688 static void grid_tangent(int gridSize, int index, int x, int y, int axis, DMGridData **gridData, float t[3])
00689 {
00690     if(axis == 0) {
00691         if(x == gridSize - 1) {
00692             if(y == gridSize - 1)
00693                 sub_v3_v3v3(t, gridData[index][x + gridSize*(y - 1)].co, gridData[index][x - 1 + gridSize*(y - 1)].co);
00694             else
00695                 sub_v3_v3v3(t, gridData[index][x + gridSize*y].co, gridData[index][x - 1 + gridSize*y].co);
00696         }
00697         else
00698             sub_v3_v3v3(t, gridData[index][x + 1 + gridSize*y].co, gridData[index][x + gridSize*y].co);
00699     }
00700     else if(axis == 1) {
00701         if(y == gridSize - 1) {
00702             if(x == gridSize - 1)
00703                 sub_v3_v3v3(t, gridData[index][x - 1 + gridSize*y].co, gridData[index][x - 1 + gridSize*(y - 1)].co);
00704             else
00705                 sub_v3_v3v3(t, gridData[index][x + gridSize*y].co, gridData[index][x + gridSize*(y - 1)].co);
00706         }
00707         else
00708             sub_v3_v3v3(t, gridData[index][x + gridSize*(y + 1)].co, gridData[index][x + gridSize*y].co);
00709     }
00710 }
00711 
00712 static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, int invert, int add, DMGridData **oldGridData, int totlvl)
00713 {
00714     CCGDerivedMesh *ccgdm = (CCGDerivedMesh*)dm;
00715     DMGridData **gridData, **subGridData;
00716     MFace *mface = me->mface;
00717     MDisps *mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS);
00718     int *gridOffset;
00719     int i, /*numGrids,*/ gridSize, dGridSize, dSkip;
00720 
00721     if(!mdisps) {
00722         if(invert)
00723             mdisps = CustomData_add_layer(&me->fdata, CD_MDISPS, CD_DEFAULT, NULL, me->totface);
00724         else
00725             return;
00726     }
00727 
00728     /*numGrids = dm->getNumGrids(dm);*/ /*UNUSED*/
00729     gridSize = dm->getGridSize(dm);
00730     gridData = dm->getGridData(dm);
00731     gridOffset = dm->getGridOffset(dm);
00732     subGridData = (oldGridData)? oldGridData: gridData;
00733 
00734     dGridSize = multires_side_tot[totlvl];
00735     dSkip = (dGridSize-1)/(gridSize-1);
00736 
00737     #pragma omp parallel for private(i) if(me->totface*gridSize*gridSize*4 >= CCG_OMP_LIMIT)
00738     for(i = 0; i < me->totface; ++i) {
00739         const int numVerts = mface[i].v4 ? 4 : 3;
00740         MDisps *mdisp = &mdisps[i];
00741         int S, x, y, gIndex = gridOffset[i];
00742 
00743         /* when adding new faces in edit mode, need to allocate disps */
00744         if(!mdisp->disps)
00745         #pragma omp critical
00746         {
00747             multires_reallocate_mdisps(me, mdisps, totlvl);
00748         }
00749 
00750         for(S = 0; S < numVerts; ++S, ++gIndex) {
00751             DMGridData *grid = gridData[gIndex];
00752             DMGridData *subgrid = subGridData[gIndex];
00753             float (*dispgrid)[3] = &mdisp->disps[S*dGridSize*dGridSize];
00754 
00755             for(y = 0; y < gridSize; y++) {
00756                 for(x = 0; x < gridSize; x++) {
00757                     float *co = grid[x + y*gridSize].co;
00758                     float *sco = subgrid[x + y*gridSize].co;
00759                     float *no = subgrid[x + y*gridSize].no;
00760                     float *data = dispgrid[dGridSize*y*dSkip + x*dSkip];
00761                     float mat[3][3], tx[3], ty[3], disp[3], d[3];
00762 
00763                     /* construct tangent space matrix */
00764                     grid_tangent(gridSize, gIndex, x, y, 0, subGridData, tx);
00765                     normalize_v3(tx);
00766 
00767                     grid_tangent(gridSize, gIndex, x, y, 1, subGridData, ty);
00768                     normalize_v3(ty);
00769 
00770                     //mul_v3_fl(tx, 1.0f/(gridSize-1));
00771                     //mul_v3_fl(ty, 1.0f/(gridSize-1));
00772                     //cross_v3_v3v3(no, tx, ty);
00773 
00774                     column_vectors_to_mat3(mat, tx, ty, no);
00775 
00776                     if(!invert) {
00777                         /* convert to object space and add */
00778                         mul_v3_m3v3(disp, mat, data);
00779                         add_v3_v3v3(co, sco, disp);
00780                     }
00781                     else if(!add) {
00782                         /* convert difference to tangent space */
00783                         sub_v3_v3v3(disp, co, sco);
00784                         invert_m3(mat);
00785                         mul_v3_m3v3(data, mat, disp);
00786                     }
00787                     else {
00788                         /* convert difference to tangent space */
00789                         invert_m3(mat);
00790                         mul_v3_m3v3(d, mat, co);
00791                         add_v3_v3(data, d);
00792                     }
00793                 }
00794             }
00795         }
00796     }
00797 
00798     if(!invert) {
00799         ccgSubSurf_stitchFaces(ccgdm->ss, 0, NULL, 0);
00800         ccgSubSurf_updateNormals(ccgdm->ss, NULL, 0);
00801     }
00802 }
00803 
00804 static void multiresModifier_update(DerivedMesh *dm)
00805 {
00806     CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
00807     Object *ob;
00808     Mesh *me;
00809     MDisps *mdisps;
00810     MultiresModifierData *mmd;
00811 
00812     ob = ccgdm->multires.ob;
00813     me = ccgdm->multires.ob->data;
00814     mmd = ccgdm->multires.mmd;
00815     multires_set_tot_mdisps(me, mmd->totlvl);
00816     CustomData_external_read(&me->fdata, &me->id, CD_MASK_MDISPS, me->totface);
00817     mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS);
00818 
00819     if(mdisps) {
00820         int lvl = ccgdm->multires.lvl;
00821         int totlvl = ccgdm->multires.totlvl;
00822         
00823         if(lvl < totlvl) {
00824             Mesh *me = ob->data;
00825             DerivedMesh *lowdm, *cddm, *highdm;
00826             DMGridData **highGridData, **lowGridData, **subGridData, **gridData, *diffGrid;
00827             CCGSubSurf *ss;
00828             int i, j, numGrids, highGridSize, lowGridSize;
00829 
00830             /* create subsurf DM from original mesh at high level */
00831             if (ob->derivedDeform) cddm = CDDM_copy(ob->derivedDeform);
00832             else cddm = CDDM_from_mesh(me, NULL);
00833             DM_set_only_copy(cddm, CD_MASK_BAREMESH);
00834 
00835             highdm = subsurf_dm_create_local(ob, cddm, totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv);
00836 
00837             /* create multires DM from original mesh and displacements */
00838             lowdm = multires_dm_create_local(ob, cddm, lvl, totlvl, mmd->simple);
00839             cddm->release(cddm);
00840 
00841             /* gather grid data */
00842             numGrids = highdm->getNumGrids(highdm);
00843             highGridSize = highdm->getGridSize(highdm);
00844             highGridData = highdm->getGridData(highdm);
00845             lowGridSize = lowdm->getGridSize(lowdm);
00846             lowGridData = lowdm->getGridData(lowdm);
00847             gridData = dm->getGridData(dm);
00848 
00849             subGridData = MEM_callocN(sizeof(DMGridData*)*numGrids, "subGridData*");
00850             diffGrid = MEM_callocN(sizeof(DMGridData)*lowGridSize*lowGridSize, "diff");
00851 
00852             for(i = 0; i < numGrids; ++i) {
00853                 /* backup subsurf grids */
00854                 subGridData[i] = MEM_callocN(sizeof(DMGridData)*highGridSize*highGridSize, "subGridData");
00855                 memcpy(subGridData[i], highGridData[i], sizeof(DMGridData)*highGridSize*highGridSize);
00856 
00857                 /* write difference of subsurf and displaced low level into high subsurf */
00858                 for(j = 0; j < lowGridSize*lowGridSize; ++j)
00859                     sub_v3_v3v3(diffGrid[j].co, gridData[i][j].co, lowGridData[i][j].co);
00860 
00861                 multires_copy_dm_grid(highGridData[i], diffGrid, highGridSize, lowGridSize);
00862             }
00863 
00864             /* lower level dm no longer needed at this point */
00865             MEM_freeN(diffGrid);
00866             lowdm->release(lowdm);
00867 
00868             /* subsurf higher levels again with difference of coordinates */
00869             ss= ((CCGDerivedMesh*)highdm)->ss;
00870             ccgSubSurf_updateFromFaces(ss, lvl, NULL, 0);
00871             ccgSubSurf_updateLevels(ss, lvl, NULL, 0);
00872 
00873             /* add to displacements */
00874             multiresModifier_disp_run(highdm, me, 1, 1, subGridData, mmd->totlvl);
00875 
00876             /* free */
00877             highdm->release(highdm);
00878             for(i = 0; i < numGrids; ++i)
00879                 MEM_freeN(subGridData[i]);
00880             MEM_freeN(subGridData);
00881         }
00882         else {
00883             DerivedMesh *cddm, *subdm;
00884 
00885             if (ob->derivedDeform) cddm = CDDM_copy(ob->derivedDeform);
00886             else cddm = CDDM_from_mesh(me, NULL);
00887             DM_set_only_copy(cddm, CD_MASK_BAREMESH);
00888 
00889             subdm = subsurf_dm_create_local(ob, cddm, mmd->totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv);
00890             cddm->release(cddm);
00891 
00892             multiresModifier_disp_run(dm, me, 1, 0, subdm->getGridData(subdm), mmd->totlvl);
00893 
00894             subdm->release(subdm);
00895         }
00896     }
00897 }
00898 
00899 void multires_stitch_grids(Object *ob)
00900 {
00901     /* utility for smooth brush */
00902     if(ob && ob->derivedFinal) {
00903         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*)ob->derivedFinal;
00904         CCGFace **faces;
00905         int totface;
00906 
00907         if(ccgdm->pbvh) {
00908             BLI_pbvh_get_grid_updates(ccgdm->pbvh, 0, (void***)&faces, &totface);
00909 
00910             if(totface) {
00911                 ccgSubSurf_stitchFaces(ccgdm->ss, 0, faces, totface);
00912                 MEM_freeN(faces);
00913             }
00914         }
00915     }
00916 }
00917 
00918 DerivedMesh *multires_dm_create_from_derived(MultiresModifierData *mmd, int local_mmd, DerivedMesh *dm, Object *ob,
00919                             int useRenderParams, int UNUSED(isFinalCalc))
00920 {
00921     Mesh *me= ob->data;
00922     DerivedMesh *result;
00923     CCGDerivedMesh *ccgdm;
00924     DMGridData **gridData, **subGridData;
00925     int lvl= multires_get_level(ob, mmd, useRenderParams);
00926     int i, gridSize, numGrids;
00927 
00928     if(lvl == 0)
00929         return dm;
00930 
00931     result = subsurf_dm_create_local(ob, dm, lvl,
00932         mmd->simple, mmd->flags & eMultiresModifierFlag_ControlEdges,
00933         mmd->flags & eMultiresModifierFlag_PlainUv);
00934 
00935     if(!local_mmd) {
00936         ccgdm = (CCGDerivedMesh*)result;
00937 
00938         ccgdm->multires.ob = ob;
00939         ccgdm->multires.mmd = mmd;
00940         ccgdm->multires.local_mmd = local_mmd;
00941         ccgdm->multires.lvl = lvl;
00942         ccgdm->multires.totlvl = mmd->totlvl;
00943         ccgdm->multires.modified = 0;
00944         ccgdm->multires.update = multiresModifier_update;
00945     }
00946 
00947     numGrids = result->getNumGrids(result);
00948     gridSize = result->getGridSize(result);
00949     gridData = result->getGridData(result);
00950 
00951     subGridData = MEM_callocN(sizeof(DMGridData*)*numGrids, "subGridData*");
00952 
00953     for(i = 0; i < numGrids; i++) {
00954         subGridData[i] = MEM_callocN(sizeof(DMGridData)*gridSize*gridSize, "subGridData");
00955         memcpy(subGridData[i], gridData[i], sizeof(DMGridData)*gridSize*gridSize);
00956     }
00957 
00958     multires_set_tot_mdisps(me, mmd->totlvl);
00959     CustomData_external_read(&me->fdata, &me->id, CD_MASK_MDISPS, me->totface);
00960     multiresModifier_disp_run(result, ob->data, 0, 0, subGridData, mmd->totlvl);
00961 
00962     for(i = 0; i < numGrids; i++)
00963         MEM_freeN(subGridData[i]);
00964     MEM_freeN(subGridData);
00965 
00966     return result;
00967 }
00968 
00969 /**** Old Multires code ****
00970 ***************************/
00971 
00972 /* Adapted from sculptmode.c */
00973 void old_mdisps_bilinear(float out[3], float (*disps)[3], const int st, float u, float v)
00974 {
00975     int x, y, x2, y2;
00976     const int st_max = st - 1;
00977     float urat, vrat, uopp;
00978     float d[4][3], d2[2][3];
00979 
00980     if(u < 0)
00981         u = 0;
00982     else if(u >= st)
00983         u = st_max;
00984     if(v < 0)
00985         v = 0;
00986     else if(v >= st)
00987         v = st_max;
00988 
00989     x = floor(u);
00990     y = floor(v);
00991     x2 = x + 1;
00992     y2 = y + 1;
00993 
00994     if(x2 >= st) x2 = st_max;
00995     if(y2 >= st) y2 = st_max;
00996     
00997     urat = u - x;
00998     vrat = v - y;
00999     uopp = 1 - urat;
01000 
01001     mul_v3_v3fl(d[0], disps[y * st + x], uopp);
01002     mul_v3_v3fl(d[1], disps[y * st + x2], urat);
01003     mul_v3_v3fl(d[2], disps[y2 * st + x], uopp);
01004     mul_v3_v3fl(d[3], disps[y2 * st + x2], urat);
01005 
01006     add_v3_v3v3(d2[0], d[0], d[1]);
01007     add_v3_v3v3(d2[1], d[2], d[3]);
01008     mul_v3_fl(d2[0], 1 - vrat);
01009     mul_v3_fl(d2[1], vrat);
01010 
01011     add_v3_v3v3(out, d2[0], d2[1]);
01012 }
01013 
01014 static void old_mdisps_rotate(int S, int UNUSED(newside), int oldside, int x, int y, float *u, float *v)
01015 {
01016     float offset = oldside*0.5f - 0.5f;
01017 
01018     if(S == 1) { *u= offset + x; *v = offset - y; }
01019     if(S == 2) { *u= offset + y; *v = offset + x; }
01020     if(S == 3) { *u= offset - x; *v = offset + y; }
01021     if(S == 0) { *u= offset - y; *v = offset - x; }
01022 }
01023 
01024 static void old_mdisps_convert(MFace *mface, MDisps *mdisp)
01025 {
01026     int newlvl = log(sqrt(mdisp->totdisp)-1)/M_LN2;
01027     int oldlvl = newlvl+1;
01028     int oldside = multires_side_tot[oldlvl];
01029     int newside = multires_side_tot[newlvl];
01030     int nvert = (mface->v4)? 4: 3;
01031     int newtotdisp = multires_grid_tot[newlvl]*nvert;
01032     int x, y, S;
01033     float (*disps)[3], (*out)[3], u = 0.0f, v = 0.0f; /* Quite gcc barking. */
01034 
01035     disps = MEM_callocN(sizeof(float) * 3 * newtotdisp, "multires disps");
01036 
01037     out = disps;
01038     for(S = 0; S < nvert; S++) {
01039         for(y = 0; y < newside; ++y) {
01040             for(x = 0; x < newside; ++x, ++out) {
01041                 old_mdisps_rotate(S, newside, oldside, x, y, &u, &v);
01042                 old_mdisps_bilinear(*out, mdisp->disps, oldside, u, v);
01043 
01044                 if(S == 1) { (*out)[1]= -(*out)[1]; }
01045                 else if(S == 2) { SWAP(float, (*out)[0], (*out)[1]); }
01046                 else if(S == 3) { (*out)[0]= -(*out)[0]; }
01047                 else if(S == 0) { SWAP(float, (*out)[0], (*out)[1]); (*out)[0]= -(*out)[0]; (*out)[1]= -(*out)[1]; };
01048             }
01049         }
01050     }
01051 
01052     MEM_freeN(mdisp->disps);
01053 
01054     mdisp->totdisp= newtotdisp;
01055     mdisp->disps= disps;
01056 }
01057 
01058 void multires_load_old_250(Mesh *me)
01059 {
01060     MDisps *mdisps;
01061     int a;
01062 
01063     mdisps= CustomData_get_layer(&me->fdata, CD_MDISPS);
01064 
01065     if(mdisps) {
01066         for(a=0; a<me->totface; a++)
01067             if(mdisps[a].totdisp)
01068                 old_mdisps_convert(&me->mface[a], &mdisps[a]);
01069     }
01070 }
01071 
01072 /* Does not actually free lvl itself */
01073 static void multires_free_level(MultiresLevel *lvl)
01074 {
01075     if(lvl) {
01076         if(lvl->faces) MEM_freeN(lvl->faces);
01077         if(lvl->edges) MEM_freeN(lvl->edges);
01078         if(lvl->colfaces) MEM_freeN(lvl->colfaces);
01079     }
01080 }
01081 
01082 void multires_free(Multires *mr)
01083 {
01084     if(mr) {
01085         MultiresLevel* lvl= mr->levels.first;
01086 
01087         /* Free the first-level data */
01088         if(lvl) {
01089             CustomData_free(&mr->vdata, lvl->totvert);
01090             CustomData_free(&mr->fdata, lvl->totface);
01091             if(mr->edge_flags)
01092                 MEM_freeN(mr->edge_flags);
01093             if(mr->edge_creases)
01094                 MEM_freeN(mr->edge_creases);
01095         }
01096 
01097         while(lvl) {
01098             multires_free_level(lvl);           
01099             lvl= lvl->next;
01100         }
01101 
01102         MEM_freeN(mr->verts);
01103 
01104         BLI_freelistN(&mr->levels);
01105 
01106         MEM_freeN(mr);
01107     }
01108 }
01109 
01110 static void create_old_vert_face_map(ListBase **map, IndexNode **mem, const MultiresFace *mface,
01111                      const int totvert, const int totface)
01112 {
01113     int i,j;
01114     IndexNode *node = NULL;
01115     
01116     (*map) = MEM_callocN(sizeof(ListBase) * totvert, "vert face map");
01117     (*mem) = MEM_callocN(sizeof(IndexNode) * totface*4, "vert face map mem");
01118     node = *mem;
01119     
01120     /* Find the users */
01121     for(i = 0; i < totface; ++i){
01122         for(j = 0; j < (mface[i].v[3]?4:3); ++j, ++node) {
01123             node->index = i;
01124             BLI_addtail(&(*map)[mface[i].v[j]], node);
01125         }
01126     }
01127 }
01128 
01129 static void create_old_vert_edge_map(ListBase **map, IndexNode **mem, const MultiresEdge *medge,
01130                      const int totvert, const int totedge)
01131 {
01132     int i,j;
01133     IndexNode *node = NULL;
01134     
01135     (*map) = MEM_callocN(sizeof(ListBase) * totvert, "vert edge map");
01136     (*mem) = MEM_callocN(sizeof(IndexNode) * totedge*2, "vert edge map mem");
01137     node = *mem;
01138     
01139     /* Find the users */
01140     for(i = 0; i < totedge; ++i){
01141         for(j = 0; j < 2; ++j, ++node) {
01142             node->index = i;
01143             BLI_addtail(&(*map)[medge[i].v[j]], node);
01144         }
01145     }
01146 }
01147 
01148 static MultiresFace *find_old_face(ListBase *map, MultiresFace *faces, int v1, int v2, int v3, int v4)
01149 {
01150     IndexNode *n1;
01151     int v[4], i, j;
01152 
01153     v[0]= v1;
01154     v[1]= v2;
01155     v[2]= v3;
01156     v[3]= v4;
01157 
01158     for(n1 = map[v1].first; n1; n1 = n1->next) {
01159         int fnd[4] = {0, 0, 0, 0};
01160 
01161         for(i = 0; i < 4; ++i) {
01162             for(j = 0; j < 4; ++j) {
01163                 if(v[i] == faces[n1->index].v[j])
01164                     fnd[i] = 1;
01165             }
01166         }
01167 
01168         if(fnd[0] && fnd[1] && fnd[2] && fnd[3])
01169             return &faces[n1->index];
01170     }
01171 
01172     return NULL;
01173 }
01174 
01175 static MultiresEdge *find_old_edge(ListBase *map, MultiresEdge *edges, int v1, int v2)
01176 {
01177     IndexNode *n1, *n2;
01178 
01179     for(n1 = map[v1].first; n1; n1 = n1->next) {
01180         for(n2 = map[v2].first; n2; n2 = n2->next) {
01181             if(n1->index == n2->index)
01182                 return &edges[n1->index];
01183         }
01184     }
01185 
01186     return NULL;
01187 }
01188 
01189 static void multires_load_old_edges(ListBase **emap, MultiresLevel *lvl, int *vvmap, int dst, int v1, int v2, int mov)
01190 {
01191     int emid = find_old_edge(emap[2], lvl->edges, v1, v2)->mid;
01192     vvmap[dst + mov] = emid;
01193 
01194     if(lvl->next->next) {
01195         multires_load_old_edges(emap + 1, lvl->next, vvmap, dst + mov, v1, emid, mov / 2);
01196         multires_load_old_edges(emap + 1, lvl->next, vvmap, dst + mov, v2, emid, -mov / 2);
01197     }
01198 }
01199 
01200 static void multires_load_old_faces(ListBase **fmap, ListBase **emap, MultiresLevel *lvl, int *vvmap, int dst,
01201                     int v1, int v2, int v3, int v4, int st2, int st3)
01202 {
01203     int fmid;
01204     int emid13, emid14, emid23, emid24;
01205 
01206     if(lvl && lvl->next) {
01207         fmid = find_old_face(fmap[1], lvl->faces, v1, v2, v3, v4)->mid;
01208         vvmap[dst] = fmid;
01209 
01210         emid13 = find_old_edge(emap[1], lvl->edges, v1, v3)->mid;
01211         emid14 = find_old_edge(emap[1], lvl->edges, v1, v4)->mid;
01212         emid23 = find_old_edge(emap[1], lvl->edges, v2, v3)->mid;
01213         emid24 = find_old_edge(emap[1], lvl->edges, v2, v4)->mid;
01214 
01215 
01216         multires_load_old_faces(fmap + 1, emap + 1, lvl->next, vvmap, dst + st2 * st3 + st3,
01217                     fmid, v2, emid23, emid24, st2, st3 / 2);
01218 
01219         multires_load_old_faces(fmap + 1, emap + 1, lvl->next, vvmap, dst - st2 * st3 + st3,
01220                     emid14, emid24, fmid, v4, st2, st3 / 2);
01221 
01222         multires_load_old_faces(fmap + 1, emap + 1, lvl->next, vvmap, dst + st2 * st3 - st3,
01223                     emid13, emid23, v3, fmid, st2, st3 / 2);
01224 
01225         multires_load_old_faces(fmap + 1, emap + 1, lvl->next, vvmap, dst - st2 * st3 - st3,
01226                     v1, fmid, emid13, emid14, st2, st3 / 2);
01227 
01228         if(lvl->next->next) {
01229             multires_load_old_edges(emap, lvl->next, vvmap, dst, emid24, fmid, st3);
01230             multires_load_old_edges(emap, lvl->next, vvmap, dst, emid13, fmid, -st3);
01231             multires_load_old_edges(emap, lvl->next, vvmap, dst, emid14, fmid, -st2 * st3);
01232             multires_load_old_edges(emap, lvl->next, vvmap, dst, emid23, fmid, st2 * st3);
01233         }
01234     }
01235 }
01236 
01237 static void multires_mvert_to_ss(DerivedMesh *dm, MVert *mvert)
01238 {
01239     CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
01240     CCGSubSurf *ss = ccgdm->ss;
01241     DMGridData *vd;
01242     int index;
01243     int totvert, totedge, totface;
01244     int gridSize = ccgSubSurf_getGridSize(ss);
01245     int edgeSize = ccgSubSurf_getEdgeSize(ss);
01246     int i = 0;
01247 
01248     totface = ccgSubSurf_getNumFaces(ss);
01249     for(index = 0; index < totface; index++) {
01250         CCGFace *f = ccgdm->faceMap[index].face;
01251         int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
01252 
01253         vd= ccgSubSurf_getFaceCenterData(f);
01254         copy_v3_v3(vd->co, mvert[i].co);
01255         i++;
01256         
01257         for(S = 0; S < numVerts; S++) {
01258             for(x = 1; x < gridSize - 1; x++, i++) {
01259                 vd= ccgSubSurf_getFaceGridEdgeData(ss, f, S, x);
01260                 copy_v3_v3(vd->co, mvert[i].co);
01261             }
01262         }
01263 
01264         for(S = 0; S < numVerts; S++) {
01265             for(y = 1; y < gridSize - 1; y++) {
01266                 for(x = 1; x < gridSize - 1; x++, i++) {
01267                     vd= ccgSubSurf_getFaceGridData(ss, f, S, x, y);
01268                     copy_v3_v3(vd->co, mvert[i].co);
01269                 }
01270             }
01271         }
01272     }
01273 
01274     totedge = ccgSubSurf_getNumEdges(ss);
01275     for(index = 0; index < totedge; index++) {
01276         CCGEdge *e = ccgdm->edgeMap[index].edge;
01277         int x;
01278 
01279         for(x = 1; x < edgeSize - 1; x++, i++) {
01280             vd= ccgSubSurf_getEdgeData(ss, e, x);
01281             copy_v3_v3(vd->co, mvert[i].co);
01282         }
01283     }
01284 
01285     totvert = ccgSubSurf_getNumVerts(ss);
01286     for(index = 0; index < totvert; index++) {
01287         CCGVert *v = ccgdm->vertMap[index].vert;
01288 
01289         vd= ccgSubSurf_getVertData(ss, v);
01290         copy_v3_v3(vd->co, mvert[i].co);
01291         i++;
01292     }
01293 
01294     ccgSubSurf_updateToFaces(ss, 0, NULL, 0);
01295 }
01296 
01297 /* Loads a multires object stored in the old Multires struct into the new format */
01298 static void multires_load_old_dm(DerivedMesh *dm, Mesh *me, int totlvl)
01299 {
01300     MultiresLevel *lvl, *lvl1;
01301     Multires *mr= me->mr;
01302     MVert *vsrc, *vdst;
01303     unsigned int src, dst;
01304     int st = multires_side_tot[totlvl - 1] - 1;
01305     int extedgelen = multires_side_tot[totlvl] - 2;
01306     int *vvmap; // inorder for dst, map to src
01307     int crossedgelen;
01308     int s, x, tottri, totquad;
01309     unsigned int i, j, totvert;
01310 
01311     src = 0;
01312     vsrc = mr->verts;
01313     vdst = dm->getVertArray(dm);
01314     totvert = (unsigned int)dm->getNumVerts(dm);
01315     vvmap = MEM_callocN(sizeof(int) * totvert, "multires vvmap");
01316 
01317     lvl1 = mr->levels.first;
01318     /* Load base verts */
01319     for(i = 0; i < lvl1->totvert; ++i) {
01320         vvmap[totvert - lvl1->totvert + i] = src;
01321         ++src;
01322     }
01323 
01324     /* Original edges */
01325     dst = totvert - lvl1->totvert - extedgelen * lvl1->totedge;
01326     for(i = 0; i < lvl1->totedge; ++i) {
01327         int ldst = dst + extedgelen * i;
01328         int lsrc = src;
01329         lvl = lvl1->next;
01330 
01331         for(j = 2; j <= mr->level_count; ++j) {
01332             int base = multires_side_tot[totlvl - j + 1] - 2;
01333             int skip = multires_side_tot[totlvl - j + 2] - 1;
01334             int st = multires_side_tot[j - 1] - 1;
01335 
01336             for(x = 0; x < st; ++x)
01337                 vvmap[ldst + base + x * skip] = lsrc + st * i + x;
01338 
01339             lsrc += lvl->totvert - lvl->prev->totvert;
01340             lvl = lvl->next;
01341         }
01342     }
01343 
01344     /* Center points */
01345     dst = 0;
01346     for(i = 0; i < lvl1->totface; ++i) {
01347         int sides = lvl1->faces[i].v[3] ? 4 : 3;
01348 
01349         vvmap[dst] = src + lvl1->totedge + i;
01350         dst += 1 + sides * (st - 1) * st;
01351     }
01352 
01353 
01354     /* The rest is only for level 3 and up */
01355     if(lvl1->next && lvl1->next->next) {
01356         ListBase **fmap, **emap;
01357         IndexNode **fmem, **emem;
01358 
01359         /* Face edge cross */
01360         tottri = totquad = 0;
01361         crossedgelen = multires_side_tot[totlvl - 1] - 2;
01362         dst = 0;
01363         for(i = 0; i < lvl1->totface; ++i) {
01364             int sides = lvl1->faces[i].v[3] ? 4 : 3;
01365 
01366             lvl = lvl1->next->next;
01367             ++dst;
01368 
01369             for(j = 3; j <= mr->level_count; ++j) {
01370                 int base = multires_side_tot[totlvl - j + 1] - 2;
01371                 int skip = multires_side_tot[totlvl - j + 2] - 1;
01372                 int st = pow(2, j - 2);
01373                 int st2 = pow(2, j - 3);
01374                 int lsrc = lvl->prev->totvert;
01375 
01376                 /* Skip exterior edge verts */
01377                 lsrc += lvl1->totedge * st;
01378 
01379                 /* Skip earlier face edge crosses */
01380                 lsrc += st2 * (tottri * 3 + totquad * 4);
01381 
01382                 for(s = 0; s < sides; ++s) {
01383                     for(x = 0; x < st2; ++x) {
01384                         vvmap[dst + crossedgelen * (s + 1) - base - x * skip - 1] = lsrc;
01385                         ++lsrc;
01386                     }
01387                 }
01388 
01389                 lvl = lvl->next;
01390             }
01391 
01392             dst += sides * (st - 1) * st;
01393 
01394             if(sides == 4) ++totquad;
01395             else ++tottri;
01396 
01397         }
01398 
01399         /* calculate vert to edge/face maps for each level (except the last) */
01400         fmap = MEM_callocN(sizeof(ListBase*) * (mr->level_count-1), "multires fmap");
01401         emap = MEM_callocN(sizeof(ListBase*) * (mr->level_count-1), "multires emap");
01402         fmem = MEM_callocN(sizeof(IndexNode*) * (mr->level_count-1), "multires fmem");
01403         emem = MEM_callocN(sizeof(IndexNode*) * (mr->level_count-1), "multires emem");
01404         lvl = lvl1;
01405         for(i = 0; i < (unsigned int)mr->level_count - 1; ++i) {
01406             create_old_vert_face_map(fmap + i, fmem + i, lvl->faces, lvl->totvert, lvl->totface);
01407             create_old_vert_edge_map(emap + i, emem + i, lvl->edges, lvl->totvert, lvl->totedge);
01408             lvl = lvl->next;
01409         }
01410 
01411         /* Interior face verts */
01412         /* lvl = lvl1->next->next; */ /* UNUSED */
01413         dst = 0;
01414         for(j = 0; j < lvl1->totface; ++j) {
01415             int sides = lvl1->faces[j].v[3] ? 4 : 3;
01416             int ldst = dst + 1 + sides * (st - 1);
01417 
01418             for(s = 0; s < sides; ++s) {
01419                 int st2 = multires_side_tot[totlvl - 1] - 2;
01420                 int st3 = multires_side_tot[totlvl - 2] - 2;
01421                 int st4 = st3 == 0 ? 1 : (st3 + 1) / 2;
01422                 int mid = ldst + st2 * st3 + st3;
01423                 int cv = lvl1->faces[j].v[s];
01424                 int nv = lvl1->faces[j].v[s == sides - 1 ? 0 : s + 1];
01425                 int pv = lvl1->faces[j].v[s == 0 ? sides - 1 : s - 1];
01426 
01427                 multires_load_old_faces(fmap, emap, lvl1->next, vvmap, mid,
01428                             vvmap[dst], cv,
01429                             find_old_edge(emap[0], lvl1->edges, pv, cv)->mid,
01430                             find_old_edge(emap[0], lvl1->edges, cv, nv)->mid,
01431                             st2, st4);
01432 
01433                 ldst += (st - 1) * (st - 1);
01434             }
01435 
01436 
01437             dst = ldst;
01438         }
01439 
01440         /*lvl = lvl->next;*/ /*UNUSED*/
01441 
01442         for(i = 0; i < (unsigned int)(mr->level_count - 1); ++i) {
01443             MEM_freeN(fmap[i]);
01444             MEM_freeN(fmem[i]);
01445             MEM_freeN(emap[i]);
01446             MEM_freeN(emem[i]);
01447         }
01448 
01449         MEM_freeN(fmap);
01450         MEM_freeN(emap);
01451         MEM_freeN(fmem);
01452         MEM_freeN(emem);
01453     }
01454 
01455     /* Transfer verts */
01456     for(i = 0; i < totvert; ++i)
01457         copy_v3_v3(vdst[i].co, vsrc[vvmap[i]].co);
01458 
01459     MEM_freeN(vvmap);
01460 
01461     multires_mvert_to_ss(dm, vdst);
01462 }
01463 
01464 /* Copy the first-level vcol data to the mesh, if it exists */
01465 /* Warning: higher-level vcol data will be lost */
01466 static void multires_load_old_vcols(Mesh *me)
01467 {
01468     MultiresLevel *lvl;
01469     MultiresColFace *colface;
01470     MCol *mcol;
01471     int i, j;
01472 
01473     if(!(lvl = me->mr->levels.first))
01474         return;
01475 
01476     if(!(colface = lvl->colfaces))
01477         return;
01478 
01479     /* older multires format never supported multiple vcol layers,
01480        so we can assume the active vcol layer is the correct one */
01481     if(!(mcol = CustomData_get_layer(&me->fdata, CD_MCOL)))
01482         return;
01483     
01484     for(i = 0; i < me->totface; ++i) {
01485         for(j = 0; j < 4; ++j) {
01486             mcol[i*4 + j].a = colface[i].col[j].a;
01487             mcol[i*4 + j].r = colface[i].col[j].r;
01488             mcol[i*4 + j].g = colface[i].col[j].g;
01489             mcol[i*4 + j].b = colface[i].col[j].b;
01490         }
01491     }
01492 }
01493 
01494 /* Copy the first-level face-flag data to the mesh */
01495 static void multires_load_old_face_flags(Mesh *me)
01496 {
01497     MultiresLevel *lvl;
01498     MultiresFace *faces;
01499     int i;
01500 
01501     if(!(lvl = me->mr->levels.first))
01502         return;
01503 
01504     if(!(faces = lvl->faces))
01505         return;
01506 
01507     for(i = 0; i < me->totface; ++i)
01508         me->mface[i].flag = faces[i].flag;
01509 }
01510 
01511 void multires_load_old(Object *ob, Mesh *me)
01512 {
01513     MultiresLevel *lvl;
01514     ModifierData *md;
01515     MultiresModifierData *mmd;
01516     DerivedMesh *dm, *orig;
01517     CustomDataLayer *l;
01518     int i;
01519 
01520     /* Load original level into the mesh */
01521     lvl = me->mr->levels.first;
01522     CustomData_free_layers(&me->vdata, CD_MVERT, lvl->totvert);
01523     CustomData_free_layers(&me->edata, CD_MEDGE, lvl->totedge);
01524     CustomData_free_layers(&me->fdata, CD_MFACE, lvl->totface);
01525     me->totvert = lvl->totvert;
01526     me->totedge = lvl->totedge;
01527     me->totface = lvl->totface;
01528     me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert);
01529     me->medge = CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, me->totedge);
01530     me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface);
01531     memcpy(me->mvert, me->mr->verts, sizeof(MVert) * me->totvert);
01532     for(i = 0; i < me->totedge; ++i) {
01533         me->medge[i].v1 = lvl->edges[i].v[0];
01534         me->medge[i].v2 = lvl->edges[i].v[1];
01535     }
01536     for(i = 0; i < me->totface; ++i) {
01537         me->mface[i].v1 = lvl->faces[i].v[0];
01538         me->mface[i].v2 = lvl->faces[i].v[1];
01539         me->mface[i].v3 = lvl->faces[i].v[2];
01540         me->mface[i].v4 = lvl->faces[i].v[3];
01541         me->mface[i].mat_nr = lvl->faces[i].mat_nr;
01542     }
01543 
01544     /* Add a multires modifier to the object */
01545     md = ob->modifiers.first;
01546     while(md && modifierType_getInfo(md->type)->type == eModifierTypeType_OnlyDeform)
01547         md = md->next;                          
01548     mmd = (MultiresModifierData*)modifier_new(eModifierType_Multires);
01549     BLI_insertlinkbefore(&ob->modifiers, md, mmd);
01550 
01551     for(i = 0; i < me->mr->level_count - 1; ++i)
01552         multiresModifier_subdivide(mmd, ob, 1, 0);
01553 
01554     mmd->lvl = mmd->totlvl;
01555     orig = CDDM_from_mesh(me, NULL);
01556     dm = multires_dm_create_from_derived(mmd, 0, orig, ob, 0, 0);
01557                        
01558     multires_load_old_dm(dm, me, mmd->totlvl+1);
01559 
01560     multires_dm_mark_as_modified(dm);
01561     dm->release(dm);
01562     orig->release(orig);
01563 
01564     /* Copy the first-level data to the mesh */
01565     for(i = 0, l = me->mr->vdata.layers; i < me->mr->vdata.totlayer; ++i, ++l)
01566         CustomData_add_layer(&me->vdata, l->type, CD_REFERENCE, l->data, me->totvert);
01567     for(i = 0, l = me->mr->fdata.layers; i < me->mr->fdata.totlayer; ++i, ++l)
01568         CustomData_add_layer(&me->fdata, l->type, CD_REFERENCE, l->data, me->totface);
01569     memset(&me->mr->vdata, 0, sizeof(CustomData));
01570     memset(&me->mr->fdata, 0, sizeof(CustomData));
01571 
01572     multires_load_old_vcols(me);
01573     multires_load_old_face_flags(me);
01574 
01575     /* Remove the old multires */
01576     multires_free(me->mr);
01577     me->mr= NULL;
01578 }
01579 
01580 static void multires_sync_levels(Scene *scene, Object *ob, Object *to_ob)
01581 {
01582     MultiresModifierData *mmd= get_multires_modifier(scene, ob, 1);
01583     MultiresModifierData *to_mmd= get_multires_modifier(scene, to_ob, 1);
01584 
01585     if(!mmd) {
01586         /* object could have MDISP even when there is no multires modifier
01587            this could lead to troubles due to i've got no idea how mdisp could be
01588            upsampled correct without modifier data.
01589            just remove mdisps if no multires present (nazgul) */
01590 
01591         Mesh *me= (Mesh*)ob->data;
01592 
01593         CustomData_external_remove(&me->fdata, &me->id, CD_MDISPS, me->totface);
01594         CustomData_free_layer_active(&me->fdata, CD_MDISPS, me->totface);
01595     }
01596 
01597     if(!mmd || !to_mmd) return;
01598 
01599     if(mmd->totlvl>to_mmd->totlvl) multires_del_higher(mmd, ob, to_mmd->totlvl);
01600     else multires_subdivide(mmd, ob, to_mmd->totlvl, 0, mmd->simple);
01601 }
01602 
01603 static void multires_apply_smat(Scene *scene, Object *ob, float smat[3][3])
01604 {
01605     DerivedMesh *dm= NULL, *cddm= NULL, *subdm= NULL;
01606     DMGridData **gridData, **subGridData;
01607     Mesh *me= (Mesh*)ob->data;
01608     MFace *mface= me->mface;
01609     MDisps *mdisps;
01610     int *gridOffset;
01611     int i, /*numGrids,*/ gridSize, dGridSize, dSkip, totvert;
01612     float (*vertCos)[3] = NULL;
01613     MultiresModifierData *mmd= get_multires_modifier(scene, ob, 1);
01614     MultiresModifierData high_mmd;
01615 
01616     CustomData_external_read(&me->fdata, &me->id, CD_MASK_MDISPS, me->totface);
01617     mdisps= CustomData_get_layer(&me->fdata, CD_MDISPS);
01618 
01619     if(!mdisps || !mmd || !mmd->totlvl) return;
01620 
01621     /* we need derived mesh created from highest resolution */
01622     high_mmd= *mmd;
01623     high_mmd.lvl= high_mmd.totlvl;
01624 
01625     /* unscaled multires with applied displacement */
01626     subdm= get_multires_dm(scene, &high_mmd, ob);
01627 
01628     /* prepare scaled CDDM to create ccgDN */
01629     cddm= mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
01630 
01631     totvert= cddm->getNumVerts(cddm);
01632     vertCos= MEM_mallocN(sizeof(*vertCos) * totvert, "multiresScale vertCos");
01633     cddm->getVertCos(cddm, vertCos);
01634     for(i=0; i<totvert; i++)
01635         mul_m3_v3(smat, vertCos[i]);
01636     CDDM_apply_vert_coords(cddm, vertCos);
01637     MEM_freeN(vertCos);
01638 
01639     /* scaled ccgDM for tangent space of object with applied scale */
01640     dm= subsurf_dm_create_local(ob, cddm, high_mmd.totlvl, high_mmd.simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv);
01641     cddm->release(cddm);
01642 
01643     /*numGrids= dm->getNumGrids(dm);*/ /*UNUSED*/
01644     gridSize= dm->getGridSize(dm);
01645     gridData= dm->getGridData(dm);
01646     gridOffset= dm->getGridOffset(dm);
01647     subGridData= subdm->getGridData(subdm);
01648 
01649     dGridSize= multires_side_tot[high_mmd.totlvl];
01650     dSkip= (dGridSize-1)/(gridSize-1);
01651 
01652     #pragma omp parallel for private(i) if(me->totface*gridSize*gridSize*4 >= CCG_OMP_LIMIT)
01653     for(i = 0; i < me->totface; ++i) {
01654         const int numVerts= mface[i].v4 ? 4 : 3;
01655         MDisps *mdisp= &mdisps[i];
01656         int S, x, y, gIndex = gridOffset[i];
01657 
01658         for(S = 0; S < numVerts; ++S, ++gIndex) {
01659             DMGridData *grid= gridData[gIndex];
01660             DMGridData *subgrid= subGridData[gIndex];
01661             float (*dispgrid)[3]= &mdisp->disps[S*dGridSize*dGridSize];
01662 
01663             for(y = 0; y < gridSize; y++) {
01664                 for(x = 0; x < gridSize; x++) {
01665                     float *co= grid[x + y*gridSize].co;
01666                     float *sco= subgrid[x + y*gridSize].co;
01667                     float *no= grid[x + y*gridSize].no;
01668                     float *data= dispgrid[dGridSize*y*dSkip + x*dSkip];
01669                     float mat[3][3], tx[3], ty[3], disp[3];
01670 
01671                     /* construct tangent space matrix */
01672                     grid_tangent(gridSize, gIndex, x, y, 0, gridData, tx);
01673                     normalize_v3(tx);
01674 
01675                     grid_tangent(gridSize, gIndex, x, y, 1, gridData, ty);
01676                     normalize_v3(ty);
01677 
01678                     column_vectors_to_mat3(mat, tx, ty, no);
01679 
01680                     /* scale subgrid coord and calculate displacement */
01681                     mul_m3_v3(smat, sco);
01682                     sub_v3_v3v3(disp, sco, co);
01683 
01684                     /* convert difference to tangent space */
01685                     invert_m3(mat);
01686                     mul_v3_m3v3(data, mat, disp);
01687                 }
01688             }
01689         }
01690     }
01691 
01692     dm->release(dm);
01693     subdm->release(subdm);
01694 }
01695 
01696 int multires_mdisp_corners(MDisps *s)
01697 {
01698     int lvl= 13;
01699 
01700     while(lvl > 0) {
01701         int side = (1 << (lvl-1)) + 1;
01702         if ((s->totdisp % (side*side)) == 0) return s->totdisp / (side*side);
01703         lvl--;
01704     }
01705 
01706     return 0;
01707 }
01708 
01709 void multiresModifier_scale_disp(Scene *scene, Object *ob)
01710 {
01711     float smat[3][3];
01712 
01713     /* object's scale matrix */
01714     object_scale_to_mat3(ob, smat);
01715 
01716     multires_apply_smat(scene, ob, smat);
01717 }
01718 
01719 void multiresModifier_prepare_join(Scene *scene, Object *ob, Object *to_ob)
01720 {
01721     float smat[3][3], tmat[3][3], mat[3][3];
01722     multires_sync_levels(scene, ob, to_ob);
01723 
01724     /* construct scale matrix for displacement */
01725     object_scale_to_mat3(to_ob, tmat);
01726     invert_m3(tmat);
01727     object_scale_to_mat3(ob, smat);
01728     mul_m3_m3m3(mat, smat, tmat);
01729 
01730     multires_apply_smat(scene, ob, mat);
01731 }
01732 
01733 /* update multires data after topology changing */
01734 void multires_topology_changed(Scene *scene, Object *ob)
01735 {
01736     Mesh *me= (Mesh*)ob->data;
01737     MDisps *mdisp= NULL, *cur= NULL;
01738     int i, grid= 0, corners;
01739     MultiresModifierData *mmd= get_multires_modifier(scene, ob, 1);
01740 
01741     if(mmd)
01742         multires_set_tot_mdisps(me, mmd->totlvl);
01743 
01744     CustomData_external_read(&me->fdata, &me->id, CD_MASK_MDISPS, me->totface);
01745     mdisp= CustomData_get_layer(&me->fdata, CD_MDISPS);
01746 
01747     if(!mdisp) return;
01748 
01749     cur= mdisp;
01750     for(i = 0; i < me->totface; i++, cur++) {
01751         if(mdisp->totdisp) {
01752             corners= multires_mdisp_corners(mdisp);
01753             grid= mdisp->totdisp / corners;
01754 
01755             break;
01756         }
01757     }
01758 
01759     for(i = 0; i < me->totface; i++, mdisp++) {
01760         int nvert= me->mface[i].v4 ? 4 : 3;
01761 
01762         /* allocate memory for mdisp, the whole disp layer would be erased otherwise */
01763         if(!mdisp->totdisp || !mdisp->disps) {
01764             if(grid) {
01765                 mdisp->totdisp= nvert*grid;
01766                 mdisp->disps= MEM_callocN(mdisp->totdisp*sizeof(float)*3, "mdisp topology");
01767             }
01768 
01769             continue;
01770         }
01771 
01772         corners= multires_mdisp_corners(mdisp);
01773 
01774         if(corners!=nvert) {
01775             mdisp->totdisp= (mdisp->totdisp/corners)*nvert;
01776 
01777             if(mdisp->disps)
01778                 MEM_freeN(mdisp->disps);
01779 
01780             mdisp->disps= MEM_callocN(mdisp->totdisp*sizeof(float)*3, "mdisp topology");
01781         }
01782     }
01783 }
01784 
01785 /* makes displacement along grid boundary symmetrical */
01786 void multires_mdisp_smooth_bounds(MDisps *disps)
01787 {
01788     int x, y, side, S, corners;
01789     float (*out)[3];
01790 
01791     corners = multires_mdisp_corners(disps);
01792     side = sqrt(disps->totdisp / corners);
01793 
01794     out = disps->disps;
01795     for(S = 0; S < corners; S++) {
01796         for(y = 0; y < side; ++y) {
01797             for(x = 0; x < side; ++x, ++out) {
01798                 float (*dispgrid)[3];
01799                 float *data;
01800 
01801                 if(x != 0 && y != 0) continue;
01802 
01803                 if(corners == 4) {
01804                     if(S == 0) {
01805                         if(y == 0) {
01806                             dispgrid = &disps->disps[1*side*side];
01807                             data = dispgrid[side * x + 0];
01808 
01809                             (*out)[0] = (*out)[0] + data[1];
01810                             (*out)[1] = (*out)[1] - data[0];
01811                             (*out)[2] = (*out)[2] + data[2];
01812 
01813                             mul_v3_fl(*out, 0.5);
01814 
01815                             data[0] = -(*out)[1];
01816                             data[1] = (*out)[0];
01817                             data[2] = (*out)[2];
01818                         } else if (x == 0) {
01819                             dispgrid = &disps->disps[3 * side * side];
01820                             data = dispgrid[side * 0 + y];
01821 
01822                             (*out)[0] = (*out)[0] - data[1];
01823                             (*out)[1] = (*out)[1] + data[0];
01824                             (*out)[2] = (*out)[2] + data[2];
01825 
01826                             mul_v3_fl(*out, 0.5);
01827 
01828                             data[0] = (*out)[1];
01829                             data[1] = -(*out)[0];
01830                             data[2] = (*out)[2];
01831                         }
01832                     } else if (S == 2) {
01833                         if(y == 0) {
01834                             dispgrid = &disps->disps[3 * side * side];
01835                             data = dispgrid[side * x + 0];
01836 
01837                             (*out)[0] = (*out)[0] + data[1];
01838                             (*out)[1] = (*out)[1] - data[0];
01839                             (*out)[2] = (*out)[2] + data[2];
01840 
01841                             mul_v3_fl(*out, 0.5);
01842 
01843                             data[0] = -(*out)[1];
01844                             data[1] = (*out)[0];
01845                             data[2] = (*out)[2];
01846                         } else if(x == 0) {
01847                             dispgrid = &disps->disps[1 * side * side];
01848                             data = dispgrid[side * 0 + y];
01849 
01850                             (*out)[0] = (*out)[0] - data[1];
01851                             (*out)[1] = (*out)[1] + data[0];
01852                             (*out)[2] = (*out)[2] + data[2];
01853 
01854                             mul_v3_fl(*out, 0.5);
01855 
01856                             data[0] = (*out)[1];
01857                             data[1] = -(*out)[0];
01858                             data[2] = (*out)[2];
01859                         }
01860                     }
01861                 } else if (corners == 3) {
01862                     if(S == 0) {
01863                         if(y == 0) {
01864                             dispgrid = &disps->disps[1*side*side];
01865                             data = dispgrid[side * x + 0];
01866 
01867                             (*out)[0] = (*out)[0] + data[1];
01868                             (*out)[1] = (*out)[1] - data[0];
01869                             (*out)[2] = (*out)[2] + data[2];
01870 
01871                             mul_v3_fl(*out, 0.5);
01872 
01873                             data[0] = -(*out)[1];
01874                             data[1] = (*out)[0];
01875                             data[2] = (*out)[2];
01876                         } else if (x == 0) {
01877                             dispgrid = &disps->disps[2 * side * side];
01878                             data = dispgrid[side * 0 + y];
01879 
01880                             (*out)[0] = (*out)[0] - data[1];
01881                             (*out)[1] = (*out)[1] + data[0];
01882                             (*out)[2] = (*out)[2] + data[2];
01883 
01884                             mul_v3_fl(*out, 0.5);
01885 
01886                             data[0] = (*out)[1];
01887                             data[1] = -(*out)[0];
01888                             data[2] = (*out)[2];
01889                         }
01890                     } else if (S == 2) {
01891                         if(x == 0) {
01892                             dispgrid = &disps->disps[1 * side * side];
01893                             data = dispgrid[side * 0 + y];
01894 
01895                             (*out)[0] = (*out)[0] - data[1];
01896                             (*out)[1] = (*out)[1] + data[0];
01897                             (*out)[2] = (*out)[2] + data[2];
01898 
01899                             mul_v3_fl(*out, 0.5);
01900 
01901                             data[0] = (*out)[1];
01902                             data[1] = -(*out)[0];
01903                             data[2] = (*out)[2];
01904                         }
01905                     }
01906                 }
01907             }
01908         }
01909     }
01910 }
01911 
01912 /***************** Multires interpolation stuff *****************/
01913 
01914 static void mdisp_get_crn_rect(int face_side, float crn[3][4][2])
01915 {
01916     float offset = face_side*0.5f - 0.5f;
01917     float mid[2];
01918 
01919     mid[0] = offset * 4 / 3;
01920     mid[1] = offset * 2 / 3;
01921 
01922     crn[0][0][0] = mid[0]; crn[0][0][1] = mid[1];
01923     crn[0][1][0] = offset; crn[0][1][1] = 0;
01924     crn[0][2][0] = 0; crn[0][2][1] = 0;
01925     crn[0][3][0] = offset; crn[0][3][1] = offset;
01926 
01927     crn[1][0][0] = mid[0]; crn[1][0][1] = mid[1];
01928     crn[1][1][0] = offset * 2; crn[1][1][1] = offset;
01929     crn[1][2][0] = offset * 2; crn[1][2][1] = 0;
01930     crn[1][3][0] = offset; crn[1][3][1] = 0;
01931 
01932     crn[2][0][0] = mid[0]; crn[2][0][1] = mid[1];
01933     crn[2][1][0] = offset; crn[2][1][1] = offset;
01934     crn[2][2][0] = offset * 2; crn[2][2][1] = offset * 2;
01935     crn[2][3][0] = offset * 2; crn[2][3][1] = offset;
01936 }
01937 
01938 static int mdisp_pt_in_crn(float p[2], float crn[4][2])
01939 {
01940     float v[2][2];
01941     float a[2][2];
01942 
01943     sub_v2_v2v2(v[0], crn[1], crn[0]);
01944     sub_v2_v2v2(v[1], crn[3], crn[0]);
01945 
01946     sub_v2_v2v2(a[0], p, crn[0]);
01947     sub_v2_v2v2(a[1], crn[2], crn[0]);
01948 
01949     if(cross_v2v2(a[0], v[0]) * cross_v2v2(a[1], v[0]) < 0)
01950         return 0;
01951 
01952     if(cross_v2v2(a[0], v[1]) * cross_v2v2(a[1], v[1]) < 0)
01953         return 0;
01954 
01955     return 1;
01956 }
01957 
01958 static void face_to_crn_interp(float u, float v, float v1[2], float v2[2], float v3[2], float v4[2], float *x)
01959 {
01960     float a = (v4[1]-v3[1])*v2[0]+(-v4[1]+v3[1])*v1[0]+(-v2[1]+v1[1])*v4[0]+(v2[1]-v1[1])*v3[0];
01961     float b = (v3[1]-v)*v2[0]+(v4[1]-2*v3[1]+v)*v1[0]+(-v4[1]+v3[1]+v2[1]-v1[1])*u+(v4[0]-v3[0])*v-v1[1]*v4[0]+(-v2[1]+2*v1[1])*v3[0];
01962     float c = (v3[1]-v)*v1[0]+(-v3[1]+v1[1])*u+v3[0]*v-v1[1]*v3[0];
01963     float d = b * b - 4 * a * c;
01964     float x1, x2;
01965 
01966     if(a == 0) {
01967         *x = -c / b;
01968         return;
01969     }
01970 
01971     x1 = (-b - sqrtf(d)) / (2 * a);
01972     x2 = (-b + sqrtf(d)) / (2 * a);
01973 
01974     *x = maxf(x1, x2);
01975 }
01976 
01977 void mdisp_rot_crn_to_face(const int S, const int corners, const int face_side, const float x, const float y, float *u, float *v)
01978 {
01979     float offset = face_side*0.5f - 0.5f;
01980 
01981     if(corners == 4) {
01982         if(S == 1) { *u= offset + x; *v = offset - y; }
01983         if(S == 2) { *u= offset + y; *v = offset + x; }
01984         if(S == 3) { *u= offset - x; *v = offset + y; }
01985         if(S == 0) { *u= offset - y; *v = offset - x; }
01986     } else {
01987         float crn[3][4][2], vec[4][2];
01988         float p[2];
01989 
01990         mdisp_get_crn_rect(face_side, crn);
01991 
01992         interp_v2_v2v2(vec[0], crn[S][0], crn[S][1], x / offset);
01993         interp_v2_v2v2(vec[1], crn[S][3], crn[S][2], x / offset);
01994         interp_v2_v2v2(vec[2], crn[S][0], crn[S][3], y / offset);
01995         interp_v2_v2v2(vec[3], crn[S][1], crn[S][2], y / offset);
01996 
01997         isect_seg_seg_v2_point(vec[0], vec[1], vec[2], vec[3], p);
01998 
01999         (*u) = p[0];
02000         (*v) = p[1];
02001     }
02002 }
02003 
02004 /* Find per-corner coordinate with given per-face UV coord */
02005 int mdisp_rot_face_to_crn(const int corners, const int face_side, const float u, const float v, float *x, float *y)
02006 {
02007     const float offset = face_side*0.5f - 0.5f;
02008     int S = 0;
02009 
02010     if (corners == 4) {
02011         if(u <= offset && v <= offset) S = 0;
02012         else if(u > offset  && v <= offset) S = 1;
02013         else if(u > offset  && v > offset) S = 2;
02014         else if(u <= offset && v >= offset)  S = 3;
02015 
02016         if(S == 0) {
02017             *y = offset - u;
02018             *x = offset - v;
02019         } else if(S == 1) {
02020             *x = u - offset;
02021             *y = offset - v;
02022         } else if(S == 2) {
02023             *y = u - offset;
02024             *x = v - offset;
02025         } else if(S == 3) {
02026             *x= offset - u;
02027             *y = v - offset;
02028         }
02029     } else {
02030         int grid_size = offset;
02031         float w = (face_side - 1) - u - v;
02032         float W1, W2;
02033 
02034         if (u >= v && u >= w) {S = 0; W1= w; W2= v;}
02035         else if (v >= u && v >= w) {S = 1; W1 = u; W2 = w;}
02036         else {S = 2; W1 = v; W2 = u;}
02037 
02038         W1 /= (face_side-1);
02039         W2 /= (face_side-1);
02040 
02041         *x = (1-(2*W1)/(1-W2)) * grid_size;
02042         *y = (1-(2*W2)/(1-W1)) * grid_size;
02043     }
02044 
02045     return S;
02046 }
02047 
02048 /* Find per-corner coordinate with given per-face UV coord
02049    Practically as the previous funciton but it assumes a bit different coordinate system for triangles
02050    which is optimized for MDISP layer interpolation:
02051 
02052    v
02053    ^
02054    |      /|
02055    |    /  |
02056    |  /    |
02057    |/______|___> u
02058 
02059  */
02060 int mdisp_rot_face_to_quad_crn(const int corners, const int face_side, const float u, const float v, float *x, float *y)
02061 {
02062     const float offset = face_side*0.5f - 0.5f;
02063     int S = 0;
02064 
02065     if (corners == 4) {
02066         if(u <= offset && v <= offset) S = 0;
02067         else if(u > offset  && v <= offset) S = 1;
02068         else if(u > offset  && v > offset) S = 2;
02069         else if(u <= offset && v >= offset)  S = 3;
02070 
02071         if(S == 0) {
02072             *y = offset - u;
02073             *x = offset - v;
02074         } else if(S == 1) {
02075             *x = u - offset;
02076             *y = offset - v;
02077         } else if(S == 2) {
02078             *y = u - offset;
02079             *x = v - offset;
02080         } else if(S == 3) {
02081             *x= offset - u;
02082             *y = v - offset;
02083         }
02084     } else {
02085         float crn[3][4][2];
02086         float p[2] = {u, v};
02087 
02088         mdisp_get_crn_rect(face_side, crn);
02089 
02090         for (S = 0; S < 3; ++S) {
02091             if (mdisp_pt_in_crn(p, crn[S]))
02092                 break;
02093         }
02094 
02095         face_to_crn_interp(u, v, crn[S][0], crn[S][1], crn[S][3], crn[S][2], &p[0]);
02096         face_to_crn_interp(u, v, crn[S][0], crn[S][3], crn[S][1], crn[S][2], &p[1]);
02097 
02098         *x = p[0] * offset;
02099         *y = p[1] * offset;
02100     }
02101 
02102     return S;
02103 }
02104 
02105 void mdisp_apply_weight(const int S, const int corners, int x, int y, const int face_side,
02106     float crn_weight[4][2], float *u_r, float *v_r)
02107 {
02108     float u, v, xl, yl;
02109     float mid1[2], mid2[2], mid3[2];
02110 
02111     mdisp_rot_crn_to_face(S, corners, face_side, x, y, &u, &v);
02112 
02113     if(corners == 4) {
02114         xl = u / (face_side - 1);
02115         yl = v / (face_side - 1);
02116 
02117         mid1[0] = crn_weight[0][0] * (1 - xl) + crn_weight[1][0] * xl;
02118         mid1[1] = crn_weight[0][1] * (1 - xl) + crn_weight[1][1] * xl;
02119         mid2[0] = crn_weight[3][0] * (1 - xl) + crn_weight[2][0] * xl;
02120         mid2[1] = crn_weight[3][1] * (1 - xl) + crn_weight[2][1] * xl;
02121         mid3[0] = mid1[0] * (1 - yl) + mid2[0] * yl;
02122         mid3[1] = mid1[1] * (1 - yl) + mid2[1] * yl;
02123     } else {
02124         yl = v / (face_side - 1);
02125 
02126         if(v == face_side - 1) xl = 1;
02127         else xl = 1 - (face_side - 1 - u) / (face_side - 1 - v);
02128 
02129         mid1[0] = crn_weight[0][0] * (1 - xl) + crn_weight[1][0] * xl;
02130         mid1[1] = crn_weight[0][1] * (1 - xl) + crn_weight[1][1] * xl;
02131         mid3[0] = mid1[0] * (1 - yl) + crn_weight[2][0] * yl;
02132         mid3[1] = mid1[1] * (1 - yl) + crn_weight[2][1] * yl;
02133     }
02134 
02135     *u_r = mid3[0];
02136     *v_r = mid3[1];
02137 }
02138 
02139 void mdisp_flip_disp(const int S, const int corners, const float axis_x[2], const float axis_y[2], float disp[3])
02140 {
02141     float crn_x[2], crn_y[2];
02142     float vx[2], vy[2], coord[2];
02143 
02144     if (corners == 4) {
02145         float x[4][2] = {{0, -1}, {1, 0}, {0, 1}, {-1, 0}};
02146         float y[4][2] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
02147 
02148         copy_v2_v2(crn_x, x[S]);
02149         copy_v2_v2(crn_y, y[S]);
02150 
02151         mul_v2_v2fl(vx, crn_x, disp[0]);
02152         mul_v2_v2fl(vy, crn_y, disp[1]);
02153         add_v2_v2v2(coord, vx, vy);
02154 
02155         project_v2_v2v2(vx, coord, axis_x);
02156         project_v2_v2v2(vy, coord, axis_y);
02157 
02158         disp[0] = len_v2(vx);
02159         disp[1] = len_v2(vy);
02160 
02161         if(dot_v2v2(vx, axis_x) < 0)
02162             disp[0] = -disp[0];
02163 
02164         if(dot_v2v2(vy, axis_y) < 0)
02165             disp[1] = -disp[1];
02166     } else {
02167         /* XXX: it was very overhead code to support displacement flipping
02168                 for case of tris without visible profit.
02169                 Maybe its not really big limitation? for now? (nazgul) */
02170         disp[0] = 0;
02171         disp[1] = 0;
02172     }
02173 }
02174 
02175 /* Join two triangular displacements into one quad
02176      Corners mapping:
02177      2 -------- 3
02178      | \   tri2 |
02179      |    \     |
02180      | tri1  \  |
02181      0 -------- 1 */
02182 void mdisp_join_tris(MDisps *dst, MDisps *tri1, MDisps *tri2)
02183 {
02184     int side, st;
02185     int S, x, y, crn;
02186     float face_u, face_v, crn_u, crn_v;
02187     float (*out)[3];
02188     MDisps *src;
02189 
02190     if(dst->disps)
02191         MEM_freeN(dst->disps);
02192 
02193     side = sqrt(tri1->totdisp / 3);
02194     st = (side<<1)-1;
02195 
02196     dst->totdisp = 4 * side * side;
02197     out = dst->disps = MEM_callocN(3*dst->totdisp*sizeof(float), "join disps");
02198 
02199     for(S = 0; S < 4; S++)
02200         for(y = 0; y < side; ++y)
02201             for(x = 0; x < side; ++x, ++out) {
02202                 mdisp_rot_crn_to_face(S, 4, st, x, y, &face_u, &face_v);
02203                 face_u = st - 1 - face_u;
02204 
02205                 if(face_v > face_u) {
02206                     src = tri2;
02207                     face_u = st - 1 - face_u;
02208                     face_v = st - 1 - face_v;
02209                 } else src = tri1;
02210 
02211                 crn = mdisp_rot_face_to_quad_crn(3, st, face_u, face_v, &crn_u, &crn_v);
02212 
02213                 old_mdisps_bilinear((*out), &src->disps[crn*side*side], side, crn_u, crn_v);
02214                 (*out)[0] = 0;
02215                 (*out)[1] = 0;
02216             }
02217 }