Blender V5.0
MOD_smooth.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
8
9#include "MEM_guardedalloc.h"
10
11#include "BLI_math_vector.h"
12#include "BLI_utildefines.h"
13
14#include "BLT_translation.hh"
15
16#include "DNA_defaults.h"
17#include "DNA_mesh_types.h"
18#include "DNA_meshdata_types.h"
19#include "DNA_screen_types.h"
20
21#include "BKE_deform.hh"
22
24#include "UI_resources.hh"
25
26#include "RNA_prototypes.hh"
27#include "RNA_types.hh"
28
29#include "MOD_modifiertypes.hh"
30#include "MOD_ui_common.hh"
31#include "MOD_util.hh"
32
41
42static bool is_disabled(const Scene * /*scene*/, ModifierData *md, bool /*use_render_params*/)
43{
45
46 const short flag = smd->flag & (MOD_SMOOTH_X | MOD_SMOOTH_Y | MOD_SMOOTH_Z);
47
48 /* disable if modifier is off for X, Y and Z or if factor is 0 */
49 if (smd->fac == 0.0f || flag == 0) {
50 return true;
51 }
52
53 return false;
54}
55
56static void required_data_mask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
57{
59
60 /* Ask for vertex-groups if we need them. */
61 if (smd->defgrp_name[0] != '\0') {
62 r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
63 }
64}
65
67 SmoothModifierData *smd, Object *ob, Mesh *mesh, float (*vertexCos)[3], int verts_num)
68{
69 if (mesh == nullptr) {
70 return;
71 }
72
73 float (*accumulated_vecs)[3] = MEM_calloc_arrayN<float[3]>(verts_num, __func__);
74 if (!accumulated_vecs) {
75 return;
76 }
77
78 uint *accumulated_vecs_count = MEM_calloc_arrayN<uint>(verts_num, __func__);
79 if (!accumulated_vecs_count) {
80 MEM_freeN(accumulated_vecs);
81 return;
82 }
83
84 const float fac_new = smd->fac;
85 const float fac_orig = 1.0f - fac_new;
86 const bool invert_vgroup = (smd->flag & MOD_SMOOTH_INVERT_VGROUP) != 0;
87
88 const blender::Span<blender::int2> edges = mesh->edges();
89
90 const MDeformVert *dvert;
91 int defgrp_index;
92 MOD_get_vgroup(ob, mesh, smd->defgrp_name, &dvert, &defgrp_index);
93
94 for (int j = 0; j < smd->repeat; j++) {
95 if (j != 0) {
96 memset(accumulated_vecs, 0, sizeof(*accumulated_vecs) * size_t(verts_num));
97 memset(accumulated_vecs_count, 0, sizeof(*accumulated_vecs_count) * size_t(verts_num));
98 }
99
100 for (const int i : edges.index_range()) {
101 float fvec[3];
102 const uint idx1 = edges[i][0];
103 const uint idx2 = edges[i][1];
104
105 mid_v3_v3v3(fvec, vertexCos[idx1], vertexCos[idx2]);
106
107 accumulated_vecs_count[idx1]++;
108 add_v3_v3(accumulated_vecs[idx1], fvec);
109
110 accumulated_vecs_count[idx2]++;
111 add_v3_v3(accumulated_vecs[idx2], fvec);
112 }
113
114 const short flag = smd->flag;
115 if (dvert) {
116 const MDeformVert *dv = dvert;
117 for (int i = 0; i < verts_num; i++, dv++) {
118 float *vco_orig = vertexCos[i];
119 if (accumulated_vecs_count[i] > 0) {
120 mul_v3_fl(accumulated_vecs[i], 1.0f / float(accumulated_vecs_count[i]));
121 }
122 float *vco_new = accumulated_vecs[i];
123
124 const float f_vgroup = invert_vgroup ? (1.0f - BKE_defvert_find_weight(dv, defgrp_index)) :
125 BKE_defvert_find_weight(dv, defgrp_index);
126 if (f_vgroup <= 0.0f) {
127 continue;
128 }
129 const float f_new = f_vgroup * fac_new;
130 const float f_orig = 1.0f - f_new;
131
132 if (flag & MOD_SMOOTH_X) {
133 vco_orig[0] = f_orig * vco_orig[0] + f_new * vco_new[0];
134 }
135 if (flag & MOD_SMOOTH_Y) {
136 vco_orig[1] = f_orig * vco_orig[1] + f_new * vco_new[1];
137 }
138 if (flag & MOD_SMOOTH_Z) {
139 vco_orig[2] = f_orig * vco_orig[2] + f_new * vco_new[2];
140 }
141 }
142 }
143 else { /* no vertex group */
144 for (int i = 0; i < verts_num; i++) {
145 float *vco_orig = vertexCos[i];
146 if (accumulated_vecs_count[i] > 0) {
147 mul_v3_fl(accumulated_vecs[i], 1.0f / float(accumulated_vecs_count[i]));
148 }
149 float *vco_new = accumulated_vecs[i];
150
151 if (flag & MOD_SMOOTH_X) {
152 vco_orig[0] = fac_orig * vco_orig[0] + fac_new * vco_new[0];
153 }
154 if (flag & MOD_SMOOTH_Y) {
155 vco_orig[1] = fac_orig * vco_orig[1] + fac_new * vco_new[1];
156 }
157 if (flag & MOD_SMOOTH_Z) {
158 vco_orig[2] = fac_orig * vco_orig[2] + fac_new * vco_new[2];
159 }
160 }
161 }
162 }
163
164 MEM_freeN(accumulated_vecs);
165 MEM_freeN(accumulated_vecs_count);
166}
167
169 const ModifierEvalContext *ctx,
170 Mesh *mesh,
172{
175 smd, ctx->object, mesh, reinterpret_cast<float (*)[3]>(positions.data()), positions.size());
176}
177
178static void panel_draw(const bContext * /*C*/, Panel *panel)
179{
180 uiLayout *row, *col;
181 uiLayout *layout = panel->layout;
183
184 PointerRNA ob_ptr;
186
187 layout->use_property_split_set(true);
188
189 row = &layout->row(true, IFACE_("Axis"));
190 row->prop(ptr, "use_x", toggles_flag, std::nullopt, ICON_NONE);
191 row->prop(ptr, "use_y", toggles_flag, std::nullopt, ICON_NONE);
192 row->prop(ptr, "use_z", toggles_flag, std::nullopt, ICON_NONE);
193
194 col = &layout->column(false);
195 col->prop(ptr, "factor", UI_ITEM_NONE, std::nullopt, ICON_NONE);
196 col->prop(ptr, "iterations", UI_ITEM_NONE, std::nullopt, ICON_NONE);
197
198 modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", std::nullopt);
199
201}
202
203static void panel_register(ARegionType *region_type)
204{
206}
207
209 /*idname*/ "Smooth",
210 /*name*/ N_("Smooth"),
211 /*struct_name*/ "SmoothModifierData",
212 /*struct_size*/ sizeof(SmoothModifierData),
213 /*srna*/ &RNA_SmoothModifier,
217 /*icon*/ ICON_MOD_SMOOTH,
218
219 /*copy_data*/ BKE_modifier_copydata_generic,
220
221 /*deform_verts*/ deform_verts,
222 /*deform_matrices*/ nullptr,
223 /*deform_verts_EM*/ nullptr,
224 /*deform_matrices_EM*/ nullptr,
225 /*modify_mesh*/ nullptr,
226 /*modify_geometry_set*/ nullptr,
227
228 /*init_data*/ init_data,
229 /*required_data_mask*/ required_data_mask,
230 /*free_data*/ nullptr,
231 /*is_disabled*/ is_disabled,
232 /*update_depsgraph*/ nullptr,
233 /*depends_on_time*/ nullptr,
234 /*depends_on_normals*/ nullptr,
235 /*foreach_ID_link*/ nullptr,
236 /*foreach_tex_link*/ nullptr,
237 /*free_runtime_data*/ nullptr,
238 /*panel_register*/ panel_register,
239 /*blend_write*/ nullptr,
240 /*blend_read*/ nullptr,
241 /*foreach_cache*/ nullptr,
242 /*foreach_working_space_color*/ nullptr,
243};
support for deformation groups and hooks.
float BKE_defvert_find_weight(const MDeformVert *dvert, int defgroup)
Definition deform.cc:774
void BKE_modifier_copydata_generic(const ModifierData *md, ModifierData *md_dst, int flag)
@ eModifierTypeFlag_AcceptsCVs
@ eModifierTypeFlag_SupportsEditmode
@ eModifierTypeFlag_AcceptsMesh
#define BLI_assert(a)
Definition BLI_assert.h:46
MINLINE void mul_v3_fl(float r[3], float f)
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
unsigned int uint
#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
#define DNA_struct_default_get(struct_name)
@ MOD_SMOOTH_Y
@ MOD_SMOOTH_INVERT_VGROUP
@ MOD_SMOOTH_X
@ MOD_SMOOTH_Z
@ eModifierType_Smooth
static bool is_disabled
Read Guarded memory(de)allocation.
static void init_data(ModifierData *md)
static void deform_verts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, blender::MutableSpan< blender::float3 > positions)
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 init_data(ModifierData *md)
Definition MOD_smooth.cc:33
static void deform_verts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, blender::MutableSpan< blender::float3 > positions)
static void panel_register(ARegionType *region_type)
ModifierTypeInfo modifierType_Smooth
static void smoothModifier_do(SmoothModifierData *smd, Object *ob, Mesh *mesh, float(*vertexCos)[3], int verts_num)
Definition MOD_smooth.cc:66
static void panel_draw(const bContext *, Panel *panel)
static void required_data_mask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
Definition MOD_smooth.cc:56
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 MOD_get_vgroup(const Object *ob, const Mesh *mesh, const char *name, const MDeformVert **dvert, int *defgrp_index)
Definition MOD_util.cc:156
@ UI_ITEM_R_TOGGLE
@ UI_ITEM_R_FORCE_BLANK_DECORATE
#define UI_ITEM_NONE
constexpr int64_t size() const
Definition BLI_span.hh:493
constexpr T * data() const
Definition BLI_span.hh:539
constexpr IndexRange index_range() const
Definition BLI_span.hh:401
nullptr float
uint col
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:123
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
struct uiLayout * layout
uiLayout & column(bool align)
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