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