Blender  V3.3
MOD_weightvgproximity.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2011 by Bastien Montagne. All rights reserved. */
3 
8 #include "BLI_utildefines.h"
9 
10 #include "BLI_ghash.h"
11 #include "BLI_listbase.h"
12 #include "BLI_math.h"
13 #include "BLI_rand.h"
14 #include "BLI_task.h"
15 
16 #include "BLT_translation.h"
17 
18 #include "DNA_color_types.h" /* CurveMapping. */
19 #include "DNA_defaults.h"
20 #include "DNA_mesh_types.h"
21 #include "DNA_meshdata_types.h"
22 #include "DNA_modifier_types.h"
23 #include "DNA_object_types.h"
24 #include "DNA_screen_types.h"
25 
26 #include "BKE_bvhutils.h"
27 #include "BKE_colortools.h" /* CurveMapping. */
28 #include "BKE_context.h"
29 #include "BKE_curve.h"
30 #include "BKE_customdata.h"
31 #include "BKE_deform.h"
32 #include "BKE_lib_id.h"
33 #include "BKE_lib_query.h"
34 #include "BKE_mesh.h"
35 #include "BKE_mesh_wrapper.h"
36 #include "BKE_modifier.h"
37 #include "BKE_screen.h"
38 #include "BKE_texture.h" /* Texture masking. */
39 
40 #include "UI_interface.h"
41 #include "UI_resources.h"
42 
43 #include "BLO_read_write.h"
44 
45 #include "RNA_access.h"
46 #include "RNA_prototypes.h"
47 
48 #include "DEG_depsgraph_build.h"
49 #include "DEG_depsgraph_query.h"
50 
51 #include "MEM_guardedalloc.h"
52 
53 #include "MOD_modifiertypes.h"
54 #include "MOD_ui_common.h"
55 #include "MOD_util.h"
56 #include "MOD_weightvg_util.h"
57 
58 //#define USE_TIMEIT
59 
60 #ifdef USE_TIMEIT
61 # include "PIL_time.h"
62 # include "PIL_time_utildefines.h"
63 #endif
64 
65 /**************************************
66  * Util functions. *
67  **************************************/
68 
69 /* Util macro. */
70 #define OUT_OF_MEMORY() ((void)printf("WeightVGProximity: Out of memory.\n"))
71 
72 typedef struct Vert2GeomData {
73  /* Read-only data */
74  float (*v_cos)[3];
75 
77 
79 
80  /* Write data, but not needing locking (two different threads will never write same index). */
81  float *dist[3];
83 
88 typedef struct Vert2GeomDataChunk {
89  /* Read-only data */
90  float last_hit_co[3][3];
91  bool is_init[3];
93 
97 static void vert2geom_task_cb_ex(void *__restrict userdata,
98  const int iter,
99  const TaskParallelTLS *__restrict tls)
100 {
101  Vert2GeomData *data = userdata;
102  Vert2GeomDataChunk *data_chunk = tls->userdata_chunk;
103 
104  float tmp_co[3];
105  int i;
106 
107  /* Convert the vertex to tree coordinates. */
108  copy_v3_v3(tmp_co, data->v_cos[iter]);
109  BLI_space_transform_apply(data->loc2trgt, tmp_co);
110 
111  for (i = 0; i < ARRAY_SIZE(data->dist); i++) {
112  if (data->dist[i]) {
113  BVHTreeNearest nearest = {0};
114 
115  /* Note that we use local proximity heuristics (to reduce the nearest search).
116  *
117  * If we already had an hit before in same chunk of tasks (i.e. previous vertex by index),
118  * we assume this vertex is going to have a close hit to that other vertex,
119  * so we can initiate the "nearest.dist" with the expected value to that last hit.
120  * This will lead in pruning of the search tree.
121  */
122  nearest.dist_sq = data_chunk->is_init[i] ?
123  len_squared_v3v3(tmp_co, data_chunk->last_hit_co[i]) :
124  FLT_MAX;
125  nearest.index = -1;
126 
127  /* Compute and store result. If invalid (-1 idx), keep FLT_MAX dist. */
128  BLI_bvhtree_find_nearest(data->treeData[i]->tree,
129  tmp_co,
130  &nearest,
131  data->treeData[i]->nearest_callback,
132  data->treeData[i]);
133  data->dist[i][iter] = sqrtf(nearest.dist_sq);
134 
135  if (nearest.index != -1) {
136  copy_v3_v3(data_chunk->last_hit_co[i], nearest.co);
137  data_chunk->is_init[i] = true;
138  }
139  }
140  }
141 }
142 
146 static void get_vert2geom_distance(int verts_num,
147  float (*v_cos)[3],
148  float *dist_v,
149  float *dist_e,
150  float *dist_f,
151  Mesh *target,
152  const SpaceTransform *loc2trgt)
153 {
154  Vert2GeomData data = {0};
155  Vert2GeomDataChunk data_chunk = {{{0}}};
156 
157  BVHTreeFromMesh treeData_v = {NULL};
158  BVHTreeFromMesh treeData_e = {NULL};
159  BVHTreeFromMesh treeData_f = {NULL};
160 
161  if (dist_v) {
162  /* Create a BVH-tree of the given target's verts. */
163  BKE_bvhtree_from_mesh_get(&treeData_v, target, BVHTREE_FROM_VERTS, 2);
164  if (treeData_v.tree == NULL) {
165  OUT_OF_MEMORY();
166  return;
167  }
168  }
169  if (dist_e) {
170  /* Create a BVH-tree of the given target's edges. */
171  BKE_bvhtree_from_mesh_get(&treeData_e, target, BVHTREE_FROM_EDGES, 2);
172  if (treeData_e.tree == NULL) {
173  OUT_OF_MEMORY();
174  return;
175  }
176  }
177  if (dist_f) {
178  /* Create a BVH-tree of the given target's faces. */
179  BKE_bvhtree_from_mesh_get(&treeData_f, target, BVHTREE_FROM_LOOPTRI, 2);
180  if (treeData_f.tree == NULL) {
181  OUT_OF_MEMORY();
182  return;
183  }
184  }
185 
186  data.v_cos = v_cos;
187  data.loc2trgt = loc2trgt;
188  data.treeData[0] = &treeData_v;
189  data.treeData[1] = &treeData_e;
190  data.treeData[2] = &treeData_f;
191  data.dist[0] = dist_v;
192  data.dist[1] = dist_e;
193  data.dist[2] = dist_f;
194 
195  TaskParallelSettings settings;
197  settings.use_threading = (verts_num > 10000);
198  settings.userdata_chunk = &data_chunk;
199  settings.userdata_chunk_size = sizeof(data_chunk);
200  BLI_task_parallel_range(0, verts_num, &data, vert2geom_task_cb_ex, &settings);
201 
202  if (dist_v) {
203  free_bvhtree_from_mesh(&treeData_v);
204  }
205  if (dist_e) {
206  free_bvhtree_from_mesh(&treeData_e);
207  }
208  if (dist_f) {
209  free_bvhtree_from_mesh(&treeData_f);
210  }
211 }
212 
218  int verts_num, float (*v_cos)[3], float *dist, Object *ob, Object *obr)
219 {
220  /* Vertex and ref object coordinates. */
221  float v_wco[3];
222  uint i = verts_num;
223 
224  while (i-- > 0) {
225  /* Get world-coordinates of the vertex (constraints and anim included). */
226  mul_v3_m4v3(v_wco, ob->obmat, v_cos[i]);
227  /* Return distance between both coordinates. */
228  dist[i] = len_v3v3(v_wco, obr->obmat[3]);
229  }
230 }
231 
236 static float get_ob2ob_distance(const Object *ob, const Object *obr)
237 {
238  return len_v3v3(ob->obmat[3], obr->obmat[3]);
239 }
240 
244 static void do_map(Object *ob,
245  float *weights,
246  const int nidx,
247  const float min_d,
248  const float max_d,
249  short mode,
250  const bool do_invert_mapping,
251  CurveMapping *cmap)
252 {
253  const float range_inv = 1.0f / (max_d - min_d); /* invert since multiplication is faster */
254  uint i = nidx;
255  if (max_d == min_d) {
256  while (i-- > 0) {
257  weights[i] = (weights[i] >= max_d) ? 1.0f : 0.0f; /* "Step" behavior... */
258  }
259  }
260  else if (max_d > min_d) {
261  while (i-- > 0) {
262  if (weights[i] >= max_d) {
263  weights[i] = 1.0f; /* most likely case first */
264  }
265  else if (weights[i] <= min_d) {
266  weights[i] = 0.0f;
267  }
268  else {
269  weights[i] = (weights[i] - min_d) * range_inv;
270  }
271  }
272  }
273  else {
274  while (i-- > 0) {
275  if (weights[i] <= max_d) {
276  weights[i] = 1.0f; /* most likely case first */
277  }
278  else if (weights[i] >= min_d) {
279  weights[i] = 0.0f;
280  }
281  else {
282  weights[i] = (weights[i] - min_d) * range_inv;
283  }
284  }
285  }
286 
287  if (do_invert_mapping || mode != MOD_WVG_MAPPING_NONE) {
288  RNG *rng = NULL;
289 
290  if (mode == MOD_WVG_MAPPING_RANDOM) {
292  }
293 
294  weightvg_do_map(nidx, weights, mode, do_invert_mapping, cmap, rng);
295 
296  if (rng) {
297  BLI_rng_free(rng);
298  }
299  }
300 }
301 
302 /**************************************
303  * Modifiers functions. *
304  **************************************/
305 static void initData(ModifierData *md)
306 {
308 
309  BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(wmd, modifier));
310 
312 
313  wmd->cmap_curve = BKE_curvemapping_add(1, 0.0, 0.0, 1.0, 1.0);
315 }
316 
317 static void freeData(ModifierData *md)
318 {
321 }
322 
323 static void copyData(const ModifierData *md, ModifierData *target, const int flag)
324 {
327 
328  BKE_modifier_copydata_generic(md, target, flag);
329 
331 }
332 
333 static void requiredDataMask(Object *UNUSED(ob),
334  ModifierData *md,
335  CustomData_MeshMasks *r_cddata_masks)
336 {
338 
339  /* We need vertex groups! */
340  r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
341 
342  /* Ask for UV coordinates if we need them. */
343  if (wmd->mask_tex_mapping == MOD_DISP_MAP_UV) {
344  r_cddata_masks->fmask |= CD_MASK_MTFACE;
345  }
346 
347  /* No need to ask for CD_PREVIEW_MLOOPCOL... */
348 }
349 
350 static bool dependsOnTime(struct Scene *UNUSED(scene), ModifierData *md)
351 {
353 
354  if (wmd->mask_texture) {
356  }
357  return 0;
358 }
359 
360 static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
361 {
363 
364  walk(userData, ob, (ID **)&wmd->mask_texture, IDWALK_CB_USER);
365  walk(userData, ob, (ID **)&wmd->proximity_ob_target, IDWALK_CB_NOP);
366  walk(userData, ob, (ID **)&wmd->mask_tex_map_obj, IDWALK_CB_NOP);
367 }
368 
369 static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void *userData)
370 {
371  walk(userData, ob, md, "mask_texture");
372 }
373 
375 {
377  bool need_transform_relation = false;
378 
379  if (wmd->proximity_ob_target != NULL) {
381  ctx->node, wmd->proximity_ob_target, DEG_OB_COMP_TRANSFORM, "WeightVGProximity Modifier");
382  if (wmd->proximity_ob_target->data != NULL &&
385  ctx->node, wmd->proximity_ob_target, DEG_OB_COMP_GEOMETRY, "WeightVGProximity Modifier");
386  }
387  need_transform_relation = true;
388  }
389 
390  if (wmd->mask_texture != NULL) {
391  DEG_add_generic_id_relation(ctx->node, &wmd->mask_texture->id, "WeightVGProximity Modifier");
392 
395  ctx->node, wmd->mask_tex_map_obj, wmd->mask_tex_map_bone, "WeightVGProximity Modifier");
396  need_transform_relation = true;
397  }
398  else if (wmd->mask_tex_mapping == MOD_DISP_MAP_GLOBAL) {
399  need_transform_relation = true;
400  }
401  }
402 
403  if (need_transform_relation) {
404  DEG_add_modifier_to_transform_relation(ctx->node, "WeightVGProximity Modifier");
405  }
406 }
407 
408 static bool isDisabled(const struct Scene *UNUSED(scene),
409  ModifierData *md,
410  bool UNUSED(useRenderParams))
411 {
413  /* If no vertex group, bypass. */
414  if (wmd->defgrp_name[0] == '\0') {
415  return true;
416  }
417  /* If no target object, bypass. */
418  return (wmd->proximity_ob_target == NULL);
419 }
420 
422 {
423  BLI_assert(mesh != NULL);
424 
426  MDeformVert *dvert = NULL;
427  MDeformWeight **dw, **tdw;
428  float(*v_cos)[3] = NULL; /* The vertices coordinates. */
429  Object *ob = ctx->object;
430  Object *obr = NULL; /* Our target object. */
431  int defgrp_index;
432  float *tw = NULL;
433  float *org_w = NULL;
434  float *new_w = NULL;
435  int *tidx, *indices = NULL;
436  int index_num = 0;
437  int i;
438  const bool invert_vgroup_mask = (wmd->proximity_flags & MOD_WVG_PROXIMITY_INVERT_VGROUP_MASK) !=
439  0;
440  const bool do_normalize = (wmd->proximity_flags & MOD_WVG_PROXIMITY_WEIGHTS_NORMALIZE) != 0;
441  /* Flags. */
442 #if 0
443  const bool do_prev = (wmd->modifier.mode & eModifierMode_DoWeightPreview) != 0;
444 #endif
445 
446 #ifdef USE_TIMEIT
447  TIMEIT_START(perf);
448 #endif
449 
450  /* Get number of verts. */
451  const int verts_num = mesh->totvert;
452 
453  /* Check if we can just return the original mesh.
454  * Must have verts and therefore verts assigned to vgroups to do anything useful!
455  */
456  if ((verts_num == 0) || BLI_listbase_is_empty(&mesh->vertex_group_names)) {
457  return mesh;
458  }
459 
460  /* Get our target object. */
461  obr = wmd->proximity_ob_target;
462  if (obr == NULL) {
463  return mesh;
464  }
465 
466  /* Get vgroup idx from its name. */
467  defgrp_index = BKE_id_defgroup_name_index(&mesh->id, wmd->defgrp_name);
468  if (defgrp_index == -1) {
469  return mesh;
470  }
471  const bool has_mdef = CustomData_has_layer(&mesh->vdata, CD_MDEFORMVERT);
472  /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */
473  /* As this modifier never add vertices to vgroup, just return. */
474  if (!has_mdef) {
475  return mesh;
476  }
477 
479  /* Ultimate security check. */
480  if (!dvert) {
481  return mesh;
482  }
483  mesh->dvert = dvert;
484 
485  /* Find out which vertices to work on (all vertices in vgroup), and get their relevant weight. */
486  tidx = MEM_malloc_arrayN(verts_num, sizeof(int), "WeightVGProximity Modifier, tidx");
487  tw = MEM_malloc_arrayN(verts_num, sizeof(float), "WeightVGProximity Modifier, tw");
488  tdw = MEM_malloc_arrayN(verts_num, sizeof(MDeformWeight *), "WeightVGProximity Modifier, tdw");
489  for (i = 0; i < verts_num; i++) {
490  MDeformWeight *_dw = BKE_defvert_find_index(&dvert[i], defgrp_index);
491  if (_dw) {
492  tidx[index_num] = i;
493  tw[index_num] = _dw->weight;
494  tdw[index_num++] = _dw;
495  }
496  }
497  /* If no vertices found, return org data! */
498  if (index_num == 0) {
499  MEM_freeN(tidx);
500  MEM_freeN(tw);
501  MEM_freeN(tdw);
502  return mesh;
503  }
504  if (index_num != verts_num) {
505  indices = MEM_malloc_arrayN(index_num, sizeof(int), "WeightVGProximity Modifier, indices");
506  memcpy(indices, tidx, sizeof(int) * index_num);
507  org_w = MEM_malloc_arrayN(index_num, sizeof(float), "WeightVGProximity Modifier, org_w");
508  memcpy(org_w, tw, sizeof(float) * index_num);
509  dw = MEM_malloc_arrayN(index_num, sizeof(MDeformWeight *), "WeightVGProximity Modifier, dw");
510  memcpy(dw, tdw, sizeof(MDeformWeight *) * index_num);
511  MEM_freeN(tw);
512  MEM_freeN(tdw);
513  }
514  else {
515  org_w = tw;
516  dw = tdw;
517  }
518  new_w = MEM_malloc_arrayN(index_num, sizeof(float), "WeightVGProximity Modifier, new_w");
519  MEM_freeN(tidx);
520 
521  /* Get our vertex coordinates. */
522  if (index_num != verts_num) {
523  float(*tv_cos)[3] = BKE_mesh_vert_coords_alloc(mesh, NULL);
524  v_cos = MEM_malloc_arrayN(index_num, sizeof(float[3]), "WeightVGProximity Modifier, v_cos");
525  for (i = 0; i < index_num; i++) {
526  copy_v3_v3(v_cos[i], tv_cos[indices[i]]);
527  }
528  MEM_freeN(tv_cos);
529  }
530  else {
532  }
533 
534  /* Compute wanted distances. */
536  const float dist = get_ob2ob_distance(ob, obr);
537  for (i = 0; i < index_num; i++) {
538  new_w[i] = dist;
539  }
540  }
541  else if (wmd->proximity_mode == MOD_WVG_PROXIMITY_GEOMETRY) {
542  const bool use_trgt_verts = (wmd->proximity_flags & MOD_WVG_PROXIMITY_GEOM_VERTS) != 0;
543  const bool use_trgt_edges = (wmd->proximity_flags & MOD_WVG_PROXIMITY_GEOM_EDGES) != 0;
544  const bool use_trgt_faces = (wmd->proximity_flags & MOD_WVG_PROXIMITY_GEOM_FACES) != 0;
545 
546  if (use_trgt_verts || use_trgt_edges || use_trgt_faces) {
548 
549  /* We must check that we do have a valid target_mesh! */
550  if (target_mesh != NULL) {
551 
552  /* TODO: edit-mode versions of the BVH lookup functions are available so it could be
553  * avoided. */
554  BKE_mesh_wrapper_ensure_mdata(target_mesh);
555 
556  SpaceTransform loc2trgt;
557  float *dists_v = use_trgt_verts ? MEM_malloc_arrayN(index_num, sizeof(float), "dists_v") :
558  NULL;
559  float *dists_e = use_trgt_edges ? MEM_malloc_arrayN(index_num, sizeof(float), "dists_e") :
560  NULL;
561  float *dists_f = use_trgt_faces ? MEM_malloc_arrayN(index_num, sizeof(float), "dists_f") :
562  NULL;
563 
564  BLI_SPACE_TRANSFORM_SETUP(&loc2trgt, ob, obr);
566  index_num, v_cos, dists_v, dists_e, dists_f, target_mesh, &loc2trgt);
567  for (i = 0; i < index_num; i++) {
568  new_w[i] = dists_v ? dists_v[i] : FLT_MAX;
569  if (dists_e) {
570  new_w[i] = min_ff(dists_e[i], new_w[i]);
571  }
572  if (dists_f) {
573  new_w[i] = min_ff(dists_f[i], new_w[i]);
574  }
575  }
576 
577  MEM_SAFE_FREE(dists_v);
578  MEM_SAFE_FREE(dists_e);
579  MEM_SAFE_FREE(dists_f);
580  }
581  /* Else, fall back to default obj2vert behavior. */
582  else {
583  get_vert2ob_distance(index_num, v_cos, new_w, ob, obr);
584  }
585  }
586  else {
587  get_vert2ob_distance(index_num, v_cos, new_w, ob, obr);
588  }
589  }
590 
591  /* Map distances to weights. */
592  do_map(ob,
593  new_w,
594  index_num,
595  wmd->min_dist,
596  wmd->max_dist,
597  wmd->falloff_type,
599  wmd->cmap_curve);
600 
601  /* Do masking. */
603  weightvg_do_mask(ctx,
604  index_num,
605  indices,
606  org_w,
607  new_w,
608  ob,
609  mesh,
610  wmd->mask_constant,
611  wmd->mask_defgrp_name,
612  scene,
613  wmd->mask_texture,
615  wmd->mask_tex_mapping,
616  wmd->mask_tex_map_obj,
617  wmd->mask_tex_map_bone,
619  invert_vgroup_mask);
620 
621  /* Update vgroup. Note we never add nor remove vertices from vgroup here. */
623  dvert, defgrp_index, dw, index_num, indices, org_w, false, 0.0f, false, 0.0f, do_normalize);
624 
625  /* If weight preview enabled... */
626 #if 0 /* XXX Currently done in mod stack :/ */
627  if (do_prev) {
628  DM_update_weight_mcol(ob, dm, 0, org_w, index_num, indices);
629  }
630 #endif
631 
632  /* Freeing stuff. */
633  MEM_freeN(org_w);
634  MEM_freeN(new_w);
635  MEM_freeN(dw);
636  MEM_freeN(v_cos);
638 
639 #ifdef USE_TIMEIT
640  TIMEIT_END(perf);
641 #endif
642 
643  mesh->runtime.is_original = false;
644 
645  /* Return the vgroup-modified mesh. */
646  return mesh;
647 }
648 
649 static void panel_draw(const bContext *UNUSED(C), Panel *panel)
650 {
651  uiLayout *col;
652  uiLayout *layout = panel->layout;
653 
654  PointerRNA ob_ptr;
656 
657  uiLayoutSetPropSep(layout, true);
658 
659  uiItemPointerR(layout, ptr, "vertex_group", &ob_ptr, "vertex_groups", NULL, ICON_NONE);
660 
661  uiItemR(layout, ptr, "target", 0, NULL, ICON_NONE);
662 
663  uiItemS(layout);
664 
665  uiItemR(layout, ptr, "proximity_mode", 0, NULL, ICON_NONE);
666  if (RNA_enum_get(ptr, "proximity_mode") == MOD_WVG_PROXIMITY_GEOMETRY) {
667  uiItemR(layout, ptr, "proximity_geometry", UI_ITEM_R_EXPAND, IFACE_("Geometry"), ICON_NONE);
668  }
669 
670  col = uiLayoutColumn(layout, true);
671  uiItemR(col, ptr, "min_dist", 0, NULL, ICON_NONE);
672  uiItemR(col, ptr, "max_dist", 0, NULL, ICON_NONE);
673 
674  uiItemR(layout, ptr, "normalize", 0, NULL, ICON_NONE);
675 }
676 
677 static void falloff_panel_draw(const bContext *UNUSED(C), Panel *panel)
678 {
679  uiLayout *row, *sub;
680  uiLayout *layout = panel->layout;
681 
682  PointerRNA ob_ptr;
684 
685  uiLayoutSetPropSep(layout, true);
686 
687  row = uiLayoutRow(layout, true);
688  uiItemR(row, ptr, "falloff_type", 0, IFACE_("Type"), ICON_NONE);
689  sub = uiLayoutRow(row, true);
690  uiLayoutSetPropSep(sub, false);
691  uiItemR(row, ptr, "invert_falloff", 0, "", ICON_ARROW_LEFTRIGHT);
692  if (RNA_enum_get(ptr, "falloff_type") == MOD_WVG_MAPPING_CURVE) {
693  uiTemplateCurveMapping(layout, ptr, "map_curve", 0, false, false, false, false);
694  }
695  modifier_panel_end(layout, ptr);
696 }
697 
698 static void influence_panel_draw(const bContext *C, Panel *panel)
699 {
700  uiLayout *layout = panel->layout;
701 
702  PointerRNA ob_ptr;
704 
705  weightvg_ui_common(C, &ob_ptr, ptr, layout);
706 }
707 
708 static void panelRegister(ARegionType *region_type)
709 {
710  PanelType *panel_type = modifier_panel_register(
713  region_type, "falloff", "Falloff", NULL, falloff_panel_draw, panel_type);
715  region_type, "influence", "Influence", NULL, influence_panel_draw, panel_type);
716 }
717 
718 static void blendWrite(BlendWriter *writer, const ID *UNUSED(id_owner), const ModifierData *md)
719 {
721 
723 
724  if (wmd->cmap_curve) {
726  }
727 }
728 
729 static void blendRead(BlendDataReader *reader, ModifierData *md)
730 {
732 
733  BLO_read_data_address(reader, &wmd->cmap_curve);
734  if (wmd->cmap_curve) {
736  }
737 }
738 
740  /* name */ N_("VertexWeightProximity"),
741  /* structName */ "WeightVGProximityModifierData",
742  /* structSize */ sizeof(WeightVGProximityModifierData),
743  /* srna */ &RNA_VertexWeightProximityModifier,
747  /* icon */ ICON_MOD_VERTEX_WEIGHT,
748 
749  /* copyData */ copyData,
750 
751  /* deformVerts */ NULL,
752  /* deformMatrices */ NULL,
753  /* deformVertsEM */ NULL,
754  /* deformMatricesEM */ NULL,
755  /* modifyMesh */ modifyMesh,
756  /* modifyGeometrySet */ NULL,
757 
758  /* initData */ initData,
759  /* requiredDataMask */ requiredDataMask,
760  /* freeData */ freeData,
761  /* isDisabled */ isDisabled,
762  /* updateDepsgraph */ updateDepsgraph,
763  /* dependsOnTime */ dependsOnTime,
764  /* dependsOnNormals */ NULL,
765  /* foreachIDLink */ foreachIDLink,
766  /* foreachTexLink */ foreachTexLink,
767  /* freeRuntimeData */ NULL,
768  /* panelRegister */ panelRegister,
769  /* blendWrite */ blendWrite,
770  /* blendRead */ blendRead,
771 };
typedef float(TangentPoint)[2]
void free_bvhtree_from_mesh(struct BVHTreeFromMesh *data)
Definition: bvhutils.cc:1410
@ BVHTREE_FROM_EDGES
Definition: BKE_bvhutils.h:71
@ BVHTREE_FROM_LOOPTRI
Definition: BKE_bvhutils.h:73
@ BVHTREE_FROM_VERTS
Definition: BKE_bvhutils.h:70
BVHTree * BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data, const struct Mesh *mesh, BVHCacheType bvh_cache_type, int tree_type)
Definition: bvhutils.cc:1213
void BKE_curvemapping_init(struct CurveMapping *cumap)
Definition: colortools.c:1235
struct CurveMapping * BKE_curvemapping_copy(const struct CurveMapping *cumap)
void BKE_curvemapping_blend_read(struct BlendDataReader *reader, struct CurveMapping *cumap)
Definition: colortools.c:1300
void BKE_curvemapping_blend_write(struct BlendWriter *writer, const struct CurveMapping *cumap)
void BKE_curvemapping_free(struct CurveMapping *cumap)
Definition: colortools.c:103
struct CurveMapping * BKE_curvemapping_add(int tot, float minx, float miny, float maxx, float maxy)
Definition: colortools.c:72
CustomData interface, see also DNA_customdata_types.h.
bool CustomData_has_layer(const struct CustomData *data, int type)
void * CustomData_duplicate_referenced_layer(struct CustomData *data, int type, int totelem)
Definition: customdata.cc:2976
support for deformation groups and hooks.
struct MDeformWeight * BKE_defvert_find_index(const struct MDeformVert *dv, int defgroup)
int BKE_id_defgroup_name_index(const struct ID *id, const char *name)
@ IDWALK_CB_USER
Definition: BKE_lib_query.h:73
@ IDWALK_CB_NOP
Definition: BKE_lib_query.h:33
float(* BKE_mesh_vert_coords_alloc(const struct Mesh *mesh, int *r_vert_len))[3]
void BKE_mesh_wrapper_ensure_mdata(struct Mesh *me)
Definition: mesh_wrapper.cc:94
void(* IDWalkFunc)(void *userData, struct Object *ob, struct ID **idpoin, int cb_flag)
Definition: BKE_modifier.h:107
@ eModifierTypeFlag_SupportsMapping
Definition: BKE_modifier.h:68
@ eModifierTypeFlag_UsesPreview
Definition: BKE_modifier.h:99
@ eModifierTypeFlag_SupportsEditmode
Definition: BKE_modifier.h:69
@ eModifierTypeFlag_AcceptsMesh
Definition: BKE_modifier.h:66
void(* TexWalkFunc)(void *userData, struct Object *ob, struct ModifierData *md, const char *propname)
Definition: BKE_modifier.h:108
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_NonGeometrical
Definition: BKE_modifier.h:62
bool BKE_texture_dependsOnTime(const struct Tex *texture)
Definition: texture.c:670
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_ghashutil_strhash(key)
Definition: BLI_ghash.h:573
int BLI_bvhtree_find_nearest(BVHTree *tree, const float co[3], BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata)
Definition: BLI_kdopbvh.c:1616
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:269
MINLINE float min_ff(float a, float b)
void BLI_space_transform_apply(const struct SpaceTransform *data, float co[3])
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:739
#define BLI_SPACE_TRANSFORM_SETUP(data, local, target)
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v3_v3(float r[3], const float a[3])
Random number functions.
void BLI_rng_free(struct RNG *rng) ATTR_NONNULL(1)
Definition: rand.cc:58
struct RNG * BLI_rng_new_srandom(unsigned int seed)
Definition: rand.cc:46
unsigned int uint
Definition: BLI_sys_types.h:67
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 ARRAY_SIZE(arr)
#define UNUSED(x)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define BLO_read_data_address(reader, ptr_p)
#define BLO_write_struct(writer, struct_name, data_ptr)
#define IFACE_(msgid)
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)
void DEG_add_generic_id_relation(struct DepsNodeHandle *node_handle, struct ID *id, const char *description)
@ DEG_OB_COMP_GEOMETRY
@ DEG_OB_COMP_TRANSFORM
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
#define CD_MASK_MDEFORMVERT
#define CD_MASK_MTFACE
@ CD_MDEFORMVERT
#define DNA_struct_default_get(struct_name)
Definition: DNA_defaults.h:29
struct WeightVGProximityModifierData WeightVGProximityModifierData
@ MOD_WVG_PROXIMITY_OBJECT
@ MOD_WVG_PROXIMITY_GEOMETRY
@ eModifierType_WeightVGProximity
@ MOD_DISP_MAP_OBJECT
@ MOD_DISP_MAP_GLOBAL
@ MOD_DISP_MAP_UV
@ MOD_WVG_MAPPING_NONE
@ MOD_WVG_MAPPING_CURVE
@ MOD_WVG_MAPPING_RANDOM
@ MOD_WVG_PROXIMITY_WEIGHTS_NORMALIZE
@ MOD_WVG_PROXIMITY_INVERT_VGROUP_MASK
@ MOD_WVG_PROXIMITY_GEOM_VERTS
@ MOD_WVG_PROXIMITY_INVERT_FALLOFF
@ MOD_WVG_PROXIMITY_GEOM_EDGES
@ MOD_WVG_PROXIMITY_GEOM_FACES
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)
Definition: MOD_ui_common.c:91
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
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:258
void weightvg_do_map(int num, float *new_w, short falloff_type, const bool do_invert, CurveMapping *cmap, RNG *rng)
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)
static void influence_panel_draw(const bContext *C, Panel *panel)
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
#define OUT_OF_MEMORY()
static Mesh * modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
static void vert2geom_task_cb_ex(void *__restrict userdata, const int iter, const TaskParallelTLS *__restrict tls)
struct Vert2GeomData Vert2GeomData
static void falloff_panel_draw(const bContext *UNUSED(C), Panel *panel)
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
static bool dependsOnTime(struct Scene *UNUSED(scene), ModifierData *md)
ModifierTypeInfo modifierType_WeightVGProximity
static void get_vert2geom_distance(int verts_num, float(*v_cos)[3], float *dist_v, float *dist_e, float *dist_f, Mesh *target, const SpaceTransform *loc2trgt)
static bool isDisabled(const struct Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams))
static void blendRead(BlendDataReader *reader, ModifierData *md)
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
static float get_ob2ob_distance(const Object *ob, const Object *obr)
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
struct Vert2GeomDataChunk Vert2GeomDataChunk
static void initData(ModifierData *md)
static void panelRegister(ARegionType *region_type)
static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void *userData)
static void do_map(Object *ob, float *weights, const int nidx, const float min_d, const float max_d, short mode, const bool do_invert_mapping, CurveMapping *cmap)
static void blendWrite(BlendWriter *writer, const ID *UNUSED(id_owner), const ModifierData *md)
static void freeData(ModifierData *md)
static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
static void get_vert2ob_distance(int verts_num, float(*v_cos)[3], float *dist, Object *ob, Object *obr)
Platform independent time functions.
Utility defines for timing/benchmarks.
#define TIMEIT_START(var)
#define TIMEIT_END(var)
#define C
Definition: RandGen.cpp:25
void uiTemplateCurveMapping(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int type, bool levels, bool brush, bool neg_slope, bool tone)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemS(uiLayout *layout)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
@ UI_ITEM_R_EXPAND
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
void uiItemPointerR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, struct PointerRNA *searchptr, const char *searchpropname, const char *name, int icon)
Scene scene
uint col
ccl_gpu_kernel_postfix int ccl_global int * indices
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:34
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
#define sqrtf(x)
Definition: metal/compat.h:243
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5004
struct BVHTree * tree
Definition: BKE_bvhutils.h:50
float co[3]
Definition: BLI_kdopbvh.h:43
Definition: DNA_ID.h:368
char name[66]
Definition: DNA_ID.h:378
CustomData vdata
struct MDeformVert * dvert
ListBase vertex_group_names
int totvert
Mesh_Runtime runtime
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]
void * data
struct uiLayout * layout
Definition: rand.cc:33
size_t userdata_chunk_size
Definition: BLI_task.h:169
BVHTreeFromMesh * treeData[3]
const SpaceTransform * loc2trgt
struct CurveMapping * cmap_curve
#define N_(msgid)
PointerRNA * ptr
Definition: wm_files.c:3480