Blender  V3.3
MOD_weld.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2005 Blender Foundation. All rights reserved. */
3 
10 /* TODOs:
11  * - Review weight and vertex color interpolation.;
12  */
13 
14 #include "MEM_guardedalloc.h"
15 
16 #include "BLI_utildefines.h"
17 
18 #include "BLI_array.hh"
19 #include "BLI_index_range.hh"
20 #include "BLI_span.hh"
21 #include "BLI_vector.hh"
22 
23 #include "BLT_translation.h"
24 
25 #include "DNA_defaults.h"
26 #include "DNA_mesh_types.h"
27 #include "DNA_meshdata_types.h"
28 #include "DNA_modifier_types.h"
29 #include "DNA_screen_types.h"
30 
31 #ifdef USE_BVHTREEKDOP
32 # include "BKE_bvhutils.h"
33 #endif
34 
35 #include "BKE_context.h"
36 #include "BKE_deform.h"
37 #include "BKE_modifier.h"
38 #include "BKE_screen.h"
39 
40 #include "UI_interface.h"
41 #include "UI_resources.h"
42 
43 #include "RNA_access.h"
44 #include "RNA_prototypes.h"
45 
46 #include "DEG_depsgraph.h"
47 
48 #include "MOD_modifiertypes.h"
49 #include "MOD_ui_common.h"
50 
52 
53 using blender::Array;
54 using blender::IndexMask;
55 using blender::Span;
56 using blender::Vector;
57 
58 static Span<MDeformVert> get_vertex_group(const Mesh &mesh, const int defgrp_index)
59 {
60  if (defgrp_index == -1) {
61  return {};
62  }
63  const MDeformVert *vertex_group = static_cast<const MDeformVert *>(
65  if (!vertex_group) {
66  return {};
67  }
68  return {vertex_group, mesh.totvert};
69 }
70 
72  const int index,
73  const bool invert)
74 {
75  Vector<int64_t> selected_indices;
76  for (const int i : vertex_group.index_range()) {
77  const bool found = BKE_defvert_find_weight(&vertex_group[i], index) > 0.0f;
78  if (found != invert) {
79  selected_indices.append(i);
80  }
81  }
82  return selected_indices;
83 }
84 
86  const int index,
87  const bool invert)
88 {
89  Array<bool> selection(vertex_group.size());
90  for (const int i : vertex_group.index_range()) {
91  const bool found = BKE_defvert_find_weight(&vertex_group[i], index) > 0.0f;
92  selection[i] = (found != invert);
93  }
94  return selection;
95 }
96 
97 static std::optional<Mesh *> calculate_weld(const Mesh &mesh, const WeldModifierData &wmd)
98 {
99  const int defgrp_index = BKE_id_defgroup_name_index(&mesh.id, wmd.defgrp_name);
100  Span<MDeformVert> vertex_group = get_vertex_group(mesh, defgrp_index);
101  const bool invert = (wmd.flag & MOD_WELD_INVERT_VGROUP) != 0;
102 
103  if (wmd.mode == MOD_WELD_MODE_ALL) {
104  if (!vertex_group.is_empty()) {
106  vertex_group, defgrp_index, invert);
108  mesh, IndexMask(selected_indices), wmd.merge_dist);
109  }
112  }
113  if (wmd.mode == MOD_WELD_MODE_CONNECTED) {
114  const bool only_loose_edges = (wmd.flag & MOD_WELD_LOOSE_EDGES) != 0;
115  if (!vertex_group.is_empty()) {
117  vertex_group, defgrp_index, invert);
119  mesh, selection, wmd.merge_dist, only_loose_edges);
120  }
121  Array<bool> selection(mesh.totvert, true);
123  mesh, selection, wmd.merge_dist, only_loose_edges);
124  }
125 
127  return nullptr;
128 }
129 
131 {
132  const WeldModifierData &wmd = reinterpret_cast<WeldModifierData &>(*md);
133 
134  std::optional<Mesh *> result = calculate_weld(*mesh, wmd);
135  if (!result) {
136  return mesh;
137  }
138  return *result;
139 }
140 
141 static void initData(ModifierData *md)
142 {
143  WeldModifierData *wmd = (WeldModifierData *)md;
144 
145  BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(wmd, modifier));
146 
148 }
149 
150 static void requiredDataMask(Object *UNUSED(ob),
151  ModifierData *md,
152  CustomData_MeshMasks *r_cddata_masks)
153 {
154  WeldModifierData *wmd = (WeldModifierData *)md;
155 
156  /* Ask for vertexgroups if we need them. */
157  if (wmd->defgrp_name[0] != '\0') {
158  r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
159  }
160 }
161 
162 static void panel_draw(const bContext *UNUSED(C), Panel *panel)
163 {
164  uiLayout *layout = panel->layout;
165 
166  PointerRNA ob_ptr;
168  int weld_mode = RNA_enum_get(ptr, "mode");
169 
170  uiLayoutSetPropSep(layout, true);
171 
172  uiItemR(layout, ptr, "mode", 0, nullptr, ICON_NONE);
173  uiItemR(layout, ptr, "merge_threshold", 0, IFACE_("Distance"), ICON_NONE);
174  if (weld_mode == MOD_WELD_MODE_CONNECTED) {
175  uiItemR(layout, ptr, "loose_edges", 0, nullptr, ICON_NONE);
176  }
177  modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", nullptr);
178 
179  modifier_panel_end(layout, ptr);
180 }
181 
182 static void panelRegister(ARegionType *region_type)
183 {
185 }
186 
188  /* name */ N_("Weld"),
189  /* structName */ "WeldModifierData",
190  /* structSize */ sizeof(WeldModifierData),
191  /* srna */ &RNA_WeldModifier,
193  /* flags */
197  /* icon */ ICON_AUTOMERGE_OFF, /* TODO: Use correct icon. */
198 
199  /* copyData */ BKE_modifier_copydata_generic,
200 
201  /* deformVerts */ nullptr,
202  /* deformMatrices */ nullptr,
203  /* deformVertsEM */ nullptr,
204  /* deformMatricesEM */ nullptr,
205  /* modifyMesh */ modifyMesh,
206  /* modifyGeometrySet */ nullptr,
207 
208  /* initData */ initData,
209  /* requiredDataMask */ requiredDataMask,
210  /* freeData */ nullptr,
211  /* isDisabled */ nullptr,
212  /* updateDepsgraph */ nullptr,
213  /* dependsOnTime */ nullptr,
214  /* dependsOnNormals */ nullptr,
215  /* foreachIDLink */ nullptr,
216  /* foreachTexLink */ nullptr,
217  /* freeRuntimeData */ nullptr,
218  /* panelRegister */ panelRegister,
219  /* blendWrite */ nullptr,
220  /* blendRead */ nullptr,
221 };
void * CustomData_get_layer(const struct CustomData *data, int type)
support for deformation groups and hooks.
float BKE_defvert_find_weight(const struct MDeformVert *dvert, int defgroup)
Definition: deform.c:704
int BKE_id_defgroup_name_index(const struct ID *id, const char *name)
ModifierTypeFlag
Definition: BKE_modifier.h:65
@ eModifierTypeFlag_AcceptsCVs
Definition: BKE_modifier.h:67
@ eModifierTypeFlag_SupportsMapping
Definition: BKE_modifier.h:68
@ eModifierTypeFlag_EnableInEditmode
Definition: BKE_modifier.h:78
@ eModifierTypeFlag_SupportsEditmode
Definition: BKE_modifier.h:69
@ eModifierTypeFlag_AcceptsMesh
Definition: BKE_modifier.h:66
void BKE_modifier_copydata_generic(const struct ModifierData *md, struct ModifierData *md_dst, int flag)
@ eModifierTypeType_Constructive
Definition: BKE_modifier.h:47
#define BLI_assert_unreachable()
Definition: BLI_assert.h:93
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define UNUSED(x)
#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)
Definition: DNA_defaults.h:29
struct WeldModifierData WeldModifierData
@ eModifierType_Weld
@ MOD_WELD_MODE_CONNECTED
@ MOD_WELD_MODE_ALL
@ MOD_WELD_LOOSE_EDGES
@ MOD_WELD_INVERT_VGROUP
Read Guarded memory(de)allocation.
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
void modifier_panel_end(uiLayout *layout, PointerRNA *ptr)
Definition: MOD_ui_common.c:91
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
void modifier_vgroup_ui(uiLayout *layout, PointerRNA *ptr, PointerRNA *ob_ptr, const char *vgroup_prop, const char *invert_vgroup_prop, const char *text)
static Span< MDeformVert > get_vertex_group(const Mesh &mesh, const int defgrp_index)
Definition: MOD_weld.cc:58
ModifierTypeInfo modifierType_Weld
Definition: MOD_weld.cc:187
static std::optional< Mesh * > calculate_weld(const Mesh &mesh, const WeldModifierData &wmd)
Definition: MOD_weld.cc:97
static Vector< int64_t > selected_indices_from_vertex_group(Span< MDeformVert > vertex_group, const int index, const bool invert)
Definition: MOD_weld.cc:71
static Array< bool > selection_array_from_vertex_group(Span< MDeformVert > vertex_group, const int index, const bool invert)
Definition: MOD_weld.cc:85
static Mesh * modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx), Mesh *mesh)
Definition: MOD_weld.cc:130
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
Definition: MOD_weld.cc:162
static void initData(ModifierData *md)
Definition: MOD_weld.cc:141
static void panelRegister(ARegionType *region_type)
Definition: MOD_weld.cc:182
static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
Definition: MOD_weld.cc:150
#define C
Definition: RandGen.cpp:25
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
constexpr int64_t size() const
Definition: BLI_span.hh:240
constexpr IndexRange index_range() const
Definition: BLI_span.hh:401
constexpr bool is_empty() const
Definition: BLI_span.hh:248
void append(const T &value)
Definition: BLI_vector.hh:433
CCL_NAMESPACE_BEGIN ccl_device float invert(float color, float factor)
Definition: invert.h:8
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, IndexMask selection, float merge_distance)
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5004
CustomData vdata
int totvert
struct uiLayout * layout
#define N_(msgid)
PointerRNA * ptr
Definition: wm_files.c:3480