Cleanup: misc spelling fixes
[blender.git] / source / blender / modifiers / intern / MOD_correctivesmooth.c
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) 2005 by the Blender Foundation.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup modifiers
22  *
23  * Method of smoothing deformation, also known as 'delta-mush'.
24  */
25
26 #include "BLI_utildefines.h"
27
28 #include "BLI_math.h"
29
30 #include "DNA_scene_types.h"
31 #include "DNA_meshdata_types.h"
32 #include "DNA_object_types.h"
33 #include "DNA_mesh_types.h"
34
35 #include "MEM_guardedalloc.h"
36
37 #include "BKE_deform.h"
38 #include "BKE_mesh.h"
39 #include "BKE_editmesh.h"
40 #include "BKE_library.h"
41
42 #include "MOD_modifiertypes.h"
43 #include "MOD_util.h"
44
45 #include "BLI_strict_flags.h"
46
47 #include "DEG_depsgraph_query.h"
48
49 // #define DEBUG_TIME
50
51 #include "PIL_time.h"
52 #ifdef DEBUG_TIME
53 #  include "PIL_time_utildefines.h"
54 #endif
55
56 /* minor optimization, calculate this inline */
57 #define USE_TANGENT_CALC_INLINE
58
59 static void initData(ModifierData *md)
60 {
61   CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md;
62
63   csmd->bind_coords = NULL;
64   csmd->bind_coords_num = 0;
65
66   csmd->lambda = 0.5f;
67   csmd->repeat = 5;
68   csmd->flag = 0;
69   csmd->smooth_type = MOD_CORRECTIVESMOOTH_SMOOTH_SIMPLE;
70
71   csmd->defgrp_name[0] = '\0';
72
73   csmd->delta_cache = NULL;
74 }
75
76 static void copyData(const ModifierData *md, ModifierData *target, const int flag)
77 {
78   const CorrectiveSmoothModifierData *csmd = (const CorrectiveSmoothModifierData *)md;
79   CorrectiveSmoothModifierData *tcsmd = (CorrectiveSmoothModifierData *)target;
80
81   modifier_copyData_generic(md, target, flag);
82
83   if (csmd->bind_coords) {
84     tcsmd->bind_coords = MEM_dupallocN(csmd->bind_coords);
85   }
86
87   tcsmd->delta_cache = NULL;
88   tcsmd->delta_cache_num = 0;
89 }
90
91 static void freeBind(CorrectiveSmoothModifierData *csmd)
92 {
93   MEM_SAFE_FREE(csmd->bind_coords);
94   MEM_SAFE_FREE(csmd->delta_cache);
95
96   csmd->bind_coords_num = 0;
97 }
98
99 static void freeData(ModifierData *md)
100 {
101   CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md;
102   freeBind(csmd);
103 }
104
105 static void requiredDataMask(Object *UNUSED(ob),
106                              ModifierData *md,
107                              CustomData_MeshMasks *r_cddata_masks)
108 {
109   CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md;
110
111   /* ask for vertex groups if we need them */
112   if (csmd->defgrp_name[0] != '\0') {
113     r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
114   }
115 }
116
117 /* check individual weights for changes and cache values */
118 static void mesh_get_weights(MDeformVert *dvert,
119                              const int defgrp_index,
120                              const unsigned int numVerts,
121                              const bool use_invert_vgroup,
122                              float *smooth_weights)
123 {
124   unsigned int i;
125
126   for (i = 0; i < numVerts; i++, dvert++) {
127     const float w = defvert_find_weight(dvert, defgrp_index);
128
129     if (use_invert_vgroup == false) {
130       smooth_weights[i] = w;
131     }
132     else {
133       smooth_weights[i] = 1.0f - w;
134     }
135   }
136 }
137
138 static void mesh_get_boundaries(Mesh *mesh, float *smooth_weights)
139 {
140   const MPoly *mpoly = mesh->mpoly;
141   const MLoop *mloop = mesh->mloop;
142   const MEdge *medge = mesh->medge;
143   unsigned int mpoly_num, medge_num, i;
144   unsigned short *boundaries;
145
146   mpoly_num = (unsigned int)mesh->totpoly;
147   medge_num = (unsigned int)mesh->totedge;
148
149   boundaries = MEM_calloc_arrayN(medge_num, sizeof(*boundaries), __func__);
150
151   /* count the number of adjacent faces */
152   for (i = 0; i < mpoly_num; i++) {
153     const MPoly *p = &mpoly[i];
154     const int totloop = p->totloop;
155     int j;
156     for (j = 0; j < totloop; j++) {
157       boundaries[mloop[p->loopstart + j].e]++;
158     }
159   }
160
161   for (i = 0; i < medge_num; i++) {
162     if (boundaries[i] == 1) {
163       smooth_weights[medge[i].v1] = 0.0f;
164       smooth_weights[medge[i].v2] = 0.0f;
165     }
166   }
167
168   MEM_freeN(boundaries);
169 }
170
171 /* -------------------------------------------------------------------- */
172 /* Simple Weighted Smoothing
173  *
174  * (average of surrounding verts)
175  */
176 static void smooth_iter__simple(CorrectiveSmoothModifierData *csmd,
177                                 Mesh *mesh,
178                                 float (*vertexCos)[3],
179                                 unsigned int numVerts,
180                                 const float *smooth_weights,
181                                 unsigned int iterations)
182 {
183   const float lambda = csmd->lambda;
184   unsigned int i;
185
186   const unsigned int numEdges = (unsigned int)mesh->totedge;
187   const MEdge *edges = mesh->medge;
188   float *vertex_edge_count_div;
189
190   struct SmoothingData_Simple {
191     float delta[3];
192   } *smooth_data = MEM_calloc_arrayN(numVerts, sizeof(*smooth_data), __func__);
193
194   vertex_edge_count_div = MEM_calloc_arrayN(numVerts, sizeof(float), __func__);
195
196   /* calculate as floats to avoid int->float conversion in #smooth_iter */
197   for (i = 0; i < numEdges; i++) {
198     vertex_edge_count_div[edges[i].v1] += 1.0f;
199     vertex_edge_count_div[edges[i].v2] += 1.0f;
200   }
201
202   /* a little confusing, but we can include 'lambda' and smoothing weight
203    * here to avoid multiplying for every iteration */
204   if (smooth_weights == NULL) {
205     for (i = 0; i < numVerts; i++) {
206       vertex_edge_count_div[i] = lambda * (vertex_edge_count_div[i] ?
207                                                (1.0f / vertex_edge_count_div[i]) :
208                                                1.0f);
209     }
210   }
211   else {
212     for (i = 0; i < numVerts; i++) {
213       vertex_edge_count_div[i] = smooth_weights[i] * lambda *
214                                  (vertex_edge_count_div[i] ? (1.0f / vertex_edge_count_div[i]) :
215                                                              1.0f);
216     }
217   }
218
219   /* -------------------------------------------------------------------- */
220   /* Main Smoothing Loop */
221
222   while (iterations--) {
223     for (i = 0; i < numEdges; i++) {
224       struct SmoothingData_Simple *sd_v1;
225       struct SmoothingData_Simple *sd_v2;
226       float edge_dir[3];
227
228       sub_v3_v3v3(edge_dir, vertexCos[edges[i].v2], vertexCos[edges[i].v1]);
229
230       sd_v1 = &smooth_data[edges[i].v1];
231       sd_v2 = &smooth_data[edges[i].v2];
232
233       add_v3_v3(sd_v1->delta, edge_dir);
234       sub_v3_v3(sd_v2->delta, edge_dir);
235     }
236
237     for (i = 0; i < numVerts; i++) {
238       struct SmoothingData_Simple *sd = &smooth_data[i];
239       madd_v3_v3fl(vertexCos[i], sd->delta, vertex_edge_count_div[i]);
240       /* zero for the next iteration (saves memset on entire array) */
241       memset(sd, 0, sizeof(*sd));
242     }
243   }
244
245   MEM_freeN(vertex_edge_count_div);
246   MEM_freeN(smooth_data);
247 }
248
249 /* -------------------------------------------------------------------- */
250 /* Edge-Length Weighted Smoothing
251  */
252 static void smooth_iter__length_weight(CorrectiveSmoothModifierData *csmd,
253                                        Mesh *mesh,
254                                        float (*vertexCos)[3],
255                                        unsigned int numVerts,
256                                        const float *smooth_weights,
257                                        unsigned int iterations)
258 {
259   const float eps = FLT_EPSILON * 10.0f;
260   const unsigned int numEdges = (unsigned int)mesh->totedge;
261   /* note: the way this smoothing method works, its approx half as strong as the simple-smooth,
262    * and 2.0 rarely spikes, double the value for consistent behavior. */
263   const float lambda = csmd->lambda * 2.0f;
264   const MEdge *edges = mesh->medge;
265   float *vertex_edge_count;
266   unsigned int i;
267
268   struct SmoothingData_Weighted {
269     float delta[3];
270     float edge_length_sum;
271   } *smooth_data = MEM_calloc_arrayN(numVerts, sizeof(*smooth_data), __func__);
272
273   /* calculate as floats to avoid int->float conversion in #smooth_iter */
274   vertex_edge_count = MEM_calloc_arrayN(numVerts, sizeof(float), __func__);
275   for (i = 0; i < numEdges; i++) {
276     vertex_edge_count[edges[i].v1] += 1.0f;
277     vertex_edge_count[edges[i].v2] += 1.0f;
278   }
279
280   /* -------------------------------------------------------------------- */
281   /* Main Smoothing Loop */
282
283   while (iterations--) {
284     for (i = 0; i < numEdges; i++) {
285       struct SmoothingData_Weighted *sd_v1;
286       struct SmoothingData_Weighted *sd_v2;
287       float edge_dir[3];
288       float edge_dist;
289
290       sub_v3_v3v3(edge_dir, vertexCos[edges[i].v2], vertexCos[edges[i].v1]);
291       edge_dist = len_v3(edge_dir);
292
293       /* weight by distance */
294       mul_v3_fl(edge_dir, edge_dist);
295
296       sd_v1 = &smooth_data[edges[i].v1];
297       sd_v2 = &smooth_data[edges[i].v2];
298
299       add_v3_v3(sd_v1->delta, edge_dir);
300       sub_v3_v3(sd_v2->delta, edge_dir);
301
302       sd_v1->edge_length_sum += edge_dist;
303       sd_v2->edge_length_sum += edge_dist;
304     }
305
306     if (smooth_weights == NULL) {
307       /* fast-path */
308       for (i = 0; i < numVerts; i++) {
309         struct SmoothingData_Weighted *sd = &smooth_data[i];
310         /* Divide by sum of all neighbour distances (weighted) and amount of neighbors,
311          * (mean average). */
312         const float div = sd->edge_length_sum * vertex_edge_count[i];
313         if (div > eps) {
314 #if 0
315           /* first calculate the new location */
316           mul_v3_fl(sd->delta, 1.0f / div);
317           /* then interpolate */
318           madd_v3_v3fl(vertexCos[i], sd->delta, lambda);
319 #else
320           /* do this in one step */
321           madd_v3_v3fl(vertexCos[i], sd->delta, lambda / div);
322 #endif
323         }
324         /* zero for the next iteration (saves memset on entire array) */
325         memset(sd, 0, sizeof(*sd));
326       }
327     }
328     else {
329       for (i = 0; i < numVerts; i++) {
330         struct SmoothingData_Weighted *sd = &smooth_data[i];
331         const float div = sd->edge_length_sum * vertex_edge_count[i];
332         if (div > eps) {
333           const float lambda_w = lambda * smooth_weights[i];
334           madd_v3_v3fl(vertexCos[i], sd->delta, lambda_w / div);
335         }
336
337         memset(sd, 0, sizeof(*sd));
338       }
339     }
340   }
341
342   MEM_freeN(vertex_edge_count);
343   MEM_freeN(smooth_data);
344 }
345
346 static void smooth_iter(CorrectiveSmoothModifierData *csmd,
347                         Mesh *mesh,
348                         float (*vertexCos)[3],
349                         unsigned int numVerts,
350                         const float *smooth_weights,
351                         unsigned int iterations)
352 {
353   switch (csmd->smooth_type) {
354     case MOD_CORRECTIVESMOOTH_SMOOTH_LENGTH_WEIGHT:
355       smooth_iter__length_weight(csmd, mesh, vertexCos, numVerts, smooth_weights, iterations);
356       break;
357
358     /* case MOD_CORRECTIVESMOOTH_SMOOTH_SIMPLE: */
359     default:
360       smooth_iter__simple(csmd, mesh, vertexCos, numVerts, smooth_weights, iterations);
361       break;
362   }
363 }
364
365 static void smooth_verts(CorrectiveSmoothModifierData *csmd,
366                          Mesh *mesh,
367                          MDeformVert *dvert,
368                          const int defgrp_index,
369                          float (*vertexCos)[3],
370                          unsigned int numVerts)
371 {
372   float *smooth_weights = NULL;
373
374   if (dvert || (csmd->flag & MOD_CORRECTIVESMOOTH_PIN_BOUNDARY)) {
375
376     smooth_weights = MEM_malloc_arrayN(numVerts, sizeof(float), __func__);
377
378     if (dvert) {
379       mesh_get_weights(dvert,
380                        defgrp_index,
381                        numVerts,
382                        (csmd->flag & MOD_CORRECTIVESMOOTH_INVERT_VGROUP) != 0,
383                        smooth_weights);
384     }
385     else {
386       copy_vn_fl(smooth_weights, (int)numVerts, 1.0f);
387     }
388
389     if (csmd->flag & MOD_CORRECTIVESMOOTH_PIN_BOUNDARY) {
390       mesh_get_boundaries(mesh, smooth_weights);
391     }
392   }
393
394   smooth_iter(csmd, mesh, vertexCos, numVerts, smooth_weights, (unsigned int)csmd->repeat);
395
396   if (smooth_weights) {
397     MEM_freeN(smooth_weights);
398   }
399 }
400
401 /**
402  * finalize after accumulation.
403  */
404 static void calc_tangent_ortho(float ts[3][3])
405 {
406   float v_tan_a[3], v_tan_b[3];
407   float t_vec_a[3], t_vec_b[3];
408
409   normalize_v3(ts[2]);
410
411   copy_v3_v3(v_tan_a, ts[0]);
412   copy_v3_v3(v_tan_b, ts[1]);
413
414   cross_v3_v3v3(ts[1], ts[2], v_tan_a);
415   mul_v3_fl(ts[1], dot_v3v3(ts[1], v_tan_b) < 0.0f ? -1.0f : 1.0f);
416
417   /* orthognalise tangent */
418   mul_v3_v3fl(t_vec_a, ts[2], dot_v3v3(ts[2], v_tan_a));
419   sub_v3_v3v3(ts[0], v_tan_a, t_vec_a);
420
421   /* orthognalise bitangent */
422   mul_v3_v3fl(t_vec_a, ts[2], dot_v3v3(ts[2], ts[1]));
423   mul_v3_v3fl(t_vec_b, ts[0], dot_v3v3(ts[0], ts[1]) / dot_v3v3(v_tan_a, v_tan_a));
424   sub_v3_v3(ts[1], t_vec_a);
425   sub_v3_v3(ts[1], t_vec_b);
426
427   normalize_v3(ts[0]);
428   normalize_v3(ts[1]);
429 }
430
431 /**
432  * accumulate edge-vectors from all polys.
433  */
434 static void calc_tangent_loop_accum(const float v_dir_prev[3],
435                                     const float v_dir_next[3],
436                                     float r_tspace[3][3])
437 {
438   add_v3_v3v3(r_tspace[1], v_dir_prev, v_dir_next);
439
440   if (compare_v3v3(v_dir_prev, v_dir_next, FLT_EPSILON * 10.0f) == false) {
441     const float weight = fabsf(acosf(dot_v3v3(v_dir_next, v_dir_prev)));
442     float nor[3];
443
444     cross_v3_v3v3(nor, v_dir_prev, v_dir_next);
445     normalize_v3(nor);
446
447     cross_v3_v3v3(r_tspace[0], r_tspace[1], nor);
448
449     mul_v3_fl(nor, weight);
450     /* accumulate weighted normals */
451     add_v3_v3(r_tspace[2], nor);
452   }
453 }
454
455 static void calc_tangent_spaces(Mesh *mesh, float (*vertexCos)[3], float (*r_tangent_spaces)[3][3])
456 {
457   const unsigned int mpoly_num = (unsigned int)mesh->totpoly;
458 #ifndef USE_TANGENT_CALC_INLINE
459   const unsigned int mvert_num = (unsigned int)dm->getNumVerts(dm);
460 #endif
461   const MPoly *mpoly = mesh->mpoly;
462   const MLoop *mloop = mesh->mloop;
463   unsigned int i;
464
465   for (i = 0; i < mpoly_num; i++) {
466     const MPoly *mp = &mpoly[i];
467     const MLoop *l_next = &mloop[mp->loopstart];
468     const MLoop *l_term = l_next + mp->totloop;
469     const MLoop *l_prev = l_term - 2;
470     const MLoop *l_curr = l_term - 1;
471
472     /* loop directions */
473     float v_dir_prev[3], v_dir_next[3];
474
475     /* needed entering the loop */
476     sub_v3_v3v3(v_dir_prev, vertexCos[l_prev->v], vertexCos[l_curr->v]);
477     normalize_v3(v_dir_prev);
478
479     for (; l_next != l_term; l_prev = l_curr, l_curr = l_next, l_next++) {
480       float(*ts)[3] = r_tangent_spaces[l_curr->v];
481
482       /* re-use the previous value */
483 #if 0
484       sub_v3_v3v3(v_dir_prev, vertexCos[l_prev->v], vertexCos[l_curr->v]);
485       normalize_v3(v_dir_prev);
486 #endif
487       sub_v3_v3v3(v_dir_next, vertexCos[l_curr->v], vertexCos[l_next->v]);
488       normalize_v3(v_dir_next);
489
490       calc_tangent_loop_accum(v_dir_prev, v_dir_next, ts);
491
492       copy_v3_v3(v_dir_prev, v_dir_next);
493     }
494   }
495
496   /* do inline */
497 #ifndef USE_TANGENT_CALC_INLINE
498   for (i = 0; i < mvert_num; i++) {
499     float(*ts)[3] = r_tangent_spaces[i];
500     calc_tangent_ortho(ts);
501   }
502 #endif
503 }
504
505 /**
506  * This calculates #CorrectiveSmoothModifierData.delta_cache
507  * It's not run on every update (during animation for example).
508  */
509 static void calc_deltas(CorrectiveSmoothModifierData *csmd,
510                         Mesh *mesh,
511                         MDeformVert *dvert,
512                         const int defgrp_index,
513                         const float (*rest_coords)[3],
514                         unsigned int numVerts)
515 {
516   float(*smooth_vertex_coords)[3] = MEM_dupallocN(rest_coords);
517   float(*tangent_spaces)[3][3];
518   unsigned int i;
519
520   tangent_spaces = MEM_calloc_arrayN(numVerts, sizeof(float[3][3]), __func__);
521
522   if (csmd->delta_cache_num != numVerts) {
523     MEM_SAFE_FREE(csmd->delta_cache);
524   }
525
526   /* allocate deltas if they have not yet been allocated, otherwise we will just write over them */
527   if (!csmd->delta_cache) {
528     csmd->delta_cache_num = numVerts;
529     csmd->delta_cache = MEM_malloc_arrayN(numVerts, sizeof(float[3]), __func__);
530   }
531
532   smooth_verts(csmd, mesh, dvert, defgrp_index, smooth_vertex_coords, numVerts);
533
534   calc_tangent_spaces(mesh, smooth_vertex_coords, tangent_spaces);
535
536   for (i = 0; i < numVerts; i++) {
537     float imat[3][3], delta[3];
538
539 #ifdef USE_TANGENT_CALC_INLINE
540     calc_tangent_ortho(tangent_spaces[i]);
541 #endif
542
543     sub_v3_v3v3(delta, rest_coords[i], smooth_vertex_coords[i]);
544     if (UNLIKELY(!invert_m3_m3(imat, tangent_spaces[i]))) {
545       transpose_m3_m3(imat, tangent_spaces[i]);
546     }
547     mul_v3_m3v3(csmd->delta_cache[i], imat, delta);
548   }
549
550   MEM_freeN(tangent_spaces);
551   MEM_freeN(smooth_vertex_coords);
552 }
553
554 static void correctivesmooth_modifier_do(ModifierData *md,
555                                          Depsgraph *depsgraph,
556                                          Object *ob,
557                                          Mesh *mesh,
558                                          float (*vertexCos)[3],
559                                          unsigned int numVerts,
560                                          struct BMEditMesh *em)
561 {
562   CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md;
563
564   const bool force_delta_cache_update =
565       /* XXX, take care! if mesh data its self changes we need to forcefully recalculate deltas */
566       ((csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_ORCO) &&
567        (((ID *)ob->data)->recalc & ID_RECALC_ALL));
568
569   bool use_only_smooth = (csmd->flag & MOD_CORRECTIVESMOOTH_ONLY_SMOOTH) != 0;
570   MDeformVert *dvert = NULL;
571   int defgrp_index;
572
573   MOD_get_vgroup(ob, mesh, csmd->defgrp_name, &dvert, &defgrp_index);
574
575   /* if rest bind_coords not are defined, set them (only run during bind) */
576   if ((csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) &&
577       /* signal to recalculate, whoever sets MUST also free bind coords */
578       (csmd->bind_coords_num == (unsigned int)-1)) {
579     if (DEG_is_active(depsgraph)) {
580       BLI_assert(csmd->bind_coords == NULL);
581       csmd->bind_coords = MEM_dupallocN(vertexCos);
582       csmd->bind_coords_num = numVerts;
583       BLI_assert(csmd->bind_coords != NULL);
584       /* Copy bound data to the original modifier. */
585       CorrectiveSmoothModifierData *csmd_orig = (CorrectiveSmoothModifierData *)
586           modifier_get_original(&csmd->modifier);
587       csmd_orig->bind_coords = MEM_dupallocN(csmd->bind_coords);
588       csmd_orig->bind_coords_num = csmd->bind_coords_num;
589     }
590     else {
591       modifier_setError(md, "Attempt to bind from inactive dependency graph");
592     }
593   }
594
595   if (UNLIKELY(use_only_smooth)) {
596     smooth_verts(csmd, mesh, dvert, defgrp_index, vertexCos, numVerts);
597     return;
598   }
599
600   if ((csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) && (csmd->bind_coords == NULL)) {
601     modifier_setError(md, "Bind data required");
602     goto error;
603   }
604
605   /* If the number of verts has changed, the bind is invalid, so we do nothing */
606   if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) {
607     if (csmd->bind_coords_num != numVerts) {
608       modifier_setError(
609           md, "Bind vertex count mismatch: %u to %u", csmd->bind_coords_num, numVerts);
610       goto error;
611     }
612   }
613   else {
614     /* MOD_CORRECTIVESMOOTH_RESTSOURCE_ORCO */
615     if (ob->type != OB_MESH) {
616       modifier_setError(md, "Object is not a mesh");
617       goto error;
618     }
619     else {
620       unsigned int me_numVerts = (unsigned int)((em) ? em->bm->totvert :
621                                                        ((Mesh *)ob->data)->totvert);
622
623       if (me_numVerts != numVerts) {
624         modifier_setError(md, "Original vertex count mismatch: %u to %u", me_numVerts, numVerts);
625         goto error;
626       }
627     }
628   }
629
630   /* check to see if our deltas are still valid */
631   if (!csmd->delta_cache || (csmd->delta_cache_num != numVerts) || force_delta_cache_update) {
632     const float(*rest_coords)[3];
633     bool is_rest_coords_alloc = false;
634
635     if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) {
636       /* caller needs to do sanity check here */
637       csmd->bind_coords_num = numVerts;
638       rest_coords = (const float(*)[3])csmd->bind_coords;
639     }
640     else {
641       int me_numVerts;
642       rest_coords = (const float(*)[3])((em) ? BKE_editmesh_vertexCos_get_orco(em, &me_numVerts) :
643                                                BKE_mesh_vertexCos_get(ob->data, &me_numVerts));
644
645       BLI_assert((unsigned int)me_numVerts == numVerts);
646       is_rest_coords_alloc = true;
647     }
648
649 #ifdef DEBUG_TIME
650     TIMEIT_START(corrective_smooth_deltas);
651 #endif
652
653     calc_deltas(csmd, mesh, dvert, defgrp_index, rest_coords, numVerts);
654
655 #ifdef DEBUG_TIME
656     TIMEIT_END(corrective_smooth_deltas);
657 #endif
658     if (is_rest_coords_alloc) {
659       MEM_freeN((void *)rest_coords);
660     }
661   }
662
663   if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) {
664     /* this could be a check, but at this point it _must_ be valid */
665     BLI_assert(csmd->bind_coords_num == numVerts && csmd->delta_cache);
666   }
667
668 #ifdef DEBUG_TIME
669   TIMEIT_START(corrective_smooth);
670 #endif
671
672   /* do the actual delta mush */
673   smooth_verts(csmd, mesh, dvert, defgrp_index, vertexCos, numVerts);
674
675   {
676     unsigned int i;
677
678     float(*tangent_spaces)[3][3];
679
680     /* calloc, since values are accumulated */
681     tangent_spaces = MEM_calloc_arrayN(numVerts, sizeof(float[3][3]), __func__);
682
683     calc_tangent_spaces(mesh, vertexCos, tangent_spaces);
684
685     for (i = 0; i < numVerts; i++) {
686       float delta[3];
687
688 #ifdef USE_TANGENT_CALC_INLINE
689       calc_tangent_ortho(tangent_spaces[i]);
690 #endif
691
692       mul_v3_m3v3(delta, tangent_spaces[i], csmd->delta_cache[i]);
693       add_v3_v3(vertexCos[i], delta);
694     }
695
696     MEM_freeN(tangent_spaces);
697   }
698
699 #ifdef DEBUG_TIME
700   TIMEIT_END(corrective_smooth);
701 #endif
702
703   return;
704
705   /* when the modifier fails to execute */
706 error:
707   MEM_SAFE_FREE(csmd->delta_cache);
708   csmd->delta_cache_num = 0;
709 }
710
711 static void deformVerts(ModifierData *md,
712                         const ModifierEvalContext *ctx,
713                         Mesh *mesh,
714                         float (*vertexCos)[3],
715                         int numVerts)
716 {
717   Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
718
719   correctivesmooth_modifier_do(
720       md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (unsigned int)numVerts, NULL);
721
722   if (mesh_src != mesh) {
723     BKE_id_free(NULL, mesh_src);
724   }
725 }
726
727 static void deformVertsEM(ModifierData *md,
728                           const ModifierEvalContext *ctx,
729                           struct BMEditMesh *editData,
730                           Mesh *mesh,
731                           float (*vertexCos)[3],
732                           int numVerts)
733 {
734   Mesh *mesh_src = MOD_deform_mesh_eval_get(
735       ctx->object, editData, mesh, NULL, numVerts, false, false);
736
737   correctivesmooth_modifier_do(
738       md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (unsigned int)numVerts, editData);
739
740   if (mesh_src != mesh) {
741     BKE_id_free(NULL, mesh_src);
742   }
743 }
744
745 ModifierTypeInfo modifierType_CorrectiveSmooth = {
746     /* name */ "CorrectiveSmooth",
747     /* structName */ "CorrectiveSmoothModifierData",
748     /* structSize */ sizeof(CorrectiveSmoothModifierData),
749     /* type */ eModifierTypeType_OnlyDeform,
750     /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode,
751
752     /* copyData */ copyData,
753
754     /* deformVerts */ deformVerts,
755     /* deformMatrices */ NULL,
756     /* deformVertsEM */ deformVertsEM,
757     /* deformMatricesEM */ NULL,
758     /* applyModifier */ NULL,
759
760     /* initData */ initData,
761     /* requiredDataMask */ requiredDataMask,
762     /* freeData */ freeData,
763     /* isDisabled */ NULL,
764     /* updateDepsgraph */ NULL,
765     /* dependsOnTime */ NULL,
766     /* dependsOnNormals */ NULL,
767     /* foreachObjectLink */ NULL,
768     /* foreachIDLink */ NULL,
769     /* foreachTexLink */ NULL,
770     /* freeRuntimeData */ NULL,
771 };