Blender V5.0
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
8
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#include "DNA_texture_types.h"
28
29#include "BKE_bvhutils.hh"
30#include "BKE_colortools.hh" /* CurveMapping. */
31#include "BKE_customdata.hh"
32#include "BKE_deform.hh"
33#include "BKE_lib_query.hh"
34#include "BKE_mesh.hh"
35#include "BKE_mesh_wrapper.hh"
36#include "BKE_modifier.hh"
37#include "BKE_texture.h" /* Texture masking. */
38
39#include "UI_interface.hh"
41#include "UI_resources.hh"
42
43#include "BLO_read_write.hh"
44
45#include "RNA_access.hh"
46#include "RNA_prototypes.hh"
47
50
51#include "MEM_guardedalloc.h"
52
53#include "MOD_ui_common.hh"
54#include "MOD_util.hh"
55#include "MOD_weightvg_util.hh"
56
57// #define USE_TIMEIT
58
59#ifdef USE_TIMEIT
60# include "BLI_time.h"
61# include "BLI_time_utildefines.h"
62#endif
63
64/**************************************
65 * Util functions. *
66 **************************************/
67
68/* Util macro. */
69#define OUT_OF_MEMORY() (void)printf("WeightVGProximity: Out of memory.\n")
70
72 /* Read-only data */
74
75 const int *indices;
76
78
80
81 /* Write data, but not needing locking (two different threads will never write same index). */
82 float *dist[3];
83};
84
90 /* Read-only data */
91 float last_hit_co[3][3];
92 bool is_init[3];
93};
94
98static void vert2geom_task_cb_ex(void *__restrict userdata,
99 const int iter,
100 const TaskParallelTLS *__restrict tls)
101{
102 Vert2GeomData *data = static_cast<Vert2GeomData *>(userdata);
103 Vert2GeomDataChunk *data_chunk = static_cast<Vert2GeomDataChunk *>(tls->userdata_chunk);
104
105 float tmp_co[3];
106 int i;
107
108 /* Convert the vertex to tree coordinates. */
109 copy_v3_v3(tmp_co, data->positions[data->indices ? data->indices[iter] : iter]);
110 BLI_space_transform_apply(data->loc2trgt, tmp_co);
111
112 for (i = 0; i < ARRAY_SIZE(data->dist); i++) {
113 if (data->dist[i]) {
114 BVHTreeNearest nearest = {0};
115
116 /* Note that we use local proximity heuristics (to reduce the nearest search).
117 *
118 * If we already had an hit before in same chunk of tasks (i.e. previous vertex by index),
119 * we assume this vertex is going to have a close hit to that other vertex,
120 * so we can initiate the "nearest.dist" with the expected value to that last hit.
121 * This will lead in pruning of the search tree.
122 */
123 nearest.dist_sq = data_chunk->is_init[i] ?
124 len_squared_v3v3(tmp_co, data_chunk->last_hit_co[i]) :
125 FLT_MAX;
126 nearest.index = -1;
127
128 /* Compute and store result. If invalid (-1 idx), keep FLT_MAX dist. */
129 BLI_bvhtree_find_nearest(data->treeData[i]->tree,
130 tmp_co,
131 &nearest,
132 data->treeData[i]->nearest_callback,
133 data->treeData[i]);
134 data->dist[i][iter] = sqrtf(nearest.dist_sq);
135
136 if (nearest.index != -1) {
137 copy_v3_v3(data_chunk->last_hit_co[i], nearest.co);
138 data_chunk->is_init[i] = true;
139 }
140 }
141 }
142}
143
147static void get_vert2geom_distance(int verts_num,
148 const blender::Span<blender::float3> positions,
149 const int *indices,
150 float *dist_v,
151 float *dist_e,
152 float *dist_f,
153 Mesh *target,
154 const SpaceTransform *loc2trgt)
155{
157 Vert2GeomDataChunk data_chunk = {{{0}}};
158
162
163 if (dist_v) {
164 /* Create a BVH-tree of the given target's verts. */
165 treeData_v = target->bvh_verts();
166 if (treeData_v.tree == nullptr) {
168 return;
169 }
170 }
171 if (dist_e) {
172 /* Create a BVH-tree of the given target's edges. */
173 treeData_e = target->bvh_edges();
174 if (treeData_e.tree == nullptr) {
176 return;
177 }
178 }
179 if (dist_f) {
180 /* Create a BVH-tree of the given target's faces. */
181 treeData_f = target->bvh_corner_tris();
182 if (treeData_f.tree == nullptr) {
184 return;
185 }
186 }
187
188 data.positions = positions;
189 data.indices = indices;
190 data.loc2trgt = loc2trgt;
191 data.treeData[0] = &treeData_v;
192 data.treeData[1] = &treeData_e;
193 data.treeData[2] = &treeData_f;
194 data.dist[0] = dist_v;
195 data.dist[1] = dist_e;
196 data.dist[2] = dist_f;
197
198 TaskParallelSettings settings;
200 settings.use_threading = (verts_num > 10000);
201 settings.userdata_chunk = &data_chunk;
202 settings.userdata_chunk_size = sizeof(data_chunk);
203 BLI_task_parallel_range(0, verts_num, &data, vert2geom_task_cb_ex, &settings);
204}
205
210static void get_vert2ob_distance(int verts_num,
211 const blender::Span<blender::float3> positions,
212 const int *indices,
213 float *dist,
214 Object *ob,
215 Object *obr)
216{
217 /* Vertex and ref object coordinates. */
218 float v_wco[3];
219 uint i = verts_num;
220
221 while (i-- > 0) {
222 /* Get world-coordinates of the vertex (constraints and anim included). */
223 mul_v3_m4v3(v_wco, ob->object_to_world().ptr(), positions[indices ? indices[i] : i]);
224 /* Return distance between both coordinates. */
225 dist[i] = len_v3v3(v_wco, obr->object_to_world().location());
226 }
227}
228
233static float get_ob2ob_distance(const Object *ob, const Object *obr)
234{
235 return len_v3v3(ob->object_to_world().location(), obr->object_to_world().location());
236}
237
241static void do_map(Object *ob,
242 float *weights,
243 const int nidx,
244 const float min_d,
245 const float max_d,
246 short mode,
247 const bool do_invert_mapping,
248 CurveMapping *cmap)
249{
250 const float range_inv = 1.0f / (max_d - min_d); /* invert since multiplication is faster */
251 uint i = nidx;
252 if (max_d == min_d) {
253 while (i-- > 0) {
254 weights[i] = (weights[i] >= max_d) ? 1.0f : 0.0f; /* "Step" behavior... */
255 }
256 }
257 else if (max_d > min_d) {
258 while (i-- > 0) {
259 if (weights[i] >= max_d) {
260 weights[i] = 1.0f; /* most likely case first */
261 }
262 else if (weights[i] <= min_d) {
263 weights[i] = 0.0f;
264 }
265 else {
266 weights[i] = (weights[i] - min_d) * range_inv;
267 }
268 }
269 }
270 else {
271 while (i-- > 0) {
272 if (weights[i] <= max_d) {
273 weights[i] = 1.0f; /* most likely case first */
274 }
275 else if (weights[i] >= min_d) {
276 weights[i] = 0.0f;
277 }
278 else {
279 weights[i] = (weights[i] - min_d) * range_inv;
280 }
281 }
282 }
283
284 if (do_invert_mapping || mode != MOD_WVG_MAPPING_NONE) {
285 RNG *rng = nullptr;
286
287 if (mode == MOD_WVG_MAPPING_RANDOM) {
289 }
290
291 weightvg_do_map(nidx, weights, mode, do_invert_mapping, cmap, rng);
292
293 if (rng) {
294 BLI_rng_free(rng);
295 }
296 }
297}
298
299/**************************************
300 * Modifiers functions. *
301 **************************************/
313
319
320static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
321{
324
326
328}
329
330static void required_data_mask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
331{
333
334 /* We need vertex groups! */
335 r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
336
337 /* Ask for UV coordinates if we need them. */
338 if (wmd->mask_tex_mapping == MOD_DISP_MAP_UV) {
339 r_cddata_masks->fmask |= CD_MASK_MTFACE;
340 }
341}
342
343static bool depends_on_time(Scene * /*scene*/, ModifierData *md)
344{
346
347 if (wmd->mask_texture) {
349 }
350 return false;
351}
352
353static void foreach_ID_link(ModifierData *md, Object *ob, IDWalkFunc walk, void *user_data)
354{
356
357 walk(user_data, ob, (ID **)&wmd->mask_texture, IDWALK_CB_USER);
358 walk(user_data, ob, (ID **)&wmd->proximity_ob_target, IDWALK_CB_NOP);
359 walk(user_data, ob, (ID **)&wmd->mask_tex_map_obj, IDWALK_CB_NOP);
360}
361
362static void foreach_tex_link(ModifierData *md, Object *ob, TexWalkFunc walk, void *user_data)
363{
364 PointerRNA ptr = RNA_pointer_create_discrete(&ob->id, &RNA_Modifier, md);
365 PropertyRNA *prop = RNA_struct_find_property(&ptr, "mask_texture");
366 walk(user_data, ob, md, &ptr, prop);
367}
368
370{
372 bool need_transform_relation = false;
373
374 if (wmd->proximity_ob_target != nullptr) {
376 ctx->node, wmd->proximity_ob_target, DEG_OB_COMP_TRANSFORM, "WeightVGProximity Modifier");
377 if (wmd->proximity_ob_target->data != nullptr &&
379 {
381 ctx->node, wmd->proximity_ob_target, DEG_OB_COMP_GEOMETRY, "WeightVGProximity Modifier");
382 }
383 need_transform_relation = true;
384 }
385
386 if (wmd->mask_texture != nullptr) {
387 DEG_add_generic_id_relation(ctx->node, &wmd->mask_texture->id, "WeightVGProximity Modifier");
388
389 if (wmd->mask_tex_map_obj != nullptr && wmd->mask_tex_mapping == MOD_DISP_MAP_OBJECT) {
391 ctx->node, wmd->mask_tex_map_obj, wmd->mask_tex_map_bone, "WeightVGProximity Modifier");
392 need_transform_relation = true;
393 }
394 else if (wmd->mask_tex_mapping == MOD_DISP_MAP_GLOBAL) {
395 need_transform_relation = true;
396 }
397 }
398
399 if (need_transform_relation) {
400 DEG_add_depends_on_transform_relation(ctx->node, "WeightVGProximity Modifier");
401 }
402}
403
404static bool is_disabled(const Scene * /*scene*/, ModifierData *md, bool /*use_render_params*/)
405{
407 /* If no vertex group, bypass. */
408 if (wmd->defgrp_name[0] == '\0') {
409 return true;
410 }
411 /* If no target object, bypass. */
412 return (wmd->proximity_ob_target == nullptr);
413}
414
415static Mesh *modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
416{
417 BLI_assert(mesh != nullptr);
418
420 MDeformWeight **dw, **tdw;
421 Object *ob = ctx->object;
422 Object *obr = nullptr; /* Our target object. */
423 int defgrp_index;
424 float *tw = nullptr;
425 float *org_w = nullptr;
426 float *new_w = nullptr;
427 int *tidx, *indices = nullptr;
428 int index_num = 0;
429 int i;
430 const bool invert_vgroup_mask = (wmd->proximity_flags & MOD_WVG_PROXIMITY_INVERT_VGROUP_MASK) !=
431 0;
432 const bool do_normalize = (wmd->proximity_flags & MOD_WVG_PROXIMITY_WEIGHTS_NORMALIZE) != 0;
433 /* Flags. */
434#if 0
435 const bool do_prev = (wmd->modifier.mode & eModifierMode_DoWeightPreview) != 0;
436#endif
437
438#ifdef USE_TIMEIT
439 TIMEIT_START(perf);
440#endif
441
442 /* Get number of verts. */
443 const int verts_num = mesh->verts_num;
444
445 /* Check if we can just return the original mesh.
446 * Must have verts and therefore verts assigned to vgroups to do anything useful!
447 */
448 if ((verts_num == 0) || BLI_listbase_is_empty(&mesh->vertex_group_names)) {
449 return mesh;
450 }
451
452 /* Get our target object. */
453 obr = wmd->proximity_ob_target;
454 if (obr == nullptr) {
455 return mesh;
456 }
457
458 /* Get vgroup idx from its name. */
459 defgrp_index = BKE_id_defgroup_name_index(&mesh->id, wmd->defgrp_name);
460 if (defgrp_index == -1) {
461 return mesh;
462 }
463 const bool has_mdef = !mesh->deform_verts().is_empty();
464 /* If no vertices were ever added to an object's vgroup, dvert might be nullptr. */
465 /* As this modifier never add vertices to vgroup, just return. */
466 if (!has_mdef) {
467 return mesh;
468 }
469
470 MDeformVert *dvert = mesh->deform_verts_for_write().data();
471 /* Ultimate security check. */
472 if (!dvert) {
473 return mesh;
474 }
475
476 /* Find out which vertices to work on (all vertices in vgroup), and get their relevant weight. */
477 tidx = MEM_malloc_arrayN<int>(size_t(verts_num), __func__);
478 tw = MEM_malloc_arrayN<float>(size_t(verts_num), __func__);
479 tdw = MEM_malloc_arrayN<MDeformWeight *>(size_t(verts_num), __func__);
480 for (i = 0; i < verts_num; i++) {
481 MDeformWeight *_dw = BKE_defvert_find_index(&dvert[i], defgrp_index);
482 if (_dw) {
483 tidx[index_num] = i;
484 tw[index_num] = _dw->weight;
485 tdw[index_num++] = _dw;
486 }
487 }
488 /* If no vertices found, return org data! */
489 if (index_num == 0) {
490 MEM_freeN(tidx);
491 MEM_freeN(tw);
492 MEM_freeN(tdw);
493 return mesh;
494 }
495 if (index_num != verts_num) {
496 indices = MEM_malloc_arrayN<int>(size_t(index_num), __func__);
497 memcpy(indices, tidx, sizeof(int) * index_num);
498 org_w = MEM_malloc_arrayN<float>(size_t(index_num), __func__);
499 memcpy(org_w, tw, sizeof(float) * index_num);
500 dw = MEM_malloc_arrayN<MDeformWeight *>(size_t(index_num), __func__);
501 memcpy(dw, tdw, sizeof(MDeformWeight *) * index_num);
502 MEM_freeN(tw);
503 MEM_freeN(tdw);
504 }
505 else {
506 org_w = tw;
507 dw = tdw;
508 }
509 new_w = MEM_malloc_arrayN<float>(size_t(index_num), __func__);
510 MEM_freeN(tidx);
511
512 const blender::Span<blender::float3> positions = mesh->vert_positions();
513
514 /* Compute wanted distances. */
516 const float dist = get_ob2ob_distance(ob, obr);
517 for (i = 0; i < index_num; i++) {
518 new_w[i] = dist;
519 }
520 }
522 const bool use_trgt_verts = (wmd->proximity_flags & MOD_WVG_PROXIMITY_GEOM_VERTS) != 0;
523 const bool use_trgt_edges = (wmd->proximity_flags & MOD_WVG_PROXIMITY_GEOM_EDGES) != 0;
524 const bool use_trgt_faces = (wmd->proximity_flags & MOD_WVG_PROXIMITY_GEOM_FACES) != 0;
525
526 if (use_trgt_verts || use_trgt_edges || use_trgt_faces) {
528
529 /* We must check that we do have a valid target_mesh! */
530 if (target_mesh != nullptr) {
531
532 /* TODO: edit-mode versions of the BVH lookup functions are available so it could be
533 * avoided. */
535
536 SpaceTransform loc2trgt;
537 float *dists_v = use_trgt_verts ? MEM_malloc_arrayN<float>(size_t(index_num), __func__) :
538 nullptr;
539 float *dists_e = use_trgt_edges ? MEM_malloc_arrayN<float>(size_t(index_num), __func__) :
540 nullptr;
541 float *dists_f = use_trgt_faces ? MEM_malloc_arrayN<float>(size_t(index_num), __func__) :
542 nullptr;
543
544 BLI_SPACE_TRANSFORM_SETUP(&loc2trgt, ob, obr);
546 index_num, positions, indices, dists_v, dists_e, dists_f, target_mesh, &loc2trgt);
547 for (i = 0; i < index_num; i++) {
548 new_w[i] = dists_v ? dists_v[i] : FLT_MAX;
549 if (dists_e) {
550 new_w[i] = min_ff(dists_e[i], new_w[i]);
551 }
552 if (dists_f) {
553 new_w[i] = min_ff(dists_f[i], new_w[i]);
554 }
555 }
556
557 MEM_SAFE_FREE(dists_v);
558 MEM_SAFE_FREE(dists_e);
559 MEM_SAFE_FREE(dists_f);
560 }
561 /* Else, fall back to default obj2vert behavior. */
562 else {
563 get_vert2ob_distance(index_num, positions, indices, new_w, ob, obr);
564 }
565 }
566 else {
567 get_vert2ob_distance(index_num, positions, indices, new_w, ob, obr);
568 }
569 }
570
571 /* Map distances to weights. */
572 do_map(ob,
573 new_w,
574 index_num,
575 wmd->min_dist,
576 wmd->max_dist,
577 wmd->falloff_type,
579 wmd->cmap_curve);
580
581 /* Do masking. */
584 index_num,
585 indices,
586 org_w,
587 new_w,
588 ob,
589 mesh,
590 wmd->mask_constant,
591 wmd->mask_defgrp_name,
592 scene,
593 wmd->mask_texture,
595 wmd->mask_tex_mapping,
596 wmd->mask_tex_map_obj,
599 invert_vgroup_mask);
600
601 /* Update vgroup. Note we never add nor remove vertices from vgroup here. */
603 dvert, defgrp_index, dw, index_num, indices, org_w, false, 0.0f, false, 0.0f, do_normalize);
604
605 /* If weight preview enabled... */
606#if 0 /* XXX Currently done in mod stack :/ */
607 if (do_prev) {
608 DM_update_weight_mcol(ob, dm, 0, org_w, index_num, indices);
609 }
610#endif
611
612 /* Freeing stuff. */
613 MEM_freeN(org_w);
614 MEM_freeN(new_w);
615 MEM_freeN(dw);
617
618#ifdef USE_TIMEIT
619 TIMEIT_END(perf);
620#endif
621
622 mesh->runtime->is_original_bmesh = false;
623
624 /* Return the vgroup-modified mesh. */
625 return mesh;
626}
627
628static void panel_draw(const bContext * /*C*/, Panel *panel)
629{
630 uiLayout *col;
631 uiLayout *layout = panel->layout;
632
633 PointerRNA ob_ptr;
635
636 layout->use_property_split_set(true);
637
638 layout->prop_search(
639 ptr, "vertex_group", &ob_ptr, "vertex_groups", std::nullopt, ICON_GROUP_VERTEX);
640
641 layout->prop(ptr, "target", UI_ITEM_NONE, std::nullopt, ICON_NONE);
642
643 layout->separator();
644
645 layout->prop(ptr, "proximity_mode", UI_ITEM_NONE, std::nullopt, ICON_NONE);
646 if (RNA_enum_get(ptr, "proximity_mode") == MOD_WVG_PROXIMITY_GEOMETRY) {
647 layout->prop(ptr, "proximity_geometry", UI_ITEM_R_EXPAND, IFACE_("Geometry"), ICON_NONE);
648 }
649
650 col = &layout->column(true);
651 col->prop(ptr, "min_dist", UI_ITEM_NONE, std::nullopt, ICON_NONE);
652 col->prop(ptr, "max_dist", UI_ITEM_NONE, std::nullopt, ICON_NONE);
653
654 layout->prop(ptr, "normalize", UI_ITEM_NONE, std::nullopt, ICON_NONE);
655}
656
657static void falloff_panel_draw(const bContext * /*C*/, Panel *panel)
658{
659 uiLayout *row, *sub;
660 uiLayout *layout = panel->layout;
661
662 PointerRNA ob_ptr;
664
665 layout->use_property_split_set(true);
666
667 row = &layout->row(true);
668 row->prop(ptr, "falloff_type", UI_ITEM_NONE, IFACE_("Type"), ICON_NONE);
669 sub = &row->row(true);
670 sub->use_property_split_set(false);
671 row->prop(ptr, "invert_falloff", UI_ITEM_NONE, "", ICON_ARROW_LEFTRIGHT);
672 if (RNA_enum_get(ptr, "falloff_type") == MOD_WVG_MAPPING_CURVE) {
673 uiTemplateCurveMapping(layout, ptr, "map_curve", 0, false, false, false, false, false);
674 }
676}
677
678static void influence_panel_draw(const bContext *C, Panel *panel)
679{
680 uiLayout *layout = panel->layout;
681
682 PointerRNA ob_ptr;
684
685 weightvg_ui_common(C, &ob_ptr, ptr, layout);
686}
687
688static void panel_register(ARegionType *region_type)
689{
693 region_type, "falloff", "Falloff", nullptr, falloff_panel_draw, panel_type);
695 region_type, "influence", "Influence", nullptr, influence_panel_draw, panel_type);
696}
697
698static void blend_write(BlendWriter *writer, const ID * /*id_owner*/, const ModifierData *md)
699{
701
703
704 if (wmd->cmap_curve) {
706 }
707}
708
709static void blend_read(BlendDataReader *reader, ModifierData *md)
710{
712
714 if (wmd->cmap_curve) {
716 }
717}
718
720 /*idname*/ "VertexWeightProximity",
721 /*name*/ N_("VertexWeightProximity"),
722 /*struct_name*/ "WeightVGProximityModifierData",
723 /*struct_size*/ sizeof(WeightVGProximityModifierData),
724 /*srna*/ &RNA_VertexWeightProximityModifier,
728 /*icon*/ ICON_MOD_VERTEX_WEIGHT,
729
730 /*copy_data*/ copy_data,
731
732 /*deform_verts*/ nullptr,
733 /*deform_matrices*/ nullptr,
734 /*deform_verts_EM*/ nullptr,
735 /*deform_matrices_EM*/ nullptr,
736 /*modify_mesh*/ modify_mesh,
737 /*modify_geometry_set*/ nullptr,
738
739 /*init_data*/ init_data,
740 /*required_data_mask*/ required_data_mask,
741 /*free_data*/ free_data,
742 /*is_disabled*/ is_disabled,
743 /*update_depsgraph*/ update_depsgraph,
744 /*depends_on_time*/ depends_on_time,
745 /*depends_on_normals*/ nullptr,
746 /*foreach_ID_link*/ foreach_ID_link,
747 /*foreach_tex_link*/ foreach_tex_link,
748 /*free_runtime_data*/ nullptr,
749 /*panel_register*/ panel_register,
750 /*blend_write*/ blend_write,
751 /*blend_read*/ blend_read,
752 /*foreach_cache*/ nullptr,
753 /*foreach_working_space_color*/ nullptr,
754};
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:89
void BKE_curvemapping_free(CurveMapping *cumap)
void BKE_curvemapping_blend_write(BlendWriter *writer, const CurveMapping *cumap)
CustomData interface, see also DNA_customdata_types.h.
support for deformation groups and hooks.
MDeformWeight * BKE_defvert_find_index(const MDeformVert *dv, int defgroup)
Definition deform.cc:806
int BKE_id_defgroup_name_index(const ID *id, blender::StringRef name)
Definition deform.cc:549
@ IDWALK_CB_USER
@ IDWALK_CB_NOP
void BKE_mesh_wrapper_ensure_mdata(Mesh *mesh)
void(*)(void *user_data, Object *ob, ID **idpoin, LibraryForeachIDCallbackFlag cb_flag) IDWalkFunc
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)
@ eModifierTypeFlag_SupportsMapping
@ eModifierTypeFlag_SupportsEditmode
@ eModifierTypeFlag_AcceptsMesh
void(*)(void *user_data, Object *ob, ModifierData *md, const PointerRNA *ptr, PropertyRNA *texture_prop) TexWalkFunc
bool BKE_texture_dependsOnTime(const struct Tex *texture)
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_ghashutil_strhash(key)
Definition BLI_ghash.h:570
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 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:53
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:221
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
#define DNA_struct_default_get(struct_name)
@ 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
@ eModifierType_WeightVGProximity
@ MOD_DISP_MAP_OBJECT
@ MOD_DISP_MAP_GLOBAL
@ MOD_DISP_MAP_UV
@ MOD_WVG_PROXIMITY_OBJECT
@ MOD_WVG_PROXIMITY_GEOMETRY
@ 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)
static void init_data(ModifierData *md)
static void panel_register(ARegionType *region_type)
static void required_data_mask(ModifierData *, CustomData_MeshMasks *r_cddata_masks)
static void blend_read(BlendDataReader *, ModifierData *md)
static void panel_draw(const bContext *, Panel *panel)
static void foreach_ID_link(ModifierData *md, Object *ob, IDWalkFunc walk, void *user_data)
static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
static Mesh * modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
Definition MOD_array.cc:862
static void free_data(ModifierData *md)
Definition MOD_bevel.cc:272
static void blend_write(BlendWriter *writer, const ID *, const ModifierData *md)
Definition MOD_bevel.cc:433
static bool depends_on_time(Scene *, ModifierData *)
Definition MOD_build.cc:47
static void foreach_tex_link(ModifierData *md, Object *ob, TexWalkFunc walk, void *user_data)
static void falloff_panel_draw(const bContext *, Panel *panel)
Definition MOD_hook.cc:484
PanelType * modifier_subpanel_register(ARegionType *region_type, const char *name, const char *label, PanelDrawFn draw_header, PanelDrawFn draw, PanelType *parent)
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
void modifier_error_message_draw(uiLayout *layout, PointerRNA *ptr)
void MOD_depsgraph_update_object_bone_relation(DepsNodeHandle *node, Object *object, const char *bonename, const char *description)
Definition MOD_util.cc:186
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 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)
#define C
Definition RandGen.cpp:29
void uiTemplateCurveMapping(uiLayout *layout, PointerRNA *ptr, blender::StringRefNull propname, int type, bool levels, bool brush, bool neg_slope, bool tone, bool presets)
@ UI_ITEM_R_EXPAND
#define UI_ITEM_NONE
BMesh const char void * data
static ushort indices[]
uint col
static void update_depsgraph(tGraphSliderOp *gso)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:133
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
#define sqrtf
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
PointerRNA RNA_pointer_create_discrete(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:414
char name[258]
Definition DNA_ID.h:432
MeshRuntimeHandle * runtime
ListBase vertex_group_names
int verts_num
struct uiLayout * layout
Definition rand.cc:33
size_t userdata_chunk_size
Definition BLI_task.h:164
blender::bke::BVHTreeFromMesh * treeData[3]
const SpaceTransform * loc2trgt
blender::Span< blender::float3 > positions
uiLayout & column(bool align)
void prop_search(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *searchptr, PropertyRNA *searchprop, PropertyRNA *item_searchpropname, std::optional< blender::StringRefNull > name, int icon, bool results_are_suggestions)
void separator(float factor=1.0f, LayoutSeparatorType type=LayoutSeparatorType::Auto)
uiLayout & row(bool align)
void use_property_split_set(bool value)
void prop(PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, std::optional< blender::StringRef > name_opt, int icon, std::optional< blender::StringRef > placeholder=std::nullopt)
i
Definition text_draw.cc:230
#define N_(msgid)
PointerRNA * ptr
Definition wm_files.cc:4238
uint8_t flag
Definition wm_window.cc:145