Blender V4.5
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
23#include "UI_interface.hh"
24#include "UI_resources.hh"
25
26#include "RNA_prototypes.hh"
27
28#include "MOD_modifiertypes.hh"
29#include "MOD_ui_common.hh"
30#include "MOD_util.hh"
31
40
41static bool is_disabled(const Scene * /*scene*/, ModifierData *md, bool /*use_render_params*/)
42{
44
45 const short flag = smd->flag & (MOD_SMOOTH_X | MOD_SMOOTH_Y | MOD_SMOOTH_Z);
46
47 /* disable if modifier is off for X, Y and Z or if factor is 0 */
48 if (smd->fac == 0.0f || flag == 0) {
49 return true;
50 }
51
52 return false;
53}
54
55static void required_data_mask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
56{
58
59 /* Ask for vertex-groups if we need them. */
60 if (smd->defgrp_name[0] != '\0') {
61 r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
62 }
63}
64
66 SmoothModifierData *smd, Object *ob, Mesh *mesh, float (*vertexCos)[3], int verts_num)
67{
68 if (mesh == nullptr) {
69 return;
70 }
71
72 float(*accumulated_vecs)[3] = MEM_calloc_arrayN<float[3]>(verts_num, __func__);
73 if (!accumulated_vecs) {
74 return;
75 }
76
77 uint *accumulated_vecs_count = MEM_calloc_arrayN<uint>(verts_num, __func__);
78 if (!accumulated_vecs_count) {
79 MEM_freeN(accumulated_vecs);
80 return;
81 }
82
83 const float fac_new = smd->fac;
84 const float fac_orig = 1.0f - fac_new;
85 const bool invert_vgroup = (smd->flag & MOD_SMOOTH_INVERT_VGROUP) != 0;
86
87 const blender::Span<blender::int2> edges = mesh->edges();
88
89 const MDeformVert *dvert;
90 int defgrp_index;
91 MOD_get_vgroup(ob, mesh, smd->defgrp_name, &dvert, &defgrp_index);
92
93 for (int j = 0; j < smd->repeat; j++) {
94 if (j != 0) {
95 memset(accumulated_vecs, 0, sizeof(*accumulated_vecs) * size_t(verts_num));
96 memset(accumulated_vecs_count, 0, sizeof(*accumulated_vecs_count) * size_t(verts_num));
97 }
98
99 for (const int i : edges.index_range()) {
100 float fvec[3];
101 const uint idx1 = edges[i][0];
102 const uint idx2 = edges[i][1];
103
104 mid_v3_v3v3(fvec, vertexCos[idx1], vertexCos[idx2]);
105
106 accumulated_vecs_count[idx1]++;
107 add_v3_v3(accumulated_vecs[idx1], fvec);
108
109 accumulated_vecs_count[idx2]++;
110 add_v3_v3(accumulated_vecs[idx2], fvec);
111 }
112
113 const short flag = smd->flag;
114 if (dvert) {
115 const MDeformVert *dv = dvert;
116 for (int i = 0; i < verts_num; i++, dv++) {
117 float *vco_orig = vertexCos[i];
118 if (accumulated_vecs_count[i] > 0) {
119 mul_v3_fl(accumulated_vecs[i], 1.0f / float(accumulated_vecs_count[i]));
120 }
121 float *vco_new = accumulated_vecs[i];
122
123 const float f_vgroup = invert_vgroup ? (1.0f - BKE_defvert_find_weight(dv, defgrp_index)) :
124 BKE_defvert_find_weight(dv, defgrp_index);
125 if (f_vgroup <= 0.0f) {
126 continue;
127 }
128 const float f_new = f_vgroup * fac_new;
129 const float f_orig = 1.0f - f_new;
130
131 if (flag & MOD_SMOOTH_X) {
132 vco_orig[0] = f_orig * vco_orig[0] + f_new * vco_new[0];
133 }
134 if (flag & MOD_SMOOTH_Y) {
135 vco_orig[1] = f_orig * vco_orig[1] + f_new * vco_new[1];
136 }
137 if (flag & MOD_SMOOTH_Z) {
138 vco_orig[2] = f_orig * vco_orig[2] + f_new * vco_new[2];
139 }
140 }
141 }
142 else { /* no vertex group */
143 for (int i = 0; i < verts_num; i++) {
144 float *vco_orig = vertexCos[i];
145 if (accumulated_vecs_count[i] > 0) {
146 mul_v3_fl(accumulated_vecs[i], 1.0f / float(accumulated_vecs_count[i]));
147 }
148 float *vco_new = accumulated_vecs[i];
149
150 if (flag & MOD_SMOOTH_X) {
151 vco_orig[0] = fac_orig * vco_orig[0] + fac_new * vco_new[0];
152 }
153 if (flag & MOD_SMOOTH_Y) {
154 vco_orig[1] = fac_orig * vco_orig[1] + fac_new * vco_new[1];
155 }
156 if (flag & MOD_SMOOTH_Z) {
157 vco_orig[2] = fac_orig * vco_orig[2] + fac_new * vco_new[2];
158 }
159 }
160 }
161 }
162
163 MEM_freeN(accumulated_vecs);
164 MEM_freeN(accumulated_vecs_count);
165}
166
168 const ModifierEvalContext *ctx,
169 Mesh *mesh,
171{
174 smd, ctx->object, mesh, reinterpret_cast<float(*)[3]>(positions.data()), positions.size());
175}
176
177static void panel_draw(const bContext * /*C*/, Panel *panel)
178{
179 uiLayout *row, *col;
180 uiLayout *layout = panel->layout;
182
183 PointerRNA ob_ptr;
185
186 uiLayoutSetPropSep(layout, true);
187
188 row = &layout->row(true, IFACE_("Axis"));
189 row->prop(ptr, "use_x", toggles_flag, std::nullopt, ICON_NONE);
190 row->prop(ptr, "use_y", toggles_flag, std::nullopt, ICON_NONE);
191 row->prop(ptr, "use_z", toggles_flag, std::nullopt, ICON_NONE);
192
193 col = &layout->column(false);
194 col->prop(ptr, "factor", UI_ITEM_NONE, std::nullopt, ICON_NONE);
195 col->prop(ptr, "iterations", UI_ITEM_NONE, std::nullopt, ICON_NONE);
196
197 modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", std::nullopt);
198
200}
201
202static void panel_register(ARegionType *region_type)
203{
205}
206
208 /*idname*/ "Smooth",
209 /*name*/ N_("Smooth"),
210 /*struct_name*/ "SmoothModifierData",
211 /*struct_size*/ sizeof(SmoothModifierData),
212 /*srna*/ &RNA_SmoothModifier,
216 /*icon*/ ICON_MOD_SMOOTH,
217
218 /*copy_data*/ BKE_modifier_copydata_generic,
219
220 /*deform_verts*/ deform_verts,
221 /*deform_matrices*/ nullptr,
222 /*deform_verts_EM*/ nullptr,
223 /*deform_matrices_EM*/ nullptr,
224 /*modify_mesh*/ nullptr,
225 /*modify_geometry_set*/ nullptr,
226
227 /*init_data*/ init_data,
228 /*required_data_mask*/ required_data_mask,
229 /*free_data*/ nullptr,
230 /*is_disabled*/ is_disabled,
231 /*update_depsgraph*/ nullptr,
232 /*depends_on_time*/ nullptr,
233 /*depends_on_normals*/ nullptr,
234 /*foreach_ID_link*/ nullptr,
235 /*foreach_tex_link*/ nullptr,
236 /*free_runtime_data*/ nullptr,
237 /*panel_register*/ panel_register,
238 /*blend_write*/ nullptr,
239 /*blend_read*/ nullptr,
240 /*foreach_cache*/ nullptr,
241};
support for deformation groups and hooks.
float BKE_defvert_find_weight(const MDeformVert *dvert, int defgroup)
Definition deform.cc:763
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 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:32
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:65
static void panel_draw(const bContext *, Panel *panel)
static void required_data_mask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
Definition MOD_smooth.cc:55
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
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
#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
uint col
#define CD_MASK_MDEFORMVERT
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 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:4226
uint8_t flag
Definition wm_window.cc:139