Blender  V3.3
MOD_meshdeform.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2005 Blender Foundation. All rights reserved. */
3 
8 #include "BLI_utildefines.h"
9 
10 #include "BLI_math.h"
11 #include "BLI_simd.h"
12 #include "BLI_task.h"
13 
14 #include "BLT_translation.h"
15 
16 #include "DNA_defaults.h"
17 #include "DNA_mesh_types.h"
18 #include "DNA_meshdata_types.h"
19 #include "DNA_object_types.h"
20 #include "DNA_scene_types.h"
21 #include "DNA_screen_types.h"
22 
23 #include "BKE_context.h"
24 #include "BKE_deform.h"
25 #include "BKE_editmesh.h"
26 #include "BKE_lib_id.h"
27 #include "BKE_lib_query.h"
28 #include "BKE_mesh.h"
29 #include "BKE_mesh_runtime.h"
30 #include "BKE_mesh_wrapper.h"
31 #include "BKE_modifier.h"
32 #include "BKE_screen.h"
33 
34 #include "UI_interface.h"
35 #include "UI_resources.h"
36 
37 #include "BLO_read_write.h"
38 
39 #include "RNA_access.h"
40 #include "RNA_prototypes.h"
41 
42 #include "MEM_guardedalloc.h"
43 
44 #include "DEG_depsgraph.h"
45 #include "DEG_depsgraph_query.h"
46 
47 #include "MOD_ui_common.h"
48 #include "MOD_util.h"
49 
50 static void initData(ModifierData *md)
51 {
53 
55 
57 }
58 
59 static void freeData(ModifierData *md)
60 {
62 
63  if (mmd->bindinfluences) {
65  }
66  if (mmd->bindoffsets) {
67  MEM_freeN(mmd->bindoffsets);
68  }
69  if (mmd->bindcagecos) {
70  MEM_freeN(mmd->bindcagecos);
71  }
72  if (mmd->dyngrid) {
73  MEM_freeN(mmd->dyngrid);
74  }
75  if (mmd->dyninfluences) {
77  }
78  if (mmd->dynverts) {
79  MEM_freeN(mmd->dynverts);
80  }
81  if (mmd->bindweights) {
82  MEM_freeN(mmd->bindweights); /* deprecated */
83  }
84  if (mmd->bindcos) {
85  MEM_freeN(mmd->bindcos); /* deprecated */
86  }
87 }
88 
89 static void copyData(const ModifierData *md, ModifierData *target, const int flag)
90 {
91  const MeshDeformModifierData *mmd = (const MeshDeformModifierData *)md;
93 
94  BKE_modifier_copydata_generic(md, target, flag);
95 
96  if (mmd->bindinfluences) {
98  }
99  if (mmd->bindoffsets) {
100  tmmd->bindoffsets = MEM_dupallocN(mmd->bindoffsets);
101  }
102  if (mmd->bindcagecos) {
103  tmmd->bindcagecos = MEM_dupallocN(mmd->bindcagecos);
104  }
105  if (mmd->dyngrid) {
106  tmmd->dyngrid = MEM_dupallocN(mmd->dyngrid);
107  }
108  if (mmd->dyninfluences) {
110  }
111  if (mmd->dynverts) {
112  tmmd->dynverts = MEM_dupallocN(mmd->dynverts);
113  }
114  if (mmd->bindweights) {
115  tmmd->bindweights = MEM_dupallocN(mmd->bindweights); /* deprecated */
116  }
117  if (mmd->bindcos) {
118  tmmd->bindcos = MEM_dupallocN(mmd->bindcos); /* deprecated */
119  }
120 }
121 
122 static void requiredDataMask(Object *UNUSED(ob),
123  ModifierData *md,
124  CustomData_MeshMasks *r_cddata_masks)
125 {
127 
128  /* ask for vertexgroups if we need them */
129  if (mmd->defgrp_name[0] != '\0') {
130  r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
131  }
132 }
133 
134 static bool isDisabled(const struct Scene *UNUSED(scene),
135  ModifierData *md,
136  bool UNUSED(useRenderParams))
137 {
139 
140  /* The object type check is only needed here in case we have a placeholder
141  * object assigned (because the library containing the mesh is missing).
142  *
143  * In other cases it should be impossible to have a type mismatch.
144  */
145  return !mmd->object || mmd->object->type != OB_MESH;
146 }
147 
148 static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
149 {
151 
152  walk(userData, ob, (ID **)&mmd->object, IDWALK_CB_NOP);
153 }
154 
156 {
158  if (mmd->object != NULL) {
159  DEG_add_object_relation(ctx->node, mmd->object, DEG_OB_COMP_TRANSFORM, "Mesh Deform Modifier");
160  DEG_add_object_relation(ctx->node, mmd->object, DEG_OB_COMP_GEOMETRY, "Mesh Deform Modifier");
161  }
162  /* We need own transformation as well. */
163  DEG_add_modifier_to_transform_relation(ctx->node, "Mesh Deform Modifier");
164 }
165 
166 static float meshdeform_dynamic_bind(MeshDeformModifierData *mmd, float (*dco)[3], float vec[3])
167 {
168  MDefCell *cell;
169  MDefInfluence *inf;
170  float gridvec[3], dvec[3], ivec[3], wx, wy, wz;
171  float weight, cageweight, totweight, *cageco;
172  int i, j, a, x, y, z, size;
173 #ifdef BLI_HAVE_SSE2
174  __m128 co = _mm_setzero_ps();
175 #else
176  float co[3] = {0.0f, 0.0f, 0.0f};
177 #endif
178 
179  totweight = 0.0f;
180  size = mmd->dyngridsize;
181 
182  for (i = 0; i < 3; i++) {
183  gridvec[i] = (vec[i] - mmd->dyncellmin[i] - mmd->dyncellwidth * 0.5f) / mmd->dyncellwidth;
184  ivec[i] = (int)gridvec[i];
185  dvec[i] = gridvec[i] - ivec[i];
186  }
187 
188  for (i = 0; i < 8; i++) {
189  if (i & 1) {
190  x = ivec[0] + 1;
191  wx = dvec[0];
192  }
193  else {
194  x = ivec[0];
195  wx = 1.0f - dvec[0];
196  }
197 
198  if (i & 2) {
199  y = ivec[1] + 1;
200  wy = dvec[1];
201  }
202  else {
203  y = ivec[1];
204  wy = 1.0f - dvec[1];
205  }
206 
207  if (i & 4) {
208  z = ivec[2] + 1;
209  wz = dvec[2];
210  }
211  else {
212  z = ivec[2];
213  wz = 1.0f - dvec[2];
214  }
215 
216  CLAMP(x, 0, size - 1);
217  CLAMP(y, 0, size - 1);
218  CLAMP(z, 0, size - 1);
219 
220  a = x + y * size + z * size * size;
221  weight = wx * wy * wz;
222 
223  cell = &mmd->dyngrid[a];
224  inf = mmd->dyninfluences + cell->offset;
225  for (j = 0; j < cell->influences_num; j++, inf++) {
226  cageco = dco[inf->vertex];
227  cageweight = weight * inf->weight;
228 #ifdef BLI_HAVE_SSE2
229  {
230  __m128 cageweight_r = _mm_set1_ps(cageweight);
231  /* This will load one extra element, this is ok because
232  * we ignore that part of register anyway.
233  */
234  __m128 cageco_r = _mm_loadu_ps(cageco);
235  co = _mm_add_ps(co, _mm_mul_ps(cageco_r, cageweight_r));
236  }
237 #else
238  co[0] += cageweight * cageco[0];
239  co[1] += cageweight * cageco[1];
240  co[2] += cageweight * cageco[2];
241 #endif
242  totweight += cageweight;
243  }
244  }
245 
246 #ifdef BLI_HAVE_SSE2
247  copy_v3_v3(vec, (float *)&co);
248 #else
249  copy_v3_v3(vec, co);
250 #endif
251 
252  return totweight;
253 }
254 
255 typedef struct MeshdeformUserdata {
258  /*const*/ float (*dco)[3];
261  float (*cagemat)[4];
264 
265 static void meshdeform_vert_task(void *__restrict userdata,
266  const int iter,
267  const TaskParallelTLS *__restrict UNUSED(tls))
268 {
269  MeshdeformUserdata *data = userdata;
270  /*const*/ MeshDeformModifierData *mmd = data->mmd;
271  const MDeformVert *dvert = data->dvert;
272  const int defgrp_index = data->defgrp_index;
273  const int *offsets = mmd->bindoffsets;
274  const MDefInfluence *__restrict influences = mmd->bindinfluences;
275  /*const*/ float(*__restrict dco)[3] = data->dco;
276  float(*vertexCos)[3] = data->vertexCos;
277  float co[3];
278  float weight, totweight, fac = 1.0f;
279 
280  if (mmd->flag & MOD_MDEF_DYNAMIC_BIND) {
281  if (!mmd->dynverts[iter]) {
282  return;
283  }
284  }
285 
286  if (dvert) {
287  fac = BKE_defvert_find_weight(&dvert[iter], defgrp_index);
288 
289  if (mmd->flag & MOD_MDEF_INVERT_VGROUP) {
290  fac = 1.0f - fac;
291  }
292 
293  if (fac <= 0.0f) {
294  return;
295  }
296  }
297 
298  if (mmd->flag & MOD_MDEF_DYNAMIC_BIND) {
299  /* transform coordinate into cage's local space */
300  mul_v3_m4v3(co, data->cagemat, vertexCos[iter]);
301  totweight = meshdeform_dynamic_bind(mmd, dco, co);
302  }
303  else {
304  totweight = 0.0f;
305  zero_v3(co);
306  int start = offsets[iter];
307  int end = offsets[iter + 1];
308 
309  for (int a = start; a < end; a++) {
310  weight = influences[a].weight;
311  madd_v3_v3fl(co, dco[influences[a].vertex], weight);
312  totweight += weight;
313  }
314  }
315 
316  if (totweight > 0.0f) {
317  mul_v3_fl(co, fac / totweight);
318  mul_m3_v3(data->icagemat, co);
319  add_v3_v3(vertexCos[iter], co);
320  }
321 }
322 
324  const ModifierEvalContext *ctx,
325  Mesh *mesh,
326  float (*vertexCos)[3],
327  const int verts_num)
328 {
330  Object *ob = ctx->object;
331 
332  Mesh *cagemesh;
333  MDeformVert *dvert = NULL;
334  float imat[4][4], cagemat[4][4], iobmat[4][4], icagemat[3][3], cmat[4][4];
335  float(*dco)[3] = NULL, (*bindcagecos)[3];
336  int a, cage_verts_num, defgrp_index;
338 
339  static int recursive_bind_sentinel = 0;
340 
341  if (mmd->object == NULL || (mmd->bindcagecos == NULL && mmd->bindfunc == NULL)) {
342  return;
343  }
344 
345  /* Get cage mesh.
346  *
347  * Only do this is the target object is in edit mode by itself, meaning
348  * we don't allow linked edit meshes here.
349  * This is because editbmesh_get_mesh_cage_and_final() might easily
350  * conflict with the thread which evaluates object which is in the edit
351  * mode for this mesh.
352  *
353  * We'll support this case once granular dependency graph is landed.
354  */
355  Object *ob_target = mmd->object;
357  if (cagemesh == NULL) {
358  BKE_modifier_set_error(ctx->object, md, "Cannot get mesh from cage object");
359  return;
360  }
361 
362  /* compute matrices to go in and out of cage object space */
363  invert_m4_m4(imat, ob_target->obmat);
364  mul_m4_m4m4(cagemat, imat, ob->obmat);
365  mul_m4_m4m4(cmat, mmd->bindmat, cagemat);
366  invert_m4_m4(iobmat, cmat);
367  copy_m3_m4(icagemat, iobmat);
368 
369  /* bind weights if needed */
370  if (!mmd->bindcagecos) {
371  /* progress bar redraw can make this recursive. */
372  if (!DEG_is_active(ctx->depsgraph)) {
373  BKE_modifier_set_error(ob, md, "Attempt to bind from inactive dependency graph");
374  goto finally;
375  }
376  if (!recursive_bind_sentinel) {
377  recursive_bind_sentinel = 1;
378  mmd->bindfunc(ob, mmd, cagemesh, (float *)vertexCos, verts_num, cagemat);
379  recursive_bind_sentinel = 0;
380  }
381 
382  goto finally;
383  }
384 
385  /* verify we have compatible weights */
386  cage_verts_num = BKE_mesh_wrapper_vert_len(cagemesh);
387 
388  if (mmd->verts_num != verts_num) {
389  BKE_modifier_set_error(ob, md, "Vertices changed from %d to %d", mmd->verts_num, verts_num);
390  goto finally;
391  }
392  else if (mmd->cage_verts_num != cage_verts_num) {
394  ob, md, "Cage vertices changed from %d to %d", mmd->cage_verts_num, cage_verts_num);
395  goto finally;
396  }
397  else if (mmd->bindcagecos == NULL) {
398  BKE_modifier_set_error(ob, md, "Bind data missing");
399  goto finally;
400  }
401 
402  /* We allocate 1 element extra to make it possible to
403  * load the values to SSE registers, which are float4.
404  */
405  dco = MEM_calloc_arrayN((cage_verts_num + 1), sizeof(*dco), "MDefDco");
406  zero_v3(dco[cage_verts_num]);
407 
408  /* setup deformation data */
409  BKE_mesh_wrapper_vert_coords_copy(cagemesh, dco, cage_verts_num);
410  bindcagecos = (float(*)[3])mmd->bindcagecos;
411 
412  for (a = 0; a < cage_verts_num; a++) {
413  /* Get cage vertex in world-space with binding transform. */
414  float co[3];
415  mul_v3_m4v3(co, mmd->bindmat, dco[a]);
416  /* compute difference with world space bind coord */
417  sub_v3_v3v3(dco[a], co, bindcagecos[a]);
418  }
419 
420  MOD_get_vgroup(ob, mesh, mmd->defgrp_name, &dvert, &defgrp_index);
421 
422  /* Initialize data to be pass to the for body function. */
423  data.mmd = mmd;
424  data.dvert = dvert;
425  data.dco = dco;
426  data.defgrp_index = defgrp_index;
427  data.vertexCos = vertexCos;
428  data.cagemat = cagemat;
429  data.icagemat = icagemat;
430 
431  /* Do deformation. */
432  TaskParallelSettings settings;
434  settings.min_iter_per_thread = 16;
435  BLI_task_parallel_range(0, verts_num, &data, meshdeform_vert_task, &settings);
436 
437 finally:
438  MEM_SAFE_FREE(dco);
439 }
440 
441 static void deformVerts(ModifierData *md,
442  const ModifierEvalContext *ctx,
443  Mesh *mesh,
444  float (*vertexCos)[3],
445  int verts_num)
446 {
447  Mesh *mesh_src = MOD_deform_mesh_eval_get(
448  ctx->object, NULL, mesh, NULL, verts_num, false, false);
449 
450  MOD_previous_vcos_store(md, vertexCos); /* if next modifier needs original vertices */
451 
452  meshdeformModifier_do(md, ctx, mesh_src, vertexCos, verts_num);
453 
454  if (!ELEM(mesh_src, NULL, mesh)) {
455  BKE_id_free(NULL, mesh_src);
456  }
457 }
458 
459 static void deformVertsEM(ModifierData *md,
460  const ModifierEvalContext *ctx,
461  struct BMEditMesh *editData,
462  Mesh *mesh,
463  float (*vertexCos)[3],
464  int verts_num)
465 {
466  Mesh *mesh_src = MOD_deform_mesh_eval_get(
467  ctx->object, editData, mesh, NULL, verts_num, false, false);
468 
469  /* TODO(Campbell): use edit-mode data only (remove this line). */
470  if (mesh_src != NULL) {
472  }
473 
474  meshdeformModifier_do(md, ctx, mesh_src, vertexCos, verts_num);
475 
476  if (!ELEM(mesh_src, NULL, mesh)) {
477  BKE_id_free(NULL, mesh_src);
478  }
479 }
480 
481 #define MESHDEFORM_MIN_INFLUENCE 0.00001f
482 
484 {
486  float weight, *weights, totweight;
487  int influences_num, verts_num, cage_verts_num, a, b;
488 
489  weights = mmd->bindweights;
490  if (!weights) {
491  return;
492  }
493 
494  verts_num = mmd->verts_num;
495  cage_verts_num = mmd->cage_verts_num;
496 
497  /* count number of influences above threshold */
498  for (b = 0; b < verts_num; b++) {
499  for (a = 0; a < cage_verts_num; a++) {
500  weight = weights[a + b * cage_verts_num];
501 
502  if (weight > MESHDEFORM_MIN_INFLUENCE) {
503  mmd->influences_num++;
504  }
505  }
506  }
507 
508  /* allocate bind influences */
510  mmd->influences_num, sizeof(MDefInfluence), "MDefBindInfluence");
511  mmd->bindoffsets = MEM_calloc_arrayN((verts_num + 1), sizeof(int), "MDefBindOffset");
512 
513  /* write influences */
514  influences_num = 0;
515 
516  for (b = 0; b < verts_num; b++) {
517  mmd->bindoffsets[b] = influences_num;
518  totweight = 0.0f;
519 
520  /* sum total weight */
521  for (a = 0; a < cage_verts_num; a++) {
522  weight = weights[a + b * cage_verts_num];
523 
524  if (weight > MESHDEFORM_MIN_INFLUENCE) {
525  totweight += weight;
526  }
527  }
528 
529  /* assign weights normalized */
530  for (a = 0; a < cage_verts_num; a++) {
531  weight = weights[a + b * cage_verts_num];
532 
533  if (weight > MESHDEFORM_MIN_INFLUENCE) {
534  mmd->bindinfluences[influences_num].weight = weight / totweight;
535  mmd->bindinfluences[influences_num].vertex = a;
536  influences_num++;
537  }
538  }
539  }
540 
541  mmd->bindoffsets[b] = influences_num;
542 
543  /* free */
544  MEM_freeN(mmd->bindweights);
545  mmd->bindweights = NULL;
546 }
547 
548 static void panel_draw(const bContext *UNUSED(C), Panel *panel)
549 {
550  uiLayout *col;
551  uiLayout *layout = panel->layout;
552 
553  PointerRNA ob_ptr;
555 
556  bool is_bound = RNA_boolean_get(ptr, "is_bound");
557 
558  uiLayoutSetPropSep(layout, true);
559 
560  col = uiLayoutColumn(layout, true);
561  uiLayoutSetEnabled(col, !is_bound);
562  uiItemR(col, ptr, "object", 0, NULL, ICON_NONE);
563 
564  modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", NULL);
565 
566  col = uiLayoutColumn(layout, false);
567  uiLayoutSetEnabled(col, !is_bound);
568  uiItemR(col, ptr, "precision", 0, NULL, ICON_NONE);
569  uiItemR(col, ptr, "use_dynamic_bind", 0, NULL, ICON_NONE);
570 
571  uiItemO(layout,
572  is_bound ? IFACE_("Unbind") : IFACE_("Bind"),
573  ICON_NONE,
574  "OBJECT_OT_meshdeform_bind");
575 
576  modifier_panel_end(layout, ptr);
577 }
578 
579 static void panelRegister(ARegionType *region_type)
580 {
582 }
583 
584 static void blendWrite(BlendWriter *writer, const ID *id_owner, const ModifierData *md)
585 {
587  const bool is_undo = BLO_write_is_undo(writer);
588 
589  if (ID_IS_OVERRIDE_LIBRARY(id_owner) && !is_undo) {
590  BLI_assert(!ID_IS_LINKED(id_owner));
591  const bool is_local = (md->flag & eModifierFlag_OverrideLibrary_Local) != 0;
592  if (!is_local) {
593  /* Modifier coming from linked data cannot be bound from an override, so we can remove all
594  * binding data, can save a significant amount of memory. */
595  mmd.influences_num = 0;
596  mmd.bindinfluences = NULL;
597  mmd.verts_num = 0;
598  mmd.bindoffsets = NULL;
599  mmd.cage_verts_num = 0;
600  mmd.bindcagecos = NULL;
601  mmd.dyngridsize = 0;
602  mmd.dyngrid = NULL;
603  mmd.influences_num = 0;
604  mmd.dyninfluences = NULL;
605  mmd.dynverts = NULL;
606  }
607  }
608 
609  const int size = mmd.dyngridsize;
610 
612 
614 
615  /* NOTE: `bindoffset` is abusing `verts_num + 1` as its size, this becomes an incorrect value in
616  * case `verts_num == 0`, since `bindoffset` is then NULL, not a size 1 allocated array. */
617  if (mmd.verts_num > 0) {
618  BLO_write_int32_array(writer, mmd.verts_num + 1, mmd.bindoffsets);
619  }
620  else {
621  BLI_assert(mmd.bindoffsets == NULL);
622  }
623 
627  BLO_write_int32_array(writer, mmd.verts_num, mmd.dynverts);
628 }
629 
630 static void blendRead(BlendDataReader *reader, ModifierData *md)
631 {
633 
634  BLO_read_data_address(reader, &mmd->bindinfluences);
635 
636  /* NOTE: `bindoffset` is abusing `verts_num + 1` as its size, this becomes an incorrect value in
637  * case `verts_num == 0`, since `bindoffset` is then NULL, not a size 1 allocated array. */
638  if (mmd->verts_num > 0) {
639  BLO_read_int32_array(reader, mmd->verts_num + 1, &mmd->bindoffsets);
640  }
641 
642  BLO_read_float3_array(reader, mmd->cage_verts_num, &mmd->bindcagecos);
643  BLO_read_data_address(reader, &mmd->dyngrid);
644  BLO_read_data_address(reader, &mmd->dyninfluences);
645  BLO_read_int32_array(reader, mmd->verts_num, &mmd->dynverts);
646 
647  /* Deprecated storage. */
648  BLO_read_float_array(reader, mmd->verts_num, &mmd->bindweights);
649  BLO_read_float3_array(reader, mmd->cage_verts_num, &mmd->bindcos);
650 }
651 
653  /* name */ N_("MeshDeform"),
654  /* structName */ "MeshDeformModifierData",
655  /* structSize */ sizeof(MeshDeformModifierData),
656  /* srna */ &RNA_MeshDeformModifier,
657  /* type */ eModifierTypeType_OnlyDeform,
660  /* icon */ ICON_MOD_MESHDEFORM,
661 
662  /* copyData */ copyData,
663 
664  /* deformVerts */ deformVerts,
665  /* deformMatrices */ NULL,
666  /* deformVertsEM */ deformVertsEM,
667  /* deformMatricesEM */ NULL,
668  /* modifyMesh */ NULL,
669  /* modifyGeometrySet */ NULL,
670 
671  /* initData */ initData,
672  /* requiredDataMask */ requiredDataMask,
673  /* freeData */ freeData,
674  /* isDisabled */ isDisabled,
675  /* updateDepsgraph */ updateDepsgraph,
676  /* dependsOnTime */ NULL,
677  /* dependsOnNormals */ NULL,
678  /* foreachIDLink */ foreachIDLink,
679  /* foreachTexLink */ NULL,
680  /* freeRuntimeData */ NULL,
681  /* panelRegister */ panelRegister,
682  /* blendWrite */ blendWrite,
683  /* blendRead */ blendRead,
684 };
typedef float(TangentPoint)[2]
support for deformation groups and hooks.
float BKE_defvert_find_weight(const struct MDeformVert *dvert, int defgroup)
Definition: deform.c:704
void BKE_id_free(struct Main *bmain, void *idv)
@ IDWALK_CB_NOP
Definition: BKE_lib_query.h:33
void BKE_mesh_wrapper_ensure_mdata(struct Mesh *me)
Definition: mesh_wrapper.cc:94
int BKE_mesh_wrapper_vert_len(const struct Mesh *me)
void BKE_mesh_wrapper_vert_coords_copy(const struct Mesh *me, float(*vert_coords)[3], int vert_coords_len)
void(* IDWalkFunc)(void *userData, struct Object *ob, struct ID **idpoin, int cb_flag)
Definition: BKE_modifier.h:107
@ eModifierTypeFlag_AcceptsCVs
Definition: BKE_modifier.h:67
@ eModifierTypeFlag_SupportsEditmode
Definition: BKE_modifier.h:69
@ eModifierTypeFlag_AcceptsVertexCosOnly
Definition: BKE_modifier.h:100
void BKE_modifier_copydata_generic(const struct ModifierData *md, struct ModifierData *md_dst, int flag)
struct Mesh * BKE_modifier_get_evaluated_mesh_from_evaluated_object(struct Object *ob_eval)
@ eModifierTypeType_OnlyDeform
Definition: BKE_modifier.h:44
void BKE_modifier_set_error(const struct Object *ob, struct ModifierData *md, const char *format,...) ATTR_PRINTF_FORMAT(3
#define BLI_assert(a)
Definition: BLI_assert.h:46
void mul_m3_v3(const float M[3][3], float r[3])
Definition: math_matrix.c:926
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:259
void copy_m3_m4(float m1[3][3], const float m2[4][4])
Definition: math_matrix.c:87
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1287
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:739
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
void BLI_task_parallel_range(int start, int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
Definition: task_range.cc:94
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
Definition: BLI_task.h:293
#define UNUSED(x)
#define ELEM(...)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
void BLO_read_float3_array(BlendDataReader *reader, int array_size, float **ptr_p)
Definition: readfile.c:5201
#define BLO_read_data_address(reader, ptr_p)
void BLO_write_float3_array(BlendWriter *writer, uint num, const float *data_ptr)
Definition: writefile.c:1596
void BLO_write_int32_array(BlendWriter *writer, uint num, const int32_t *data_ptr)
Definition: writefile.c:1571
void BLO_read_float_array(BlendDataReader *reader, int array_size, float **ptr_p)
Definition: readfile.c:5193
void BLO_read_int32_array(BlendDataReader *reader, int array_size, int32_t **ptr_p)
Definition: readfile.c:5177
#define BLO_write_struct_array(writer, struct_name, array_size, data_ptr)
bool BLO_write_is_undo(BlendWriter *writer)
Definition: writefile.c:1608
#define BLO_write_struct_at_address(writer, struct_name, address, data_ptr)
#define IFACE_(msgid)
bool DEG_is_active(const struct Depsgraph *depsgraph)
Definition: depsgraph.cc:312
void DEG_add_object_relation(struct DepsNodeHandle *node_handle, struct Object *object, eDepsObjectComponentType component, const char *description)
void DEG_add_modifier_to_transform_relation(struct DepsNodeHandle *node_handle, const char *description)
@ DEG_OB_COMP_GEOMETRY
@ DEG_OB_COMP_TRANSFORM
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:566
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition: DNA_ID.h:588
#define CD_MASK_MDEFORMVERT
#define DNA_struct_default_get(struct_name)
Definition: DNA_defaults.h:29
@ eModifierFlag_OverrideLibrary_Local
@ eModifierType_MeshDeform
@ MOD_MDEF_DYNAMIC_BIND
@ MOD_MDEF_INVERT_VGROUP
struct MeshDeformModifierData MeshDeformModifierData
Object is a sort of wrapper for general info.
@ OB_MESH
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble z
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
static void meshdeform_vert_task(void *__restrict userdata, const int iter, const TaskParallelTLS *__restrict UNUSED(tls))
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, float(*vertexCos)[3], int verts_num)
static void deformVertsEM(ModifierData *md, const ModifierEvalContext *ctx, struct BMEditMesh *editData, Mesh *mesh, float(*vertexCos)[3], int verts_num)
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
static bool isDisabled(const struct Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams))
#define MESHDEFORM_MIN_INFLUENCE
ModifierTypeInfo modifierType_MeshDeform
static void blendRead(BlendDataReader *reader, ModifierData *md)
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
void BKE_modifier_mdef_compact_influences(ModifierData *md)
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
static void initData(ModifierData *md)
static void panelRegister(ARegionType *region_type)
static void meshdeformModifier_do(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, float(*vertexCos)[3], const int verts_num)
static float meshdeform_dynamic_bind(MeshDeformModifierData *mmd, float(*dco)[3], float vec[3])
static void freeData(ModifierData *md)
static void blendWrite(BlendWriter *writer, const ID *id_owner, const ModifierData *md)
static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
struct MeshdeformUserdata MeshdeformUserdata
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
void modifier_panel_end(uiLayout *layout, PointerRNA *ptr)
Definition: MOD_ui_common.c:91
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
void modifier_vgroup_ui(uiLayout *layout, PointerRNA *ptr, PointerRNA *ob_ptr, const char *vgroup_prop, const char *invert_vgroup_prop, const char *text)
Mesh * MOD_deform_mesh_eval_get(Object *ob, struct BMEditMesh *em, Mesh *mesh, const float(*vertexCos)[3], const int verts_num, const bool use_normals, const bool use_orco)
Definition: MOD_util.c:167
void MOD_previous_vcos_store(ModifierData *md, const float(*vert_coords)[3])
Definition: MOD_util.c:153
void MOD_get_vgroup(Object *ob, struct Mesh *mesh, const char *name, MDeformVert **dvert, int *defgrp_index)
Definition: MOD_util.c:235
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position CLAMP
#define C
Definition: RandGen.cpp:25
void uiLayoutSetEnabled(uiLayout *layout, bool enabled)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
Scene scene
uint col
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:28
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:32
static unsigned a[3]
Definition: RandGen.cpp:78
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4863
Definition: DNA_ID.h:368
void(* bindfunc)(struct Object *object, struct MeshDeformModifierData *mmd, struct Mesh *cagemesh, float *vertexcos, int verts_num, float cagemat[4][4])
MDefInfluence * bindinfluences
MDefInfluence * dyninfluences
float(* vertexCos)[3]
MeshDeformModifierData * mmd
float(* icagemat)[3]
const MDeformVert * dvert
struct Depsgraph * depsgraph
Definition: BKE_modifier.h:140
struct Object * object
Definition: BKE_modifier.h:141
struct DepsNodeHandle * node
Definition: BKE_modifier.h:134
float obmat[4][4]
struct uiLayout * layout
#define N_(msgid)
PointerRNA * ptr
Definition: wm_files.c:3480