1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 *
16 * The Original Code is Copyright (C) 2007 by Nicholas Bishop
17 * All rights reserved.
18 */
19
20 /** \file
21 * \ingroup bke
22 */
23
24 #include "MEM_guardedalloc.h"
25
26 /* for reading old multires */
27 #define DNA_DEPRECATED_ALLOW
28
29 #include "DNA_mesh_types.h"
30 #include "DNA_meshdata_types.h"
31 #include "DNA_object_types.h"
32 #include "DNA_scene_types.h"
33
34 #include "BLI_bitmap.h"
35 #include "BLI_blenlib.h"
36 #include "BLI_math.h"
37 #include "BLI_task.h"
38 #include "BLI_utildefines.h"
39
40 #include "BKE_ccg.h"
41 #include "BKE_cdderivedmesh.h"
42 #include "BKE_editmesh.h"
43 #include "BKE_mesh.h"
44 #include "BKE_mesh_mapping.h"
45 #include "BKE_mesh_runtime.h"
46 #include "BKE_modifier.h"
47 #include "BKE_multires.h"
48 #include "BKE_paint.h"
49 #include "BKE_pbvh.h"
50 #include "BKE_scene.h"
51 #include "BKE_subdiv_ccg.h"
52 #include "BKE_subsurf.h"
53
54 #include "BKE_object.h"
55
56 #include "CCGSubSurf.h"
57
58 #include "DEG_depsgraph_query.h"
59
60 #include "multires_reshape.h"
61
62 #include <math.h>
63 #include <string.h>
64
65 /* MULTIRES MODIFIER */
66 static const int multires_max_levels = 13;
67 static const int multires_grid_tot[] = {
68 0, 4, 9, 25, 81, 289, 1089, 4225, 16641, 66049, 263169, 1050625, 4198401, 16785409};
69 static const int multires_side_tot[] = {
70 0, 2, 3, 5, 9, 17, 33, 65, 129, 257, 513, 1025, 2049, 4097};
71
72 /* See multiresModifier_disp_run for description of each operation */
73 typedef enum {
74 APPLY_DISPLACEMENTS,
75 CALC_DISPLACEMENTS,
76 ADD_DISPLACEMENTS,
77 } DispOp;
78
79 static void multires_mvert_to_ss(DerivedMesh *dm, MVert *mvert);
80 static void multiresModifier_disp_run(
81 DerivedMesh *dm, Mesh *me, DerivedMesh *dm2, DispOp op, CCGElem **oldGridData, int totlvl);
82
83 /** Customdata */
84
multires_customdata_delete(Mesh * me)85 void multires_customdata_delete(Mesh *me)
86 {
87 if (me->edit_mesh) {
88 BMEditMesh *em = me->edit_mesh;
89 /* CustomData_external_remove is used here only to mark layer
90 * as non-external for further free-ing, so zero element count
91 * looks safer than em->totface */
92 CustomData_external_remove(&em->bm->ldata, &me->id, CD_MDISPS, 0);
93
94 if (CustomData_has_layer(&em->bm->ldata, CD_MDISPS)) {
95 BM_data_layer_free(em->bm, &em->bm->ldata, CD_MDISPS);
96 }
97
98 if (CustomData_has_layer(&em->bm->ldata, CD_GRID_PAINT_MASK)) {
99 BM_data_layer_free(em->bm, &em->bm->ldata, CD_GRID_PAINT_MASK);
100 }
101 }
102 else {
103 CustomData_external_remove(&me->ldata, &me->id, CD_MDISPS, me->totloop);
104 CustomData_free_layer_active(&me->ldata, CD_MDISPS, me->totloop);
105
106 CustomData_free_layer_active(&me->ldata, CD_GRID_PAINT_MASK, me->totloop);
107 }
108 }
109
110 /** Grid hiding */
multires_mdisps_upsample_hidden(BLI_bitmap * lo_hidden,int lo_level,int hi_level,const BLI_bitmap * prev_hidden)111 static BLI_bitmap *multires_mdisps_upsample_hidden(BLI_bitmap *lo_hidden,
112 int lo_level,
113 int hi_level,
114
115 /* assumed to be at hi_level (or null) */
116 const BLI_bitmap *prev_hidden)
117 {
118 BLI_bitmap *subd;
119 int hi_gridsize = BKE_ccg_gridsize(hi_level);
120 int lo_gridsize = BKE_ccg_gridsize(lo_level);
121 int yh, xh, xl, yl, xo, yo, hi_ndx;
122 int offset, factor;
123
124 BLI_assert(lo_level <= hi_level);
125
126 /* fast case */
127 if (lo_level == hi_level) {
128 return MEM_dupallocN(lo_hidden);
129 }
130
131 subd = BLI_BITMAP_NEW(square_i(hi_gridsize), "MDisps.hidden upsample");
132
133 factor = BKE_ccg_factor(lo_level, hi_level);
134 offset = 1 << (hi_level - lo_level - 1);
135
136 /* low-res blocks */
137 for (yl = 0; yl < lo_gridsize; yl++) {
138 for (xl = 0; xl < lo_gridsize; xl++) {
139 int lo_val = BLI_BITMAP_TEST(lo_hidden, yl * lo_gridsize + xl);
140
141 /* high-res blocks */
142 for (yo = -offset; yo <= offset; yo++) {
143 yh = yl * factor + yo;
144 if (yh < 0 || yh >= hi_gridsize) {
145 continue;
146 }
147
148 for (xo = -offset; xo <= offset; xo++) {
149 xh = xl * factor + xo;
150 if (xh < 0 || xh >= hi_gridsize) {
151 continue;
152 }
153
154 hi_ndx = yh * hi_gridsize + xh;
155
156 if (prev_hidden) {
157 /* If prev_hidden is available, copy it to
158 * subd, except when the equivalent element in
159 * lo_hidden is different */
160 if (lo_val != prev_hidden[hi_ndx]) {
161 BLI_BITMAP_SET(subd, hi_ndx, lo_val);
162 }
163 else {
164 BLI_BITMAP_SET(subd, hi_ndx, prev_hidden[hi_ndx]);
165 }
166 }
167 else {
168 BLI_BITMAP_SET(subd, hi_ndx, lo_val);
169 }
170 }
171 }
172 }
173 }
174
175 return subd;
176 }
177
multires_mdisps_downsample_hidden(const BLI_bitmap * old_hidden,int old_level,int new_level)178 static BLI_bitmap *multires_mdisps_downsample_hidden(const BLI_bitmap *old_hidden,
179 int old_level,
180 int new_level)
181 {
182 BLI_bitmap *new_hidden;
183 int new_gridsize = BKE_ccg_gridsize(new_level);
184 int old_gridsize = BKE_ccg_gridsize(old_level);
185 int x, y, factor, old_value;
186
187 BLI_assert(new_level <= old_level);
188 factor = BKE_ccg_factor(new_level, old_level);
189 new_hidden = BLI_BITMAP_NEW(square_i(new_gridsize), "downsample hidden");
190
191 for (y = 0; y < new_gridsize; y++) {
192 for (x = 0; x < new_gridsize; x++) {
193 old_value = BLI_BITMAP_TEST(old_hidden, factor * y * old_gridsize + x * factor);
194
195 BLI_BITMAP_SET(new_hidden, y * new_gridsize + x, old_value);
196 }
197 }
198
199 return new_hidden;
200 }
201
multires_output_hidden_to_ccgdm(CCGDerivedMesh * ccgdm,Mesh * me,int level)202 static void multires_output_hidden_to_ccgdm(CCGDerivedMesh *ccgdm, Mesh *me, int level)
203 {
204 const MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
205 BLI_bitmap **grid_hidden = ccgdm->gridHidden;
206 int *gridOffset;
207 int i, j;
208
209 gridOffset = ccgdm->dm.getGridOffset(&ccgdm->dm);
210
211 for (i = 0; i < me->totpoly; i++) {
212 for (j = 0; j < me->mpoly[i].totloop; j++) {
213 int g = gridOffset[i] + j;
214 const MDisps *md = &mdisps[g];
215 BLI_bitmap *gh = md->hidden;
216
217 if (gh) {
218 grid_hidden[g] = multires_mdisps_downsample_hidden(gh, md->level, level);
219 }
220 }
221 }
222 }
223
224 /* subdivide mdisps.hidden if needed (assumes that md.level reflects
225 * the current level of md.hidden) */
multires_mdisps_subdivide_hidden(MDisps * md,int new_level)226 static void multires_mdisps_subdivide_hidden(MDisps *md, int new_level)
227 {
228 BLI_bitmap *subd;
229
230 BLI_assert(md->hidden);
231
232 /* nothing to do if already subdivided enough */
233 if (md->level >= new_level) {
234 return;
235 }
236
237 subd = multires_mdisps_upsample_hidden(md->hidden, md->level, new_level, NULL);
238
239 /* swap in the subdivided data */
240 MEM_freeN(md->hidden);
241 md->hidden = subd;
242 }
243
multires_mdisps_init_hidden(Mesh * me,int level)244 static MDisps *multires_mdisps_init_hidden(Mesh *me, int level)
245 {
246 MDisps *mdisps = CustomData_add_layer(&me->ldata, CD_MDISPS, CD_CALLOC, NULL, me->totloop);
247 int gridsize = BKE_ccg_gridsize(level);
248 int gridarea = square_i(gridsize);
249 int i, j;
250
251 for (i = 0; i < me->totpoly; i++) {
252 bool hide = false;
253
254 for (j = 0; j < me->mpoly[i].totloop; j++) {
255 if (me->mvert[me->mloop[me->mpoly[i].loopstart + j].v].flag & ME_HIDE) {
256 hide = true;
257 break;
258 }
259 }
260
261 if (!hide) {
262 continue;
263 }
264
265 for (j = 0; j < me->mpoly[i].totloop; j++) {
266 MDisps *md = &mdisps[me->mpoly[i].loopstart + j];
267
268 BLI_assert(!md->hidden);
269
270 md->hidden = BLI_BITMAP_NEW(gridarea, "MDisps.hidden initialize");
271 BLI_bitmap_set_all(md->hidden, true, gridarea);
272 }
273 }
274
275 return mdisps;
276 }
277
BKE_multires_create_mesh(struct Depsgraph * depsgraph,Object * object,MultiresModifierData * mmd)278 Mesh *BKE_multires_create_mesh(struct Depsgraph *depsgraph,
279 Object *object,
280 MultiresModifierData *mmd)
281 {
282 Object *object_eval = DEG_get_evaluated_object(depsgraph, object);
283 Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
284 Mesh *deformed_mesh = mesh_get_eval_deform(
285 depsgraph, scene_eval, object_eval, &CD_MASK_BAREMESH);
286 ModifierEvalContext modifier_ctx = {
287 .depsgraph = depsgraph,
288 .object = object_eval,
289 .flag = MOD_APPLY_USECACHE | MOD_APPLY_IGNORE_SIMPLIFY,
290 };
291
292 const ModifierTypeInfo *mti = BKE_modifier_get_info(mmd->modifier.type);
293 Mesh *result = mti->modifyMesh(&mmd->modifier, &modifier_ctx, deformed_mesh);
294
295 if (result == deformed_mesh) {
296 result = BKE_mesh_copy_for_eval(deformed_mesh, true);
297 }
298 return result;
299 }
300
BKE_multires_create_deformed_base_mesh_vert_coords(struct Depsgraph * depsgraph,struct Object * object,struct MultiresModifierData * mmd,int * r_num_deformed_verts)301 float (*BKE_multires_create_deformed_base_mesh_vert_coords(struct Depsgraph *depsgraph,
302 struct Object *object,
303 struct MultiresModifierData *mmd,
304 int *r_num_deformed_verts))[3]
305 {
306 Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
307 Object *object_eval = DEG_get_evaluated_object(depsgraph, object);
308
309 Object object_for_eval = *object_eval;
310 object_for_eval.data = object->data;
311 object_for_eval.sculpt = NULL;
312
313 const bool use_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
314 ModifierEvalContext mesh_eval_context = {depsgraph, &object_for_eval, 0};
315 if (use_render) {
316 mesh_eval_context.flag |= MOD_APPLY_RENDER;
317 }
318 const int required_mode = use_render ? eModifierMode_Render : eModifierMode_Realtime;
319
320 VirtualModifierData virtual_modifier_data;
321 ModifierData *first_md = BKE_modifiers_get_virtual_modifierlist(&object_for_eval,
322 &virtual_modifier_data);
323
324 Mesh *base_mesh = object->data;
325
326 int num_deformed_verts;
327 float(*deformed_verts)[3] = BKE_mesh_vert_coords_alloc(base_mesh, &num_deformed_verts);
328
329 for (ModifierData *md = first_md; md != NULL; md = md->next) {
330 const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
331
332 if (md == &mmd->modifier) {
333 break;
334 }
335
336 if (!BKE_modifier_is_enabled(scene_eval, md, required_mode)) {
337 continue;
338 }
339
340 if (mti->type != eModifierTypeType_OnlyDeform) {
341 break;
342 }
343
344 BKE_modifier_deform_verts(
345 md, &mesh_eval_context, base_mesh, deformed_verts, num_deformed_verts);
346 }
347
348 if (r_num_deformed_verts != NULL) {
349 *r_num_deformed_verts = num_deformed_verts;
350 }
351 return deformed_verts;
352 }
353
find_multires_modifier_before(Scene * scene,ModifierData * lastmd)354 MultiresModifierData *find_multires_modifier_before(Scene *scene, ModifierData *lastmd)
355 {
356 ModifierData *md;
357
358 for (md = lastmd; md; md = md->prev) {
359 if (md->type == eModifierType_Multires) {
360 if (BKE_modifier_is_enabled(scene, md, eModifierMode_Realtime)) {
361 return (MultiresModifierData *)md;
362 }
363 }
364 }
365
366 return NULL;
367 }
368
369 /* used for applying scale on mdisps layer and syncing subdivide levels when joining objects
370 * use_first - return first multires modifier if all multires'es are disabled
371 */
get_multires_modifier(Scene * scene,Object * ob,bool use_first)372 MultiresModifierData *get_multires_modifier(Scene *scene, Object *ob, bool use_first)
373 {
374 ModifierData *md;
375 MultiresModifierData *mmd = NULL, *firstmmd = NULL;
376
377 /* find first active multires modifier */
378 for (md = ob->modifiers.first; md; md = md->next) {
379 if (md->type == eModifierType_Multires) {
380 if (!firstmmd) {
381 firstmmd = (MultiresModifierData *)md;
382 }
383
384 if (BKE_modifier_is_enabled(scene, md, eModifierMode_Realtime)) {
385 mmd = (MultiresModifierData *)md;
386 break;
387 }
388 }
389 }
390
391 if (!mmd && use_first) {
392 /* active multires have not been found
393 * try to use first one */
394 return firstmmd;
395 }
396
397 return mmd;
398 }
399
multires_get_level(const Scene * scene,const Object * ob,const MultiresModifierData * mmd,bool render,bool ignore_simplify)400 int multires_get_level(const Scene *scene,
401 const Object *ob,
402 const MultiresModifierData *mmd,
403 bool render,
404 bool ignore_simplify)
405 {
406 if (render) {
407 return (scene != NULL) ? get_render_subsurf_level(&scene->r, mmd->renderlvl, true) :
408 mmd->renderlvl;
409 }
410 if (ob->mode == OB_MODE_SCULPT) {
411 return mmd->sculptlvl;
412 }
413 if (ignore_simplify) {
414 return mmd->lvl;
415 }
416
417 return (scene != NULL) ? get_render_subsurf_level(&scene->r, mmd->lvl, false) : mmd->lvl;
418 }
419
multires_set_tot_level(Object * ob,MultiresModifierData * mmd,int lvl)420 void multires_set_tot_level(Object *ob, MultiresModifierData *mmd, int lvl)
421 {
422 mmd->totlvl = lvl;
423
424 if (ob->mode != OB_MODE_SCULPT) {
425 mmd->lvl = CLAMPIS(MAX2(mmd->lvl, lvl), 0, mmd->totlvl);
426 }
427
428 mmd->sculptlvl = CLAMPIS(MAX2(mmd->sculptlvl, lvl), 0, mmd->totlvl);
429 mmd->renderlvl = CLAMPIS(MAX2(mmd->renderlvl, lvl), 0, mmd->totlvl);
430 }
431
multires_dm_mark_as_modified(DerivedMesh * dm,MultiresModifiedFlags flags)432 static void multires_dm_mark_as_modified(DerivedMesh *dm, MultiresModifiedFlags flags)
433 {
434 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
435 ccgdm->multires.modified_flags |= flags;
436 }
437
multires_ccg_mark_as_modified(SubdivCCG * subdiv_ccg,MultiresModifiedFlags flags)438 static void multires_ccg_mark_as_modified(SubdivCCG *subdiv_ccg, MultiresModifiedFlags flags)
439 {
440 if (flags & MULTIRES_COORDS_MODIFIED) {
441 subdiv_ccg->dirty.coords = true;
442 }
443 if (flags & MULTIRES_HIDDEN_MODIFIED) {
444 subdiv_ccg->dirty.hidden = true;
445 }
446 }
447
multires_mark_as_modified(Depsgraph * depsgraph,Object * object,MultiresModifiedFlags flags)448 void multires_mark_as_modified(Depsgraph *depsgraph, Object *object, MultiresModifiedFlags flags)
449 {
450 if (object == NULL) {
451 return;
452 }
453 /* NOTE: CCG live inside of evaluated object.
454 *
455 * While this is a bit weird to tag the only one, this is how other areas were built
456 * historically: they are tagging multires for update and then rely on object re-evaluation to
457 * do an actual update.
458 *
459 * In a longer term maybe special dependency graph tag can help sanitizing this a bit. */
460 Object *object_eval = DEG_get_evaluated_object(depsgraph, object);
461 Mesh *mesh = object_eval->data;
462 SubdivCCG *subdiv_ccg = mesh->runtime.subdiv_ccg;
463 if (subdiv_ccg == NULL) {
464 return;
465 }
466 multires_ccg_mark_as_modified(subdiv_ccg, flags);
467 }
468
multires_flush_sculpt_updates(Object * object)469 void multires_flush_sculpt_updates(Object *object)
470 {
471 if (object == NULL || object->sculpt == NULL || object->sculpt->pbvh == NULL) {
472 return;
473 }
474
475 SculptSession *sculpt_session = object->sculpt;
476 if (BKE_pbvh_type(sculpt_session->pbvh) != PBVH_GRIDS || !sculpt_session->multires.active ||
477 sculpt_session->multires.modifier == NULL) {
478 return;
479 }
480
481 SubdivCCG *subdiv_ccg = sculpt_session->subdiv_ccg;
482 if (subdiv_ccg == NULL) {
483 return;
484 }
485
486 if (!subdiv_ccg->dirty.coords && !subdiv_ccg->dirty.hidden) {
487 return;
488 }
489
490 Mesh *mesh = object->data;
491 multiresModifier_reshapeFromCCG(
492 sculpt_session->multires.modifier->totlvl, mesh, sculpt_session->subdiv_ccg);
493
494 subdiv_ccg->dirty.coords = false;
495 subdiv_ccg->dirty.hidden = false;
496 }
497
multires_force_sculpt_rebuild(Object * object)498 void multires_force_sculpt_rebuild(Object *object)
499 {
500 multires_flush_sculpt_updates(object);
501
502 if (object == NULL || object->sculpt == NULL) {
503 return;
504 }
505
506 SculptSession *ss = object->sculpt;
507
508 if (ss->pbvh != NULL) {
509 BKE_pbvh_free(ss->pbvh);
510 object->sculpt->pbvh = NULL;
511 }
512
513 if (ss->pmap != NULL) {
514 MEM_freeN(ss->pmap);
515 ss->pmap = NULL;
516 }
517
518 if (ss->pmap_mem != NULL) {
519 MEM_freeN(ss->pmap_mem);
520 ss->pmap_mem = NULL;
521 }
522 }
523
multires_force_external_reload(Object * object)524 void multires_force_external_reload(Object *object)
525 {
526 Mesh *mesh = BKE_mesh_from_object(object);
527
528 CustomData_external_reload(&mesh->ldata, &mesh->id, CD_MASK_MDISPS, mesh->totloop);
529 multires_force_sculpt_rebuild(object);
530 }
531
532 /* reset the multires levels to match the number of mdisps */
get_levels_from_disps(Object * ob)533 static int get_levels_from_disps(Object *ob)
534 {
535 Mesh *me = ob->data;
536 MDisps *mdisp, *md;
537 int i, j, totlvl = 0;
538
539 mdisp = CustomData_get_layer(&me->ldata, CD_MDISPS);
540
541 for (i = 0; i < me->totpoly; i++) {
542 md = mdisp + me->mpoly[i].loopstart;
543
544 for (j = 0; j < me->mpoly[i].totloop; j++, md++) {
545 if (md->totdisp == 0) {
546 continue;
547 }
548
549 while (1) {
550 int side = (1 << (totlvl - 1)) + 1;
551 int lvl_totdisp = side * side;
552 if (md->totdisp == lvl_totdisp) {
553 break;
554 }
555 if (md->totdisp < lvl_totdisp) {
556 totlvl--;
557 }
558 else {
559 totlvl++;
560 }
561 }
562
563 break;
564 }
565 }
566
567 return totlvl;
568 }
569
570 /* reset the multires levels to match the number of mdisps */
multiresModifier_set_levels_from_disps(MultiresModifierData * mmd,Object * ob)571 void multiresModifier_set_levels_from_disps(MultiresModifierData *mmd, Object *ob)
572 {
573 Mesh *me = ob->data;
574 MDisps *mdisp;
575
576 if (me->edit_mesh) {
577 mdisp = CustomData_get_layer(&me->edit_mesh->bm->ldata, CD_MDISPS);
578 }
579 else {
580 mdisp = CustomData_get_layer(&me->ldata, CD_MDISPS);
581 }
582
583 if (mdisp) {
584 mmd->totlvl = get_levels_from_disps(ob);
585 mmd->lvl = MIN2(mmd->sculptlvl, mmd->totlvl);
586 mmd->sculptlvl = MIN2(mmd->sculptlvl, mmd->totlvl);
587 mmd->renderlvl = MIN2(mmd->renderlvl, mmd->totlvl);
588 }
589 }
590
multires_set_tot_mdisps(Mesh * me,int lvl)591 static void multires_set_tot_mdisps(Mesh *me, int lvl)
592 {
593 MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
594 int i;
595
596 if (mdisps) {
597 for (i = 0; i < me->totloop; i++, mdisps++) {
598 mdisps->totdisp = multires_grid_tot[lvl];
599 mdisps->level = lvl;
600 }
601 }
602 }
603
multires_reallocate_mdisps(int totloop,MDisps * mdisps,int lvl)604 static void multires_reallocate_mdisps(int totloop, MDisps *mdisps, int lvl)
605 {
606 int i;
607
608 /* reallocate displacements to be filled in */
609 for (i = 0; i < totloop; i++) {
610 int totdisp = multires_grid_tot[lvl];
611 float(*disps)[3] = MEM_calloc_arrayN(totdisp, sizeof(float[3]), "multires disps");
612
613 if (mdisps[i].disps) {
614 MEM_freeN(mdisps[i].disps);
615 }
616
617 if (mdisps[i].level && mdisps[i].hidden) {
618 multires_mdisps_subdivide_hidden(&mdisps[i], lvl);
619 }
620
621 mdisps[i].disps = disps;
622 mdisps[i].totdisp = totdisp;
623 mdisps[i].level = lvl;
624 }
625 }
626
multires_copy_grid(float (* gridA)[3],float (* gridB)[3],int sizeA,int sizeB)627 static void multires_copy_grid(float (*gridA)[3], float (*gridB)[3], int sizeA, int sizeB)
628 {
629 int x, y, j, skip;
630
631 if (sizeA > sizeB) {
632 skip = (sizeA - 1) / (sizeB - 1);
633
634 for (j = 0, y = 0; y < sizeB; y++) {
635 for (x = 0; x < sizeB; x++, j++) {
636 copy_v3_v3(gridA[y * skip * sizeA + x * skip], gridB[j]);
637 }
638 }
639 }
640 else {
641 skip = (sizeB - 1) / (sizeA - 1);
642
643 for (j = 0, y = 0; y < sizeA; y++) {
644 for (x = 0; x < sizeA; x++, j++) {
645 copy_v3_v3(gridA[j], gridB[y * skip * sizeB + x * skip]);
646 }
647 }
648 }
649 }
650
multires_copy_dm_grid(CCGElem * gridA,CCGElem * gridB,CCGKey * keyA,CCGKey * keyB)651 static void multires_copy_dm_grid(CCGElem *gridA, CCGElem *gridB, CCGKey *keyA, CCGKey *keyB)
652 {
653 int x, y, j, skip;
654
655 if (keyA->grid_size > keyB->grid_size) {
656 skip = (keyA->grid_size - 1) / (keyB->grid_size - 1);
657
658 for (j = 0, y = 0; y < keyB->grid_size; y++) {
659 for (x = 0; x < keyB->grid_size; x++, j++) {
660 memcpy(CCG_elem_offset_co(keyA, gridA, y * skip * keyA->grid_size + x * skip),
661 CCG_elem_offset_co(keyB, gridB, j),
662 keyA->elem_size);
663 }
664 }
665 }
666 else {
667 skip = (keyB->grid_size - 1) / (keyA->grid_size - 1);
668
669 for (j = 0, y = 0; y < keyA->grid_size; y++) {
670 for (x = 0; x < keyA->grid_size; x++, j++) {
671 memcpy(CCG_elem_offset_co(keyA, gridA, j),
672 CCG_elem_offset_co(keyB, gridB, y * skip * keyB->grid_size + x * skip),
673 keyA->elem_size);
674 }
675 }
676 }
677 }
678
679 /* Reallocate gpm->data at a lower resolution and copy values over
680 * from the original high-resolution data */
multires_grid_paint_mask_downsample(GridPaintMask * gpm,int level)681 static void multires_grid_paint_mask_downsample(GridPaintMask *gpm, int level)
682 {
683 if (level < gpm->level) {
684 int gridsize = BKE_ccg_gridsize(level);
685 float *data = MEM_calloc_arrayN(
686 square_i(gridsize), sizeof(float), "multires_grid_paint_mask_downsample");
687 int x, y;
688
689 for (y = 0; y < gridsize; y++) {
690 for (x = 0; x < gridsize; x++) {
691 data[y * gridsize + x] = paint_grid_paint_mask(gpm, level, x, y);
692 }
693 }
694
695 MEM_freeN(gpm->data);
696 gpm->data = data;
697 gpm->level = level;
698 }
699 }
700
multires_del_higher(MultiresModifierData * mmd,Object * ob,int lvl)701 static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl)
702 {
703 Mesh *me = (Mesh *)ob->data;
704 int levels = mmd->totlvl - lvl;
705 MDisps *mdisps;
706 GridPaintMask *gpm;
707
708 multires_set_tot_mdisps(me, mmd->totlvl);
709 multiresModifier_ensure_external_read(me, mmd);
710 mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
711 gpm = CustomData_get_layer(&me->ldata, CD_GRID_PAINT_MASK);
712
713 multires_force_sculpt_rebuild(ob);
714
715 if (mdisps && levels > 0) {
716 if (lvl > 0) {
717 /* MLoop *ml = me->mloop; */ /*UNUSED*/
718 int nsize = multires_side_tot[lvl];
719 int hsize = multires_side_tot[mmd->totlvl];
720 int i, j;
721
722 for (i = 0; i < me->totpoly; i++) {
723 for (j = 0; j < me->mpoly[i].totloop; j++) {
724 int g = me->mpoly[i].loopstart + j;
725 MDisps *mdisp = &mdisps[g];
726 float(*disps)[3], (*ndisps)[3], (*hdisps)[3];
727 int totdisp = multires_grid_tot[lvl];
728
729 disps = MEM_calloc_arrayN(totdisp, sizeof(float[3]), "multires disps");
730
731 if (mdisp->disps != NULL) {
732 ndisps = disps;
733 hdisps = mdisp->disps;
734
735 multires_copy_grid(ndisps, hdisps, nsize, hsize);
736 if (mdisp->hidden) {
737 BLI_bitmap *gh = multires_mdisps_downsample_hidden(mdisp->hidden, mdisp->level, lvl);
738 MEM_freeN(mdisp->hidden);
739 mdisp->hidden = gh;
740 }
741
742 MEM_freeN(mdisp->disps);
743 }
744
745 mdisp->disps = disps;
746 mdisp->totdisp = totdisp;
747 mdisp->level = lvl;
748
749 if (gpm) {
750 multires_grid_paint_mask_downsample(&gpm[g], lvl);
751 }
752 }
753 }
754 }
755 else {
756 multires_customdata_delete(me);
757 }
758 }
759
760 multires_set_tot_level(ob, mmd, lvl);
761 }
762
763 /* (direction = 1) for delete higher, (direction = 0) for lower (not implemented yet) */
multiresModifier_del_levels(MultiresModifierData * mmd,Scene * scene,Object * ob,int direction)764 void multiresModifier_del_levels(MultiresModifierData *mmd,
765 Scene *scene,
766 Object *ob,
767 int direction)
768 {
769 Mesh *me = BKE_mesh_from_object(ob);
770 int lvl = multires_get_level(scene, ob, mmd, false, true);
771 int levels = mmd->totlvl - lvl;
772 MDisps *mdisps;
773
774 multires_set_tot_mdisps(me, mmd->totlvl);
775 multiresModifier_ensure_external_read(me, mmd);
776 mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
777
778 multires_force_sculpt_rebuild(ob);
779
780 if (mdisps && levels > 0 && direction == 1) {
781 multires_del_higher(mmd, ob, lvl);
782 }
783
784 multires_set_tot_level(ob, mmd, lvl);
785 }
786
multires_dm_create_local(Scene * scene,Object * ob,DerivedMesh * dm,int lvl,int totlvl,int simple,bool alloc_paint_mask,int flags)787 static DerivedMesh *multires_dm_create_local(Scene *scene,
788 Object *ob,
789 DerivedMesh *dm,
790 int lvl,
791 int totlvl,
792 int simple,
793 bool alloc_paint_mask,
794 int flags)
795 {
796 MultiresModifierData mmd = {{NULL}};
797
798 mmd.lvl = lvl;
799 mmd.sculptlvl = lvl;
800 mmd.renderlvl = lvl;
801 mmd.totlvl = totlvl;
802 mmd.simple = simple;
803
804 flags |= MULTIRES_USE_LOCAL_MMD;
805 if (alloc_paint_mask) {
806 flags |= MULTIRES_ALLOC_PAINT_MASK;
807 }
808
809 return multires_make_derived_from_derived(dm, &mmd, scene, ob, flags);
810 }
811
subsurf_dm_create_local(Scene * scene,Object * ob,DerivedMesh * dm,int lvl,bool is_simple,bool is_optimal,bool is_plain_uv,bool alloc_paint_mask,bool for_render,SubsurfFlags flags)812 static DerivedMesh *subsurf_dm_create_local(Scene *scene,
813 Object *ob,
814 DerivedMesh *dm,
815 int lvl,
816 bool is_simple,
817 bool is_optimal,
818 bool is_plain_uv,
819 bool alloc_paint_mask,
820 bool for_render,
821 SubsurfFlags flags)
822 {
823 SubsurfModifierData smd = {{NULL}};
824
825 smd.levels = smd.renderLevels = lvl;
826 smd.quality = 3;
827 if (!is_plain_uv) {
828 smd.uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS;
829 }
830 else {
831 smd.uv_smooth = SUBSURF_UV_SMOOTH_NONE;
832 }
833 if (is_simple) {
834 smd.subdivType = ME_SIMPLE_SUBSURF;
835 }
836 if (is_optimal) {
837 smd.flags |= eSubsurfModifierFlag_ControlEdges;
838 }
839
840 if (ob->mode & OB_MODE_EDIT) {
841 flags |= SUBSURF_IN_EDIT_MODE;
842 }
843 if (alloc_paint_mask) {
844 flags |= SUBSURF_ALLOC_PAINT_MASK;
845 }
846 if (for_render) {
847 flags |= SUBSURF_USE_RENDER_PARAMS;
848 }
849
850 return subsurf_make_derived_from_derived(dm, &smd, scene, NULL, flags);
851 }
852
multires_subdivide_legacy(MultiresModifierData * mmd,Scene * scene,Object * ob,int totlvl,int updateblock,int simple)853 static void multires_subdivide_legacy(
854 MultiresModifierData *mmd, Scene *scene, Object *ob, int totlvl, int updateblock, int simple)
855 {
856 Mesh *me = ob->data;
857 MDisps *mdisps;
858 const int lvl = mmd->totlvl;
859
860 if ((totlvl > multires_max_levels) || (me->totpoly == 0)) {
861 return;
862 }
863
864 BLI_assert(totlvl > lvl);
865
866 multires_force_sculpt_rebuild(ob);
867
868 mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
869 if (!mdisps) {
870 mdisps = multires_mdisps_init_hidden(me, totlvl);
871 }
872
873 if (mdisps->disps && !updateblock && lvl != 0) {
874 /* upsample */
875 DerivedMesh *lowdm, *cddm, *highdm;
876 CCGElem **highGridData, **lowGridData, **subGridData;
877 CCGKey highGridKey, lowGridKey;
878 CCGSubSurf *ss;
879 int i, numGrids, highGridSize;
880 const bool has_mask = CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK);
881
882 /* create subsurf DM from original mesh at high level */
883 cddm = CDDM_from_mesh(me);
884 DM_set_only_copy(cddm, &CD_MASK_BAREMESH);
885 highdm = subsurf_dm_create_local(NULL,
886 ob,
887 cddm,
888 totlvl,
889 simple,
890 0,
891 mmd->uv_smooth == SUBSURF_UV_SMOOTH_NONE,
892 has_mask,
893 false,
894 SUBSURF_IGNORE_SIMPLIFY);
895 ss = ((CCGDerivedMesh *)highdm)->ss;
896
897 /* create multires DM from original mesh at low level */
898 lowdm = multires_dm_create_local(
899 scene, ob, cddm, lvl, lvl, simple, has_mask, MULTIRES_IGNORE_SIMPLIFY);
900 BLI_assert(lowdm != cddm);
901 cddm->release(cddm);
902
903 /* copy subsurf grids and replace them with low displaced grids */
904 numGrids = highdm->getNumGrids(highdm);
905 highGridSize = highdm->getGridSize(highdm);
906 highGridData = highdm->getGridData(highdm);
907 highdm->getGridKey(highdm, &highGridKey);
908 lowGridData = lowdm->getGridData(lowdm);
909 lowdm->getGridKey(lowdm, &lowGridKey);
910
911 subGridData = MEM_calloc_arrayN(numGrids, sizeof(float *), "subGridData*");
912
913 for (i = 0; i < numGrids; i++) {
914 /* backup subsurf grids */
915 subGridData[i] = MEM_calloc_arrayN(
916 highGridKey.elem_size, highGridSize * highGridSize, "subGridData");
917 memcpy(subGridData[i], highGridData[i], highGridKey.elem_size * highGridSize * highGridSize);
918
919 /* overwrite with current displaced grids */
920 multires_copy_dm_grid(highGridData[i], lowGridData[i], &highGridKey, &lowGridKey);
921 }
922
923 /* low lower level dm no longer needed at this point */
924 lowdm->release(lowdm);
925
926 /* subsurf higher levels again with displaced data */
927 ccgSubSurf_updateFromFaces(ss, lvl, NULL, 0);
928 ccgSubSurf_updateLevels(ss, lvl, NULL, 0);
929
930 /* reallocate displacements */
931 multires_reallocate_mdisps(me->totloop, mdisps, totlvl);
932
933 /* compute displacements */
934 multiresModifier_disp_run(highdm, me, NULL, CALC_DISPLACEMENTS, subGridData, totlvl);
935
936 /* free */
937 highdm->release(highdm);
938 for (i = 0; i < numGrids; i++) {
939 MEM_freeN(subGridData[i]);
940 }
941 MEM_freeN(subGridData);
942 }
943 else {
944 /* only reallocate, nothing to upsample */
945 multires_reallocate_mdisps(me->totloop, mdisps, totlvl);
946 }
947
948 multires_set_tot_level(ob, mmd, totlvl);
949 }
950
multiresModifier_subdivide_legacy(MultiresModifierData * mmd,Scene * scene,Object * ob,int updateblock,int simple)951 void multiresModifier_subdivide_legacy(
952 MultiresModifierData *mmd, Scene *scene, Object *ob, int updateblock, int simple)
953 {
954 multires_subdivide_legacy(mmd, scene, ob, mmd->totlvl + 1, updateblock, simple);
955 }
956
grid_tangent(const CCGKey * key,int x,int y,int axis,CCGElem * grid,float t[3])957 static void grid_tangent(const CCGKey *key, int x, int y, int axis, CCGElem *grid, float t[3])
958 {
959 if (axis == 0) {
960 if (x == key->grid_size - 1) {
961 if (y == key->grid_size - 1) {
962 sub_v3_v3v3(
963 t, CCG_grid_elem_co(key, grid, x, y - 1), CCG_grid_elem_co(key, grid, x - 1, y - 1));
964 }
965 else {
966 sub_v3_v3v3(t, CCG_grid_elem_co(key, grid, x, y), CCG_grid_elem_co(key, grid, x - 1, y));
967 }
968 }
969 else {
970 sub_v3_v3v3(t, CCG_grid_elem_co(key, grid, x + 1, y), CCG_grid_elem_co(key, grid, x, y));
971 }
972 }
973 else if (axis == 1) {
974 if (y == key->grid_size - 1) {
975 if (x == key->grid_size - 1) {
976 sub_v3_v3v3(
977 t, CCG_grid_elem_co(key, grid, x - 1, y), CCG_grid_elem_co(key, grid, x - 1, (y - 1)));
978 }
979 else {
980 sub_v3_v3v3(t, CCG_grid_elem_co(key, grid, x, y), CCG_grid_elem_co(key, grid, x, (y - 1)));
981 }
982 }
983 else {
984 sub_v3_v3v3(t, CCG_grid_elem_co(key, grid, x, (y + 1)), CCG_grid_elem_co(key, grid, x, y));
985 }
986 }
987 }
988
989 /* Construct 3x3 tangent-space matrix in 'mat' */
grid_tangent_matrix(float mat[3][3],const CCGKey * key,int x,int y,CCGElem * grid)990 static void grid_tangent_matrix(float mat[3][3], const CCGKey *key, int x, int y, CCGElem *grid)
991 {
992 grid_tangent(key, x, y, 0, grid, mat[0]);
993 normalize_v3(mat[0]);
994
995 grid_tangent(key, x, y, 1, grid, mat[1]);
996 normalize_v3(mat[1]);
997
998 copy_v3_v3(mat[2], CCG_grid_elem_no(key, grid, x, y));
999 }
1000
1001 typedef struct MultiresThreadedData {
1002 DispOp op;
1003 CCGElem **gridData, **subGridData;
1004 CCGKey *key;
1005 CCGKey *sub_key;
1006 MPoly *mpoly;
1007 MDisps *mdisps;
1008 GridPaintMask *grid_paint_mask;
1009 int *gridOffset;
1010 int gridSize, dGridSize, dSkip;
1011 float (*smat)[3];
1012 } MultiresThreadedData;
1013
multires_disp_run_cb(void * __restrict userdata,const int pidx,const TaskParallelTLS * __restrict UNUSED (tls))1014 static void multires_disp_run_cb(void *__restrict userdata,
1015 const int pidx,
1016 const TaskParallelTLS *__restrict UNUSED(tls))
1017 {
1018 MultiresThreadedData *tdata = userdata;
1019
1020 DispOp op = tdata->op;
1021 CCGElem **gridData = tdata->gridData;
1022 CCGElem **subGridData = tdata->subGridData;
1023 CCGKey *key = tdata->key;
1024 MPoly *mpoly = tdata->mpoly;
1025 MDisps *mdisps = tdata->mdisps;
1026 GridPaintMask *grid_paint_mask = tdata->grid_paint_mask;
1027 int *gridOffset = tdata->gridOffset;
1028 int gridSize = tdata->gridSize;
1029 int dGridSize = tdata->dGridSize;
1030 int dSkip = tdata->dSkip;
1031
1032 const int numVerts = mpoly[pidx].totloop;
1033 int S, x, y, gIndex = gridOffset[pidx];
1034
1035 for (S = 0; S < numVerts; S++, gIndex++) {
1036 GridPaintMask *gpm = grid_paint_mask ? &grid_paint_mask[gIndex] : NULL;
1037 MDisps *mdisp = &mdisps[mpoly[pidx].loopstart + S];
1038 CCGElem *grid = gridData[gIndex];
1039 CCGElem *subgrid = subGridData[gIndex];
1040 float(*dispgrid)[3] = NULL;
1041
1042 dispgrid = mdisp->disps;
1043
1044 /* if needed, reallocate multires paint mask */
1045 if (gpm && gpm->level < key->level) {
1046 gpm->level = key->level;
1047 if (gpm->data) {
1048 MEM_freeN(gpm->data);
1049 }
1050 gpm->data = MEM_calloc_arrayN(key->grid_area, sizeof(float), "gpm.data");
1051 }
1052
1053 for (y = 0; y < gridSize; y++) {
1054 for (x = 0; x < gridSize; x++) {
1055 float *co = CCG_grid_elem_co(key, grid, x, y);
1056 float *sco = CCG_grid_elem_co(key, subgrid, x, y);
1057 float *data = dispgrid[dGridSize * y * dSkip + x * dSkip];
1058 float mat[3][3], disp[3], d[3], mask;
1059
1060 /* construct tangent space matrix */
1061 grid_tangent_matrix(mat, key, x, y, subgrid);
1062
1063 switch (op) {
1064 case APPLY_DISPLACEMENTS:
1065 /* Convert displacement to object space
1066 * and add to grid points */
1067 mul_v3_m3v3(disp, mat, data);
1068 add_v3_v3v3(co, sco, disp);
1069 break;
1070 case CALC_DISPLACEMENTS:
1071 /* Calculate displacement between new and old
1072 * grid points and convert to tangent space */
1073 sub_v3_v3v3(disp, co, sco);
1074 invert_m3(mat);
1075 mul_v3_m3v3(data, mat, disp);
1076 break;
1077 case ADD_DISPLACEMENTS:
1078 /* Convert subdivided displacements to tangent
1079 * space and add to the original displacements */
1080 invert_m3(mat);
1081 mul_v3_m3v3(d, mat, co);
1082 add_v3_v3(data, d);
1083 break;
1084 }
1085
1086 if (gpm) {
1087 switch (op) {
1088 case APPLY_DISPLACEMENTS:
1089 /* Copy mask from gpm to DM */
1090 *CCG_grid_elem_mask(key, grid, x, y) = paint_grid_paint_mask(gpm, key->level, x, y);
1091 break;
1092 case CALC_DISPLACEMENTS:
1093 /* Copy mask from DM to gpm */
1094 mask = *CCG_grid_elem_mask(key, grid, x, y);
1095 gpm->data[y * gridSize + x] = CLAMPIS(mask, 0, 1);
1096 break;
1097 case ADD_DISPLACEMENTS:
1098 /* Add mask displacement to gpm */
1099 gpm->data[y * gridSize + x] += *CCG_grid_elem_mask(key, grid, x, y);
1100 break;
1101 }
1102 }
1103 }
1104 }
1105 }
1106 }
1107
1108 /* XXX WARNING: subsurf elements from dm and oldGridData *must* be of the same format (size),
1109 * because this code uses CCGKey's info from dm to access oldGridData's normals
1110 * (through the call to grid_tangent_matrix())! */
multiresModifier_disp_run(DerivedMesh * dm,Mesh * me,DerivedMesh * dm2,DispOp op,CCGElem ** oldGridData,int totlvl)1111 static void multiresModifier_disp_run(
1112 DerivedMesh *dm, Mesh *me, DerivedMesh *dm2, DispOp op, CCGElem **oldGridData, int totlvl)
1113 {
1114 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1115 CCGElem **gridData, **subGridData;
1116 CCGKey key;
1117 MPoly *mpoly = me->mpoly;
1118 MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
1119 GridPaintMask *grid_paint_mask = NULL;
1120 int *gridOffset;
1121 int i, gridSize, dGridSize, dSkip;
1122 int totloop, totpoly;
1123
1124 /* this happens in the dm made by bmesh_mdisps_space_set */
1125 if (dm2 && CustomData_has_layer(&dm2->loopData, CD_MDISPS)) {
1126 mpoly = CustomData_get_layer(&dm2->polyData, CD_MPOLY);
1127 mdisps = CustomData_get_layer(&dm2->loopData, CD_MDISPS);
1128 totloop = dm2->numLoopData;
1129 totpoly = dm2->numPolyData;
1130 }
1131 else {
1132 totloop = me->totloop;
1133 totpoly = me->totpoly;
1134 }
1135
1136 if (!mdisps) {
1137 if (op == CALC_DISPLACEMENTS) {
1138 mdisps = CustomData_add_layer(&me->ldata, CD_MDISPS, CD_DEFAULT, NULL, me->totloop);
1139 }
1140 else {
1141 return;
1142 }
1143 }
1144
1145 /*numGrids = dm->getNumGrids(dm);*/ /*UNUSED*/
1146 gridSize = dm->getGridSize(dm);
1147 gridData = dm->getGridData(dm);
1148 gridOffset = dm->getGridOffset(dm);
1149 dm->getGridKey(dm, &key);
1150 subGridData = (oldGridData) ? oldGridData : gridData;
1151
1152 dGridSize = multires_side_tot[totlvl];
1153 dSkip = (dGridSize - 1) / (gridSize - 1);
1154
1155 /* multires paint masks */
1156 if (key.has_mask) {
1157 grid_paint_mask = CustomData_get_layer(&me->ldata, CD_GRID_PAINT_MASK);
1158 }
1159
1160 /* when adding new faces in edit mode, need to allocate disps */
1161 for (i = 0; i < totloop; i++) {
1162 if (mdisps[i].disps == NULL) {
1163 multires_reallocate_mdisps(totloop, mdisps, totlvl);
1164 break;
1165 }
1166 }
1167
1168 TaskParallelSettings settings;
1169 BLI_parallel_range_settings_defaults(&settings);
1170 settings.min_iter_per_thread = CCG_TASK_LIMIT;
1171
1172 MultiresThreadedData data = {
1173 .op = op,
1174 .gridData = gridData,
1175 .subGridData = subGridData,
1176 .key = &key,
1177 .mpoly = mpoly,
1178 .mdisps = mdisps,
1179 .grid_paint_mask = grid_paint_mask,
1180 .gridOffset = gridOffset,
1181 .gridSize = gridSize,
1182 .dGridSize = dGridSize,
1183 .dSkip = dSkip,
1184 };
1185
1186 BLI_task_parallel_range(0, totpoly, &data, multires_disp_run_cb, &settings);
1187
1188 if (op == APPLY_DISPLACEMENTS) {
1189 ccgSubSurf_stitchFaces(ccgdm->ss, 0, NULL, 0);
1190 ccgSubSurf_updateNormals(ccgdm->ss, NULL, 0);
1191 }
1192 }
1193
multires_modifier_update_mdisps(struct DerivedMesh * dm,Scene * scene)1194 void multires_modifier_update_mdisps(struct DerivedMesh *dm, Scene *scene)
1195 {
1196 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1197 Object *ob;
1198 Mesh *me;
1199 MDisps *mdisps;
1200 MultiresModifierData *mmd;
1201
1202 ob = ccgdm->multires.ob;
1203 me = ccgdm->multires.ob->data;
1204 mmd = ccgdm->multires.mmd;
1205 multires_set_tot_mdisps(me, mmd->totlvl);
1206 multiresModifier_ensure_external_read(me, mmd);
1207 mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
1208
1209 if (mdisps) {
1210 int lvl = ccgdm->multires.lvl;
1211 int totlvl = ccgdm->multires.totlvl;
1212
1213 if (lvl < totlvl) {
1214 DerivedMesh *lowdm, *cddm, *highdm;
1215 CCGElem **highGridData, **lowGridData, **subGridData, **gridData, *diffGrid;
1216 CCGKey highGridKey, lowGridKey;
1217 CCGSubSurf *ss;
1218 int i, j, numGrids, highGridSize, lowGridSize;
1219 const bool has_mask = CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK);
1220
1221 /* Create subsurf DM from original mesh at high level. */
1222 /* TODO: use mesh_deform_eval when sculpting on deformed mesh. */
1223 cddm = CDDM_from_mesh(me);
1224 DM_set_only_copy(cddm, &CD_MASK_BAREMESH);
1225
1226 highdm = subsurf_dm_create_local(scene,
1227 ob,
1228 cddm,
1229 totlvl,
1230 mmd->simple,
1231 0,
1232 mmd->uv_smooth == SUBSURF_UV_SMOOTH_NONE,
1233 has_mask,
1234 false,
1235 SUBSURF_IGNORE_SIMPLIFY);
1236 ss = ((CCGDerivedMesh *)highdm)->ss;
1237
1238 /* create multires DM from original mesh and displacements */
1239 lowdm = multires_dm_create_local(
1240 scene, ob, cddm, lvl, totlvl, mmd->simple, has_mask, MULTIRES_IGNORE_SIMPLIFY);
1241 cddm->release(cddm);
1242
1243 /* gather grid data */
1244 numGrids = highdm->getNumGrids(highdm);
1245 highGridSize = highdm->getGridSize(highdm);
1246 highGridData = highdm->getGridData(highdm);
1247 highdm->getGridKey(highdm, &highGridKey);
1248 lowGridSize = lowdm->getGridSize(lowdm);
1249 lowGridData = lowdm->getGridData(lowdm);
1250 lowdm->getGridKey(lowdm, &lowGridKey);
1251 gridData = dm->getGridData(dm);
1252
1253 BLI_assert(highGridKey.elem_size == lowGridKey.elem_size);
1254
1255 subGridData = MEM_calloc_arrayN(numGrids, sizeof(CCGElem *), "subGridData*");
1256 diffGrid = MEM_calloc_arrayN(lowGridKey.elem_size, lowGridSize * lowGridSize, "diff");
1257
1258 for (i = 0; i < numGrids; i++) {
1259 /* backup subsurf grids */
1260 subGridData[i] = MEM_calloc_arrayN(
1261 highGridKey.elem_size, highGridSize * highGridSize, "subGridData");
1262 memcpy(
1263 subGridData[i], highGridData[i], highGridKey.elem_size * highGridSize * highGridSize);
1264
1265 /* write difference of subsurf and displaced low level into high subsurf */
1266 for (j = 0; j < lowGridSize * lowGridSize; j++) {
1267 sub_v4_v4v4(CCG_elem_offset_co(&lowGridKey, diffGrid, j),
1268 CCG_elem_offset_co(&lowGridKey, gridData[i], j),
1269 CCG_elem_offset_co(&lowGridKey, lowGridData[i], j));
1270 }
1271
1272 multires_copy_dm_grid(highGridData[i], diffGrid, &highGridKey, &lowGridKey);
1273 }
1274
1275 /* lower level dm no longer needed at this point */
1276 MEM_freeN(diffGrid);
1277 lowdm->release(lowdm);
1278
1279 /* subsurf higher levels again with difference of coordinates */
1280 ccgSubSurf_updateFromFaces(ss, lvl, NULL, 0);
1281 ccgSubSurf_updateLevels(ss, lvl, NULL, 0);
1282
1283 /* add to displacements */
1284 multiresModifier_disp_run(highdm, me, NULL, ADD_DISPLACEMENTS, subGridData, mmd->totlvl);
1285
1286 /* free */
1287 highdm->release(highdm);
1288 for (i = 0; i < numGrids; i++) {
1289 MEM_freeN(subGridData[i]);
1290 }
1291 MEM_freeN(subGridData);
1292 }
1293 else {
1294 DerivedMesh *cddm, *subdm;
1295 const bool has_mask = CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK);
1296
1297 /* TODO: use mesh_deform_eval when sculpting on deformed mesh. */
1298 cddm = CDDM_from_mesh(me);
1299 DM_set_only_copy(cddm, &CD_MASK_BAREMESH);
1300
1301 subdm = subsurf_dm_create_local(scene,
1302 ob,
1303 cddm,
1304 mmd->totlvl,
1305 mmd->simple,
1306 0,
1307 mmd->uv_smooth == SUBSURF_UV_SMOOTH_NONE,
1308 has_mask,
1309 false,
1310 SUBSURF_IGNORE_SIMPLIFY);
1311 cddm->release(cddm);
1312
1313 multiresModifier_disp_run(
1314 dm, me, NULL, CALC_DISPLACEMENTS, subdm->getGridData(subdm), mmd->totlvl);
1315
1316 subdm->release(subdm);
1317 }
1318 }
1319 }
1320
multires_modifier_update_hidden(DerivedMesh * dm)1321 void multires_modifier_update_hidden(DerivedMesh *dm)
1322 {
1323 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1324 BLI_bitmap **grid_hidden = ccgdm->gridHidden;
1325 Mesh *me = ccgdm->multires.ob->data;
1326 MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
1327 int totlvl = ccgdm->multires.totlvl;
1328 int lvl = ccgdm->multires.lvl;
1329
1330 if (mdisps) {
1331 int i;
1332
1333 for (i = 0; i < me->totloop; i++) {
1334 MDisps *md = &mdisps[i];
1335 BLI_bitmap *gh = grid_hidden[i];
1336
1337 if (!gh && md->hidden) {
1338 MEM_freeN(md->hidden);
1339 md->hidden = NULL;
1340 }
1341 else if (gh) {
1342 gh = multires_mdisps_upsample_hidden(gh, lvl, totlvl, md->hidden);
1343 if (md->hidden) {
1344 MEM_freeN(md->hidden);
1345 }
1346
1347 md->hidden = gh;
1348 }
1349 }
1350 }
1351 }
1352
multires_stitch_grids(Object * ob)1353 void multires_stitch_grids(Object *ob)
1354 {
1355 if (ob == NULL) {
1356 return;
1357 }
1358 SculptSession *sculpt_session = ob->sculpt;
1359 if (sculpt_session == NULL) {
1360 return;
1361 }
1362 PBVH *pbvh = sculpt_session->pbvh;
1363 SubdivCCG *subdiv_ccg = sculpt_session->subdiv_ccg;
1364 if (pbvh == NULL || subdiv_ccg == NULL) {
1365 return;
1366 }
1367 BLI_assert(BKE_pbvh_type(pbvh) == PBVH_GRIDS);
1368 /* NOTE: Currently CCG does not keep track of faces, making it impossible
1369 * to use BKE_pbvh_get_grid_updates().
1370 */
1371 CCGFace **faces;
1372 int num_faces;
1373 BKE_pbvh_get_grid_updates(pbvh, false, (void ***)&faces, &num_faces);
1374 if (num_faces) {
1375 BKE_subdiv_ccg_average_stitch_faces(subdiv_ccg, faces, num_faces);
1376 MEM_freeN(faces);
1377 }
1378 }
1379
multires_make_derived_from_derived(DerivedMesh * dm,MultiresModifierData * mmd,Scene * scene,Object * ob,MultiresFlags flags)1380 DerivedMesh *multires_make_derived_from_derived(
1381 DerivedMesh *dm, MultiresModifierData *mmd, Scene *scene, Object *ob, MultiresFlags flags)
1382 {
1383 Mesh *me = ob->data;
1384 DerivedMesh *result;
1385 CCGDerivedMesh *ccgdm = NULL;
1386 CCGElem **gridData, **subGridData;
1387 CCGKey key;
1388 const bool render = (flags & MULTIRES_USE_RENDER_PARAMS) != 0;
1389 const bool ignore_simplify = (flags & MULTIRES_IGNORE_SIMPLIFY) != 0;
1390 int lvl = multires_get_level(scene, ob, mmd, render, ignore_simplify);
1391 int i, gridSize, numGrids;
1392
1393 if (lvl == 0) {
1394 return dm;
1395 }
1396
1397 const int subsurf_flags = ignore_simplify ? SUBSURF_IGNORE_SIMPLIFY : 0;
1398
1399 result = subsurf_dm_create_local(scene,
1400 ob,
1401 dm,
1402 lvl,
1403 mmd->simple,
1404 mmd->flags & eMultiresModifierFlag_ControlEdges,
1405 mmd->uv_smooth == SUBSURF_UV_SMOOTH_NONE,
1406 flags & MULTIRES_ALLOC_PAINT_MASK,
1407 render,
1408 subsurf_flags);
1409
1410 if (!(flags & MULTIRES_USE_LOCAL_MMD)) {
1411 ccgdm = (CCGDerivedMesh *)result;
1412
1413 ccgdm->multires.ob = ob;
1414 ccgdm->multires.mmd = mmd;
1415 ccgdm->multires.local_mmd = 0;
1416 ccgdm->multires.lvl = lvl;
1417 ccgdm->multires.totlvl = mmd->totlvl;
1418 ccgdm->multires.modified_flags = 0;
1419 }
1420
1421 numGrids = result->getNumGrids(result);
1422 gridSize = result->getGridSize(result);
1423 gridData = result->getGridData(result);
1424 result->getGridKey(result, &key);
1425
1426 subGridData = MEM_malloc_arrayN(numGrids, sizeof(CCGElem *), "subGridData*");
1427
1428 for (i = 0; i < numGrids; i++) {
1429 subGridData[i] = MEM_malloc_arrayN(key.elem_size, gridSize * gridSize, "subGridData");
1430 memcpy(subGridData[i], gridData[i], key.elem_size * gridSize * gridSize);
1431 }
1432
1433 multires_set_tot_mdisps(me, mmd->totlvl);
1434 multiresModifier_ensure_external_read(me, mmd);
1435
1436 /*run displacement*/
1437 multiresModifier_disp_run(result, ob->data, dm, APPLY_DISPLACEMENTS, subGridData, mmd->totlvl);
1438
1439 /* copy hidden elements for this level */
1440 if (ccgdm) {
1441 multires_output_hidden_to_ccgdm(ccgdm, me, lvl);
1442 }
1443
1444 for (i = 0; i < numGrids; i++) {
1445 MEM_freeN(subGridData[i]);
1446 }
1447 MEM_freeN(subGridData);
1448
1449 return result;
1450 }
1451
1452 /**** Old Multires code ****
1453 ***************************/
1454
1455 /* Adapted from sculptmode.c */
old_mdisps_bilinear(float out[3],float (* disps)[3],const int st,float u,float v)1456 void old_mdisps_bilinear(float out[3], float (*disps)[3], const int st, float u, float v)
1457 {
1458 int x, y, x2, y2;
1459 const int st_max = st - 1;
1460 float urat, vrat, uopp;
1461 float d[4][3], d2[2][3];
1462
1463 if (!disps || isnan(u) || isnan(v)) {
1464 return;
1465 }
1466
1467 if (u < 0) {
1468 u = 0;
1469 }
1470 else if (u >= st) {
1471 u = st_max;
1472 }
1473 if (v < 0) {
1474 v = 0;
1475 }
1476 else if (v >= st) {
1477 v = st_max;
1478 }
1479
1480 x = floor(u);
1481 y = floor(v);
1482 x2 = x + 1;
1483 y2 = y + 1;
1484
1485 if (x2 >= st) {
1486 x2 = st_max;
1487 }
1488 if (y2 >= st) {
1489 y2 = st_max;
1490 }
1491
1492 urat = u - x;
1493 vrat = v - y;
1494 uopp = 1 - urat;
1495
1496 mul_v3_v3fl(d[0], disps[y * st + x], uopp);
1497 mul_v3_v3fl(d[1], disps[y * st + x2], urat);
1498 mul_v3_v3fl(d[2], disps[y2 * st + x], uopp);
1499 mul_v3_v3fl(d[3], disps[y2 * st + x2], urat);
1500
1501 add_v3_v3v3(d2[0], d[0], d[1]);
1502 add_v3_v3v3(d2[1], d[2], d[3]);
1503 mul_v3_fl(d2[0], 1 - vrat);
1504 mul_v3_fl(d2[1], vrat);
1505
1506 add_v3_v3v3(out, d2[0], d2[1]);
1507 }
1508
old_mdisps_rotate(int S,int UNUSED (newside),int oldside,int x,int y,float * u,float * v)1509 static void old_mdisps_rotate(
1510 int S, int UNUSED(newside), int oldside, int x, int y, float *u, float *v)
1511 {
1512 float offset = oldside * 0.5f - 0.5f;
1513
1514 if (S == 1) {
1515 *u = offset + x;
1516 *v = offset - y;
1517 }
1518 if (S == 2) {
1519 *u = offset + y;
1520 *v = offset + x;
1521 }
1522 if (S == 3) {
1523 *u = offset - x;
1524 *v = offset + y;
1525 }
1526 if (S == 0) {
1527 *u = offset - y;
1528 *v = offset - x;
1529 }
1530 }
1531
old_mdisps_convert(MFace * mface,MDisps * mdisp)1532 static void old_mdisps_convert(MFace *mface, MDisps *mdisp)
1533 {
1534 int newlvl = log(sqrt(mdisp->totdisp) - 1) / M_LN2;
1535 int oldlvl = newlvl + 1;
1536 int oldside = multires_side_tot[oldlvl];
1537 int newside = multires_side_tot[newlvl];
1538 int nvert = (mface->v4) ? 4 : 3;
1539 int newtotdisp = multires_grid_tot[newlvl] * nvert;
1540 int x, y, S;
1541 float(*disps)[3], (*out)[3], u = 0.0f, v = 0.0f; /* Quite gcc barking. */
1542
1543 disps = MEM_calloc_arrayN(newtotdisp, sizeof(float[3]), "multires disps");
1544
1545 out = disps;
1546 for (S = 0; S < nvert; S++) {
1547 for (y = 0; y < newside; y++) {
1548 for (x = 0; x < newside; x++, out++) {
1549 old_mdisps_rotate(S, newside, oldside, x, y, &u, &v);
1550 old_mdisps_bilinear(*out, mdisp->disps, oldside, u, v);
1551
1552 if (S == 1) {
1553 (*out)[1] = -(*out)[1];
1554 }
1555 else if (S == 2) {
1556 SWAP(float, (*out)[0], (*out)[1]);
1557 }
1558 else if (S == 3) {
1559 (*out)[0] = -(*out)[0];
1560 }
1561 else if (S == 0) {
1562 SWAP(float, (*out)[0], (*out)[1]);
1563 (*out)[0] = -(*out)[0];
1564 (*out)[1] = -(*out)[1];
1565 }
1566 }
1567 }
1568 }
1569
1570 MEM_freeN(mdisp->disps);
1571
1572 mdisp->totdisp = newtotdisp;
1573 mdisp->level = newlvl;
1574 mdisp->disps = disps;
1575 }
1576
multires_load_old_250(Mesh * me)1577 void multires_load_old_250(Mesh *me)
1578 {
1579 MDisps *mdisps, *mdisps2;
1580 MFace *mf;
1581 int i, j, k;
1582
1583 mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS);
1584
1585 if (mdisps) {
1586 for (i = 0; i < me->totface; i++) {
1587 if (mdisps[i].totdisp) {
1588 old_mdisps_convert(&me->mface[i], &mdisps[i]);
1589 }
1590 }
1591
1592 CustomData_add_layer(&me->ldata, CD_MDISPS, CD_CALLOC, NULL, me->totloop);
1593 mdisps2 = CustomData_get_layer(&me->ldata, CD_MDISPS);
1594
1595 k = 0;
1596 mf = me->mface;
1597 for (i = 0; i < me->totface; i++, mf++) {
1598 int nvert = mf->v4 ? 4 : 3;
1599 int totdisp = mdisps[i].totdisp / nvert;
1600
1601 for (j = 0; j < nvert; j++, k++) {
1602 mdisps2[k].disps = MEM_calloc_arrayN(
1603 totdisp, sizeof(float[3]), "multires disp in conversion");
1604 mdisps2[k].totdisp = totdisp;
1605 mdisps2[k].level = mdisps[i].level;
1606 memcpy(mdisps2[k].disps, mdisps[i].disps + totdisp * j, totdisp);
1607 }
1608 }
1609 }
1610 }
1611
1612 /* Does not actually free lvl itself */
multires_free_level(MultiresLevel * lvl)1613 static void multires_free_level(MultiresLevel *lvl)
1614 {
1615 if (lvl) {
1616 if (lvl->faces) {
1617 MEM_freeN(lvl->faces);
1618 }
1619 if (lvl->edges) {
1620 MEM_freeN(lvl->edges);
1621 }
1622 if (lvl->colfaces) {
1623 MEM_freeN(lvl->colfaces);
1624 }
1625 }
1626 }
1627
multires_free(Multires * mr)1628 void multires_free(Multires *mr)
1629 {
1630 if (mr) {
1631 MultiresLevel *lvl = mr->levels.first;
1632
1633 /* Free the first-level data */
1634 if (lvl) {
1635 CustomData_free(&mr->vdata, lvl->totvert);
1636 CustomData_free(&mr->fdata, lvl->totface);
1637 if (mr->edge_flags) {
1638 MEM_freeN(mr->edge_flags);
1639 }
1640 if (mr->edge_creases) {
1641 MEM_freeN(mr->edge_creases);
1642 }
1643 }
1644
1645 while (lvl) {
1646 multires_free_level(lvl);
1647 lvl = lvl->next;
1648 }
1649
1650 /* mr->verts may be NULL when loading old files,
1651 * see direct_link_mesh() in readfile.c, and T43560. */
1652 MEM_SAFE_FREE(mr->verts);
1653
1654 BLI_freelistN(&mr->levels);
1655
1656 MEM_freeN(mr);
1657 }
1658 }
1659
1660 typedef struct IndexNode {
1661 struct IndexNode *next, *prev;
1662 int index;
1663 } IndexNode;
1664
create_old_vert_face_map(ListBase ** map,IndexNode ** mem,const MultiresFace * mface,const int totvert,const int totface)1665 static void create_old_vert_face_map(ListBase **map,
1666 IndexNode **mem,
1667 const MultiresFace *mface,
1668 const int totvert,
1669 const int totface)
1670 {
1671 int i, j;
1672 IndexNode *node = NULL;
1673
1674 (*map) = MEM_calloc_arrayN(totvert, sizeof(ListBase), "vert face map");
1675 (*mem) = MEM_calloc_arrayN(totface, sizeof(IndexNode[4]), "vert face map mem");
1676 node = *mem;
1677
1678 /* Find the users */
1679 for (i = 0; i < totface; i++) {
1680 for (j = 0; j < (mface[i].v[3] ? 4 : 3); j++, node++) {
1681 node->index = i;
1682 BLI_addtail(&(*map)[mface[i].v[j]], node);
1683 }
1684 }
1685 }
1686
create_old_vert_edge_map(ListBase ** map,IndexNode ** mem,const MultiresEdge * medge,const int totvert,const int totedge)1687 static void create_old_vert_edge_map(ListBase **map,
1688 IndexNode **mem,
1689 const MultiresEdge *medge,
1690 const int totvert,
1691 const int totedge)
1692 {
1693 int i, j;
1694 IndexNode *node = NULL;
1695
1696 (*map) = MEM_calloc_arrayN(totvert, sizeof(ListBase), "vert edge map");
1697 (*mem) = MEM_calloc_arrayN(totedge, sizeof(IndexNode[2]), "vert edge map mem");
1698 node = *mem;
1699
1700 /* Find the users */
1701 for (i = 0; i < totedge; i++) {
1702 for (j = 0; j < 2; j++, node++) {
1703 node->index = i;
1704 BLI_addtail(&(*map)[medge[i].v[j]], node);
1705 }
1706 }
1707 }
1708
find_old_face(ListBase * map,MultiresFace * faces,int v1,int v2,int v3,int v4)1709 static MultiresFace *find_old_face(
1710 ListBase *map, MultiresFace *faces, int v1, int v2, int v3, int v4)
1711 {
1712 IndexNode *n1;
1713 int v[4], i, j;
1714
1715 v[0] = v1;
1716 v[1] = v2;
1717 v[2] = v3;
1718 v[3] = v4;
1719
1720 for (n1 = map[v1].first; n1; n1 = n1->next) {
1721 int fnd[4] = {0, 0, 0, 0};
1722
1723 for (i = 0; i < 4; i++) {
1724 for (j = 0; j < 4; j++) {
1725 if (v[i] == faces[n1->index].v[j]) {
1726 fnd[i] = 1;
1727 }
1728 }
1729 }
1730
1731 if (fnd[0] && fnd[1] && fnd[2] && fnd[3]) {
1732 return &faces[n1->index];
1733 }
1734 }
1735
1736 return NULL;
1737 }
1738
find_old_edge(ListBase * map,MultiresEdge * edges,int v1,int v2)1739 static MultiresEdge *find_old_edge(ListBase *map, MultiresEdge *edges, int v1, int v2)
1740 {
1741 IndexNode *n1, *n2;
1742
1743 for (n1 = map[v1].first; n1; n1 = n1->next) {
1744 for (n2 = map[v2].first; n2; n2 = n2->next) {
1745 if (n1->index == n2->index) {
1746 return &edges[n1->index];
1747 }
1748 }
1749 }
1750
1751 return NULL;
1752 }
1753
multires_load_old_edges(ListBase ** emap,MultiresLevel * lvl,int * vvmap,int dst,int v1,int v2,int mov)1754 static void multires_load_old_edges(
1755 ListBase **emap, MultiresLevel *lvl, int *vvmap, int dst, int v1, int v2, int mov)
1756 {
1757 int emid = find_old_edge(emap[2], lvl->edges, v1, v2)->mid;
1758 vvmap[dst + mov] = emid;
1759
1760 if (lvl->next->next) {
1761 multires_load_old_edges(emap + 1, lvl->next, vvmap, dst + mov, v1, emid, mov / 2);
1762 multires_load_old_edges(emap + 1, lvl->next, vvmap, dst + mov, v2, emid, -mov / 2);
1763 }
1764 }
1765
multires_load_old_faces(ListBase ** fmap,ListBase ** emap,MultiresLevel * lvl,int * vvmap,int dst,int v1,int v2,int v3,int v4,int st2,int st3)1766 static void multires_load_old_faces(ListBase **fmap,
1767 ListBase **emap,
1768 MultiresLevel *lvl,
1769 int *vvmap,
1770 int dst,
1771 int v1,
1772 int v2,
1773 int v3,
1774 int v4,
1775 int st2,
1776 int st3)
1777 {
1778 int fmid;
1779 int emid13, emid14, emid23, emid24;
1780
1781 if (lvl && lvl->next) {
1782 fmid = find_old_face(fmap[1], lvl->faces, v1, v2, v3, v4)->mid;
1783 vvmap[dst] = fmid;
1784
1785 emid13 = find_old_edge(emap[1], lvl->edges, v1, v3)->mid;
1786 emid14 = find_old_edge(emap[1], lvl->edges, v1, v4)->mid;
1787 emid23 = find_old_edge(emap[1], lvl->edges, v2, v3)->mid;
1788 emid24 = find_old_edge(emap[1], lvl->edges, v2, v4)->mid;
1789
1790 multires_load_old_faces(fmap + 1,
1791 emap + 1,
1792 lvl->next,
1793 vvmap,
1794 dst + st2 * st3 + st3,
1795 fmid,
1796 v2,
1797 emid23,
1798 emid24,
1799 st2,
1800 st3 / 2);
1801
1802 multires_load_old_faces(fmap + 1,
1803 emap + 1,
1804 lvl->next,
1805 vvmap,
1806 dst - st2 * st3 + st3,
1807 emid14,
1808 emid24,
1809 fmid,
1810 v4,
1811 st2,
1812 st3 / 2);
1813
1814 multires_load_old_faces(fmap + 1,
1815 emap + 1,
1816 lvl->next,
1817 vvmap,
1818 dst + st2 * st3 - st3,
1819 emid13,
1820 emid23,
1821 v3,
1822 fmid,
1823 st2,
1824 st3 / 2);
1825
1826 multires_load_old_faces(fmap + 1,
1827 emap + 1,
1828 lvl->next,
1829 vvmap,
1830 dst - st2 * st3 - st3,
1831 v1,
1832 fmid,
1833 emid13,
1834 emid14,
1835 st2,
1836 st3 / 2);
1837
1838 if (lvl->next->next) {
1839 multires_load_old_edges(emap, lvl->next, vvmap, dst, emid24, fmid, st3);
1840 multires_load_old_edges(emap, lvl->next, vvmap, dst, emid13, fmid, -st3);
1841 multires_load_old_edges(emap, lvl->next, vvmap, dst, emid14, fmid, -st2 * st3);
1842 multires_load_old_edges(emap, lvl->next, vvmap, dst, emid23, fmid, st2 * st3);
1843 }
1844 }
1845 }
1846
multires_mvert_to_ss(DerivedMesh * dm,MVert * mvert)1847 static void multires_mvert_to_ss(DerivedMesh *dm, MVert *mvert)
1848 {
1849 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1850 CCGSubSurf *ss = ccgdm->ss;
1851 CCGElem *vd;
1852 CCGKey key;
1853 int index;
1854 int totvert, totedge, totface;
1855 int gridSize = ccgSubSurf_getGridSize(ss);
1856 int edgeSize = ccgSubSurf_getEdgeSize(ss);
1857 int i = 0;
1858
1859 dm->getGridKey(dm, &key);
1860
1861 totface = ccgSubSurf_getNumFaces(ss);
1862 for (index = 0; index < totface; index++) {
1863 CCGFace *f = ccgdm->faceMap[index].face;
1864 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1865
1866 vd = ccgSubSurf_getFaceCenterData(f);
1867 copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co);
1868 i++;
1869
1870 for (S = 0; S < numVerts; S++) {
1871 for (x = 1; x < gridSize - 1; x++, i++) {
1872 vd = ccgSubSurf_getFaceGridEdgeData(ss, f, S, x);
1873 copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co);
1874 }
1875 }
1876
1877 for (S = 0; S < numVerts; S++) {
1878 for (y = 1; y < gridSize - 1; y++) {
1879 for (x = 1; x < gridSize - 1; x++, i++) {
1880 vd = ccgSubSurf_getFaceGridData(ss, f, S, x, y);
1881 copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co);
1882 }
1883 }
1884 }
1885 }
1886
1887 totedge = ccgSubSurf_getNumEdges(ss);
1888 for (index = 0; index < totedge; index++) {
1889 CCGEdge *e = ccgdm->edgeMap[index].edge;
1890 int x;
1891
1892 for (x = 1; x < edgeSize - 1; x++, i++) {
1893 vd = ccgSubSurf_getEdgeData(ss, e, x);
1894 copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co);
1895 }
1896 }
1897
1898 totvert = ccgSubSurf_getNumVerts(ss);
1899 for (index = 0; index < totvert; index++) {
1900 CCGVert *v = ccgdm->vertMap[index].vert;
1901
1902 vd = ccgSubSurf_getVertData(ss, v);
1903 copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co);
1904 i++;
1905 }
1906
1907 ccgSubSurf_updateToFaces(ss, 0, NULL, 0);
1908 }
1909
1910 /* Loads a multires object stored in the old Multires struct into the new format */
multires_load_old_dm(DerivedMesh * dm,Mesh * me,int totlvl)1911 static void multires_load_old_dm(DerivedMesh *dm, Mesh *me, int totlvl)
1912 {
1913 MultiresLevel *lvl, *lvl1;
1914 Multires *mr = me->mr;
1915 MVert *vsrc, *vdst;
1916 unsigned int src, dst;
1917 int st_last = multires_side_tot[totlvl - 1] - 1;
1918 int extedgelen = multires_side_tot[totlvl] - 2;
1919 int *vvmap; // inorder for dst, map to src
1920 int crossedgelen;
1921 int s, x, tottri, totquad;
1922 unsigned int i, j, totvert;
1923
1924 src = 0;
1925 vsrc = mr->verts;
1926 vdst = dm->getVertArray(dm);
1927 totvert = (unsigned int)dm->getNumVerts(dm);
1928 vvmap = MEM_calloc_arrayN(totvert, sizeof(int), "multires vvmap");
1929
1930 if (!vvmap) {
1931 return;
1932 }
1933
1934 lvl1 = mr->levels.first;
1935 /* Load base verts */
1936 for (i = 0; i < lvl1->totvert; i++) {
1937 vvmap[totvert - lvl1->totvert + i] = src;
1938 src++;
1939 }
1940
1941 /* Original edges */
1942 dst = totvert - lvl1->totvert - extedgelen * lvl1->totedge;
1943 for (i = 0; i < lvl1->totedge; i++) {
1944 int ldst = dst + extedgelen * i;
1945 int lsrc = src;
1946 lvl = lvl1->next;
1947
1948 for (j = 2; j <= mr->level_count; j++) {
1949 int base = multires_side_tot[totlvl - j + 1] - 2;
1950 int skip = multires_side_tot[totlvl - j + 2] - 1;
1951 int st = multires_side_tot[j - 1] - 1;
1952
1953 for (x = 0; x < st; x++) {
1954 vvmap[ldst + base + x * skip] = lsrc + st * i + x;
1955 }
1956
1957 lsrc += lvl->totvert - lvl->prev->totvert;
1958 lvl = lvl->next;
1959 }
1960 }
1961
1962 /* Center points */
1963 dst = 0;
1964 for (i = 0; i < lvl1->totface; i++) {
1965 int sides = lvl1->faces[i].v[3] ? 4 : 3;
1966
1967 vvmap[dst] = src + lvl1->totedge + i;
1968 dst += 1 + sides * (st_last - 1) * st_last;
1969 }
1970
1971 /* The rest is only for level 3 and up */
1972 if (lvl1->next && lvl1->next->next) {
1973 ListBase **fmap, **emap;
1974 IndexNode **fmem, **emem;
1975
1976 /* Face edge cross */
1977 tottri = totquad = 0;
1978 crossedgelen = multires_side_tot[totlvl - 1] - 2;
1979 dst = 0;
1980 for (i = 0; i < lvl1->totface; i++) {
1981 int sides = lvl1->faces[i].v[3] ? 4 : 3;
1982
1983 lvl = lvl1->next->next;
1984 dst++;
1985
1986 for (j = 3; j <= mr->level_count; j++) {
1987 int base = multires_side_tot[totlvl - j + 1] - 2;
1988 int skip = multires_side_tot[totlvl - j + 2] - 1;
1989 int st = pow(2, j - 2);
1990 int st2 = pow(2, j - 3);
1991 int lsrc = lvl->prev->totvert;
1992
1993 /* Skip exterior edge verts */
1994 lsrc += lvl1->totedge * st;
1995
1996 /* Skip earlier face edge crosses */
1997 lsrc += st2 * (tottri * 3 + totquad * 4);
1998
1999 for (s = 0; s < sides; s++) {
2000 for (x = 0; x < st2; x++) {
2001 vvmap[dst + crossedgelen * (s + 1) - base - x * skip - 1] = lsrc;
2002 lsrc++;
2003 }
2004 }
2005
2006 lvl = lvl->next;
2007 }
2008
2009 dst += sides * (st_last - 1) * st_last;
2010
2011 if (sides == 4) {
2012 totquad++;
2013 }
2014 else {
2015 tottri++;
2016 }
2017 }
2018
2019 /* calculate vert to edge/face maps for each level (except the last) */
2020 fmap = MEM_calloc_arrayN((mr->level_count - 1), sizeof(ListBase *), "multires fmap");
2021 emap = MEM_calloc_arrayN((mr->level_count - 1), sizeof(ListBase *), "multires emap");
2022 fmem = MEM_calloc_arrayN((mr->level_count - 1), sizeof(IndexNode *), "multires fmem");
2023 emem = MEM_calloc_arrayN((mr->level_count - 1), sizeof(IndexNode *), "multires emem");
2024 lvl = lvl1;
2025 for (i = 0; i < (unsigned int)mr->level_count - 1; i++) {
2026 create_old_vert_face_map(fmap + i, fmem + i, lvl->faces, lvl->totvert, lvl->totface);
2027 create_old_vert_edge_map(emap + i, emem + i, lvl->edges, lvl->totvert, lvl->totedge);
2028 lvl = lvl->next;
2029 }
2030
2031 /* Interior face verts */
2032 /* lvl = lvl1->next->next; */ /* UNUSED */
2033 dst = 0;
2034 for (j = 0; j < lvl1->totface; j++) {
2035 int sides = lvl1->faces[j].v[3] ? 4 : 3;
2036 int ldst = dst + 1 + sides * (st_last - 1);
2037
2038 for (s = 0; s < sides; s++) {
2039 int st2 = multires_side_tot[totlvl - 1] - 2;
2040 int st3 = multires_side_tot[totlvl - 2] - 2;
2041 int st4 = st3 == 0 ? 1 : (st3 + 1) / 2;
2042 int mid = ldst + st2 * st3 + st3;
2043 int cv = lvl1->faces[j].v[s];
2044 int nv = lvl1->faces[j].v[s == sides - 1 ? 0 : s + 1];
2045 int pv = lvl1->faces[j].v[s == 0 ? sides - 1 : s - 1];
2046
2047 multires_load_old_faces(fmap,
2048 emap,
2049 lvl1->next,
2050 vvmap,
2051 mid,
2052 vvmap[dst],
2053 cv,
2054 find_old_edge(emap[0], lvl1->edges, pv, cv)->mid,
2055 find_old_edge(emap[0], lvl1->edges, cv, nv)->mid,
2056 st2,
2057 st4);
2058
2059 ldst += (st_last - 1) * (st_last - 1);
2060 }
2061
2062 dst = ldst;
2063 }
2064
2065 /*lvl = lvl->next;*/ /*UNUSED*/
2066
2067 for (i = 0; i < (unsigned int)(mr->level_count - 1); i++) {
2068 MEM_freeN(fmap[i]);
2069 MEM_freeN(fmem[i]);
2070 MEM_freeN(emap[i]);
2071 MEM_freeN(emem[i]);
2072 }
2073
2074 MEM_freeN(fmap);
2075 MEM_freeN(emap);
2076 MEM_freeN(fmem);
2077 MEM_freeN(emem);
2078 }
2079
2080 /* Transfer verts */
2081 for (i = 0; i < totvert; i++) {
2082 copy_v3_v3(vdst[i].co, vsrc[vvmap[i]].co);
2083 }
2084
2085 MEM_freeN(vvmap);
2086
2087 multires_mvert_to_ss(dm, vdst);
2088 }
2089
2090 /* Copy the first-level vcol data to the mesh, if it exists */
2091 /* Warning: higher-level vcol data will be lost */
multires_load_old_vcols(Mesh * me)2092 static void multires_load_old_vcols(Mesh *me)
2093 {
2094 MultiresLevel *lvl;
2095 MultiresColFace *colface;
2096 MCol *mcol;
2097 int i, j;
2098
2099 if (!(lvl = me->mr->levels.first)) {
2100 return;
2101 }
2102
2103 if (!(colface = lvl->colfaces)) {
2104 return;
2105 }
2106
2107 /* older multires format never supported multiple vcol layers,
2108 * so we can assume the active vcol layer is the correct one */
2109 if (!(mcol = CustomData_get_layer(&me->fdata, CD_MCOL))) {
2110 return;
2111 }
2112
2113 for (i = 0; i < me->totface; i++) {
2114 for (j = 0; j < 4; j++) {
2115 mcol[i * 4 + j].a = colface[i].col[j].a;
2116 mcol[i * 4 + j].r = colface[i].col[j].r;
2117 mcol[i * 4 + j].g = colface[i].col[j].g;
2118 mcol[i * 4 + j].b = colface[i].col[j].b;
2119 }
2120 }
2121 }
2122
2123 /* Copy the first-level face-flag data to the mesh */
multires_load_old_face_flags(Mesh * me)2124 static void multires_load_old_face_flags(Mesh *me)
2125 {
2126 MultiresLevel *lvl;
2127 MultiresFace *faces;
2128 int i;
2129
2130 if (!(lvl = me->mr->levels.first)) {
2131 return;
2132 }
2133
2134 if (!(faces = lvl->faces)) {
2135 return;
2136 }
2137
2138 for (i = 0; i < me->totface; i++) {
2139 me->mface[i].flag = faces[i].flag;
2140 }
2141 }
2142
multires_load_old(Object * ob,Mesh * me)2143 void multires_load_old(Object *ob, Mesh *me)
2144 {
2145 MultiresLevel *lvl;
2146 ModifierData *md;
2147 MultiresModifierData *mmd;
2148 DerivedMesh *dm, *orig;
2149 CustomDataLayer *l;
2150 int i;
2151
2152 /* Load original level into the mesh */
2153 lvl = me->mr->levels.first;
2154 CustomData_free_layers(&me->vdata, CD_MVERT, lvl->totvert);
2155 CustomData_free_layers(&me->edata, CD_MEDGE, lvl->totedge);
2156 CustomData_free_layers(&me->fdata, CD_MFACE, lvl->totface);
2157 me->totvert = lvl->totvert;
2158 me->totedge = lvl->totedge;
2159 me->totface = lvl->totface;
2160 me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert);
2161 me->medge = CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, me->totedge);
2162 me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface);
2163 memcpy(me->mvert, me->mr->verts, sizeof(MVert) * me->totvert);
2164 for (i = 0; i < me->totedge; i++) {
2165 me->medge[i].v1 = lvl->edges[i].v[0];
2166 me->medge[i].v2 = lvl->edges[i].v[1];
2167 }
2168 for (i = 0; i < me->totface; i++) {
2169 me->mface[i].v1 = lvl->faces[i].v[0];
2170 me->mface[i].v2 = lvl->faces[i].v[1];
2171 me->mface[i].v3 = lvl->faces[i].v[2];
2172 me->mface[i].v4 = lvl->faces[i].v[3];
2173 me->mface[i].mat_nr = lvl->faces[i].mat_nr;
2174 }
2175
2176 /* Copy the first-level data to the mesh */
2177 /* XXX We must do this before converting tessfaces to polys/lopps! */
2178 for (i = 0, l = me->mr->vdata.layers; i < me->mr->vdata.totlayer; i++, l++) {
2179 CustomData_add_layer(&me->vdata, l->type, CD_REFERENCE, l->data, me->totvert);
2180 }
2181 for (i = 0, l = me->mr->fdata.layers; i < me->mr->fdata.totlayer; i++, l++) {
2182 CustomData_add_layer(&me->fdata, l->type, CD_REFERENCE, l->data, me->totface);
2183 }
2184 CustomData_reset(&me->mr->vdata);
2185 CustomData_reset(&me->mr->fdata);
2186
2187 multires_load_old_vcols(me);
2188 multires_load_old_face_flags(me);
2189
2190 /* multiresModifier_subdivide_legacy (actually, multires_subdivide_legacy) expects polys, not
2191 * tessfaces! */
2192 BKE_mesh_convert_mfaces_to_mpolys(me);
2193
2194 /* Add a multires modifier to the object */
2195 md = ob->modifiers.first;
2196 while (md && BKE_modifier_get_info(md->type)->type == eModifierTypeType_OnlyDeform) {
2197 md = md->next;
2198 }
2199 mmd = (MultiresModifierData *)BKE_modifier_new(eModifierType_Multires);
2200 BLI_insertlinkbefore(&ob->modifiers, md, mmd);
2201
2202 for (i = 0; i < me->mr->level_count - 1; i++) {
2203 multiresModifier_subdivide_legacy(mmd, NULL, ob, 1, 0);
2204 }
2205
2206 mmd->lvl = mmd->totlvl;
2207 orig = CDDM_from_mesh(me);
2208 /* XXX We *must* alloc paint mask here, else we have some kind of mismatch in
2209 * multires_modifier_update_mdisps() (called by dm->release(dm)), which always creates the
2210 * reference subsurfed dm with this option, before calling multiresModifier_disp_run(),
2211 * which implicitly expects both subsurfs from its first dm and oldGridData parameters to
2212 * be of the same "format"! */
2213 dm = multires_make_derived_from_derived(orig, mmd, NULL, ob, 0);
2214
2215 multires_load_old_dm(dm, me, mmd->totlvl + 1);
2216
2217 multires_dm_mark_as_modified(dm, MULTIRES_COORDS_MODIFIED);
2218 dm->release(dm);
2219 orig->release(orig);
2220
2221 /* Remove the old multires */
2222 multires_free(me->mr);
2223 me->mr = NULL;
2224 }
2225
2226 /* If 'ob_src' and 'ob_dst' both have multires modifiers, synchronize them
2227 * such that 'ob_dst' has the same total number of levels as 'ob_src'. */
multiresModifier_sync_levels_ex(Object * ob_dst,MultiresModifierData * mmd_src,MultiresModifierData * mmd_dst)2228 void multiresModifier_sync_levels_ex(Object *ob_dst,
2229 MultiresModifierData *mmd_src,
2230 MultiresModifierData *mmd_dst)
2231 {
2232 if (mmd_src->totlvl == mmd_dst->totlvl) {
2233 return;
2234 }
2235
2236 if (mmd_src->totlvl > mmd_dst->totlvl) {
2237 if (mmd_dst->simple) {
2238 multiresModifier_subdivide_to_level(
2239 ob_dst, mmd_dst, mmd_src->totlvl, MULTIRES_SUBDIVIDE_SIMPLE);
2240 }
2241 else {
2242 multiresModifier_subdivide_to_level(
2243 ob_dst, mmd_dst, mmd_src->totlvl, MULTIRES_SUBDIVIDE_CATMULL_CLARK);
2244 }
2245 }
2246 else {
2247 multires_del_higher(mmd_dst, ob_dst, mmd_src->totlvl);
2248 }
2249 }
2250
multires_sync_levels(Scene * scene,Object * ob_src,Object * ob_dst)2251 static void multires_sync_levels(Scene *scene, Object *ob_src, Object *ob_dst)
2252 {
2253 MultiresModifierData *mmd_src = get_multires_modifier(scene, ob_src, true);
2254 MultiresModifierData *mmd_dst = get_multires_modifier(scene, ob_dst, true);
2255
2256 if (!mmd_src) {
2257 /* object could have MDISP even when there is no multires modifier
2258 * this could lead to troubles due to i've got no idea how mdisp could be
2259 * up-sampled correct without modifier data.
2260 * just remove mdisps if no multires present (nazgul) */
2261
2262 multires_customdata_delete(ob_src->data);
2263 }
2264
2265 if (mmd_src && mmd_dst) {
2266 multiresModifier_sync_levels_ex(ob_dst, mmd_src, mmd_dst);
2267 }
2268 }
2269
multires_apply_uniform_scale(Object * object,const float scale)2270 static void multires_apply_uniform_scale(Object *object, const float scale)
2271 {
2272 Mesh *mesh = (Mesh *)object->data;
2273 MDisps *mdisps = CustomData_get_layer(&mesh->ldata, CD_MDISPS);
2274 for (int i = 0; i < mesh->totloop; i++) {
2275 MDisps *grid = &mdisps[i];
2276 for (int j = 0; j < grid->totdisp; j++) {
2277 mul_v3_fl(grid->disps[j], scale);
2278 }
2279 }
2280 }
2281
multires_apply_smat(struct Depsgraph * UNUSED (depsgraph),Scene * scene,Object * object,const float smat[3][3])2282 static void multires_apply_smat(struct Depsgraph *UNUSED(depsgraph),
2283 Scene *scene,
2284 Object *object,
2285 const float smat[3][3])
2286 {
2287 const MultiresModifierData *mmd = get_multires_modifier(scene, object, true);
2288 if (mmd == NULL || mmd->totlvl == 0) {
2289 return;
2290 }
2291 /* Make sure layer present. */
2292 Mesh *mesh = (Mesh *)object->data;
2293 multiresModifier_ensure_external_read(mesh, mmd);
2294 if (!CustomData_get_layer(&mesh->ldata, CD_MDISPS)) {
2295 return;
2296 }
2297 if (is_uniform_scaled_m3(smat)) {
2298 const float scale = mat3_to_scale(smat);
2299 multires_apply_uniform_scale(object, scale);
2300 }
2301 else {
2302 /* TODO(sergey): This branch of code actually requires more work to
2303 * preserve all the details.
2304 */
2305 const float scale = mat3_to_scale(smat);
2306 multires_apply_uniform_scale(object, scale);
2307 }
2308 }
2309
multires_mdisp_corners(MDisps * s)2310 int multires_mdisp_corners(MDisps *s)
2311 {
2312 int lvl = 13;
2313
2314 while (lvl > 0) {
2315 int side = (1 << (lvl - 1)) + 1;
2316 if ((s->totdisp % (side * side)) == 0) {
2317 return s->totdisp / (side * side);
2318 }
2319 lvl--;
2320 }
2321
2322 return 0;
2323 }
2324
multiresModifier_scale_disp(struct Depsgraph * depsgraph,Scene * scene,Object * ob)2325 void multiresModifier_scale_disp(struct Depsgraph *depsgraph, Scene *scene, Object *ob)
2326 {
2327 float smat[3][3];
2328
2329 /* object's scale matrix */
2330 BKE_object_scale_to_mat3(ob, smat);
2331
2332 multires_apply_smat(depsgraph, scene, ob, smat);
2333 }
2334
multiresModifier_prepare_join(struct Depsgraph * depsgraph,Scene * scene,Object * ob,Object * to_ob)2335 void multiresModifier_prepare_join(struct Depsgraph *depsgraph,
2336 Scene *scene,
2337 Object *ob,
2338 Object *to_ob)
2339 {
2340 float smat[3][3], tmat[3][3], mat[3][3];
2341 multires_sync_levels(scene, to_ob, ob);
2342
2343 /* construct scale matrix for displacement */
2344 BKE_object_scale_to_mat3(to_ob, tmat);
2345 invert_m3(tmat);
2346 BKE_object_scale_to_mat3(ob, smat);
2347 mul_m3_m3m3(mat, smat, tmat);
2348
2349 multires_apply_smat(depsgraph, scene, ob, mat);
2350 }
2351
2352 /* update multires data after topology changing */
multires_topology_changed(Mesh * me)2353 void multires_topology_changed(Mesh *me)
2354 {
2355 MDisps *mdisp = NULL, *cur = NULL;
2356 int i, grid = 0;
2357
2358 CustomData_external_read(&me->ldata, &me->id, CD_MASK_MDISPS, me->totloop);
2359 mdisp = CustomData_get_layer(&me->ldata, CD_MDISPS);
2360
2361 if (!mdisp) {
2362 return;
2363 }
2364
2365 cur = mdisp;
2366 for (i = 0; i < me->totloop; i++, cur++) {
2367 if (cur->totdisp) {
2368 grid = mdisp->totdisp;
2369
2370 break;
2371 }
2372 }
2373
2374 for (i = 0; i < me->totloop; i++, mdisp++) {
2375 /* allocate memory for mdisp, the whole disp layer would be erased otherwise */
2376 if (!mdisp->totdisp || !mdisp->disps) {
2377 if (grid) {
2378 mdisp->totdisp = grid;
2379 mdisp->disps = MEM_calloc_arrayN(sizeof(float[3]), mdisp->totdisp, "mdisp topology");
2380 }
2381
2382 continue;
2383 }
2384 }
2385 }
2386
2387 /* Makes sure data from an external file is fully read.
2388 *
2389 * Since the multires data files only contain displacement vectors without knowledge about
2390 * subdivision level some extra work is needed. Namely make is to all displacement grids have
2391 * proper level and number of displacement vectors set. */
multires_ensure_external_read(struct Mesh * mesh,int top_level)2392 void multires_ensure_external_read(struct Mesh *mesh, int top_level)
2393 {
2394 if (!CustomData_external_test(&mesh->ldata, CD_MDISPS)) {
2395 return;
2396 }
2397
2398 MDisps *mdisps = CustomData_get_layer(&mesh->ldata, CD_MDISPS);
2399 if (mdisps == NULL) {
2400 mdisps = CustomData_add_layer(&mesh->ldata, CD_MDISPS, CD_DEFAULT, NULL, mesh->totloop);
2401 }
2402
2403 const int totloop = mesh->totloop;
2404
2405 for (int i = 0; i < totloop; ++i) {
2406 if (mdisps[i].level != top_level) {
2407 MEM_SAFE_FREE(mdisps[i].disps);
2408 }
2409
2410 /* NOTE: CustomData_external_read will take care of allocation of displacement vectors if
2411 * they are missing. */
2412
2413 const int totdisp = multires_grid_tot[top_level];
2414 mdisps[i].totdisp = totdisp;
2415 mdisps[i].level = top_level;
2416 }
2417
2418 CustomData_external_read(&mesh->ldata, &mesh->id, CD_MASK_MDISPS, mesh->totloop);
2419 }
multiresModifier_ensure_external_read(struct Mesh * mesh,const MultiresModifierData * mmd)2420 void multiresModifier_ensure_external_read(struct Mesh *mesh, const MultiresModifierData *mmd)
2421 {
2422 multires_ensure_external_read(mesh, mmd->totlvl);
2423 }
2424
2425 /***************** Multires interpolation stuff *****************/
2426
2427 /* Find per-corner coordinate with given per-face UV coord */
mdisp_rot_face_to_crn(struct MVert * UNUSED (mvert),struct MPoly * mpoly,struct MLoop * UNUSED (mloop),const struct MLoopTri * UNUSED (lt),const int face_side,const float u,const float v,float * x,float * y)2428 int mdisp_rot_face_to_crn(struct MVert *UNUSED(mvert),
2429 struct MPoly *mpoly,
2430 struct MLoop *UNUSED(mloop),
2431 const struct MLoopTri *UNUSED(lt),
2432 const int face_side,
2433 const float u,
2434 const float v,
2435 float *x,
2436 float *y)
2437 {
2438 const float offset = face_side * 0.5f - 0.5f;
2439 int S = 0;
2440
2441 if (mpoly->totloop == 4) {
2442 if (u <= offset && v <= offset) {
2443 S = 0;
2444 }
2445 else if (u > offset && v <= offset) {
2446 S = 1;
2447 }
2448 else if (u > offset && v > offset) {
2449 S = 2;
2450 }
2451 else if (u <= offset && v >= offset) {
2452 S = 3;
2453 }
2454
2455 if (S == 0) {
2456 *y = offset - u;
2457 *x = offset - v;
2458 }
2459 else if (S == 1) {
2460 *x = u - offset;
2461 *y = offset - v;
2462 }
2463 else if (S == 2) {
2464 *y = u - offset;
2465 *x = v - offset;
2466 }
2467 else if (S == 3) {
2468 *x = offset - u;
2469 *y = v - offset;
2470 }
2471 }
2472 else if (mpoly->totloop == 3) {
2473 int grid_size = offset;
2474 float w = (face_side - 1) - u - v;
2475 float W1, W2;
2476
2477 if (u >= v && u >= w) {
2478 S = 0;
2479 W1 = w;
2480 W2 = v;
2481 }
2482 else if (v >= u && v >= w) {
2483 S = 1;
2484 W1 = u;
2485 W2 = w;
2486 }
2487 else {
2488 S = 2;
2489 W1 = v;
2490 W2 = u;
2491 }
2492
2493 W1 /= (face_side - 1);
2494 W2 /= (face_side - 1);
2495
2496 *x = (1 - (2 * W1) / (1 - W2)) * grid_size;
2497 *y = (1 - (2 * W2) / (1 - W1)) * grid_size;
2498 }
2499 else {
2500 /* the complicated ngon case: find the actual coordinate from
2501 * the barycentric coordinates and finally find the closest vertex
2502 * should work reliably for convex cases only but better than nothing */
2503
2504 #if 0
2505 int minS, i;
2506 float mindist = FLT_MAX;
2507
2508 for (i = 0; i < mpoly->totloop; i++) {
2509 float len = len_v3v3(NULL, mvert[mloop[mpoly->loopstart + i].v].co);
2510 if (len < mindist) {
2511 mindist = len;
2512 minS = i;
2513 }
2514 }
2515 S = minS;
2516 #endif
2517 /* temp not implemented yet and also not working properly in current master.
2518 * (was worked around by subdividing once) */
2519 S = 0;
2520 *x = 0;
2521 *y = 0;
2522 }
2523
2524 return S;
2525 }
2526