Blender V4.3
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
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] = static_cast<float(*)[3]>(
73 MEM_calloc_arrayN(size_t(verts_num), sizeof(*accumulated_vecs), __func__));
74 if (!accumulated_vecs) {
75 return;
76 }
77
78 uint *accumulated_vecs_count = static_cast<uint *>(
79 MEM_calloc_arrayN(size_t(verts_num), sizeof(*accumulated_vecs_count), __func__));
80 if (!accumulated_vecs_count) {
81 MEM_freeN(accumulated_vecs);
82 return;
83 }
84
85 const float fac_new = smd->fac;
86 const float fac_orig = 1.0f - fac_new;
87 const bool invert_vgroup = (smd->flag & MOD_SMOOTH_INVERT_VGROUP) != 0;
88
89 const blender::Span<blender::int2> edges = mesh->edges();
90
91 const MDeformVert *dvert;
92 int defgrp_index;
93 MOD_get_vgroup(ob, mesh, smd->defgrp_name, &dvert, &defgrp_index);
94
95 for (int j = 0; j < smd->repeat; j++) {
96 if (j != 0) {
97 memset(accumulated_vecs, 0, sizeof(*accumulated_vecs) * size_t(verts_num));
98 memset(accumulated_vecs_count, 0, sizeof(*accumulated_vecs_count) * size_t(verts_num));
99 }
100
101 for (const int i : edges.index_range()) {
102 float fvec[3];
103 const uint idx1 = edges[i][0];
104 const uint idx2 = edges[i][1];
105
106 mid_v3_v3v3(fvec, vertexCos[idx1], vertexCos[idx2]);
107
108 accumulated_vecs_count[idx1]++;
109 add_v3_v3(accumulated_vecs[idx1], fvec);
110
111 accumulated_vecs_count[idx2]++;
112 add_v3_v3(accumulated_vecs[idx2], fvec);
113 }
114
115 const short flag = smd->flag;
116 if (dvert) {
117 const MDeformVert *dv = dvert;
118 for (int i = 0; i < verts_num; i++, dv++) {
119 float *vco_orig = vertexCos[i];
120 if (accumulated_vecs_count[i] > 0) {
121 mul_v3_fl(accumulated_vecs[i], 1.0f / float(accumulated_vecs_count[i]));
122 }
123 float *vco_new = accumulated_vecs[i];
124
125 const float f_vgroup = invert_vgroup ? (1.0f - BKE_defvert_find_weight(dv, defgrp_index)) :
126 BKE_defvert_find_weight(dv, defgrp_index);
127 if (f_vgroup <= 0.0f) {
128 continue;
129 }
130 const float f_new = f_vgroup * fac_new;
131 const float f_orig = 1.0f - f_new;
132
133 if (flag & MOD_SMOOTH_X) {
134 vco_orig[0] = f_orig * vco_orig[0] + f_new * vco_new[0];
135 }
136 if (flag & MOD_SMOOTH_Y) {
137 vco_orig[1] = f_orig * vco_orig[1] + f_new * vco_new[1];
138 }
139 if (flag & MOD_SMOOTH_Z) {
140 vco_orig[2] = f_orig * vco_orig[2] + f_new * vco_new[2];
141 }
142 }
143 }
144 else { /* no vertex group */
145 for (int i = 0; i < verts_num; i++) {
146 float *vco_orig = vertexCos[i];
147 if (accumulated_vecs_count[i] > 0) {
148 mul_v3_fl(accumulated_vecs[i], 1.0f / float(accumulated_vecs_count[i]));
149 }
150 float *vco_new = accumulated_vecs[i];
151
152 if (flag & MOD_SMOOTH_X) {
153 vco_orig[0] = fac_orig * vco_orig[0] + fac_new * vco_new[0];
154 }
155 if (flag & MOD_SMOOTH_Y) {
156 vco_orig[1] = fac_orig * vco_orig[1] + fac_new * vco_new[1];
157 }
158 if (flag & MOD_SMOOTH_Z) {
159 vco_orig[2] = fac_orig * vco_orig[2] + fac_new * vco_new[2];
160 }
161 }
162 }
163 }
164
165 MEM_freeN(accumulated_vecs);
166 MEM_freeN(accumulated_vecs_count);
167}
168
170 const ModifierEvalContext *ctx,
171 Mesh *mesh,
173{
176 smd, ctx->object, mesh, reinterpret_cast<float(*)[3]>(positions.data()), positions.size());
177}
178
179static void panel_draw(const bContext * /*C*/, Panel *panel)
180{
181 uiLayout *row, *col;
182 uiLayout *layout = panel->layout;
184
185 PointerRNA ob_ptr;
187
188 uiLayoutSetPropSep(layout, true);
189
190 row = uiLayoutRowWithHeading(layout, true, IFACE_("Axis"));
191 uiItemR(row, ptr, "use_x", toggles_flag, nullptr, ICON_NONE);
192 uiItemR(row, ptr, "use_y", toggles_flag, nullptr, ICON_NONE);
193 uiItemR(row, ptr, "use_z", toggles_flag, nullptr, ICON_NONE);
194
195 col = uiLayoutColumn(layout, false);
196 uiItemR(col, ptr, "factor", UI_ITEM_NONE, nullptr, ICON_NONE);
197 uiItemR(col, ptr, "iterations", UI_ITEM_NONE, nullptr, ICON_NONE);
198
199 modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", nullptr);
200
201 modifier_panel_end(layout, ptr);
202}
203
204static void panel_register(ARegionType *region_type)
205{
207}
208
210 /*idname*/ "Smooth",
211 /*name*/ N_("Smooth"),
212 /*struct_name*/ "SmoothModifierData",
213 /*struct_size*/ sizeof(SmoothModifierData),
214 /*srna*/ &RNA_SmoothModifier,
218 /*icon*/ ICON_MOD_SMOOTH,
219
220 /*copy_data*/ BKE_modifier_copydata_generic,
221
222 /*deform_verts*/ deform_verts,
223 /*deform_matrices*/ nullptr,
224 /*deform_verts_EM*/ nullptr,
225 /*deform_matrices_EM*/ nullptr,
226 /*modify_mesh*/ nullptr,
227 /*modify_geometry_set*/ nullptr,
228
229 /*init_data*/ init_data,
230 /*required_data_mask*/ required_data_mask,
231 /*free_data*/ nullptr,
232 /*is_disabled*/ is_disabled,
233 /*update_depsgraph*/ nullptr,
234 /*depends_on_time*/ nullptr,
235 /*depends_on_normals*/ nullptr,
236 /*foreach_ID_link*/ nullptr,
237 /*foreach_tex_link*/ nullptr,
238 /*free_runtime_data*/ nullptr,
239 /*panel_register*/ panel_register,
240 /*blend_write*/ nullptr,
241 /*blend_read*/ nullptr,
242 /*foreach_cache*/ nullptr,
243};
support for deformation groups and hooks.
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)
@ eModifierTypeFlag_AcceptsCVs
@ eModifierTypeFlag_SupportsEditmode
@ eModifierTypeFlag_AcceptsMesh
#define BLI_assert(a)
Definition BLI_assert.h:50
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)
struct SmoothModifierData SmoothModifierData
@ eModifierType_Smooth
@ MOD_SMOOTH_Y
@ MOD_SMOOTH_INVERT_VGROUP
@ MOD_SMOOTH_X
@ MOD_SMOOTH_Z
static bool is_disabled
Read Guarded memory(de)allocation.
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_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)
void MOD_get_vgroup(const Object *ob, const Mesh *mesh, const char *name, const MDeformVert **dvert, int *defgrp_index)
Definition MOD_util.cc:159
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
uiLayout * uiLayoutRowWithHeading(uiLayout *layout, bool align, const char *heading)
#define UI_ITEM_NONE
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
eUI_Item_Flag
@ UI_ITEM_R_TOGGLE
@ UI_ITEM_R_FORCE_BLANK_DECORATE
draw_view in_light_buf[] float
uint col
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
Definition mallocn.cc:43
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
struct uiLayout * layout
#define N_(msgid)
PointerRNA * ptr
Definition wm_files.cc:4126
uint8_t flag
Definition wm_window.cc:138