Fix T58046: Crash when changing Particle type, when Hair has dynamics
[blender.git] / source / blender / modifiers / intern / MOD_meshdeform.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): Daniel Dunbar
22  *                 Ton Roosendaal,
23  *                 Ben Batt,
24  *                 Brecht Van Lommel,
25  *                 Campbell Barton
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  *
29  */
30
31 /** \file blender/modifiers/intern/MOD_meshdeform.c
32  *  \ingroup modifiers
33  */
34
35 #include "DNA_mesh_types.h"
36 #include "DNA_meshdata_types.h"
37 #include "DNA_object_types.h"
38 #include "DNA_scene_types.h"
39
40 #include "BLI_math.h"
41 #include "BLI_task.h"
42 #include "BLI_utildefines.h"
43
44 #include "BKE_global.h"
45 #include "BKE_library.h"
46 #include "BKE_library_query.h"
47 #include "BKE_mesh.h"
48 #include "BKE_modifier.h"
49 #include "BKE_deform.h"
50 #include "BKE_editmesh.h"
51
52 #include "MEM_guardedalloc.h"
53
54 #include "DEG_depsgraph.h"
55 #include "DEG_depsgraph_query.h"
56
57 #include "MOD_util.h"
58
59 #ifdef __SSE2__
60 #  include <emmintrin.h>
61 #endif
62
63 static void initData(ModifierData *md)
64 {
65         MeshDeformModifierData *mmd = (MeshDeformModifierData *) md;
66
67         mmd->gridsize = 5;
68 }
69
70 static void freeData(ModifierData *md)
71 {
72         MeshDeformModifierData *mmd = (MeshDeformModifierData *) md;
73
74         if (mmd->bindinfluences) MEM_freeN(mmd->bindinfluences);
75         if (mmd->bindoffsets) MEM_freeN(mmd->bindoffsets);
76         if (mmd->bindcagecos) MEM_freeN(mmd->bindcagecos);
77         if (mmd->dyngrid) MEM_freeN(mmd->dyngrid);
78         if (mmd->dyninfluences) MEM_freeN(mmd->dyninfluences);
79         if (mmd->dynverts) MEM_freeN(mmd->dynverts);
80         if (mmd->bindweights) MEM_freeN(mmd->bindweights);  /* deprecated */
81         if (mmd->bindcos) MEM_freeN(mmd->bindcos);  /* deprecated */
82 }
83
84 static void copyData(const ModifierData *md, ModifierData *target, const int flag)
85 {
86         const MeshDeformModifierData *mmd = (const MeshDeformModifierData *) md;
87         MeshDeformModifierData *tmmd = (MeshDeformModifierData *) target;
88
89         modifier_copyData_generic(md, target, flag);
90
91         if (mmd->bindinfluences) tmmd->bindinfluences = MEM_dupallocN(mmd->bindinfluences);
92         if (mmd->bindoffsets) tmmd->bindoffsets = MEM_dupallocN(mmd->bindoffsets);
93         if (mmd->bindcagecos) tmmd->bindcagecos = MEM_dupallocN(mmd->bindcagecos);
94         if (mmd->dyngrid) tmmd->dyngrid = MEM_dupallocN(mmd->dyngrid);
95         if (mmd->dyninfluences) tmmd->dyninfluences = MEM_dupallocN(mmd->dyninfluences);
96         if (mmd->dynverts) tmmd->dynverts = MEM_dupallocN(mmd->dynverts);
97         if (mmd->bindweights) tmmd->bindweights = MEM_dupallocN(mmd->bindweights);  /* deprecated */
98         if (mmd->bindcos) tmmd->bindcos = MEM_dupallocN(mmd->bindcos);  /* deprecated */
99 }
100
101 static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
102 {
103         MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
104         CustomDataMask dataMask = 0;
105
106         /* ask for vertexgroups if we need them */
107         if (mmd->defgrp_name[0]) dataMask |= CD_MASK_MDEFORMVERT;
108
109         return dataMask;
110 }
111
112 static bool isDisabled(const struct Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams))
113 {
114         MeshDeformModifierData *mmd = (MeshDeformModifierData *) md;
115
116         return !mmd->object;
117 }
118
119 static void foreachObjectLink(
120         ModifierData *md, Object *ob,
121         ObjectWalkFunc walk, void *userData)
122 {
123         MeshDeformModifierData *mmd = (MeshDeformModifierData *) md;
124
125         walk(userData, ob, &mmd->object, IDWALK_CB_NOP);
126 }
127
128 static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
129 {
130         MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
131         if (mmd->object != NULL) {
132                 /* TODO(sergey): Do we need transform component here? */
133                 DEG_add_object_relation(ctx->node, mmd->object, DEG_OB_COMP_GEOMETRY, "Mesh Deform Modifier");
134         }
135 }
136
137 static float meshdeform_dynamic_bind(MeshDeformModifierData *mmd, float (*dco)[3], float vec[3])
138 {
139         MDefCell *cell;
140         MDefInfluence *inf;
141         float gridvec[3], dvec[3], ivec[3], wx, wy, wz;
142         float weight, cageweight, totweight, *cageco;
143         int i, j, a, x, y, z, size;
144 #ifdef __SSE2__
145         __m128 co = _mm_setzero_ps();
146 #else
147         float co[3] = {0.0f, 0.0f, 0.0f};
148 #endif
149
150         totweight = 0.0f;
151         size = mmd->dyngridsize;
152
153         for (i = 0; i < 3; i++) {
154                 gridvec[i] = (vec[i] - mmd->dyncellmin[i] - mmd->dyncellwidth * 0.5f) / mmd->dyncellwidth;
155                 ivec[i] = (int)gridvec[i];
156                 dvec[i] = gridvec[i] - ivec[i];
157         }
158
159         for (i = 0; i < 8; i++) {
160                 if (i & 1) { x = ivec[0] + 1; wx = dvec[0]; }
161                 else {       x = ivec[0]; wx = 1.0f - dvec[0]; }
162
163                 if (i & 2) { y = ivec[1] + 1; wy = dvec[1]; }
164                 else {       y = ivec[1];     wy = 1.0f - dvec[1]; }
165
166                 if (i & 4) { z = ivec[2] + 1; wz = dvec[2]; }
167                 else {       z = ivec[2];     wz = 1.0f - dvec[2]; }
168
169                 CLAMP(x, 0, size - 1);
170                 CLAMP(y, 0, size - 1);
171                 CLAMP(z, 0, size - 1);
172
173                 a = x + y * size + z * size * size;
174                 weight = wx * wy * wz;
175
176                 cell = &mmd->dyngrid[a];
177                 inf = mmd->dyninfluences + cell->offset;
178                 for (j = 0; j < cell->totinfluence; j++, inf++) {
179                         cageco = dco[inf->vertex];
180                         cageweight = weight * inf->weight;
181 #ifdef __SSE2__
182                         {
183                                 __m128 cageweight_r = _mm_set1_ps(cageweight);
184                                 /* This will load one extra element, this is ok because
185                                  * we ignore that part of register anyway.
186                                  */
187                                 __m128 cageco_r = _mm_loadu_ps(cageco);
188                                 co = _mm_add_ps(co,
189                                                 _mm_mul_ps(cageco_r, cageweight_r));
190                         }
191 #else
192                         co[0] += cageweight * cageco[0];
193                         co[1] += cageweight * cageco[1];
194                         co[2] += cageweight * cageco[2];
195 #endif
196                         totweight += cageweight;
197                 }
198         }
199
200 #ifdef __SSE2__
201         copy_v3_v3(vec, (float *)&co);
202 #else
203         copy_v3_v3(vec, co);
204 #endif
205
206         return totweight;
207 }
208
209 typedef struct MeshdeformUserdata {
210         /*const*/ MeshDeformModifierData *mmd;
211         const MDeformVert *dvert;
212         /*const*/ float (*dco)[3];
213         int defgrp_index;
214         float (*vertexCos)[3];
215         float (*cagemat)[4];
216         float (*icagemat)[3];
217 } MeshdeformUserdata;
218
219 static void meshdeform_vert_task(
220         void *__restrict userdata,
221         const int iter,
222         const ParallelRangeTLS *__restrict UNUSED(tls))
223 {
224         MeshdeformUserdata *data = userdata;
225         /*const*/ MeshDeformModifierData *mmd = data->mmd;
226         const MDeformVert *dvert = data->dvert;
227         const int defgrp_index = data->defgrp_index;
228         const int *offsets = mmd->bindoffsets;
229         const MDefInfluence *__restrict influences = mmd->bindinfluences;
230         /*const*/ float (*__restrict dco)[3] = data->dco;
231         float (*vertexCos)[3] = data->vertexCos;
232         float co[3];
233         float weight, totweight, fac = 1.0f;
234
235         if (mmd->flag & MOD_MDEF_DYNAMIC_BIND)
236                 if (!mmd->dynverts[iter])
237                         return;
238
239         if (dvert) {
240                 fac = defvert_find_weight(&dvert[iter], defgrp_index);
241
242                 if (mmd->flag & MOD_MDEF_INVERT_VGROUP) {
243                         fac = 1.0f - fac;
244                 }
245
246                 if (fac <= 0.0f) {
247                         return;
248                 }
249         }
250
251         if (mmd->flag & MOD_MDEF_DYNAMIC_BIND) {
252                 /* transform coordinate into cage's local space */
253                 mul_v3_m4v3(co, data->cagemat, vertexCos[iter]);
254                 totweight = meshdeform_dynamic_bind(mmd, dco, co);
255         }
256         else {
257                 totweight = 0.0f;
258                 zero_v3(co);
259                 int start = offsets[iter];
260                 int end = offsets[iter + 1];
261
262                 for (int a = start; a < end; a++) {
263                         weight = influences[a].weight;
264                         madd_v3_v3fl(co, dco[influences[a].vertex], weight);
265                         totweight += weight;
266                 }
267         }
268
269         if (totweight > 0.0f) {
270                 mul_v3_fl(co, fac / totweight);
271                 mul_m3_v3(data->icagemat, co);
272                 if (G.debug_value != 527)
273                         add_v3_v3(vertexCos[iter], co);
274                 else
275                         copy_v3_v3(vertexCos[iter], co);
276         }
277 }
278
279 static void meshdeformModifier_do(
280         ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh,
281         float (*vertexCos)[3], int numVerts)
282 {
283         MeshDeformModifierData *mmd = (MeshDeformModifierData *) md;
284         Object *ob = ctx->object;
285
286         Mesh *cagemesh;
287         MDeformVert *dvert = NULL;
288         float imat[4][4], cagemat[4][4], iobmat[4][4], icagemat[3][3], cmat[4][4];
289         float co[3], (*dco)[3], (*bindcagecos)[3];
290         int a, totvert, totcagevert, defgrp_index;
291         float (*cagecos)[3];
292         MeshdeformUserdata data;
293         bool free_cagemesh = false;
294
295         if (!mmd->object || (!mmd->bindcagecos && !mmd->bindfunc))
296                 return;
297
298         /* Get cage mesh.
299          *
300          * Only do this is the target object is in edit mode by itself, meaning
301          * we don't allow linked edit meshes here.
302          * This is because editbmesh_get_mesh_cage_and_final() might easily
303          * conflict with the thread which evaluates object which is in the edit
304          * mode for this mesh.
305          *
306          * We'll support this case once granular dependency graph is landed.
307          */
308         cagemesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(mmd->object, &free_cagemesh);
309
310         if (cagemesh == NULL) {
311                 modifier_setError(md, "Cannot get mesh from cage object");
312                 return;
313         }
314
315         /* compute matrices to go in and out of cage object space */
316         invert_m4_m4(imat, mmd->object->obmat);
317         mul_m4_m4m4(cagemat, imat, ob->obmat);
318         mul_m4_m4m4(cmat, mmd->bindmat, cagemat);
319         invert_m4_m4(iobmat, cmat);
320         copy_m3_m4(icagemat, iobmat);
321
322         /* bind weights if needed */
323         if (!mmd->bindcagecos) {
324                 static int recursive = 0;
325
326                 /* progress bar redraw can make this recursive .. */
327                 if (!recursive) {
328                         /* Write binding data to original modifier. */
329                         Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
330                         Object *ob_orig = DEG_get_original_object(ob);
331                         MeshDeformModifierData *mmd_orig = (MeshDeformModifierData *)modifiers_findByName(
332                                 ob_orig, mmd->modifier.name);
333
334                         recursive = 1;
335                         mmd->bindfunc(scene, mmd_orig, cagemesh, (float *)vertexCos, numVerts, cagemat);
336                         recursive = 0;
337                 }
338
339                 return;
340         }
341
342         /* verify we have compatible weights */
343         totvert = numVerts;
344         totcagevert = cagemesh->totvert;
345
346         if (mmd->totvert != totvert) {
347                 modifier_setError(md, "Verts changed from %d to %d", mmd->totvert, totvert);
348                 if (free_cagemesh) BKE_id_free(NULL, cagemesh);
349                 return;
350         }
351         else if (mmd->totcagevert != totcagevert) {
352                 modifier_setError(md, "Cage verts changed from %d to %d", mmd->totcagevert, totcagevert);
353                 if (free_cagemesh) BKE_id_free(NULL, cagemesh);
354                 return;
355         }
356         else if (mmd->bindcagecos == NULL) {
357                 modifier_setError(md, "Bind data missing");
358                 if (free_cagemesh) BKE_id_free(NULL, cagemesh);
359                 return;
360         }
361
362         /* setup deformation data */
363         cagecos = BKE_mesh_vertexCos_get(cagemesh, NULL);
364         bindcagecos = (float(*)[3])mmd->bindcagecos;
365
366         /* We allocate 1 element extra to make it possible to
367          * load the values to SSE registers, which are float4.
368          */
369         dco = MEM_calloc_arrayN((totcagevert + 1), sizeof(*dco), "MDefDco");
370         zero_v3(dco[totcagevert]);
371         for (a = 0; a < totcagevert; a++) {
372                 /* get cage vertex in world space with binding transform */
373                 copy_v3_v3(co, cagecos[a]);
374
375                 if (G.debug_value != 527) {
376                         mul_m4_v3(mmd->bindmat, co);
377                         /* compute difference with world space bind coord */
378                         sub_v3_v3v3(dco[a], co, bindcagecos[a]);
379                 }
380                 else
381                         copy_v3_v3(dco[a], co);
382         }
383
384         MOD_get_vgroup(ob, mesh, mmd->defgrp_name, &dvert, &defgrp_index);
385
386         /* Initialize data to be pass to the for body function. */
387         data.mmd = mmd;
388         data.dvert = dvert;
389         data.dco = dco;
390         data.defgrp_index = defgrp_index;
391         data.vertexCos = vertexCos;
392         data.cagemat = cagemat;
393         data.icagemat = icagemat;
394
395         /* Do deformation. */
396         ParallelRangeSettings settings;
397         BLI_parallel_range_settings_defaults(&settings);
398         settings.min_iter_per_thread = 16;
399         BLI_task_parallel_range(0, totvert,
400                                 &data,
401                                 meshdeform_vert_task,
402                                 &settings);
403
404         /* release cage mesh */
405         MEM_freeN(dco);
406         MEM_freeN(cagecos);
407         if (cagemesh != NULL && free_cagemesh) {
408                 BKE_id_free(NULL, cagemesh);
409         }
410 }
411
412 static void deformVerts(
413         ModifierData *md, const ModifierEvalContext *ctx,
414         Mesh *mesh,
415         float (*vertexCos)[3],
416         int numVerts)
417 {
418         Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
419
420         MOD_previous_vcos_store(md, vertexCos); /* if next modifier needs original vertices */
421
422         meshdeformModifier_do(md, ctx, mesh_src, vertexCos, numVerts);
423
424         if (!ELEM(mesh_src, NULL, mesh)) {
425                 BKE_id_free(NULL, mesh_src);
426         }
427 }
428
429 static void deformVertsEM(
430         ModifierData *md, const ModifierEvalContext *ctx,
431         struct BMEditMesh *editData,
432         Mesh *mesh,
433         float (*vertexCos)[3],
434         int numVerts)
435 {
436         Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false);
437
438         meshdeformModifier_do(md, ctx, mesh_src, vertexCos, numVerts);
439
440         if (!ELEM(mesh_src, NULL, mesh)) {
441                 BKE_id_free(NULL, mesh_src);
442         }
443 }
444
445 #define MESHDEFORM_MIN_INFLUENCE 0.00001f
446
447 void modifier_mdef_compact_influences(ModifierData *md)
448 {
449         MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
450         float weight, *weights, totweight;
451         int totinfluence, totvert, totcagevert, a, b;
452
453         weights = mmd->bindweights;
454         if (!weights)
455                 return;
456
457         totvert = mmd->totvert;
458         totcagevert = mmd->totcagevert;
459
460         /* count number of influences above threshold */
461         for (b = 0; b < totvert; b++) {
462                 for (a = 0; a < totcagevert; a++) {
463                         weight = weights[a + b * totcagevert];
464
465                         if (weight > MESHDEFORM_MIN_INFLUENCE)
466                                 mmd->totinfluence++;
467                 }
468         }
469
470         /* allocate bind influences */
471         mmd->bindinfluences = MEM_calloc_arrayN(mmd->totinfluence, sizeof(MDefInfluence), "MDefBindInfluence");
472         mmd->bindoffsets = MEM_calloc_arrayN((totvert + 1), sizeof(int), "MDefBindOffset");
473
474         /* write influences */
475         totinfluence = 0;
476
477         for (b = 0; b < totvert; b++) {
478                 mmd->bindoffsets[b] = totinfluence;
479                 totweight = 0.0f;
480
481                 /* sum total weight */
482                 for (a = 0; a < totcagevert; a++) {
483                         weight = weights[a + b * totcagevert];
484
485                         if (weight > MESHDEFORM_MIN_INFLUENCE)
486                                 totweight += weight;
487                 }
488
489                 /* assign weights normalized */
490                 for (a = 0; a < totcagevert; a++) {
491                         weight = weights[a + b * totcagevert];
492
493                         if (weight > MESHDEFORM_MIN_INFLUENCE) {
494                                 mmd->bindinfluences[totinfluence].weight = weight / totweight;
495                                 mmd->bindinfluences[totinfluence].vertex = a;
496                                 totinfluence++;
497                         }
498                 }
499         }
500
501         mmd->bindoffsets[b] = totinfluence;
502
503         /* free */
504         MEM_freeN(mmd->bindweights);
505         mmd->bindweights = NULL;
506 }
507
508 ModifierTypeInfo modifierType_MeshDeform = {
509         /* name */              "MeshDeform",
510         /* structName */        "MeshDeformModifierData",
511         /* structSize */        sizeof(MeshDeformModifierData),
512         /* type */              eModifierTypeType_OnlyDeform,
513         /* flags */             eModifierTypeFlag_AcceptsCVs |
514                                 eModifierTypeFlag_AcceptsLattice |
515                                 eModifierTypeFlag_SupportsEditmode,
516
517         /* copyData */          copyData,
518
519         /* deformVerts_DM */    NULL,
520         /* deformMatrices_DM */ NULL,
521         /* deformVertsEM_DM */  NULL,
522         /* deformMatricesEM_DM*/NULL,
523         /* applyModifier_DM */  NULL,
524
525         /* deformVerts */       deformVerts,
526         /* deformMatrices */    NULL,
527         /* deformVertsEM */     deformVertsEM,
528         /* deformMatricesEM */  NULL,
529         /* applyModifier */     NULL,
530
531         /* initData */          initData,
532         /* requiredDataMask */  requiredDataMask,
533         /* freeData */          freeData,
534         /* isDisabled */        isDisabled,
535         /* updateDepsgraph */   updateDepsgraph,
536         /* dependsOnTime */     NULL,
537         /* dependsOnNormals */  NULL,
538         /* foreachObjectLink */ foreachObjectLink,
539         /* foreachIDLink */     NULL,
540         /* foreachTexLink */    NULL,
541 };