Blender V4.3
MOD_weld.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2005 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
11/* TODOs:
12 * - Review weight and vertex color interpolation.;
13 */
14
15#include "MEM_guardedalloc.h"
16
17#include "BLI_utildefines.h"
18
19#include "BLI_array.hh"
20#include "BLI_index_range.hh"
21#include "BLI_span.hh"
22#include "BLI_vector.hh"
23
24#include "BLT_translation.hh"
25
26#include "DNA_defaults.h"
27#include "DNA_mesh_types.h"
28#include "DNA_meshdata_types.h"
29#include "DNA_modifier_types.h"
30#include "DNA_screen_types.h"
31
32#include "BKE_context.hh"
33#include "BKE_customdata.hh"
34#include "BKE_deform.hh"
35#include "BKE_modifier.hh"
36#include "BKE_screen.hh"
37
38#include "UI_interface.hh"
39#include "UI_resources.hh"
40
41#include "RNA_access.hh"
42#include "RNA_prototypes.hh"
43
44#include "DEG_depsgraph.hh"
45
46#include "MOD_modifiertypes.hh"
47#include "MOD_ui_common.hh"
48
50
51using blender::Array;
54using blender::Span;
55using blender::Vector;
56
57static Span<MDeformVert> get_vertex_group(const Mesh &mesh, const int defgrp_index)
58{
59 if (defgrp_index == -1) {
60 return {};
61 }
62 const MDeformVert *vertex_group = static_cast<const MDeformVert *>(
63 CustomData_get_layer(&mesh.vert_data, CD_MDEFORMVERT));
64 if (!vertex_group) {
65 return {};
66 }
67 return {vertex_group, mesh.verts_num};
68}
69
71 const int index,
72 const bool invert,
73 IndexMaskMemory &memory)
74{
75 return IndexMask::from_predicate(
76 vertex_group.index_range(), blender::GrainSize(512), memory, [&](const int i) {
77 return (BKE_defvert_find_weight(&vertex_group[i], index) > 0.0f) != invert;
78 });
79}
80
82 const int index,
83 const bool invert)
84{
85 Array<bool> selection(vertex_group.size());
86 for (const int i : vertex_group.index_range()) {
87 const bool found = BKE_defvert_find_weight(&vertex_group[i], index) > 0.0f;
88 selection[i] = (found != invert);
89 }
90 return selection;
91}
92
93static std::optional<Mesh *> calculate_weld(const Mesh &mesh, const WeldModifierData &wmd)
94{
95 const int defgrp_index = BKE_id_defgroup_name_index(&mesh.id, wmd.defgrp_name);
96 Span<MDeformVert> vertex_group = get_vertex_group(mesh, defgrp_index);
97 const bool invert = (wmd.flag & MOD_WELD_INVERT_VGROUP) != 0;
98
99 if (wmd.mode == MOD_WELD_MODE_ALL) {
100 if (!vertex_group.is_empty()) {
101 IndexMaskMemory memory;
102 const IndexMask selected_indices = selected_indices_from_vertex_group(
103 vertex_group, defgrp_index, invert, memory);
105 mesh, IndexMask(selected_indices), wmd.merge_dist);
106 }
108 mesh, IndexMask(mesh.verts_num), wmd.merge_dist);
109 }
110 if (wmd.mode == MOD_WELD_MODE_CONNECTED) {
111 const bool only_loose_edges = (wmd.flag & MOD_WELD_LOOSE_EDGES) != 0;
112 if (!vertex_group.is_empty()) {
114 vertex_group, defgrp_index, invert);
116 mesh, selection, wmd.merge_dist, only_loose_edges);
117 }
118 Array<bool> selection(mesh.verts_num, true);
120 mesh, selection, wmd.merge_dist, only_loose_edges);
121 }
122
124 return nullptr;
125}
126
127static Mesh *modify_mesh(ModifierData *md, const ModifierEvalContext * /*ctx*/, Mesh *mesh)
128{
129 const WeldModifierData &wmd = reinterpret_cast<WeldModifierData &>(*md);
130
131 std::optional<Mesh *> result = calculate_weld(*mesh, wmd);
132 if (!result) {
133 return mesh;
134 }
135 return *result;
136}
137
138static void init_data(ModifierData *md)
139{
141
143
145}
146
147static void required_data_mask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
148{
150
151 /* Ask for vertex-groups if we need them. */
152 if (wmd->defgrp_name[0] != '\0') {
153 r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
154 }
155}
156
157static void panel_draw(const bContext * /*C*/, Panel *panel)
158{
159 uiLayout *layout = panel->layout;
160
161 PointerRNA ob_ptr;
163 int weld_mode = RNA_enum_get(ptr, "mode");
164
165 uiLayoutSetPropSep(layout, true);
166
167 uiItemR(layout, ptr, "mode", UI_ITEM_NONE, nullptr, ICON_NONE);
168 uiItemR(layout, ptr, "merge_threshold", UI_ITEM_NONE, IFACE_("Distance"), ICON_NONE);
169 if (weld_mode == MOD_WELD_MODE_CONNECTED) {
170 uiItemR(layout, ptr, "loose_edges", UI_ITEM_NONE, nullptr, ICON_NONE);
171 }
172 modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", nullptr);
173
174 modifier_panel_end(layout, ptr);
175}
176
177static void panel_register(ARegionType *region_type)
178{
180}
181
183 /*idname*/ "Weld",
184 /*name*/ N_("Weld"),
185 /*struct_name*/ "WeldModifierData",
186 /*struct_size*/ sizeof(WeldModifierData),
187 /*srna*/ &RNA_WeldModifier,
189 /*flags*/
193 /*icon*/ ICON_AUTOMERGE_OFF, /* TODO: Use correct icon. */
194
195 /*copy_data*/ BKE_modifier_copydata_generic,
196
197 /*deform_verts*/ nullptr,
198 /*deform_matrices*/ nullptr,
199 /*deform_verts_EM*/ nullptr,
200 /*deform_matrices_EM*/ nullptr,
201 /*modify_mesh*/ modify_mesh,
202 /*modify_geometry_set*/ nullptr,
203
204 /*init_data*/ init_data,
205 /*required_data_mask*/ required_data_mask,
206 /*free_data*/ nullptr,
207 /*is_disabled*/ nullptr,
208 /*update_depsgraph*/ nullptr,
209 /*depends_on_time*/ nullptr,
210 /*depends_on_normals*/ nullptr,
211 /*foreach_ID_link*/ nullptr,
212 /*foreach_tex_link*/ nullptr,
213 /*free_runtime_data*/ nullptr,
214 /*panel_register*/ panel_register,
215 /*blend_write*/ nullptr,
216 /*blend_read*/ nullptr,
217 /*foreach_cache*/ nullptr,
218};
CustomData interface, see also DNA_customdata_types.h.
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
support for deformation groups and hooks.
int BKE_id_defgroup_name_index(const ID *id, blender::StringRef name)
Definition deform.cc:543
float BKE_defvert_find_weight(const MDeformVert *dvert, int defgroup)
Definition deform.cc:770
void BKE_modifier_copydata_generic(const ModifierData *md, ModifierData *md_dst, int flag)
ModifierTypeFlag
@ eModifierTypeFlag_AcceptsCVs
@ eModifierTypeFlag_SupportsMapping
@ eModifierTypeFlag_EnableInEditmode
@ eModifierTypeFlag_SupportsEditmode
@ eModifierTypeFlag_AcceptsMesh
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
#define BLI_assert(a)
Definition BLI_assert.h:50
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define IFACE_(msgid)
#define CD_MASK_MDEFORMVERT
@ CD_MDEFORMVERT
#define DNA_struct_default_get(struct_name)
struct WeldModifierData WeldModifierData
@ MOD_WELD_LOOSE_EDGES
@ MOD_WELD_INVERT_VGROUP
@ eModifierType_Weld
@ MOD_WELD_MODE_CONNECTED
@ MOD_WELD_MODE_ALL
Read Guarded memory(de)allocation.
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 modifier_vgroup_ui(uiLayout *layout, PointerRNA *ptr, PointerRNA *ob_ptr, const char *vgroup_prop, const char *invert_vgroup_prop, const char *text)
static void init_data(ModifierData *md)
Definition MOD_weld.cc:138
static void panel_register(ARegionType *region_type)
Definition MOD_weld.cc:177
static IndexMask selected_indices_from_vertex_group(Span< MDeformVert > vertex_group, const int index, const bool invert, IndexMaskMemory &memory)
Definition MOD_weld.cc:70
ModifierTypeInfo modifierType_Weld
Definition MOD_weld.cc:182
static Span< MDeformVert > get_vertex_group(const Mesh &mesh, const int defgrp_index)
Definition MOD_weld.cc:57
static Mesh * modify_mesh(ModifierData *md, const ModifierEvalContext *, Mesh *mesh)
Definition MOD_weld.cc:127
static void panel_draw(const bContext *, Panel *panel)
Definition MOD_weld.cc:157
static void required_data_mask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
Definition MOD_weld.cc:147
static std::optional< Mesh * > calculate_weld(const Mesh &mesh, const WeldModifierData &wmd)
Definition MOD_weld.cc:93
static Array< bool > selection_array_from_vertex_group(Span< MDeformVert > vertex_group, const int index, const bool invert)
Definition MOD_weld.cc:81
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
#define UI_ITEM_NONE
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
constexpr int64_t size() const
Definition BLI_span.hh:253
constexpr IndexRange index_range() const
Definition BLI_span.hh:402
constexpr bool is_empty() const
Definition BLI_span.hh:261
CCL_NAMESPACE_BEGIN ccl_device float invert(float color, float factor)
Definition invert.h:9
std::optional< Mesh * > mesh_merge_by_distance_connected(const Mesh &mesh, Span< bool > selection, float merge_distance, bool only_loose_edges)
std::optional< Mesh * > mesh_merge_by_distance_all(const Mesh &mesh, const IndexMask &selection, float merge_distance)
GPU_SHADER_INTERFACE_INFO(overlay_edit_curve_handle_iface, "vert").flat(Type pos vertex_in(1, Type::UINT, "data") .vertex_out(overlay_edit_curve_handle_iface) .geometry_layout(PrimitiveIn Frequency::GEOMETRY storage_buf(1, Qualifier::READ, "uint", "data[]", Frequency::GEOMETRY) .push_constant(Type Frequency::GEOMETRY selection[]
int RNA_enum_get(PointerRNA *ptr, const char *name)
struct uiLayout * layout
#define N_(msgid)
PointerRNA * ptr
Definition wm_files.cc:4126