Blender V4.3
MOD_weightvgproximity.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011 by Bastien Montagne. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "BLI_utildefines.h"
10
11#include "BLI_ghash.h"
12#include "BLI_listbase.h"
13#include "BLI_math_matrix.h"
14#include "BLI_math_vector.h"
15#include "BLI_rand.h"
16#include "BLI_task.h"
17
18#include "BLT_translation.hh"
19
20#include "DNA_color_types.h" /* CurveMapping. */
21#include "DNA_defaults.h"
22#include "DNA_mesh_types.h"
23#include "DNA_meshdata_types.h"
24#include "DNA_modifier_types.h"
25#include "DNA_object_types.h"
26#include "DNA_screen_types.h"
27
28#include "BKE_bvhutils.hh"
29#include "BKE_colortools.hh" /* CurveMapping. */
30#include "BKE_customdata.hh"
31#include "BKE_deform.hh"
32#include "BKE_lib_query.hh"
33#include "BKE_mesh.hh"
34#include "BKE_mesh_wrapper.hh"
35#include "BKE_modifier.hh"
36#include "BKE_texture.h" /* Texture masking. */
37
38#include "UI_interface.hh"
39#include "UI_resources.hh"
40
41#include "BLO_read_write.hh"
42
43#include "RNA_access.hh"
44#include "RNA_prototypes.hh"
45
48
49#include "MEM_guardedalloc.h"
50
51#include "MOD_ui_common.hh"
52#include "MOD_util.hh"
53#include "MOD_weightvg_util.hh"
54
55// #define USE_TIMEIT
56
57#ifdef USE_TIMEIT
58# include "BLI_time.h"
59# include "BLI_time_utildefines.h"
60#endif
61
62/**************************************
63 * Util functions. *
64 **************************************/
65
66/* Util macro. */
67#define OUT_OF_MEMORY() (void)printf("WeightVGProximity: Out of memory.\n")
68
70 /* Read-only data */
72
73 const int *indices;
74
76
78
79 /* Write data, but not needing locking (two different threads will never write same index). */
80 float *dist[3];
81};
82
88 /* Read-only data */
89 float last_hit_co[3][3];
90 bool is_init[3];
91};
92
96static void vert2geom_task_cb_ex(void *__restrict userdata,
97 const int iter,
98 const TaskParallelTLS *__restrict tls)
99{
100 Vert2GeomData *data = static_cast<Vert2GeomData *>(userdata);
101 Vert2GeomDataChunk *data_chunk = static_cast<Vert2GeomDataChunk *>(tls->userdata_chunk);
102
103 float tmp_co[3];
104 int i;
105
106 /* Convert the vertex to tree coordinates. */
107 copy_v3_v3(tmp_co, data->positions[data->indices ? data->indices[iter] : iter]);
108 BLI_space_transform_apply(data->loc2trgt, tmp_co);
109
110 for (i = 0; i < ARRAY_SIZE(data->dist); i++) {
111 if (data->dist[i]) {
112 BVHTreeNearest nearest = {0};
113
114 /* Note that we use local proximity heuristics (to reduce the nearest search).
115 *
116 * If we already had an hit before in same chunk of tasks (i.e. previous vertex by index),
117 * we assume this vertex is going to have a close hit to that other vertex,
118 * so we can initiate the "nearest.dist" with the expected value to that last hit.
119 * This will lead in pruning of the search tree.
120 */
121 nearest.dist_sq = data_chunk->is_init[i] ?
122 len_squared_v3v3(tmp_co, data_chunk->last_hit_co[i]) :
123 FLT_MAX;
124 nearest.index = -1;
125
126 /* Compute and store result. If invalid (-1 idx), keep FLT_MAX dist. */
127 BLI_bvhtree_find_nearest(data->treeData[i]->tree,
128 tmp_co,
129 &nearest,
130 data->treeData[i]->nearest_callback,
131 data->treeData[i]);
132 data->dist[i][iter] = sqrtf(nearest.dist_sq);
133
134 if (nearest.index != -1) {
135 copy_v3_v3(data_chunk->last_hit_co[i], nearest.co);
136 data_chunk->is_init[i] = true;
137 }
138 }
139 }
140}
141
145static void get_vert2geom_distance(int verts_num,
146 const blender::Span<blender::float3> positions,
147 const int *indices,
148 float *dist_v,
149 float *dist_e,
150 float *dist_f,
151 Mesh *target,
152 const SpaceTransform *loc2trgt)
153{
154 Vert2GeomData data{};
155 Vert2GeomDataChunk data_chunk = {{{0}}};
156
157 BVHTreeFromMesh treeData_v = {nullptr};
158 BVHTreeFromMesh treeData_e = {nullptr};
159 BVHTreeFromMesh treeData_f = {nullptr};
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 == nullptr) {
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 == nullptr) {
174 return;
175 }
176 }
177 if (dist_f) {
178 /* Create a BVH-tree of the given target's faces. */
180 if (treeData_f.tree == nullptr) {
182 return;
183 }
184 }
185
186 data.positions = positions;
187 data.indices = indices;
188 data.loc2trgt = loc2trgt;
189 data.treeData[0] = &treeData_v;
190 data.treeData[1] = &treeData_e;
191 data.treeData[2] = &treeData_f;
192 data.dist[0] = dist_v;
193 data.dist[1] = dist_e;
194 data.dist[2] = dist_f;
195
196 TaskParallelSettings settings;
198 settings.use_threading = (verts_num > 10000);
199 settings.userdata_chunk = &data_chunk;
200 settings.userdata_chunk_size = sizeof(data_chunk);
201 BLI_task_parallel_range(0, verts_num, &data, vert2geom_task_cb_ex, &settings);
202
203 if (dist_v) {
204 free_bvhtree_from_mesh(&treeData_v);
205 }
206 if (dist_e) {
207 free_bvhtree_from_mesh(&treeData_e);
208 }
209 if (dist_f) {
210 free_bvhtree_from_mesh(&treeData_f);
211 }
212}
213
218static void get_vert2ob_distance(int verts_num,
219 const blender::Span<blender::float3> positions,
220 const int *indices,
221 float *dist,
222 Object *ob,
223 Object *obr)
224{
225 /* Vertex and ref object coordinates. */
226 float v_wco[3];
227 uint i = verts_num;
228
229 while (i-- > 0) {
230 /* Get world-coordinates of the vertex (constraints and anim included). */
231 mul_v3_m4v3(v_wco, ob->object_to_world().ptr(), positions[indices ? indices[i] : i]);
232 /* Return distance between both coordinates. */
233 dist[i] = len_v3v3(v_wco, obr->object_to_world().location());
234 }
235}
236
241static float get_ob2ob_distance(const Object *ob, const Object *obr)
242{
243 return len_v3v3(ob->object_to_world().location(), obr->object_to_world().location());
244}
245
249static void do_map(Object *ob,
250 float *weights,
251 const int nidx,
252 const float min_d,
253 const float max_d,
254 short mode,
255 const bool do_invert_mapping,
256 CurveMapping *cmap)
257{
258 const float range_inv = 1.0f / (max_d - min_d); /* invert since multiplication is faster */
259 uint i = nidx;
260 if (max_d == min_d) {
261 while (i-- > 0) {
262 weights[i] = (weights[i] >= max_d) ? 1.0f : 0.0f; /* "Step" behavior... */
263 }
264 }
265 else if (max_d > min_d) {
266 while (i-- > 0) {
267 if (weights[i] >= max_d) {
268 weights[i] = 1.0f; /* most likely case first */
269 }
270 else if (weights[i] <= min_d) {
271 weights[i] = 0.0f;
272 }
273 else {
274 weights[i] = (weights[i] - min_d) * range_inv;
275 }
276 }
277 }
278 else {
279 while (i-- > 0) {
280 if (weights[i] <= max_d) {
281 weights[i] = 1.0f; /* most likely case first */
282 }
283 else if (weights[i] >= min_d) {
284 weights[i] = 0.0f;
285 }
286 else {
287 weights[i] = (weights[i] - min_d) * range_inv;
288 }
289 }
290 }
291
292 if (do_invert_mapping || mode != MOD_WVG_MAPPING_NONE) {
293 RNG *rng = nullptr;
294
295 if (mode == MOD_WVG_MAPPING_RANDOM) {
297 }
298
299 weightvg_do_map(nidx, weights, mode, do_invert_mapping, cmap, rng);
300
301 if (rng) {
302 BLI_rng_free(rng);
303 }
304 }
305}
306
307/**************************************
308 * Modifiers functions. *
309 **************************************/
321
327
328static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
329{
332
334
336}
337
338static void required_data_mask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
339{
341
342 /* We need vertex groups! */
343 r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
344
345 /* Ask for UV coordinates if we need them. */
346 if (wmd->mask_tex_mapping == MOD_DISP_MAP_UV) {
347 r_cddata_masks->fmask |= CD_MASK_MTFACE;
348 }
349}
350
351static bool depends_on_time(Scene * /*scene*/, ModifierData *md)
352{
354
355 if (wmd->mask_texture) {
357 }
358 return false;
359}
360
361static void foreach_ID_link(ModifierData *md, Object *ob, IDWalkFunc walk, void *user_data)
362{
364
365 walk(user_data, ob, (ID **)&wmd->mask_texture, IDWALK_CB_USER);
366 walk(user_data, ob, (ID **)&wmd->proximity_ob_target, IDWALK_CB_NOP);
367 walk(user_data, ob, (ID **)&wmd->mask_tex_map_obj, IDWALK_CB_NOP);
368}
369
370static void foreach_tex_link(ModifierData *md, Object *ob, TexWalkFunc walk, void *user_data)
371{
372 PointerRNA ptr = RNA_pointer_create(&ob->id, &RNA_Modifier, md);
373 PropertyRNA *prop = RNA_struct_find_property(&ptr, "mask_texture");
374 walk(user_data, ob, md, &ptr, prop);
375}
376
378{
380 bool need_transform_relation = false;
381
382 if (wmd->proximity_ob_target != nullptr) {
384 ctx->node, wmd->proximity_ob_target, DEG_OB_COMP_TRANSFORM, "WeightVGProximity Modifier");
385 if (wmd->proximity_ob_target->data != nullptr &&
387 {
389 ctx->node, wmd->proximity_ob_target, DEG_OB_COMP_GEOMETRY, "WeightVGProximity Modifier");
390 }
391 need_transform_relation = true;
392 }
393
394 if (wmd->mask_texture != nullptr) {
395 DEG_add_generic_id_relation(ctx->node, &wmd->mask_texture->id, "WeightVGProximity Modifier");
396
397 if (wmd->mask_tex_map_obj != nullptr && wmd->mask_tex_mapping == MOD_DISP_MAP_OBJECT) {
399 ctx->node, wmd->mask_tex_map_obj, wmd->mask_tex_map_bone, "WeightVGProximity Modifier");
400 need_transform_relation = true;
401 }
402 else if (wmd->mask_tex_mapping == MOD_DISP_MAP_GLOBAL) {
403 need_transform_relation = true;
404 }
405 }
406
407 if (need_transform_relation) {
408 DEG_add_depends_on_transform_relation(ctx->node, "WeightVGProximity Modifier");
409 }
410}
411
412static bool is_disabled(const Scene * /*scene*/, ModifierData *md, bool /*use_render_params*/)
413{
415 /* If no vertex group, bypass. */
416 if (wmd->defgrp_name[0] == '\0') {
417 return true;
418 }
419 /* If no target object, bypass. */
420 return (wmd->proximity_ob_target == nullptr);
421}
422
423static Mesh *modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
424{
425 BLI_assert(mesh != nullptr);
426
428 MDeformWeight **dw, **tdw;
429 Object *ob = ctx->object;
430 Object *obr = nullptr; /* Our target object. */
431 int defgrp_index;
432 float *tw = nullptr;
433 float *org_w = nullptr;
434 float *new_w = nullptr;
435 int *tidx, *indices = nullptr;
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->verts_num;
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 == nullptr) {
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->vert_data, CD_MDEFORMVERT);
472 /* If no vertices were ever added to an object's vgroup, dvert might be nullptr. */
473 /* As this modifier never add vertices to vgroup, just return. */
474 if (!has_mdef) {
475 return mesh;
476 }
477
478 MDeformVert *dvert = mesh->deform_verts_for_write().data();
479 /* Ultimate security check. */
480 if (!dvert) {
481 return mesh;
482 }
483
484 /* Find out which vertices to work on (all vertices in vgroup), and get their relevant weight. */
485 tidx = static_cast<int *>(MEM_malloc_arrayN(verts_num, sizeof(int), __func__));
486 tw = static_cast<float *>(MEM_malloc_arrayN(verts_num, sizeof(float), __func__));
487 tdw = static_cast<MDeformWeight **>(
488 MEM_malloc_arrayN(verts_num, sizeof(MDeformWeight *), __func__));
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 = static_cast<int *>(MEM_malloc_arrayN(index_num, sizeof(int), __func__));
506 memcpy(indices, tidx, sizeof(int) * index_num);
507 org_w = static_cast<float *>(MEM_malloc_arrayN(index_num, sizeof(float), __func__));
508 memcpy(org_w, tw, sizeof(float) * index_num);
509 dw = static_cast<MDeformWeight **>(
510 MEM_malloc_arrayN(index_num, sizeof(MDeformWeight *), __func__));
511 memcpy(dw, tdw, sizeof(MDeformWeight *) * index_num);
512 MEM_freeN(tw);
513 MEM_freeN(tdw);
514 }
515 else {
516 org_w = tw;
517 dw = tdw;
518 }
519 new_w = static_cast<float *>(MEM_malloc_arrayN(index_num, sizeof(float), __func__));
520 MEM_freeN(tidx);
521
522 const blender::Span<blender::float3> positions = mesh->vert_positions();
523
524 /* Compute wanted distances. */
526 const float dist = get_ob2ob_distance(ob, obr);
527 for (i = 0; i < index_num; i++) {
528 new_w[i] = dist;
529 }
530 }
532 const bool use_trgt_verts = (wmd->proximity_flags & MOD_WVG_PROXIMITY_GEOM_VERTS) != 0;
533 const bool use_trgt_edges = (wmd->proximity_flags & MOD_WVG_PROXIMITY_GEOM_EDGES) != 0;
534 const bool use_trgt_faces = (wmd->proximity_flags & MOD_WVG_PROXIMITY_GEOM_FACES) != 0;
535
536 if (use_trgt_verts || use_trgt_edges || use_trgt_faces) {
538
539 /* We must check that we do have a valid target_mesh! */
540 if (target_mesh != nullptr) {
541
542 /* TODO: edit-mode versions of the BVH lookup functions are available so it could be
543 * avoided. */
545
546 SpaceTransform loc2trgt;
547 float *dists_v = use_trgt_verts ? static_cast<float *>(MEM_malloc_arrayN(
548 index_num, sizeof(float), __func__)) :
549 nullptr;
550 float *dists_e = use_trgt_edges ? static_cast<float *>(MEM_malloc_arrayN(
551 index_num, sizeof(float), __func__)) :
552 nullptr;
553 float *dists_f = use_trgt_faces ? static_cast<float *>(MEM_malloc_arrayN(
554 index_num, sizeof(float), __func__)) :
555 nullptr;
556
557 BLI_SPACE_TRANSFORM_SETUP(&loc2trgt, ob, obr);
559 index_num, positions, indices, dists_v, dists_e, dists_f, target_mesh, &loc2trgt);
560 for (i = 0; i < index_num; i++) {
561 new_w[i] = dists_v ? dists_v[i] : FLT_MAX;
562 if (dists_e) {
563 new_w[i] = min_ff(dists_e[i], new_w[i]);
564 }
565 if (dists_f) {
566 new_w[i] = min_ff(dists_f[i], new_w[i]);
567 }
568 }
569
570 MEM_SAFE_FREE(dists_v);
571 MEM_SAFE_FREE(dists_e);
572 MEM_SAFE_FREE(dists_f);
573 }
574 /* Else, fall back to default obj2vert behavior. */
575 else {
576 get_vert2ob_distance(index_num, positions, indices, new_w, ob, obr);
577 }
578 }
579 else {
580 get_vert2ob_distance(index_num, positions, indices, new_w, ob, obr);
581 }
582 }
583
584 /* Map distances to weights. */
585 do_map(ob,
586 new_w,
587 index_num,
588 wmd->min_dist,
589 wmd->max_dist,
590 wmd->falloff_type,
592 wmd->cmap_curve);
593
594 /* Do masking. */
597 index_num,
598 indices,
599 org_w,
600 new_w,
601 ob,
602 mesh,
603 wmd->mask_constant,
604 wmd->mask_defgrp_name,
605 scene,
606 wmd->mask_texture,
608 wmd->mask_tex_mapping,
609 wmd->mask_tex_map_obj,
612 invert_vgroup_mask);
613
614 /* Update vgroup. Note we never add nor remove vertices from vgroup here. */
616 dvert, defgrp_index, dw, index_num, indices, org_w, false, 0.0f, false, 0.0f, do_normalize);
617
618 /* If weight preview enabled... */
619#if 0 /* XXX Currently done in mod stack :/ */
620 if (do_prev) {
621 DM_update_weight_mcol(ob, dm, 0, org_w, index_num, indices);
622 }
623#endif
624
625 /* Freeing stuff. */
626 MEM_freeN(org_w);
627 MEM_freeN(new_w);
628 MEM_freeN(dw);
629 MEM_SAFE_FREE(indices);
630
631#ifdef USE_TIMEIT
632 TIMEIT_END(perf);
633#endif
634
635 mesh->runtime->is_original_bmesh = false;
636
637 /* Return the vgroup-modified mesh. */
638 return mesh;
639}
640
641static void panel_draw(const bContext * /*C*/, Panel *panel)
642{
643 uiLayout *col;
644 uiLayout *layout = panel->layout;
645
646 PointerRNA ob_ptr;
648
649 uiLayoutSetPropSep(layout, true);
650
652 layout, ptr, "vertex_group", &ob_ptr, "vertex_groups", nullptr, ICON_GROUP_VERTEX);
653
654 uiItemR(layout, ptr, "target", UI_ITEM_NONE, nullptr, ICON_NONE);
655
656 uiItemS(layout);
657
658 uiItemR(layout, ptr, "proximity_mode", UI_ITEM_NONE, nullptr, ICON_NONE);
659 if (RNA_enum_get(ptr, "proximity_mode") == MOD_WVG_PROXIMITY_GEOMETRY) {
660 uiItemR(layout, ptr, "proximity_geometry", UI_ITEM_R_EXPAND, IFACE_("Geometry"), ICON_NONE);
661 }
662
663 col = uiLayoutColumn(layout, true);
664 uiItemR(col, ptr, "min_dist", UI_ITEM_NONE, nullptr, ICON_NONE);
665 uiItemR(col, ptr, "max_dist", UI_ITEM_NONE, nullptr, ICON_NONE);
666
667 uiItemR(layout, ptr, "normalize", UI_ITEM_NONE, nullptr, ICON_NONE);
668}
669
670static void falloff_panel_draw(const bContext * /*C*/, Panel *panel)
671{
672 uiLayout *row, *sub;
673 uiLayout *layout = panel->layout;
674
675 PointerRNA ob_ptr;
677
678 uiLayoutSetPropSep(layout, true);
679
680 row = uiLayoutRow(layout, true);
681 uiItemR(row, ptr, "falloff_type", UI_ITEM_NONE, IFACE_("Type"), ICON_NONE);
682 sub = uiLayoutRow(row, true);
683 uiLayoutSetPropSep(sub, false);
684 uiItemR(row, ptr, "invert_falloff", UI_ITEM_NONE, "", ICON_ARROW_LEFTRIGHT);
685 if (RNA_enum_get(ptr, "falloff_type") == MOD_WVG_MAPPING_CURVE) {
686 uiTemplateCurveMapping(layout, ptr, "map_curve", 0, false, false, false, false);
687 }
688 modifier_panel_end(layout, ptr);
689}
690
691static void influence_panel_draw(const bContext *C, Panel *panel)
692{
693 uiLayout *layout = panel->layout;
694
695 PointerRNA ob_ptr;
697
698 weightvg_ui_common(C, &ob_ptr, ptr, layout);
699}
700
701static void panel_register(ARegionType *region_type)
702{
706 region_type, "falloff", "Falloff", nullptr, falloff_panel_draw, panel_type);
708 region_type, "influence", "Influence", nullptr, influence_panel_draw, panel_type);
709}
710
711static void blend_write(BlendWriter *writer, const ID * /*id_owner*/, const ModifierData *md)
712{
714
716
717 if (wmd->cmap_curve) {
719 }
720}
721
722static void blend_read(BlendDataReader *reader, ModifierData *md)
723{
725
727 if (wmd->cmap_curve) {
729 }
730}
731
733 /*idname*/ "VertexWeightProximity",
734 /*name*/ N_("VertexWeightProximity"),
735 /*struct_name*/ "WeightVGProximityModifierData",
736 /*struct_size*/ sizeof(WeightVGProximityModifierData),
737 /*srna*/ &RNA_VertexWeightProximityModifier,
741 /*icon*/ ICON_MOD_VERTEX_WEIGHT,
742
743 /*copy_data*/ copy_data,
744
745 /*deform_verts*/ nullptr,
746 /*deform_matrices*/ nullptr,
747 /*deform_verts_EM*/ nullptr,
748 /*deform_matrices_EM*/ nullptr,
749 /*modify_mesh*/ modify_mesh,
750 /*modify_geometry_set*/ nullptr,
751
752 /*init_data*/ init_data,
753 /*required_data_mask*/ required_data_mask,
754 /*free_data*/ free_data,
755 /*is_disabled*/ is_disabled,
756 /*update_depsgraph*/ update_depsgraph,
757 /*depends_on_time*/ depends_on_time,
758 /*depends_on_normals*/ nullptr,
759 /*foreach_ID_link*/ foreach_ID_link,
760 /*foreach_tex_link*/ foreach_tex_link,
761 /*free_runtime_data*/ nullptr,
762 /*panel_register*/ panel_register,
763 /*blend_write*/ blend_write,
764 /*blend_read*/ blend_read,
765 /*foreach_cache*/ nullptr,
766};
void free_bvhtree_from_mesh(BVHTreeFromMesh *data)
Definition bvhutils.cc:1160
BVHTree * BKE_bvhtree_from_mesh_get(BVHTreeFromMesh *data, const Mesh *mesh, BVHCacheType bvh_cache_type, int tree_type)
Definition bvhutils.cc:899
@ BVHTREE_FROM_CORNER_TRIS
@ BVHTREE_FROM_EDGES
@ BVHTREE_FROM_VERTS
void BKE_curvemapping_blend_read(BlendDataReader *reader, CurveMapping *cumap)
CurveMapping * BKE_curvemapping_copy(const CurveMapping *cumap)
void BKE_curvemapping_init(CurveMapping *cumap)
CurveMapping * BKE_curvemapping_add(int tot, float minx, float miny, float maxx, float maxy)
Definition colortools.cc:90
void BKE_curvemapping_free(CurveMapping *cumap)
void BKE_curvemapping_blend_write(BlendWriter *writer, const CurveMapping *cumap)
CustomData interface, see also DNA_customdata_types.h.
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
support for deformation groups and hooks.
MDeformWeight * BKE_defvert_find_index(const MDeformVert *dv, int defgroup)
Definition deform.cc:795
int BKE_id_defgroup_name_index(const ID *id, blender::StringRef name)
Definition deform.cc:543
@ IDWALK_CB_USER
@ IDWALK_CB_NOP
void BKE_mesh_wrapper_ensure_mdata(Mesh *mesh)
Mesh * BKE_modifier_get_evaluated_mesh_from_evaluated_object(Object *ob_eval)
void BKE_modifier_copydata_generic(const ModifierData *md, ModifierData *md_dst, int flag)
void(*)(void *user_data, Object *ob, ModifierData *md, const PointerRNA *ptr, PropertyRNA *texture_prop) TexWalkFunc
@ eModifierTypeFlag_SupportsMapping
@ eModifierTypeFlag_SupportsEditmode
@ eModifierTypeFlag_AcceptsMesh
void(*)(void *user_data, Object *ob, ID **idpoin, int cb_flag) IDWalkFunc
bool BKE_texture_dependsOnTime(const struct Tex *texture)
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_ghashutil_strhash(key)
Definition BLI_ghash.h:574
int BLI_bvhtree_find_nearest(const BVHTree *tree, const float co[3], BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata)
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
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 mat[4][4], const float vec[3])
#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
void BLI_task_parallel_range(int start, int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
Definition task_range.cc:99
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
Definition BLI_task.h:230
Platform independent time functions.
Utility defines for timing/benchmarks.
#define TIMEIT_START(var)
#define TIMEIT_END(var)
#define ARRAY_SIZE(arr)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define BLO_write_struct(writer, struct_name, data_ptr)
#define BLO_read_struct(reader, struct_name, ptr_p)
#define IFACE_(msgid)
void DEG_add_generic_id_relation(DepsNodeHandle *node_handle, ID *id, const char *description)
void DEG_add_depends_on_transform_relation(DepsNodeHandle *node_handle, const char *description)
void DEG_add_object_relation(DepsNodeHandle *node_handle, Object *object, eDepsObjectComponentType component, const char *description)
@ DEG_OB_COMP_GEOMETRY
@ DEG_OB_COMP_TRANSFORM
Scene * DEG_get_evaluated_scene(const Depsgraph *graph)
#define CD_MASK_MDEFORMVERT
#define CD_MASK_MTFACE
@ CD_MDEFORMVERT
#define DNA_struct_default_get(struct_name)
@ MOD_WVG_PROXIMITY_OBJECT
@ MOD_WVG_PROXIMITY_GEOMETRY
struct WeightVGProximityModifierData WeightVGProximityModifierData
@ 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
@ MOD_DISP_MAP_OBJECT
@ MOD_DISP_MAP_GLOBAL
@ MOD_DISP_MAP_UV
@ eModifierType_WeightVGProximity
@ MOD_WVG_MAPPING_NONE
@ MOD_WVG_MAPPING_CURVE
@ MOD_WVG_MAPPING_RANDOM
Object is a sort of wrapper for general info.
static bool is_disabled
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
PanelType * modifier_subpanel_register(ARegionType *region_type, const char *name, const char *label, PanelDrawFn draw_header, PanelDrawFn draw, PanelType *parent)
void modifier_panel_end(uiLayout *layout, PointerRNA *ptr)
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
void MOD_depsgraph_update_object_bone_relation(DepsNodeHandle *node, Object *object, const char *bonename, const char *description)
Definition MOD_util.cc:189
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_ui_common(const bContext *C, PointerRNA *ob_ptr, PointerRNA *ptr, uiLayout *layout)
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 *, 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)
static void influence_panel_draw(const bContext *C, Panel *panel)
static void init_data(ModifierData *md)
static void falloff_panel_draw(const bContext *, Panel *panel)
#define OUT_OF_MEMORY()
static void vert2geom_task_cb_ex(void *__restrict userdata, const int iter, const TaskParallelTLS *__restrict tls)
static void panel_register(ARegionType *region_type)
ModifierTypeInfo modifierType_WeightVGProximity
static Mesh * modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
static void free_data(ModifierData *md)
static void blend_read(BlendDataReader *reader, ModifierData *md)
static bool depends_on_time(Scene *, ModifierData *md)
static float get_ob2ob_distance(const Object *ob, const Object *obr)
static void panel_draw(const bContext *, Panel *panel)
static void foreach_tex_link(ModifierData *md, Object *ob, TexWalkFunc walk, void *user_data)
static void required_data_mask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
static void foreach_ID_link(ModifierData *md, Object *ob, IDWalkFunc walk, void *user_data)
static void blend_write(BlendWriter *writer, const ID *, const ModifierData *md)
static void get_vert2geom_distance(int verts_num, const blender::Span< blender::float3 > positions, const int *indices, float *dist_v, float *dist_e, float *dist_f, Mesh *target, const SpaceTransform *loc2trgt)
static void get_vert2ob_distance(int verts_num, const blender::Span< blender::float3 > positions, const int *indices, float *dist, Object *ob, Object *obr)
static void update_depsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
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)
void uiTemplateCurveMapping(uiLayout *layout, PointerRNA *ptr, const char *propname, int type, bool levels, bool brush, bool neg_slope, bool tone)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemS(uiLayout *layout)
#define UI_ITEM_NONE
void uiItemPointerR(uiLayout *layout, PointerRNA *ptr, const char *propname, PointerRNA *searchptr, const char *searchpropname, const char *name, int icon)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
@ UI_ITEM_R_EXPAND
#define sqrtf(x)
static ushort indices[]
uint col
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition mallocn.cc:45
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
PointerRNA RNA_pointer_create(ID *id, StructRNA *type, void *data)
int RNA_enum_get(PointerRNA *ptr, const char *name)
#define FLT_MAX
Definition stdcycles.h:14
Definition DNA_ID.h:413
char name[66]
Definition DNA_ID.h:425
struct uiLayout * layout
Definition rand.cc:33
BVHTreeFromMesh * treeData[3]
const SpaceTransform * loc2trgt
blender::Span< blender::float3 > positions
#define N_(msgid)
PointerRNA * ptr
Definition wm_files.cc:4126
uint8_t flag
Definition wm_window.cc:138