Blender V4.5
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"
40#include "UI_resources.hh"
41
42#include "BLO_read_write.hh"
43
44#include "RNA_access.hh"
45#include "RNA_prototypes.hh"
46
49
50#include "MEM_guardedalloc.h"
51
52#include "MOD_ui_common.hh"
53#include "MOD_util.hh"
54#include "MOD_weightvg_util.hh"
55
56// #define USE_TIMEIT
57
58#ifdef USE_TIMEIT
59# include "BLI_time.h"
60# include "BLI_time_utildefines.h"
61#endif
62
63/**************************************
64 * Util functions. *
65 **************************************/
66
67/* Util macro. */
68#define OUT_OF_MEMORY() (void)printf("WeightVGProximity: Out of memory.\n")
69
71 /* Read-only data */
73
74 const int *indices;
75
77
79
80 /* Write data, but not needing locking (two different threads will never write same index). */
81 float *dist[3];
82};
83
89 /* Read-only data */
90 float last_hit_co[3][3];
91 bool is_init[3];
92};
93
97static void vert2geom_task_cb_ex(void *__restrict userdata,
98 const int iter,
99 const TaskParallelTLS *__restrict tls)
100{
101 Vert2GeomData *data = static_cast<Vert2GeomData *>(userdata);
102 Vert2GeomDataChunk *data_chunk = static_cast<Vert2GeomDataChunk *>(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->positions[data->indices ? data->indices[iter] : 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
146static void get_vert2geom_distance(int verts_num,
147 const blender::Span<blender::float3> positions,
148 const int *indices,
149 float *dist_v,
150 float *dist_e,
151 float *dist_f,
152 Mesh *target,
153 const SpaceTransform *loc2trgt)
154{
156 Vert2GeomDataChunk data_chunk = {{{0}}};
157
161
162 if (dist_v) {
163 /* Create a BVH-tree of the given target's verts. */
164 treeData_v = target->bvh_verts();
165 if (treeData_v.tree == nullptr) {
167 return;
168 }
169 }
170 if (dist_e) {
171 /* Create a BVH-tree of the given target's edges. */
172 treeData_e = target->bvh_edges();
173 if (treeData_e.tree == nullptr) {
175 return;
176 }
177 }
178 if (dist_f) {
179 /* Create a BVH-tree of the given target's faces. */
180 treeData_f = target->bvh_corner_tris();
181 if (treeData_f.tree == nullptr) {
183 return;
184 }
185 }
186
187 data.positions = positions;
188 data.indices = indices;
189 data.loc2trgt = loc2trgt;
190 data.treeData[0] = &treeData_v;
191 data.treeData[1] = &treeData_e;
192 data.treeData[2] = &treeData_f;
193 data.dist[0] = dist_v;
194 data.dist[1] = dist_e;
195 data.dist[2] = dist_f;
196
197 TaskParallelSettings settings;
199 settings.use_threading = (verts_num > 10000);
200 settings.userdata_chunk = &data_chunk;
201 settings.userdata_chunk_size = sizeof(data_chunk);
202 BLI_task_parallel_range(0, verts_num, &data, vert2geom_task_cb_ex, &settings);
203}
204
209static void get_vert2ob_distance(int verts_num,
210 const blender::Span<blender::float3> positions,
211 const int *indices,
212 float *dist,
213 Object *ob,
214 Object *obr)
215{
216 /* Vertex and ref object coordinates. */
217 float v_wco[3];
218 uint i = verts_num;
219
220 while (i-- > 0) {
221 /* Get world-coordinates of the vertex (constraints and anim included). */
222 mul_v3_m4v3(v_wco, ob->object_to_world().ptr(), positions[indices ? indices[i] : i]);
223 /* Return distance between both coordinates. */
224 dist[i] = len_v3v3(v_wco, obr->object_to_world().location());
225 }
226}
227
232static float get_ob2ob_distance(const Object *ob, const Object *obr)
233{
234 return len_v3v3(ob->object_to_world().location(), obr->object_to_world().location());
235}
236
240static void do_map(Object *ob,
241 float *weights,
242 const int nidx,
243 const float min_d,
244 const float max_d,
245 short mode,
246 const bool do_invert_mapping,
247 CurveMapping *cmap)
248{
249 const float range_inv = 1.0f / (max_d - min_d); /* invert since multiplication is faster */
250 uint i = nidx;
251 if (max_d == min_d) {
252 while (i-- > 0) {
253 weights[i] = (weights[i] >= max_d) ? 1.0f : 0.0f; /* "Step" behavior... */
254 }
255 }
256 else if (max_d > min_d) {
257 while (i-- > 0) {
258 if (weights[i] >= max_d) {
259 weights[i] = 1.0f; /* most likely case first */
260 }
261 else if (weights[i] <= min_d) {
262 weights[i] = 0.0f;
263 }
264 else {
265 weights[i] = (weights[i] - min_d) * range_inv;
266 }
267 }
268 }
269 else {
270 while (i-- > 0) {
271 if (weights[i] <= max_d) {
272 weights[i] = 1.0f; /* most likely case first */
273 }
274 else if (weights[i] >= min_d) {
275 weights[i] = 0.0f;
276 }
277 else {
278 weights[i] = (weights[i] - min_d) * range_inv;
279 }
280 }
281 }
282
283 if (do_invert_mapping || mode != MOD_WVG_MAPPING_NONE) {
284 RNG *rng = nullptr;
285
286 if (mode == MOD_WVG_MAPPING_RANDOM) {
288 }
289
290 weightvg_do_map(nidx, weights, mode, do_invert_mapping, cmap, rng);
291
292 if (rng) {
293 BLI_rng_free(rng);
294 }
295 }
296}
297
298/**************************************
299 * Modifiers functions. *
300 **************************************/
312
318
319static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
320{
323
325
327}
328
329static void required_data_mask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
330{
332
333 /* We need vertex groups! */
334 r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
335
336 /* Ask for UV coordinates if we need them. */
337 if (wmd->mask_tex_mapping == MOD_DISP_MAP_UV) {
338 r_cddata_masks->fmask |= CD_MASK_MTFACE;
339 }
340}
341
342static bool depends_on_time(Scene * /*scene*/, ModifierData *md)
343{
345
346 if (wmd->mask_texture) {
348 }
349 return false;
350}
351
352static void foreach_ID_link(ModifierData *md, Object *ob, IDWalkFunc walk, void *user_data)
353{
355
356 walk(user_data, ob, (ID **)&wmd->mask_texture, IDWALK_CB_USER);
357 walk(user_data, ob, (ID **)&wmd->proximity_ob_target, IDWALK_CB_NOP);
358 walk(user_data, ob, (ID **)&wmd->mask_tex_map_obj, IDWALK_CB_NOP);
359}
360
361static void foreach_tex_link(ModifierData *md, Object *ob, TexWalkFunc walk, void *user_data)
362{
363 PointerRNA ptr = RNA_pointer_create_discrete(&ob->id, &RNA_Modifier, md);
364 PropertyRNA *prop = RNA_struct_find_property(&ptr, "mask_texture");
365 walk(user_data, ob, md, &ptr, prop);
366}
367
369{
371 bool need_transform_relation = false;
372
373 if (wmd->proximity_ob_target != nullptr) {
375 ctx->node, wmd->proximity_ob_target, DEG_OB_COMP_TRANSFORM, "WeightVGProximity Modifier");
376 if (wmd->proximity_ob_target->data != nullptr &&
378 {
380 ctx->node, wmd->proximity_ob_target, DEG_OB_COMP_GEOMETRY, "WeightVGProximity Modifier");
381 }
382 need_transform_relation = true;
383 }
384
385 if (wmd->mask_texture != nullptr) {
386 DEG_add_generic_id_relation(ctx->node, &wmd->mask_texture->id, "WeightVGProximity Modifier");
387
388 if (wmd->mask_tex_map_obj != nullptr && wmd->mask_tex_mapping == MOD_DISP_MAP_OBJECT) {
390 ctx->node, wmd->mask_tex_map_obj, wmd->mask_tex_map_bone, "WeightVGProximity Modifier");
391 need_transform_relation = true;
392 }
393 else if (wmd->mask_tex_mapping == MOD_DISP_MAP_GLOBAL) {
394 need_transform_relation = true;
395 }
396 }
397
398 if (need_transform_relation) {
399 DEG_add_depends_on_transform_relation(ctx->node, "WeightVGProximity Modifier");
400 }
401}
402
403static bool is_disabled(const Scene * /*scene*/, ModifierData *md, bool /*use_render_params*/)
404{
406 /* If no vertex group, bypass. */
407 if (wmd->defgrp_name[0] == '\0') {
408 return true;
409 }
410 /* If no target object, bypass. */
411 return (wmd->proximity_ob_target == nullptr);
412}
413
414static Mesh *modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
415{
416 BLI_assert(mesh != nullptr);
417
419 MDeformWeight **dw, **tdw;
420 Object *ob = ctx->object;
421 Object *obr = nullptr; /* Our target object. */
422 int defgrp_index;
423 float *tw = nullptr;
424 float *org_w = nullptr;
425 float *new_w = nullptr;
426 int *tidx, *indices = nullptr;
427 int index_num = 0;
428 int i;
429 const bool invert_vgroup_mask = (wmd->proximity_flags & MOD_WVG_PROXIMITY_INVERT_VGROUP_MASK) !=
430 0;
431 const bool do_normalize = (wmd->proximity_flags & MOD_WVG_PROXIMITY_WEIGHTS_NORMALIZE) != 0;
432 /* Flags. */
433#if 0
434 const bool do_prev = (wmd->modifier.mode & eModifierMode_DoWeightPreview) != 0;
435#endif
436
437#ifdef USE_TIMEIT
438 TIMEIT_START(perf);
439#endif
440
441 /* Get number of verts. */
442 const int verts_num = mesh->verts_num;
443
444 /* Check if we can just return the original mesh.
445 * Must have verts and therefore verts assigned to vgroups to do anything useful!
446 */
447 if ((verts_num == 0) || BLI_listbase_is_empty(&mesh->vertex_group_names)) {
448 return mesh;
449 }
450
451 /* Get our target object. */
452 obr = wmd->proximity_ob_target;
453 if (obr == nullptr) {
454 return mesh;
455 }
456
457 /* Get vgroup idx from its name. */
458 defgrp_index = BKE_id_defgroup_name_index(&mesh->id, wmd->defgrp_name);
459 if (defgrp_index == -1) {
460 return mesh;
461 }
462 const bool has_mdef = CustomData_has_layer(&mesh->vert_data, CD_MDEFORMVERT);
463 /* If no vertices were ever added to an object's vgroup, dvert might be nullptr. */
464 /* As this modifier never add vertices to vgroup, just return. */
465 if (!has_mdef) {
466 return mesh;
467 }
468
469 MDeformVert *dvert = mesh->deform_verts_for_write().data();
470 /* Ultimate security check. */
471 if (!dvert) {
472 return mesh;
473 }
474
475 /* Find out which vertices to work on (all vertices in vgroup), and get their relevant weight. */
476 tidx = MEM_malloc_arrayN<int>(size_t(verts_num), __func__);
477 tw = MEM_malloc_arrayN<float>(size_t(verts_num), __func__);
478 tdw = MEM_malloc_arrayN<MDeformWeight *>(size_t(verts_num), __func__);
479 for (i = 0; i < verts_num; i++) {
480 MDeformWeight *_dw = BKE_defvert_find_index(&dvert[i], defgrp_index);
481 if (_dw) {
482 tidx[index_num] = i;
483 tw[index_num] = _dw->weight;
484 tdw[index_num++] = _dw;
485 }
486 }
487 /* If no vertices found, return org data! */
488 if (index_num == 0) {
489 MEM_freeN(tidx);
490 MEM_freeN(tw);
491 MEM_freeN(tdw);
492 return mesh;
493 }
494 if (index_num != verts_num) {
495 indices = MEM_malloc_arrayN<int>(size_t(index_num), __func__);
496 memcpy(indices, tidx, sizeof(int) * index_num);
497 org_w = MEM_malloc_arrayN<float>(size_t(index_num), __func__);
498 memcpy(org_w, tw, sizeof(float) * index_num);
499 dw = MEM_malloc_arrayN<MDeformWeight *>(size_t(index_num), __func__);
500 memcpy(dw, tdw, sizeof(MDeformWeight *) * index_num);
501 MEM_freeN(tw);
502 MEM_freeN(tdw);
503 }
504 else {
505 org_w = tw;
506 dw = tdw;
507 }
508 new_w = MEM_malloc_arrayN<float>(size_t(index_num), __func__);
509 MEM_freeN(tidx);
510
511 const blender::Span<blender::float3> positions = mesh->vert_positions();
512
513 /* Compute wanted distances. */
515 const float dist = get_ob2ob_distance(ob, obr);
516 for (i = 0; i < index_num; i++) {
517 new_w[i] = dist;
518 }
519 }
521 const bool use_trgt_verts = (wmd->proximity_flags & MOD_WVG_PROXIMITY_GEOM_VERTS) != 0;
522 const bool use_trgt_edges = (wmd->proximity_flags & MOD_WVG_PROXIMITY_GEOM_EDGES) != 0;
523 const bool use_trgt_faces = (wmd->proximity_flags & MOD_WVG_PROXIMITY_GEOM_FACES) != 0;
524
525 if (use_trgt_verts || use_trgt_edges || use_trgt_faces) {
527
528 /* We must check that we do have a valid target_mesh! */
529 if (target_mesh != nullptr) {
530
531 /* TODO: edit-mode versions of the BVH lookup functions are available so it could be
532 * avoided. */
534
535 SpaceTransform loc2trgt;
536 float *dists_v = use_trgt_verts ? MEM_malloc_arrayN<float>(size_t(index_num), __func__) :
537 nullptr;
538 float *dists_e = use_trgt_edges ? MEM_malloc_arrayN<float>(size_t(index_num), __func__) :
539 nullptr;
540 float *dists_f = use_trgt_faces ? MEM_malloc_arrayN<float>(size_t(index_num), __func__) :
541 nullptr;
542
543 BLI_SPACE_TRANSFORM_SETUP(&loc2trgt, ob, obr);
545 index_num, positions, indices, dists_v, dists_e, dists_f, target_mesh, &loc2trgt);
546 for (i = 0; i < index_num; i++) {
547 new_w[i] = dists_v ? dists_v[i] : FLT_MAX;
548 if (dists_e) {
549 new_w[i] = min_ff(dists_e[i], new_w[i]);
550 }
551 if (dists_f) {
552 new_w[i] = min_ff(dists_f[i], new_w[i]);
553 }
554 }
555
556 MEM_SAFE_FREE(dists_v);
557 MEM_SAFE_FREE(dists_e);
558 MEM_SAFE_FREE(dists_f);
559 }
560 /* Else, fall back to default obj2vert behavior. */
561 else {
562 get_vert2ob_distance(index_num, positions, indices, new_w, ob, obr);
563 }
564 }
565 else {
566 get_vert2ob_distance(index_num, positions, indices, new_w, ob, obr);
567 }
568 }
569
570 /* Map distances to weights. */
571 do_map(ob,
572 new_w,
573 index_num,
574 wmd->min_dist,
575 wmd->max_dist,
576 wmd->falloff_type,
578 wmd->cmap_curve);
579
580 /* Do masking. */
583 index_num,
584 indices,
585 org_w,
586 new_w,
587 ob,
588 mesh,
589 wmd->mask_constant,
590 wmd->mask_defgrp_name,
591 scene,
592 wmd->mask_texture,
594 wmd->mask_tex_mapping,
595 wmd->mask_tex_map_obj,
598 invert_vgroup_mask);
599
600 /* Update vgroup. Note we never add nor remove vertices from vgroup here. */
602 dvert, defgrp_index, dw, index_num, indices, org_w, false, 0.0f, false, 0.0f, do_normalize);
603
604 /* If weight preview enabled... */
605#if 0 /* XXX Currently done in mod stack :/ */
606 if (do_prev) {
607 DM_update_weight_mcol(ob, dm, 0, org_w, index_num, indices);
608 }
609#endif
610
611 /* Freeing stuff. */
612 MEM_freeN(org_w);
613 MEM_freeN(new_w);
614 MEM_freeN(dw);
616
617#ifdef USE_TIMEIT
618 TIMEIT_END(perf);
619#endif
620
621 mesh->runtime->is_original_bmesh = false;
622
623 /* Return the vgroup-modified mesh. */
624 return mesh;
625}
626
627static void panel_draw(const bContext * /*C*/, Panel *panel)
628{
629 uiLayout *col;
630 uiLayout *layout = panel->layout;
631
632 PointerRNA ob_ptr;
634
635 uiLayoutSetPropSep(layout, true);
636
638 layout, ptr, "vertex_group", &ob_ptr, "vertex_groups", std::nullopt, ICON_GROUP_VERTEX);
639
640 layout->prop(ptr, "target", UI_ITEM_NONE, std::nullopt, ICON_NONE);
641
642 layout->separator();
643
644 layout->prop(ptr, "proximity_mode", UI_ITEM_NONE, std::nullopt, ICON_NONE);
645 if (RNA_enum_get(ptr, "proximity_mode") == MOD_WVG_PROXIMITY_GEOMETRY) {
646 layout->prop(ptr, "proximity_geometry", UI_ITEM_R_EXPAND, IFACE_("Geometry"), ICON_NONE);
647 }
648
649 col = &layout->column(true);
650 col->prop(ptr, "min_dist", UI_ITEM_NONE, std::nullopt, ICON_NONE);
651 col->prop(ptr, "max_dist", UI_ITEM_NONE, std::nullopt, ICON_NONE);
652
653 layout->prop(ptr, "normalize", UI_ITEM_NONE, std::nullopt, ICON_NONE);
654}
655
656static void falloff_panel_draw(const bContext * /*C*/, Panel *panel)
657{
658 uiLayout *row, *sub;
659 uiLayout *layout = panel->layout;
660
661 PointerRNA ob_ptr;
663
664 uiLayoutSetPropSep(layout, true);
665
666 row = &layout->row(true);
667 row->prop(ptr, "falloff_type", UI_ITEM_NONE, IFACE_("Type"), ICON_NONE);
668 sub = &row->row(true);
669 uiLayoutSetPropSep(sub, false);
670 row->prop(ptr, "invert_falloff", UI_ITEM_NONE, "", ICON_ARROW_LEFTRIGHT);
671 if (RNA_enum_get(ptr, "falloff_type") == MOD_WVG_MAPPING_CURVE) {
672 uiTemplateCurveMapping(layout, ptr, "map_curve", 0, false, false, false, false);
673 }
675}
676
677static void influence_panel_draw(const bContext *C, Panel *panel)
678{
679 uiLayout *layout = panel->layout;
680
681 PointerRNA ob_ptr;
683
684 weightvg_ui_common(C, &ob_ptr, ptr, layout);
685}
686
687static void panel_register(ARegionType *region_type)
688{
692 region_type, "falloff", "Falloff", nullptr, falloff_panel_draw, panel_type);
694 region_type, "influence", "Influence", nullptr, influence_panel_draw, panel_type);
695}
696
697static void blend_write(BlendWriter *writer, const ID * /*id_owner*/, const ModifierData *md)
698{
700
702
703 if (wmd->cmap_curve) {
705 }
706}
707
708static void blend_read(BlendDataReader *reader, ModifierData *md)
709{
711
713 if (wmd->cmap_curve) {
715 }
716}
717
719 /*idname*/ "VertexWeightProximity",
720 /*name*/ N_("VertexWeightProximity"),
721 /*struct_name*/ "WeightVGProximityModifierData",
722 /*struct_size*/ sizeof(WeightVGProximityModifierData),
723 /*srna*/ &RNA_VertexWeightProximityModifier,
727 /*icon*/ ICON_MOD_VERTEX_WEIGHT,
728
729 /*copy_data*/ copy_data,
730
731 /*deform_verts*/ nullptr,
732 /*deform_matrices*/ nullptr,
733 /*deform_verts_EM*/ nullptr,
734 /*deform_matrices_EM*/ nullptr,
735 /*modify_mesh*/ modify_mesh,
736 /*modify_geometry_set*/ nullptr,
737
738 /*init_data*/ init_data,
739 /*required_data_mask*/ required_data_mask,
740 /*free_data*/ free_data,
741 /*is_disabled*/ is_disabled,
742 /*update_depsgraph*/ update_depsgraph,
743 /*depends_on_time*/ depends_on_time,
744 /*depends_on_normals*/ nullptr,
745 /*foreach_ID_link*/ foreach_ID_link,
746 /*foreach_tex_link*/ foreach_tex_link,
747 /*free_runtime_data*/ nullptr,
748 /*panel_register*/ panel_register,
749 /*blend_write*/ blend_write,
750 /*blend_read*/ blend_read,
751 /*foreach_cache*/ nullptr,
752};
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.
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:538
@ 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)
@ CD_MDEFORMVERT
#define DNA_struct_default_get(struct_name)
@ 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
@ eModifierType_WeightVGProximity
@ MOD_DISP_MAP_OBJECT
@ MOD_DISP_MAP_GLOBAL
@ MOD_DISP_MAP_UV
@ MOD_WVG_PROXIMITY_OBJECT
@ MOD_WVG_PROXIMITY_GEOMETRY
Object is a sort of wrapper for general info.
static bool is_disabled
Read Guarded memory(de)allocation.
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:271
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)
@ UI_ITEM_R_EXPAND
void uiItemPointerR(uiLayout *layout, PointerRNA *ptr, blender::StringRefNull propname, PointerRNA *searchptr, blender::StringRefNull searchpropname, std::optional< blender::StringRefNull > name, int icon)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
#define UI_ITEM_NONE
BMesh const char void * data
#define sqrtf(x)
static ushort indices[]
uint col
#define CD_MASK_MDEFORMVERT
#define MEM_SAFE_FREE(v)
#define CD_MASK_MTFACE
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
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:404
char name[66]
Definition DNA_ID.h:415
MeshRuntimeHandle * runtime
ListBase vertex_group_names
CustomData vert_data
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 separator(float factor=1.0f, LayoutSeparatorType type=LayoutSeparatorType::Auto)
uiLayout & row(bool align)
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:4227
uint8_t flag
Definition wm_window.cc:139