35#include "RNA_prototypes.hh"
100 selected_bone_uses_group.
append(bone_for_group_exists);
102 const int64_t total_size = selected_bone_uses_group.
size();
106 r_vertex_mask[
i] =
false;
110 if (dw.def_nr >= total_size) {
113 if (selected_bone_uses_group[dw.def_nr]) {
114 if (dw.weight > threshold) {
115 r_vertex_mask[
i] =
true;
131 r_vertex_mask[
i] = found;
137 uint *r_verts_masked_num)
141 uint verts_masked_num = 0;
143 if (vertex_mask[i_src]) {
144 r_vertex_map[i_src] = verts_masked_num;
148 r_vertex_map[i_src] = -1;
152 *r_verts_masked_num = verts_masked_num;
158 uint *r_edges_masked_num)
163 uint edges_masked_num = 0;
165 const int2 &edge = edges[
i];
168 if (vertex_mask[edge[0]] && vertex_mask[edge[1]]) {
169 r_edge_map[
i] = edges_masked_num;
177 *r_edges_masked_num = edges_masked_num;
183 uint *r_edges_masked_num,
184 uint *r_verts_add_num)
189 uint edges_masked_num = 0;
190 uint verts_add_num = 0;
192 const int2 &edge = edges[
i];
195 bool v1 = vertex_mask[edge[0]];
196 bool v2 = vertex_mask[edge[1]];
198 r_edge_map[
i] = edges_masked_num;
210 edges_masked_num += verts_add_num;
211 *r_edges_masked_num = edges_masked_num;
212 *r_verts_add_num = verts_add_num;
219 uint *r_faces_masked_num,
220 uint *r_loops_masked_num)
224 const Span<int> corner_verts = mesh->corner_verts();
229 uint loops_masked_num = 0;
233 bool all_verts_in_mask =
true;
234 for (
const int vert_i : corner_verts.
slice(face)) {
235 if (!vertex_mask[vert_i]) {
236 all_verts_in_mask =
false;
241 if (all_verts_in_mask) {
244 loops_masked_num += face.
size();
248 *r_faces_masked_num = r_masked_face_indices.
size();
249 *r_loops_masked_num = loops_masked_num;
255 uint loops_masked_num,
258 uint *r_edges_add_num,
259 uint *r_faces_add_num,
260 uint *r_loops_add_num)
266 r_masked_face_indices.
reserve(r_masked_face_indices.
size() + verts_add_num);
267 r_loop_starts.
reserve(r_loop_starts.
size() + verts_add_num);
269 const Span<int> corner_verts = mesh->corner_verts();
271 uint edges_add_num = 0;
272 uint faces_add_num = 0;
273 uint loops_add_num = 0;
279 int dst_totloop = -1;
282 const int vert_i = face_verts_src[j];
283 if (vertex_mask[vert_i]) {
286 else if (start == -1) {
290 if (0 < in_count && in_count < face_src.
size()) {
292 int last_corner_vert = face_verts_src[start];
293 bool v_loop_in_mask_last = vertex_mask[last_corner_vert];
295 const int corner_vert = face_verts_src[(start + 1 + j) % face_src.
size()];
296 const bool v_loop_in_mask = vertex_mask[corner_vert];
297 if (v_loop_in_mask && !v_loop_in_mask_last) {
300 else if (!v_loop_in_mask && v_loop_in_mask_last) {
302 r_masked_face_indices.
append(
i);
303 r_loop_starts.
append(loops_masked_num + loops_add_num);
304 loops_add_num += dst_totloop;
309 else if (v_loop_in_mask && v_loop_in_mask_last) {
313 last_corner_vert = corner_vert;
314 v_loop_in_mask_last = v_loop_in_mask;
319 *r_edges_add_num = edges_add_num;
320 *r_faces_add_num = faces_add_num;
321 *r_loops_add_num = loops_add_num;
330 const int i_dst = vertex_map[i_src];
346 return (threshold - value1) / (value2 - value1);
356 uint edges_masked_num,
362 const Span<int2> src_edges = src_mesh.edges();
366 uint edge_index = edges_masked_num - verts_add_num;
368 if (r_edge_map[i_src] != -1) {
369 int i_dst = r_edge_map[i_src];
373 const int2 &e_src = src_edges[i_src];
374 int2 &e_dst = dst_edges[i_dst];
378 e_dst[0] = vertex_map[e_src[0]];
379 e_dst[1] = vertex_map[e_src[1]];
381 if (r_edge_map[i_src] == -2) {
382 const int i_dst = edge_index++;
383 r_edge_map[i_src] = i_dst;
384 const int2 &e_src = src_edges[i_src];
386 int2 &e_dst = dst_edges[i_dst];
387 if (!vertex_mask[e_src[0]]) {
388 e_dst[0] = vert_index;
393 e_dst[0] = vert_index;
397 dvert, defgrp_index, threshold, e_src[0], e_src[1]);
399 float weights[2] = {1.0f - fac, fac};
419 const Span<int2> src_edges = src_mesh.edges();
425 const int i_dst = edge_map[i_src];
426 if (
ELEM(i_dst, -1, -2)) {
431 dst_edges[i_dst][0] = vertex_map[src_edges[i_src][0]];
432 dst_edges[i_dst][1] = vertex_map[src_edges[i_src][1]];
442 int faces_masked_num)
446 const Span<int> src_corner_verts = src_mesh.corner_verts();
447 const Span<int> src_corner_edges = src_mesh.corner_edges();
451 for (
const int i_dst :
IndexRange(faces_masked_num)) {
452 const int i_src = masked_face_indices[i_dst];
455 dst_face_offsets[i_dst] = new_loop_starts[i_dst];
461 dst_face_offsets[i_dst],
465 dst_corner_verts[new_loop_starts[i_dst] +
i] = vertex_map[src_corner_verts[src_face[
i]]];
466 dst_corner_edges[new_loop_starts[i_dst] +
i] = edge_map[src_corner_edges[src_face[
i]]];
481 int faces_masked_num,
487 const Span<int> src_corner_verts = src_mesh.corner_verts();
488 const Span<int> src_corner_edges = src_mesh.corner_edges();
492 int edge_index = dst_mesh.
edges_num - edges_add_num;
493 int sub_face_index = 0;
495 for (
const int i_dst :
496 IndexRange(faces_masked_num, masked_face_indices.
size() - faces_masked_num))
498 const int i_src = masked_face_indices[i_dst];
499 if (i_src == last_i_src) {
508 const int i_ml_src = src_face.
start();
509 int i_ml_dst = new_loop_starts[i_dst];
512 dst_face_offsets[i_dst] = i_ml_dst;
515 int start = -sub_face_index - 1;
517 const Span<int> face_verts_src = src_corner_verts.
slice(src_face);
518 const Span<int> face_edges_src = src_corner_edges.
slice(src_face);
520 if (!vertex_mask[face_verts_src[j]]) {
538 int last_index = start;
539 bool v_loop_in_mask_last = vertex_mask[face_verts_src[last_index]];
541 const int index = (start + 1 + j) % src_face.
size();
542 const bool v_loop_in_mask = vertex_mask[face_verts_src[index]];
543 if (v_loop_in_mask && !v_loop_in_mask_last) {
546 dvert, defgrp_index, threshold, face_verts_src[last_index], face_verts_src[index]);
547 float weights[2] = {1.0f - fac, fac};
548 int indices[2] = {i_ml_src + last_index, i_ml_src + index};
551 dst_corner_edges[i_ml_dst] = edge_map[face_edges_src[last_index]];
552 dst_corner_verts[i_ml_dst] = dst_edges[dst_corner_edges[i_ml_dst]][0];
557 dst_corner_verts[i_ml_dst] = vertex_map[face_verts_src[index]];
558 dst_corner_edges[i_ml_dst] = edge_map[face_edges_src[index]];
561 else if (!v_loop_in_mask && v_loop_in_mask_last) {
562 BLI_assert(i_ml_dst != dst_face_offsets[i_dst]);
565 dvert, defgrp_index, threshold, face_verts_src[last_index], face_verts_src[index]);
566 float weights[2] = {1.0f - fac, fac};
567 int indices[2] = {i_ml_src + last_index, i_ml_src + index};
570 dst_corner_edges[i_ml_dst] = edge_index;
571 dst_corner_verts[i_ml_dst] = dst_edges[edge_map[face_edges_src[last_index]]][0];
574 int2 &cut_edge = dst_edges[edge_index];
575 cut_edge[0] = dst_corner_verts[dst_face_offsets[i_dst]];
576 cut_edge[1] = dst_corner_verts[i_ml_dst];
584 else if (v_loop_in_mask && v_loop_in_mask_last) {
585 BLI_assert(i_ml_dst != dst_face_offsets[i_dst]);
589 dst_corner_verts[i_ml_dst] = vertex_map[face_verts_src[index]];
590 dst_corner_edges[i_ml_dst] = edge_map[face_edges_src[index]];
594 v_loop_in_mask_last = v_loop_in_mask;
614 if (dverts.is_empty()) {
625 int defgrp_index = -1;
632 if (
ELEM(
nullptr, armature_ob, armature_ob->
pose)) {
638 dverts.data(), mesh, armature_ob, mmd->
threshold, vertex_mask);
645 if (defgrp_index == -1) {
651 dverts.data(), defgrp_index, mmd->
threshold, vertex_mask);
659 uint verts_masked_num;
663 uint edges_masked_num;
665 if (use_interpolation) {
675 uint faces_masked_num;
676 uint loops_masked_num;
684 uint edges_add_num = 0;
685 uint faces_add_num = 0;
686 uint loops_add_num = 0;
687 if (use_interpolation) {
700 verts_masked_num + verts_add_num,
701 edges_masked_num + edges_add_num,
702 faces_masked_num + faces_add_num,
703 loops_masked_num + loops_add_num);
706 if (use_interpolation) {
728 if (use_interpolation) {
773 row = &layout->
row(
true);
775 sub = &row->
row(
true);
Blender kernel action and pose functionality.
bPoseChannel * BKE_pose_channel_find_name(const bPose *pose, const char *name)
CustomData interface, see also DNA_customdata_types.h.
void CustomData_interp(const CustomData *source, CustomData *dest, const int *src_indices, const float *weights, const float *sub_weights, int count, int dest_index)
void CustomData_copy_data(const CustomData *source, CustomData *dest, int source_index, int dest_index, int count)
Mesh * BKE_mesh_new_nomain_from_template(const Mesh *me_src, int verts_num, int edges_num, int faces_num, int corners_num)
void(*)(void *user_data, Object *ob, ID **idpoin, LibraryForeachIDCallbackFlag cb_flag) IDWalkFunc
void BKE_modifier_copydata_generic(const ModifierData *md, ModifierData *md_dst, int flag)
@ eModifierTypeFlag_SupportsMapping
@ eModifierTypeFlag_SupportsEditmode
@ eModifierTypeFlag_AcceptsMesh
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
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)
#define DNA_struct_default_get(struct_name)
Object is a sort of wrapper for general info.
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 panel_draw(const bContext *, Panel *panel)
static void foreach_ID_link(ModifierData *md, Object *ob, IDWalkFunc walk, void *user_data)
static Mesh * modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
static void init_data(ModifierData *md)
static void panel_register(ARegionType *region_type)
static float get_interp_factor_from_vgroup(const MDeformVert *dvert, int defgrp_index, float threshold, uint v1, uint v2)
static void add_interp_verts_copy_edges_to_new_mesh(const Mesh &src_mesh, Mesh &dst_mesh, Span< bool > vertex_mask, Span< int > vertex_map, const MDeformVert *dvert, int defgrp_index, float threshold, uint edges_masked_num, uint verts_add_num, MutableSpan< int > r_edge_map)
static void required_data_mask(ModifierData *, CustomData_MeshMasks *r_cddata_masks)
static void copy_masked_faces_to_new_mesh(const Mesh &src_mesh, Mesh &dst_mesh, Span< int > vertex_map, Span< int > edge_map, Span< int > masked_face_indices, Span< int > new_loop_starts, int faces_masked_num)
static void computed_masked_faces(const Mesh *mesh, Span< bool > vertex_mask, Vector< int > &r_masked_face_indices, Vector< int > &r_loop_starts, uint *r_faces_masked_num, uint *r_loops_masked_num)
static void add_interpolated_faces_to_new_mesh(const Mesh &src_mesh, Mesh &dst_mesh, Span< bool > vertex_mask, Span< int > vertex_map, Span< int > edge_map, const MDeformVert *dvert, int defgrp_index, float threshold, Span< int > masked_face_indices, Span< int > new_loop_starts, int faces_masked_num, int edges_add_num)
static void computed_masked_edges(const Mesh *mesh, Span< bool > vertex_mask, MutableSpan< int > r_edge_map, uint *r_edges_masked_num)
static Mesh * modify_mesh(ModifierData *md, const ModifierEvalContext *, Mesh *mesh)
static void copy_masked_edges_to_new_mesh(const Mesh &src_mesh, Mesh &dst_mesh, Span< int > vertex_map, Span< int > edge_map)
static void compute_masked_verts(Span< bool > vertex_mask, MutableSpan< int > r_vertex_map, uint *r_verts_masked_num)
static void panel_draw(const bContext *, Panel *panel)
static void copy_masked_verts_to_new_mesh(const Mesh &src_mesh, Mesh &dst_mesh, Span< int > vertex_map)
static void compute_interpolated_faces(const Mesh *mesh, Span< bool > vertex_mask, uint verts_add_num, uint loops_masked_num, Vector< int > &r_masked_face_indices, Vector< int > &r_loop_starts, uint *r_edges_add_num, uint *r_faces_add_num, uint *r_loops_add_num)
static void foreach_ID_link(ModifierData *md, Object *ob, IDWalkFunc walk, void *user_data)
static void compute_vertex_mask__armature_mode(const MDeformVert *dvert, Mesh *mesh, Object *armature_ob, float threshold, MutableSpan< bool > r_vertex_mask)
static void compute_vertex_mask__vertex_group_mode(const MDeformVert *dvert, int defgrp_index, float threshold, MutableSpan< bool > r_vertex_mask)
static void update_depsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
ModifierTypeInfo modifierType_Mask
static void computed_masked_edges_smooth(const Mesh *mesh, Span< bool > vertex_mask, MutableSpan< int > r_edge_map, uint *r_edges_masked_num, uint *r_verts_add_num)
void modifier_vgroup_ui(uiLayout *layout, PointerRNA *ptr, PointerRNA *ob_ptr, const StringRefNull vgroup_prop, const std::optional< StringRefNull > invert_vgroup_prop, const std::optional< StringRefNull > text)
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 uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
constexpr int64_t size() const
constexpr int64_t start() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr Span slice(int64_t start, int64_t size) const
constexpr int64_t size() const
constexpr IndexRange index_range() const
void append(const T &value)
void append_unchecked(const T &value)
void reserve(const int64_t min_capacity)
#define CD_MASK_MDEFORMVERT
static void update_depsgraph(tGraphSliderOp *gso)
void invert_booleans(MutableSpan< bool > span)
VecBase< int32_t, 2 > int2
ListBaseWrapperTemplate< ListBase, T > ListBaseWrapper
VecBase< float, 3 > float3
int RNA_enum_get(PointerRNA *ptr, const char *name)
ListBase vertex_group_names
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)