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