Blender  V2.93
MOD_meshdeform.c
Go to the documentation of this file.
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 
24 #include "BLI_utildefines.h"
25 
26 #include "BLI_math.h"
27 #include "BLI_simd.h"
28 #include "BLI_task.h"
29 
30 #include "BLT_translation.h"
31 
32 #include "DNA_defaults.h"
33 #include "DNA_mesh_types.h"
34 #include "DNA_meshdata_types.h"
35 #include "DNA_object_types.h"
36 #include "DNA_scene_types.h"
37 #include "DNA_screen_types.h"
38 
39 #include "BKE_context.h"
40 #include "BKE_deform.h"
41 #include "BKE_editmesh.h"
42 #include "BKE_lib_id.h"
43 #include "BKE_lib_query.h"
44 #include "BKE_mesh.h"
45 #include "BKE_mesh_runtime.h"
46 #include "BKE_mesh_wrapper.h"
47 #include "BKE_modifier.h"
48 #include "BKE_screen.h"
49 
50 #include "UI_interface.h"
51 #include "UI_resources.h"
52 
53 #include "BLO_read_write.h"
54 
55 #include "RNA_access.h"
56 
57 #include "MEM_guardedalloc.h"
58 
59 #include "DEG_depsgraph.h"
60 #include "DEG_depsgraph_query.h"
61 
62 #include "MOD_ui_common.h"
63 #include "MOD_util.h"
64 
65 static void initData(ModifierData *md)
66 {
68 
70 
72 }
73 
74 static void freeData(ModifierData *md)
75 {
77 
78  if (mmd->bindinfluences) {
80  }
81  if (mmd->bindoffsets) {
82  MEM_freeN(mmd->bindoffsets);
83  }
84  if (mmd->bindcagecos) {
85  MEM_freeN(mmd->bindcagecos);
86  }
87  if (mmd->dyngrid) {
88  MEM_freeN(mmd->dyngrid);
89  }
90  if (mmd->dyninfluences) {
92  }
93  if (mmd->dynverts) {
94  MEM_freeN(mmd->dynverts);
95  }
96  if (mmd->bindweights) {
97  MEM_freeN(mmd->bindweights); /* deprecated */
98  }
99  if (mmd->bindcos) {
100  MEM_freeN(mmd->bindcos); /* deprecated */
101  }
102 }
103 
104 static void copyData(const ModifierData *md, ModifierData *target, const int flag)
105 {
106  const MeshDeformModifierData *mmd = (const MeshDeformModifierData *)md;
108 
109  BKE_modifier_copydata_generic(md, target, flag);
110 
111  if (mmd->bindinfluences) {
113  }
114  if (mmd->bindoffsets) {
115  tmmd->bindoffsets = MEM_dupallocN(mmd->bindoffsets);
116  }
117  if (mmd->bindcagecos) {
118  tmmd->bindcagecos = MEM_dupallocN(mmd->bindcagecos);
119  }
120  if (mmd->dyngrid) {
121  tmmd->dyngrid = MEM_dupallocN(mmd->dyngrid);
122  }
123  if (mmd->dyninfluences) {
125  }
126  if (mmd->dynverts) {
127  tmmd->dynverts = MEM_dupallocN(mmd->dynverts);
128  }
129  if (mmd->bindweights) {
130  tmmd->bindweights = MEM_dupallocN(mmd->bindweights); /* deprecated */
131  }
132  if (mmd->bindcos) {
133  tmmd->bindcos = MEM_dupallocN(mmd->bindcos); /* deprecated */
134  }
135 }
136 
137 static void requiredDataMask(Object *UNUSED(ob),
138  ModifierData *md,
139  CustomData_MeshMasks *r_cddata_masks)
140 {
142 
143  /* ask for vertexgroups if we need them */
144  if (mmd->defgrp_name[0] != '\0') {
145  r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
146  }
147 }
148 
149 static bool isDisabled(const struct Scene *UNUSED(scene),
150  ModifierData *md,
151  bool UNUSED(useRenderParams))
152 {
154 
155  /* The object type check is only needed here in case we have a placeholder
156  * object assigned (because the library containing the mesh is missing).
157  *
158  * In other cases it should be impossible to have a type mismatch.
159  */
160  return !mmd->object || mmd->object->type != OB_MESH;
161 }
162 
163 static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
164 {
166 
167  walk(userData, ob, (ID **)&mmd->object, IDWALK_CB_NOP);
168 }
169 
171 {
173  if (mmd->object != NULL) {
174  DEG_add_object_relation(ctx->node, mmd->object, DEG_OB_COMP_TRANSFORM, "Mesh Deform Modifier");
175  DEG_add_object_relation(ctx->node, mmd->object, DEG_OB_COMP_GEOMETRY, "Mesh Deform Modifier");
176  }
177  /* We need own transformation as well. */
178  DEG_add_modifier_to_transform_relation(ctx->node, "Mesh Deform Modifier");
179 }
180 
181 static float meshdeform_dynamic_bind(MeshDeformModifierData *mmd, float (*dco)[3], float vec[3])
182 {
183  MDefCell *cell;
184  MDefInfluence *inf;
185  float gridvec[3], dvec[3], ivec[3], wx, wy, wz;
186  float weight, cageweight, totweight, *cageco;
187  int i, j, a, x, y, z, size;
188 #ifdef BLI_HAVE_SSE2
189  __m128 co = _mm_setzero_ps();
190 #else
191  float co[3] = {0.0f, 0.0f, 0.0f};
192 #endif
193 
194  totweight = 0.0f;
195  size = mmd->dyngridsize;
196 
197  for (i = 0; i < 3; i++) {
198  gridvec[i] = (vec[i] - mmd->dyncellmin[i] - mmd->dyncellwidth * 0.5f) / mmd->dyncellwidth;
199  ivec[i] = (int)gridvec[i];
200  dvec[i] = gridvec[i] - ivec[i];
201  }
202 
203  for (i = 0; i < 8; i++) {
204  if (i & 1) {
205  x = ivec[0] + 1;
206  wx = dvec[0];
207  }
208  else {
209  x = ivec[0];
210  wx = 1.0f - dvec[0];
211  }
212 
213  if (i & 2) {
214  y = ivec[1] + 1;
215  wy = dvec[1];
216  }
217  else {
218  y = ivec[1];
219  wy = 1.0f - dvec[1];
220  }
221 
222  if (i & 4) {
223  z = ivec[2] + 1;
224  wz = dvec[2];
225  }
226  else {
227  z = ivec[2];
228  wz = 1.0f - dvec[2];
229  }
230 
231  CLAMP(x, 0, size - 1);
232  CLAMP(y, 0, size - 1);
233  CLAMP(z, 0, size - 1);
234 
235  a = x + y * size + z * size * size;
236  weight = wx * wy * wz;
237 
238  cell = &mmd->dyngrid[a];
239  inf = mmd->dyninfluences + cell->offset;
240  for (j = 0; j < cell->totinfluence; j++, inf++) {
241  cageco = dco[inf->vertex];
242  cageweight = weight * inf->weight;
243 #ifdef BLI_HAVE_SSE2
244  {
245  __m128 cageweight_r = _mm_set1_ps(cageweight);
246  /* This will load one extra element, this is ok because
247  * we ignore that part of register anyway.
248  */
249  __m128 cageco_r = _mm_loadu_ps(cageco);
250  co = _mm_add_ps(co, _mm_mul_ps(cageco_r, cageweight_r));
251  }
252 #else
253  co[0] += cageweight * cageco[0];
254  co[1] += cageweight * cageco[1];
255  co[2] += cageweight * cageco[2];
256 #endif
257  totweight += cageweight;
258  }
259  }
260 
261 #ifdef BLI_HAVE_SSE2
262  copy_v3_v3(vec, (float *)&co);
263 #else
264  copy_v3_v3(vec, co);
265 #endif
266 
267  return totweight;
268 }
269 
270 typedef struct MeshdeformUserdata {
273  /*const*/ float (*dco)[3];
276  float (*cagemat)[4];
279 
280 static void meshdeform_vert_task(void *__restrict userdata,
281  const int iter,
282  const TaskParallelTLS *__restrict UNUSED(tls))
283 {
284  MeshdeformUserdata *data = userdata;
285  /*const*/ MeshDeformModifierData *mmd = data->mmd;
286  const MDeformVert *dvert = data->dvert;
287  const int defgrp_index = data->defgrp_index;
288  const int *offsets = mmd->bindoffsets;
289  const MDefInfluence *__restrict influences = mmd->bindinfluences;
290  /*const*/ float(*__restrict dco)[3] = data->dco;
291  float(*vertexCos)[3] = data->vertexCos;
292  float co[3];
293  float weight, totweight, fac = 1.0f;
294 
295  if (mmd->flag & MOD_MDEF_DYNAMIC_BIND) {
296  if (!mmd->dynverts[iter]) {
297  return;
298  }
299  }
300 
301  if (dvert) {
302  fac = BKE_defvert_find_weight(&dvert[iter], defgrp_index);
303 
304  if (mmd->flag & MOD_MDEF_INVERT_VGROUP) {
305  fac = 1.0f - fac;
306  }
307 
308  if (fac <= 0.0f) {
309  return;
310  }
311  }
312 
313  if (mmd->flag & MOD_MDEF_DYNAMIC_BIND) {
314  /* transform coordinate into cage's local space */
315  mul_v3_m4v3(co, data->cagemat, vertexCos[iter]);
316  totweight = meshdeform_dynamic_bind(mmd, dco, co);
317  }
318  else {
319  totweight = 0.0f;
320  zero_v3(co);
321  int start = offsets[iter];
322  int end = offsets[iter + 1];
323 
324  for (int a = start; a < end; a++) {
325  weight = influences[a].weight;
326  madd_v3_v3fl(co, dco[influences[a].vertex], weight);
327  totweight += weight;
328  }
329  }
330 
331  if (totweight > 0.0f) {
332  mul_v3_fl(co, fac / totweight);
333  mul_m3_v3(data->icagemat, co);
334  add_v3_v3(vertexCos[iter], co);
335  }
336 }
337 
339  const ModifierEvalContext *ctx,
340  Mesh *mesh,
341  float (*vertexCos)[3],
342  int numVerts)
343 {
345  Object *ob = ctx->object;
346 
347  Mesh *cagemesh;
348  MDeformVert *dvert = NULL;
349  float imat[4][4], cagemat[4][4], iobmat[4][4], icagemat[3][3], cmat[4][4];
350  float(*dco)[3] = NULL, (*bindcagecos)[3];
351  int a, totvert, totcagevert, defgrp_index;
353 
354  static int recursive_bind_sentinel = 0;
355 
356  if (mmd->object == NULL || (mmd->bindcagecos == NULL && mmd->bindfunc == NULL)) {
357  return;
358  }
359 
360  /* Get cage mesh.
361  *
362  * Only do this is the target object is in edit mode by itself, meaning
363  * we don't allow linked edit meshes here.
364  * This is because editbmesh_get_mesh_cage_and_final() might easily
365  * conflict with the thread which evaluates object which is in the edit
366  * mode for this mesh.
367  *
368  * We'll support this case once granular dependency graph is landed.
369  */
370  Object *ob_target = mmd->object;
371  cagemesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(ob_target, false);
372  if (cagemesh == NULL) {
373  BKE_modifier_set_error(ctx->object, md, "Cannot get mesh from cage object");
374  return;
375  }
376 
377  /* compute matrices to go in and out of cage object space */
378  invert_m4_m4(imat, ob_target->obmat);
379  mul_m4_m4m4(cagemat, imat, ob->obmat);
380  mul_m4_m4m4(cmat, mmd->bindmat, cagemat);
381  invert_m4_m4(iobmat, cmat);
382  copy_m3_m4(icagemat, iobmat);
383 
384  /* bind weights if needed */
385  if (!mmd->bindcagecos) {
386  /* progress bar redraw can make this recursive .. */
387  if (!DEG_is_active(ctx->depsgraph)) {
388  BKE_modifier_set_error(ob, md, "Attempt to bind from inactive dependency graph");
389  goto finally;
390  }
391  if (!recursive_bind_sentinel) {
392  recursive_bind_sentinel = 1;
393  mmd->bindfunc(mmd, cagemesh, (float *)vertexCos, numVerts, cagemat);
394  recursive_bind_sentinel = 0;
395  }
396 
397  goto finally;
398  }
399 
400  /* verify we have compatible weights */
401  totvert = numVerts;
402  totcagevert = BKE_mesh_wrapper_vert_len(cagemesh);
403 
404  if (mmd->totvert != totvert) {
405  BKE_modifier_set_error(ob, md, "Vertices changed from %d to %d", mmd->totvert, totvert);
406  goto finally;
407  }
408  else if (mmd->totcagevert != totcagevert) {
410  ob, md, "Cage vertices changed from %d to %d", mmd->totcagevert, totcagevert);
411  goto finally;
412  }
413  else if (mmd->bindcagecos == NULL) {
414  BKE_modifier_set_error(ob, md, "Bind data missing");
415  goto finally;
416  }
417 
418  /* We allocate 1 element extra to make it possible to
419  * load the values to SSE registers, which are float4.
420  */
421  dco = MEM_calloc_arrayN((totcagevert + 1), sizeof(*dco), "MDefDco");
422  zero_v3(dco[totcagevert]);
423 
424  /* setup deformation data */
425  BKE_mesh_wrapper_vert_coords_copy(cagemesh, dco, totcagevert);
426  bindcagecos = (float(*)[3])mmd->bindcagecos;
427 
428  for (a = 0; a < totcagevert; a++) {
429  /* get cage vertex in world space with binding transform */
430  float co[3];
431  mul_v3_m4v3(co, mmd->bindmat, dco[a]);
432  /* compute difference with world space bind coord */
433  sub_v3_v3v3(dco[a], co, bindcagecos[a]);
434  }
435 
436  MOD_get_vgroup(ob, mesh, mmd->defgrp_name, &dvert, &defgrp_index);
437 
438  /* Initialize data to be pass to the for body function. */
439  data.mmd = mmd;
440  data.dvert = dvert;
441  data.dco = dco;
442  data.defgrp_index = defgrp_index;
443  data.vertexCos = vertexCos;
444  data.cagemat = cagemat;
445  data.icagemat = icagemat;
446 
447  /* Do deformation. */
448  TaskParallelSettings settings;
450  settings.min_iter_per_thread = 16;
451  BLI_task_parallel_range(0, totvert, &data, meshdeform_vert_task, &settings);
452 
453 finally:
454  MEM_SAFE_FREE(dco);
455 }
456 
457 static void deformVerts(ModifierData *md,
458  const ModifierEvalContext *ctx,
459  Mesh *mesh,
460  float (*vertexCos)[3],
461  int numVerts)
462 {
463  Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
464 
465  MOD_previous_vcos_store(md, vertexCos); /* if next modifier needs original vertices */
466 
467  meshdeformModifier_do(md, ctx, mesh_src, vertexCos, numVerts);
468 
469  if (!ELEM(mesh_src, NULL, mesh)) {
470  BKE_id_free(NULL, mesh_src);
471  }
472 }
473 
474 static void deformVertsEM(ModifierData *md,
475  const ModifierEvalContext *ctx,
476  struct BMEditMesh *editData,
477  Mesh *mesh,
478  float (*vertexCos)[3],
479  int numVerts)
480 {
481  Mesh *mesh_src = MOD_deform_mesh_eval_get(
482  ctx->object, editData, mesh, NULL, numVerts, false, false);
483 
484  /* TODO(Campbell): use edit-mode data only (remove this line). */
485  if (mesh_src != NULL) {
487  }
488 
489  meshdeformModifier_do(md, ctx, mesh_src, vertexCos, numVerts);
490 
491  if (!ELEM(mesh_src, NULL, mesh)) {
492  BKE_id_free(NULL, mesh_src);
493  }
494 }
495 
496 #define MESHDEFORM_MIN_INFLUENCE 0.00001f
497 
499 {
501  float weight, *weights, totweight;
502  int totinfluence, totvert, totcagevert, a, b;
503 
504  weights = mmd->bindweights;
505  if (!weights) {
506  return;
507  }
508 
509  totvert = mmd->totvert;
510  totcagevert = mmd->totcagevert;
511 
512  /* count number of influences above threshold */
513  for (b = 0; b < totvert; b++) {
514  for (a = 0; a < totcagevert; a++) {
515  weight = weights[a + b * totcagevert];
516 
517  if (weight > MESHDEFORM_MIN_INFLUENCE) {
518  mmd->totinfluence++;
519  }
520  }
521  }
522 
523  /* allocate bind influences */
525  mmd->totinfluence, sizeof(MDefInfluence), "MDefBindInfluence");
526  mmd->bindoffsets = MEM_calloc_arrayN((totvert + 1), sizeof(int), "MDefBindOffset");
527 
528  /* write influences */
529  totinfluence = 0;
530 
531  for (b = 0; b < totvert; b++) {
532  mmd->bindoffsets[b] = totinfluence;
533  totweight = 0.0f;
534 
535  /* sum total weight */
536  for (a = 0; a < totcagevert; a++) {
537  weight = weights[a + b * totcagevert];
538 
539  if (weight > MESHDEFORM_MIN_INFLUENCE) {
540  totweight += weight;
541  }
542  }
543 
544  /* assign weights normalized */
545  for (a = 0; a < totcagevert; a++) {
546  weight = weights[a + b * totcagevert];
547 
548  if (weight > MESHDEFORM_MIN_INFLUENCE) {
549  mmd->bindinfluences[totinfluence].weight = weight / totweight;
550  mmd->bindinfluences[totinfluence].vertex = a;
551  totinfluence++;
552  }
553  }
554  }
555 
556  mmd->bindoffsets[b] = totinfluence;
557 
558  /* free */
559  MEM_freeN(mmd->bindweights);
560  mmd->bindweights = NULL;
561 }
562 
563 static void panel_draw(const bContext *UNUSED(C), Panel *panel)
564 {
565  uiLayout *col;
566  uiLayout *layout = panel->layout;
567 
568  PointerRNA ob_ptr;
570 
571  bool is_bound = RNA_boolean_get(ptr, "is_bound");
572 
573  uiLayoutSetPropSep(layout, true);
574 
575  col = uiLayoutColumn(layout, true);
576  uiLayoutSetEnabled(col, !is_bound);
577  uiItemR(col, ptr, "object", 0, NULL, ICON_NONE);
578 
579  modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", NULL);
580 
581  col = uiLayoutColumn(layout, false);
582  uiLayoutSetEnabled(col, !is_bound);
583  uiItemR(col, ptr, "precision", 0, NULL, ICON_NONE);
584  uiItemR(col, ptr, "use_dynamic_bind", 0, NULL, ICON_NONE);
585 
586  uiItemO(layout,
587  is_bound ? IFACE_("Unbind") : IFACE_("Bind"),
588  ICON_NONE,
589  "OBJECT_OT_meshdeform_bind");
590 
591  modifier_panel_end(layout, ptr);
592 }
593 
594 static void panelRegister(ARegionType *region_type)
595 {
597 }
598 
599 static void blendWrite(BlendWriter *writer, const ModifierData *md)
600 {
602  int size = mmd->dyngridsize;
603 
605  /* NOTE: `bindoffset` is abusing `totvert + 1` as its size, this becomes an incorrect value in
606  * case `totvert == 0`, since `bindoffset` is then NULL, not a size 1 allocated array. */
607  if (mmd->totvert > 0) {
608  BLO_write_int32_array(writer, mmd->totvert + 1, mmd->bindoffsets);
609  }
610  else {
611  BLI_assert(mmd->bindoffsets == NULL);
612  }
613  BLO_write_float3_array(writer, mmd->totcagevert, mmd->bindcagecos);
614  BLO_write_struct_array(writer, MDefCell, size * size * size, mmd->dyngrid);
616  BLO_write_int32_array(writer, mmd->totvert, mmd->dynverts);
617 }
618 
619 static void blendRead(BlendDataReader *reader, ModifierData *md)
620 {
622 
623  BLO_read_data_address(reader, &mmd->bindinfluences);
624  /* NOTE: `bindoffset` is abusing `totvert + 1` as its size, this becomes an incorrect value in
625  * case `totvert == 0`, since `bindoffset` is then NULL, not a size 1 allocated array. */
626  if (mmd->totvert > 0) {
627  BLO_read_int32_array(reader, mmd->totvert + 1, &mmd->bindoffsets);
628  }
629  BLO_read_float3_array(reader, mmd->totcagevert, &mmd->bindcagecos);
630  BLO_read_data_address(reader, &mmd->dyngrid);
631  BLO_read_data_address(reader, &mmd->dyninfluences);
632  BLO_read_int32_array(reader, mmd->totvert, &mmd->dynverts);
633 
634  /* Deprecated storage. */
635  BLO_read_float_array(reader, mmd->totvert, &mmd->bindweights);
636  BLO_read_float3_array(reader, mmd->totcagevert, &mmd->bindcos);
637 }
638 
640  /* name */ "MeshDeform",
641  /* structName */ "MeshDeformModifierData",
642  /* structSize */ sizeof(MeshDeformModifierData),
643  /* srna */ &RNA_MeshDeformModifier,
644  /* type */ eModifierTypeType_OnlyDeform,
647  /* icon */ ICON_MOD_MESHDEFORM,
648 
649  /* copyData */ copyData,
650 
651  /* deformVerts */ deformVerts,
652  /* deformMatrices */ NULL,
653  /* deformVertsEM */ deformVertsEM,
654  /* deformMatricesEM */ NULL,
655  /* modifyMesh */ NULL,
656  /* modifyHair */ NULL,
657  /* modifyGeometrySet */ NULL,
658  /* modifyVolume */ NULL,
659 
660  /* initData */ initData,
661  /* requiredDataMask */ requiredDataMask,
662  /* freeData */ freeData,
663  /* isDisabled */ isDisabled,
664  /* updateDepsgraph */ updateDepsgraph,
665  /* dependsOnTime */ NULL,
666  /* dependsOnNormals */ NULL,
667  /* foreachIDLink */ foreachIDLink,
668  /* foreachTexLink */ NULL,
669  /* freeRuntimeData */ NULL,
670  /* panelRegister */ panelRegister,
671  /* blendWrite */ blendWrite,
672  /* blendRead */ blendRead,
673 };
typedef float(TangentPoint)[2]
support for deformation groups and hooks.
float BKE_defvert_find_weight(const struct MDeformVert *dvert, const int defgroup)
Definition: deform.c:632
void BKE_id_free(struct Main *bmain, void *idv)
@ IDWALK_CB_NOP
Definition: BKE_lib_query.h:47
void BKE_mesh_wrapper_ensure_mdata(struct Mesh *me)
Definition: mesh_wrapper.c:98
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:120
@ eModifierTypeFlag_AcceptsCVs
Definition: BKE_modifier.h:81
@ eModifierTypeFlag_SupportsEditmode
Definition: BKE_modifier.h:83
@ eModifierTypeFlag_AcceptsVertexCosOnly
Definition: BKE_modifier.h:114
void BKE_modifier_copydata_generic(const struct ModifierData *md, struct ModifierData *md_dst, const int flag)
@ eModifierTypeType_OnlyDeform
Definition: BKE_modifier.h:58
void BKE_modifier_set_error(const struct Object *ob, struct ModifierData *md, const char *format,...) ATTR_PRINTF_FORMAT(3
struct Mesh * BKE_modifier_get_evaluated_mesh_from_evaluated_object(struct Object *ob_eval, const bool get_cage_mesh)
#define BLI_assert(a)
Definition: BLI_assert.h:58
void mul_m3_v3(const float M[3][3], float r[3])
Definition: math_matrix.c:930
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:262
void copy_m3_m4(float m1[3][3], const float m2[4][4])
Definition: math_matrix.c:105
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1278
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:742
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(const int start, const int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
Definition: task_range.cc:110
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
Definition: BLI_task.h:231
#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:5683
#define BLO_read_data_address(reader, ptr_p)
void BLO_write_float3_array(BlendWriter *writer, uint num, const float *data_ptr)
Definition: writefile.c:1393
void BLO_write_int32_array(BlendWriter *writer, uint num, const int32_t *data_ptr)
Definition: writefile.c:1368
void BLO_read_float_array(BlendDataReader *reader, int array_size, float **ptr_p)
Definition: readfile.c:5675
void BLO_read_int32_array(BlendDataReader *reader, int array_size, int32_t **ptr_p)
Definition: readfile.c:5659
#define BLO_write_struct_array(writer, struct_name, array_size, data_ptr)
#define IFACE_(msgid)
bool DEG_is_active(const struct Depsgraph *depsgraph)
Definition: depsgraph.cc:331
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 CD_MASK_MDEFORMVERT
#define DNA_struct_default_get(struct_name)
Definition: DNA_defaults.h:44
@ eModifierType_MeshDeform
struct MeshDeformModifierData MeshDeformModifierData
@ MOD_MDEF_DYNAMIC_BIND
@ MOD_MDEF_INVERT_VGROUP
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 deformVertsEM(ModifierData *md, const ModifierEvalContext *ctx, struct BMEditMesh *editData, Mesh *mesh, float(*vertexCos)[3], int numVerts)
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 meshdeformModifier_do(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, float(*vertexCos)[3], int numVerts)
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 blendWrite(BlendWriter *writer, const ModifierData *md)
static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, float(*vertexCos)[3], int numVerts)
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 float meshdeform_dynamic_bind(MeshDeformModifierData *mmd, float(*dco)[3], float vec[3])
static void freeData(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)
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 num_verts, const bool use_normals, const bool use_orco)
Definition: MOD_util.c:186
void MOD_previous_vcos_store(ModifierData *md, const float(*vert_coords)[3])
Definition: MOD_util.c:171
void MOD_get_vgroup(Object *ob, struct Mesh *mesh, const char *name, MDeformVert **dvert, int *defgrp_index)
Definition: MOD_util.c:254
Group RGB to Bright Vector Camera CLAMP
StructRNA RNA_MeshDeformModifier
#define C
Definition: RandGen.cpp:39
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:41
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:42
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:46
static unsigned a[3]
Definition: RandGen.cpp:92
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
Definition: DNA_ID.h:273
void(* bindfunc)(struct MeshDeformModifierData *mmd, struct Mesh *cagemesh, float *vertexcos, int totvert, 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:153
struct Object * object
Definition: BKE_modifier.h:154
struct DepsNodeHandle * node
Definition: BKE_modifier.h:147
float obmat[4][4]
struct uiLayout * layout
PointerRNA * ptr
Definition: wm_files.c:3157