Blender  V2.93
MOD_weightvgmix.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) 2011 by Bastien Montagne.
17  * All rights reserved.
18  */
19 
24 #include "BLI_utildefines.h"
25 
26 #include "BLI_listbase.h"
27 #include "BLI_math.h"
28 
29 #include "BLT_translation.h"
30 
31 #include "DNA_defaults.h"
32 #include "DNA_mesh_types.h"
33 #include "DNA_meshdata_types.h"
34 #include "DNA_modifier_types.h"
35 #include "DNA_object_types.h"
36 #include "DNA_screen_types.h"
37 
38 #include "BKE_context.h"
39 #include "BKE_customdata.h"
40 #include "BKE_deform.h"
41 #include "BKE_lib_query.h"
42 #include "BKE_modifier.h"
43 #include "BKE_screen.h"
44 #include "BKE_texture.h" /* Texture masking. */
45 
46 #include "UI_interface.h"
47 #include "UI_resources.h"
48 
49 #include "RNA_access.h"
50 
51 #include "DEG_depsgraph_build.h"
52 #include "DEG_depsgraph_query.h"
53 
54 #include "MEM_guardedalloc.h"
55 
56 #include "MOD_modifiertypes.h"
57 #include "MOD_ui_common.h"
58 #include "MOD_util.h"
59 #include "MOD_weightvg_util.h"
60 
64 static float mix_weight(float weight, float weight2, char mix_mode)
65 {
66 #if 0
67  /*
68  * XXX Don't know why, but the switch version takes many CPU time,
69  * and produces lag in realtime playback...
70  */
71  switch (mix_mode) {
72  case MOD_WVG_MIX_ADD:
73  return (weight + weight2);
74  case MOD_WVG_MIX_SUB:
75  return (weight - weight2);
76  case MOD_WVG_MIX_MUL:
77  return (weight * weight2);
78  case MOD_WVG_MIX_DIV:
79  /* Avoid dividing by zero (or really small values). */
80  if (0.0 <= weight2 < MOD_WVG_ZEROFLOOR) {
81  weight2 = MOD_WVG_ZEROFLOOR;
82  }
83  else if (-MOD_WVG_ZEROFLOOR < weight2) {
84  weight2 = -MOD_WVG_ZEROFLOOR;
85  }
86  return (weight / weight2);
87  case MOD_WVG_MIX_DIF:
88  return (weight < weight2 ? weight2 - weight : weight - weight2);
89  case MOD_WVG_MIX_AVG:
90  return (weight + weight2) / 2.0;
91  case MOD_WVG_MIX_SET:
92  default:
93  return weight2;
94  }
95 #endif
96  if (mix_mode == MOD_WVG_MIX_SET) {
97  return weight2;
98  }
99  if (mix_mode == MOD_WVG_MIX_ADD) {
100  return (weight + weight2);
101  }
102  if (mix_mode == MOD_WVG_MIX_SUB) {
103  return (weight - weight2);
104  }
105  if (mix_mode == MOD_WVG_MIX_MUL) {
106  return (weight * weight2);
107  }
108  if (mix_mode == MOD_WVG_MIX_DIV) {
109  /* Avoid dividing by zero (or really small values). */
110  if (weight2 < 0.0f && weight2 > -MOD_WVG_ZEROFLOOR) {
111  weight2 = -MOD_WVG_ZEROFLOOR;
112  }
113  else if (weight2 >= 0.0f && weight2 < MOD_WVG_ZEROFLOOR) {
114  weight2 = MOD_WVG_ZEROFLOOR;
115  }
116  return (weight / weight2);
117  }
118  if (mix_mode == MOD_WVG_MIX_DIF) {
119  return (weight < weight2 ? weight2 - weight : weight - weight2);
120  }
121  if (mix_mode == MOD_WVG_MIX_AVG) {
122  return (weight + weight2) * 0.5f;
123  }
124 
125  return weight2;
126 }
127 
128 /**************************************
129  * Modifiers functions. *
130  **************************************/
131 static void initData(ModifierData *md)
132 {
134 
135  BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(wmd, modifier));
136 
138 }
139 
140 static void requiredDataMask(Object *UNUSED(ob),
141  ModifierData *md,
142  CustomData_MeshMasks *r_cddata_masks)
143 {
145 
146  /* We need vertex groups! */
147  r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
148 
149  /* Ask for UV coordinates if we need them. */
150  if (wmd->mask_tex_mapping == MOD_DISP_MAP_UV) {
151  r_cddata_masks->fmask |= CD_MASK_MTFACE;
152  }
153 
154  /* No need to ask for CD_PREVIEW_MLOOPCOL... */
155 }
156 
157 static bool dependsOnTime(ModifierData *md)
158 {
160 
161  if (wmd->mask_texture) {
163  }
164  return false;
165 }
166 
167 static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
168 {
170 
171  walk(userData, ob, (ID **)&wmd->mask_texture, IDWALK_CB_USER);
172  walk(userData, ob, (ID **)&wmd->mask_tex_map_obj, IDWALK_CB_NOP);
173 }
174 
175 static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void *userData)
176 {
177  walk(userData, ob, md, "mask_texture");
178 }
179 
181 {
183  bool need_transform_relation = false;
184 
185  if (wmd->mask_texture != NULL) {
186  DEG_add_generic_id_relation(ctx->node, &wmd->mask_texture->id, "WeightVGMix Modifier");
187 
190  ctx->node, wmd->mask_tex_map_obj, wmd->mask_tex_map_bone, "WeightVGMix Modifier");
191  need_transform_relation = true;
192  }
193  else if (wmd->mask_tex_mapping == MOD_DISP_MAP_GLOBAL) {
194  need_transform_relation = true;
195  }
196  }
197 
198  if (need_transform_relation) {
199  DEG_add_modifier_to_transform_relation(ctx->node, "WeightVGMix Modifier");
200  }
201 }
202 
203 static bool isDisabled(const struct Scene *UNUSED(scene),
204  ModifierData *md,
205  bool UNUSED(useRenderParams))
206 {
208  /* If no vertex group, bypass. */
209  return (wmd->defgrp_name_a[0] == '\0');
210 }
211 
213 {
214  BLI_assert(mesh != NULL);
215 
217 
218  MDeformVert *dvert = NULL;
219  MDeformWeight **dw1, **tdw1, **dw2, **tdw2;
220  float *org_w;
221  float *new_w;
222  int *tidx, *indices = NULL;
223  int numIdx = 0;
224  int i;
225  const bool invert_vgroup_mask = (wmd->flag & MOD_WVG_MIX_INVERT_VGROUP_MASK) != 0;
226  const bool do_normalize = (wmd->flag & MOD_WVG_MIX_WEIGHTS_NORMALIZE) != 0;
227 
228  /*
229  * Note that we only invert the weight values within provided vgroups, the selection based on
230  * which vertice is affected because it belongs or not to a group remains unchanged.
231  * In other words, vertices not belonging to a group won't be affected, even though their
232  * inverted 'virtual' weight would be 1.0f.
233  */
234  const bool invert_vgroup_a = (wmd->flag & MOD_WVG_MIX_INVERT_VGROUP_A) != 0;
235  const bool invert_vgroup_b = (wmd->flag & MOD_WVG_MIX_INVERT_VGROUP_B) != 0;
236 
237  /* Flags. */
238 #if 0
239  const bool do_prev = (wmd->modifier.mode & eModifierMode_DoWeightPreview) != 0;
240 #endif
241 
242  /* Get number of verts. */
243  const int numVerts = mesh->totvert;
244 
245  /* Check if we can just return the original mesh.
246  * Must have verts and therefore verts assigned to vgroups to do anything useful!
247  */
248  if ((numVerts == 0) || BLI_listbase_is_empty(&ctx->object->defbase)) {
249  return mesh;
250  }
251 
252  /* Get vgroup idx from its name. */
253  const int defgrp_index = BKE_object_defgroup_name_index(ctx->object, wmd->defgrp_name_a);
254  if (defgrp_index == -1) {
255  return mesh;
256  }
257  /* Get second vgroup idx from its name, if given. */
258  int defgrp_index_other = -1;
259  if (wmd->defgrp_name_b[0] != '\0') {
260  defgrp_index_other = BKE_object_defgroup_name_index(ctx->object, wmd->defgrp_name_b);
261  if (defgrp_index_other == -1) {
262  return mesh;
263  }
264  }
265 
266  const bool has_mdef = CustomData_has_layer(&mesh->vdata, CD_MDEFORMVERT);
267  /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */
268  if (!has_mdef) {
269  /* If not affecting all vertices, just return. */
270  if (wmd->mix_set != MOD_WVG_SET_ALL) {
271  return mesh;
272  }
273  }
274 
275  if (has_mdef) {
276  dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, numVerts);
277  }
278  else {
279  /* Add a valid data layer! */
280  dvert = CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, numVerts);
281  }
282  /* Ultimate security check. */
283  if (!dvert) {
284  return mesh;
285  }
286  mesh->dvert = dvert;
287 
288  /* Find out which vertices to work on. */
289  tidx = MEM_malloc_arrayN(numVerts, sizeof(int), "WeightVGMix Modifier, tidx");
290  tdw1 = MEM_malloc_arrayN(numVerts, sizeof(MDeformWeight *), "WeightVGMix Modifier, tdw1");
291  tdw2 = MEM_malloc_arrayN(numVerts, sizeof(MDeformWeight *), "WeightVGMix Modifier, tdw2");
292  switch (wmd->mix_set) {
293  case MOD_WVG_SET_A:
294  /* All vertices in first vgroup. */
295  for (i = 0; i < numVerts; i++) {
296  MDeformWeight *dw = BKE_defvert_find_index(&dvert[i], defgrp_index);
297  if (dw) {
298  tdw1[numIdx] = dw;
299  tdw2[numIdx] = (defgrp_index_other >= 0) ?
300  BKE_defvert_find_index(&dvert[i], defgrp_index_other) :
301  NULL;
302  tidx[numIdx++] = i;
303  }
304  }
305  break;
306  case MOD_WVG_SET_B:
307  /* All vertices in second vgroup. */
308  for (i = 0; i < numVerts; i++) {
309  MDeformWeight *dw = (defgrp_index_other >= 0) ?
310  BKE_defvert_find_index(&dvert[i], defgrp_index_other) :
311  NULL;
312  if (dw) {
313  tdw1[numIdx] = BKE_defvert_find_index(&dvert[i], defgrp_index);
314  tdw2[numIdx] = dw;
315  tidx[numIdx++] = i;
316  }
317  }
318  break;
319  case MOD_WVG_SET_OR:
320  /* All vertices in one vgroup or the other. */
321  for (i = 0; i < numVerts; i++) {
322  MDeformWeight *adw = BKE_defvert_find_index(&dvert[i], defgrp_index);
323  MDeformWeight *bdw = (defgrp_index_other >= 0) ?
324  BKE_defvert_find_index(&dvert[i], defgrp_index_other) :
325  NULL;
326  if (adw || bdw) {
327  tdw1[numIdx] = adw;
328  tdw2[numIdx] = bdw;
329  tidx[numIdx++] = i;
330  }
331  }
332  break;
333  case MOD_WVG_SET_AND:
334  /* All vertices in both vgroups. */
335  for (i = 0; i < numVerts; i++) {
336  MDeformWeight *adw = BKE_defvert_find_index(&dvert[i], defgrp_index);
337  MDeformWeight *bdw = (defgrp_index_other >= 0) ?
338  BKE_defvert_find_index(&dvert[i], defgrp_index_other) :
339  NULL;
340  if (adw && bdw) {
341  tdw1[numIdx] = adw;
342  tdw2[numIdx] = bdw;
343  tidx[numIdx++] = i;
344  }
345  }
346  break;
347  case MOD_WVG_SET_ALL:
348  default:
349  /* Use all vertices. */
350  for (i = 0; i < numVerts; i++) {
351  tdw1[i] = BKE_defvert_find_index(&dvert[i], defgrp_index);
352  tdw2[i] = (defgrp_index_other >= 0) ?
353  BKE_defvert_find_index(&dvert[i], defgrp_index_other) :
354  NULL;
355  }
356  numIdx = -1;
357  break;
358  }
359  if (numIdx == 0) {
360  /* Use no vertices! Hence, return org data. */
361  MEM_freeN(tdw1);
362  MEM_freeN(tdw2);
363  MEM_freeN(tidx);
364  return mesh;
365  }
366  if (numIdx != -1) {
367  indices = MEM_malloc_arrayN(numIdx, sizeof(int), "WeightVGMix Modifier, indices");
368  memcpy(indices, tidx, sizeof(int) * numIdx);
369  dw1 = MEM_malloc_arrayN(numIdx, sizeof(MDeformWeight *), "WeightVGMix Modifier, dw1");
370  memcpy(dw1, tdw1, sizeof(MDeformWeight *) * numIdx);
371  MEM_freeN(tdw1);
372  dw2 = MEM_malloc_arrayN(numIdx, sizeof(MDeformWeight *), "WeightVGMix Modifier, dw2");
373  memcpy(dw2, tdw2, sizeof(MDeformWeight *) * numIdx);
374  MEM_freeN(tdw2);
375  }
376  else {
377  /* Use all vertices. */
378  numIdx = numVerts;
379  /* Just copy MDeformWeight pointers arrays, they will be freed at the end. */
380  dw1 = tdw1;
381  dw2 = tdw2;
382  }
383  MEM_freeN(tidx);
384 
385  org_w = MEM_malloc_arrayN(numIdx, sizeof(float), "WeightVGMix Modifier, org_w");
386  new_w = MEM_malloc_arrayN(numIdx, sizeof(float), "WeightVGMix Modifier, new_w");
387 
388  /* Mix weights. */
389  for (i = 0; i < numIdx; i++) {
390  float weight2;
391  if (invert_vgroup_a) {
392  org_w[i] = 1.0f - (dw1[i] ? dw1[i]->weight : wmd->default_weight_a);
393  }
394  else {
395  org_w[i] = dw1[i] ? dw1[i]->weight : wmd->default_weight_a;
396  }
397  if (invert_vgroup_b) {
398  weight2 = 1.0f - (dw2[i] ? dw2[i]->weight : wmd->default_weight_b);
399  }
400  else {
401  weight2 = dw2[i] ? dw2[i]->weight : wmd->default_weight_b;
402  }
403 
404  new_w[i] = mix_weight(org_w[i], weight2, wmd->mix_mode);
405  }
406 
407  /* Do masking. */
409  weightvg_do_mask(ctx,
410  numIdx,
411  indices,
412  org_w,
413  new_w,
414  ctx->object,
415  mesh,
416  wmd->mask_constant,
417  wmd->mask_defgrp_name,
418  scene,
419  wmd->mask_texture,
421  wmd->mask_tex_mapping,
422  wmd->mask_tex_map_obj,
423  wmd->mask_tex_map_bone,
425  invert_vgroup_mask);
426 
427  /* Update (add to) vgroup.
428  * XXX Depending on the MOD_WVG_SET_xxx option chosen, we might have to add vertices to vgroup.
429  */
431  dvert, defgrp_index, dw1, numIdx, indices, org_w, true, -FLT_MAX, false, 0.0f, do_normalize);
432 
433  /* If weight preview enabled... */
434 #if 0 /* XXX Currently done in mod stack :/ */
435  if (do_prev) {
436  DM_update_weight_mcol(ob, dm, 0, org_w, numIdx, indices);
437  }
438 #endif
439 
440  /* Freeing stuff. */
441  MEM_freeN(org_w);
442  MEM_freeN(new_w);
443  MEM_freeN(dw1);
444  MEM_freeN(dw2);
446 
447  mesh->runtime.is_original = false;
448 
449  /* Return the vgroup-modified mesh. */
450  return mesh;
451 }
452 
453 static void panel_draw(const bContext *UNUSED(C), Panel *panel)
454 {
455  uiLayout *layout = panel->layout;
456 
457  PointerRNA ob_ptr;
459 
460  uiLayoutSetPropSep(layout, true);
461 
462  modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group_a", "invert_vertex_group_a", NULL);
463  modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group_b", "invert_vertex_group_b", IFACE_("B"));
464 
465  uiItemS(layout);
466 
467  uiItemR(layout, ptr, "default_weight_a", 0, NULL, ICON_NONE);
468  uiItemR(layout, ptr, "default_weight_b", 0, IFACE_("B"), ICON_NONE);
469 
470  uiItemS(layout);
471 
472  uiItemR(layout, ptr, "mix_set", 0, NULL, ICON_NONE);
473  uiItemR(layout, ptr, "mix_mode", 0, NULL, ICON_NONE);
474 
475  uiItemR(layout, ptr, "normalize", 0, NULL, ICON_NONE);
476 
477  modifier_panel_end(layout, ptr);
478 }
479 
480 static void influence_panel_draw(const bContext *C, Panel *panel)
481 {
482  uiLayout *layout = panel->layout;
483 
484  PointerRNA ob_ptr;
486 
487  weightvg_ui_common(C, &ob_ptr, ptr, layout);
488 }
489 
490 static void panelRegister(ARegionType *region_type)
491 {
492  PanelType *panel_type = modifier_panel_register(
493  region_type, eModifierType_WeightVGMix, panel_draw);
495  region_type, "influence", "Influence", NULL, influence_panel_draw, panel_type);
496 }
497 
499  /* name */ "VertexWeightMix",
500  /* structName */ "WeightVGMixModifierData",
501  /* structSize */ sizeof(WeightVGMixModifierData),
502  /* srna */ &RNA_VertexWeightMixModifier,
506  /* icon */ ICON_MOD_VERTEX_WEIGHT,
507 
508  /* copyData */ BKE_modifier_copydata_generic,
509 
510  /* deformVerts */ NULL,
511  /* deformMatrices */ NULL,
512  /* deformVertsEM */ NULL,
513  /* deformMatricesEM */ NULL,
514  /* modifyMesh */ modifyMesh,
515  /* modifyHair */ NULL,
516  /* modifyGeometrySet */ NULL,
517  /* modifyVolume */ NULL,
518 
519  /* initData */ initData,
520  /* requiredDataMask */ requiredDataMask,
521  /* freeData */ NULL,
522  /* isDisabled */ isDisabled,
523  /* updateDepsgraph */ updateDepsgraph,
524  /* dependsOnTime */ dependsOnTime,
525  /* dependsOnNormals */ NULL,
526  /* foreachIDLink */ foreachIDLink,
527  /* foreachTexLink */ foreachTexLink,
528  /* freeRuntimeData */ NULL,
529  /* panelRegister */ panelRegister,
530  /* blendWrite */ NULL,
531  /* blendRead */ NULL,
532 };
CustomData interface, see also DNA_customdata_types.h.
@ CD_CALLOC
bool CustomData_has_layer(const struct CustomData *data, int type)
void * CustomData_duplicate_referenced_layer(struct CustomData *data, const int type, const int totelem)
Definition: customdata.c:2788
void * CustomData_add_layer(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem)
Definition: customdata.c:2620
support for deformation groups and hooks.
int BKE_object_defgroup_name_index(const struct Object *ob, const char *name)
struct MDeformWeight * BKE_defvert_find_index(const struct MDeformVert *dv, const int defgroup)
@ IDWALK_CB_USER
Definition: BKE_lib_query.h:87
@ IDWALK_CB_NOP
Definition: BKE_lib_query.h:47
void(* IDWalkFunc)(void *userData, struct Object *ob, struct ID **idpoin, int cb_flag)
Definition: BKE_modifier.h:120
@ eModifierTypeFlag_SupportsMapping
Definition: BKE_modifier.h:82
@ eModifierTypeFlag_UsesPreview
Definition: BKE_modifier.h:113
@ eModifierTypeFlag_SupportsEditmode
Definition: BKE_modifier.h:83
@ eModifierTypeFlag_AcceptsMesh
Definition: BKE_modifier.h:80
void(* TexWalkFunc)(void *userData, struct Object *ob, struct ModifierData *md, const char *propname)
Definition: BKE_modifier.h:121
void BKE_modifier_copydata_generic(const struct ModifierData *md, struct ModifierData *md_dst, const int flag)
@ eModifierTypeType_NonGeometrical
Definition: BKE_modifier.h:76
bool BKE_texture_dependsOnTime(const struct Tex *texture)
Definition: texture.c:697
#define BLI_assert(a)
Definition: BLI_assert.h:58
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:124
#define UNUSED(x)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define IFACE_(msgid)
void DEG_add_modifier_to_transform_relation(struct DepsNodeHandle *node_handle, const char *description)
void DEG_add_generic_id_relation(struct DepsNodeHandle *node_handle, struct ID *id, const char *description)
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
#define CD_MASK_MDEFORMVERT
@ CD_MDEFORMVERT
#define CD_MASK_MTFACE
#define DNA_struct_default_get(struct_name)
Definition: DNA_defaults.h:44
@ MOD_DISP_MAP_OBJECT
@ MOD_DISP_MAP_GLOBAL
@ MOD_DISP_MAP_UV
@ MOD_WVG_SET_AND
@ MOD_WVG_SET_B
@ MOD_WVG_SET_ALL
@ MOD_WVG_SET_OR
@ MOD_WVG_SET_A
@ MOD_WVG_MIX_INVERT_VGROUP_MASK
@ MOD_WVG_MIX_INVERT_VGROUP_B
@ MOD_WVG_MIX_WEIGHTS_NORMALIZE
@ MOD_WVG_MIX_INVERT_VGROUP_A
@ MOD_WVG_MIX_ADD
@ MOD_WVG_MIX_SUB
@ MOD_WVG_MIX_DIF
@ MOD_WVG_MIX_SET
@ MOD_WVG_MIX_DIV
@ MOD_WVG_MIX_AVG
@ MOD_WVG_MIX_MUL
@ eModifierType_WeightVGMix
struct WeightVGMixModifierData WeightVGMixModifierData
Object is a sort of wrapper for general info.
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
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)
PanelType * modifier_subpanel_register(ARegionType *region_type, const char *name, const char *label, PanelDrawFn draw_header, PanelDrawFn draw, PanelType *parent)
void MOD_depsgraph_update_object_bone_relation(struct DepsNodeHandle *node, Object *object, const char *bonename, const char *description)
Definition: MOD_util.c:270
void weightvg_update_vg(MDeformVert *dvert, int defgrp_idx, MDeformWeight **dws, int num, const int *indices, const float *weights, const bool do_add, const float add_thresh, const bool do_rem, const float rem_thresh, const bool do_normalize)
void weightvg_do_mask(const ModifierEvalContext *ctx, const int num, const int *indices, float *org_w, const float *new_w, Object *ob, Mesh *mesh, const float fact, const char defgrp_name[MAX_VGROUP_NAME], Scene *scene, Tex *texture, const int tex_use_channel, const int tex_mapping, Object *tex_map_object, const char *text_map_bone, const char *tex_uvlayer_name, const bool invert_vgroup_mask)
void weightvg_ui_common(const bContext *C, PointerRNA *ob_ptr, PointerRNA *ptr, uiLayout *layout)
#define MOD_WVG_ZEROFLOOR
static void influence_panel_draw(const bContext *C, Panel *panel)
static Mesh * modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
static bool isDisabled(const struct Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams))
static float mix_weight(float weight, float weight2, char mix_mode)
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
ModifierTypeInfo modifierType_WeightVGMix
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
static void initData(ModifierData *md)
static void panelRegister(ARegionType *region_type)
static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void *userData)
static bool dependsOnTime(ModifierData *md)
static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
StructRNA RNA_VertexWeightMixModifier
#define C
Definition: RandGen.cpp:39
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemS(uiLayout *layout)
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
Scene scene
static ushort indices[]
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:48
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
Definition: DNA_ID.h:273
struct MDeformVert * dvert
int totvert
Mesh_Runtime runtime
struct Depsgraph * depsgraph
Definition: BKE_modifier.h:153
struct Object * object
Definition: BKE_modifier.h:154
struct DepsNodeHandle * node
Definition: BKE_modifier.h:147
ListBase defbase
struct uiLayout * layout
struct Object * mask_tex_map_obj
PointerRNA * ptr
Definition: wm_files.c:3157