33#include "RNA_prototypes.hh"
104 const int defgrp_index,
105 const uint verts_num,
106 const bool use_invert_vgroup,
107 float *smooth_weights)
111 for (i = 0; i < verts_num; i++, dvert++) {
114 if (use_invert_vgroup ==
false) {
115 smooth_weights[i] =
w;
118 smooth_weights[i] = 1.0f -
w;
133 for (
const int64_t i : faces.index_range()) {
134 for (
const int edge : corner_edges.
slice(faces[i])) {
135 uint8_t *e_value = &boundaries[edge];
136 *e_value |=
uint8_t((*e_value) + 1);
140 for (
const int64_t i : edges.index_range()) {
141 if (boundaries[i] == 1) {
142 smooth_weights[edges[i][0]] = 0.0f;
143 smooth_weights[edges[i][1]] = 0.0f;
158 const float *smooth_weights,
161 const float lambda = csmd->
lambda;
164 const int edges_num = mesh->edges_num;
167 struct SmoothingData_Simple {
170 SmoothingData_Simple *smooth_data = MEM_cnew_array<SmoothingData_Simple>(
171 size_t(vertexCos.
size()), __func__);
173 float *vertex_edge_count_div =
static_cast<float *
>(
177 for (i = 0; i < edges_num; i++) {
178 vertex_edge_count_div[edges[i][0]] += 1.0f;
179 vertex_edge_count_div[edges[i][1]] += 1.0f;
184 if (smooth_weights ==
nullptr) {
185 for (i = 0; i < vertexCos.
size(); i++) {
186 vertex_edge_count_div[i] = lambda * (vertex_edge_count_div[i] ?
187 (1.0f / vertex_edge_count_div[i]) :
192 for (i = 0; i < vertexCos.
size(); i++) {
193 vertex_edge_count_div[i] = smooth_weights[i] * lambda *
194 (vertex_edge_count_div[i] ? (1.0f / vertex_edge_count_div[i]) :
202 while (iterations--) {
203 for (i = 0; i < edges_num; i++) {
204 SmoothingData_Simple *sd_v1;
205 SmoothingData_Simple *sd_v2;
208 sub_v3_v3v3(edge_dir, vertexCos[edges[i][1]], vertexCos[edges[i][0]]);
210 sd_v1 = &smooth_data[edges[i][0]];
211 sd_v2 = &smooth_data[edges[i][1]];
217 for (i = 0; i < vertexCos.
size(); i++) {
218 SmoothingData_Simple *sd = &smooth_data[i];
219 madd_v3_v3fl(vertexCos[i], sd->delta, vertex_edge_count_div[i]);
221 memset(sd, 0,
sizeof(*sd));
235 const float *smooth_weights,
238 const float eps = FLT_EPSILON * 10.0f;
239 const uint edges_num =
uint(mesh->edges_num);
242 const float lambda = csmd->
lambda * 2.0f;
246 struct SmoothingData_Weighted {
248 float edge_length_sum;
250 SmoothingData_Weighted *smooth_data = MEM_cnew_array<SmoothingData_Weighted>(
251 size_t(vertexCos.
size()), __func__);
254 float *vertex_edge_count =
static_cast<float *
>(
256 for (i = 0; i < edges_num; i++) {
257 vertex_edge_count[edges[i][0]] += 1.0f;
258 vertex_edge_count[edges[i][1]] += 1.0f;
264 while (iterations--) {
265 for (i = 0; i < edges_num; i++) {
266 SmoothingData_Weighted *sd_v1;
267 SmoothingData_Weighted *sd_v2;
271 sub_v3_v3v3(edge_dir, vertexCos[edges[i][1]], vertexCos[edges[i][0]]);
272 edge_dist =
len_v3(edge_dir);
277 sd_v1 = &smooth_data[edges[i][0]];
278 sd_v2 = &smooth_data[edges[i][1]];
283 sd_v1->edge_length_sum += edge_dist;
284 sd_v2->edge_length_sum += edge_dist;
287 if (smooth_weights ==
nullptr) {
289 for (i = 0; i < vertexCos.
size(); i++) {
290 SmoothingData_Weighted *sd = &smooth_data[i];
293 const float div = sd->edge_length_sum * vertex_edge_count[i];
306 memset(sd, 0,
sizeof(*sd));
310 for (i = 0; i < vertexCos.
size(); i++) {
311 SmoothingData_Weighted *sd = &smooth_data[i];
312 const float div = sd->edge_length_sum * vertex_edge_count[i];
314 const float lambda_w = lambda * smooth_weights[i];
318 memset(sd, 0,
sizeof(*sd));
330 const float *smooth_weights,
348 const int defgrp_index,
351 float *smooth_weights =
nullptr;
355 smooth_weights =
static_cast<float *
>(
376 if (smooth_weights) {
386 const float v_dir_next[3],
387 float r_tspace[3][3])
423 float (*r_tangent_spaces)[3][3],
424 float *r_tangent_weights,
425 float *r_tangent_weights_per_vertex)
427 const uint mvert_num =
uint(mesh->verts_num);
431 if (r_tangent_weights_per_vertex !=
nullptr) {
432 copy_vn_fl(r_tangent_weights_per_vertex,
int(mvert_num), 0.0f);
435 for (
const int64_t i : faces.index_range()) {
437 int next_corner =
int(face.start());
438 int term_corner = next_corner +
int(face.size());
439 int prev_corner = term_corner - 2;
440 int curr_corner = term_corner - 1;
443 float v_dir_prev[3], v_dir_next[3];
447 v_dir_prev, vertexCos[corner_verts[prev_corner]], vertexCos[corner_verts[curr_corner]]);
450 for (; next_corner != term_corner;
451 prev_corner = curr_corner, curr_corner = next_corner, next_corner++)
453 float(*ts)[3] = r_tangent_spaces[curr_corner];
458 v_dir_prev, vertexCos[corner_verts[prev_corner]], vertexCos[corner_verts[curr_corner]]);
462 v_dir_next, vertexCos[corner_verts[curr_corner]], vertexCos[corner_verts[next_corner]]);
466 if (r_tangent_weights !=
nullptr) {
467 const float weight =
fabsf(
469 r_tangent_weights[curr_corner] = weight;
470 r_tangent_weights_per_vertex[corner_verts[curr_corner]] += weight;
474 if (r_tangent_weights !=
nullptr) {
475 r_tangent_weights[curr_corner] = 0;
508 const int defgrp_index,
517 float(*tangent_spaces)[3][3] =
static_cast<float(*)[3][3]
>(
531 smooth_verts(csmd, mesh, dvert, defgrp_index, smooth_vertex_coords);
537 for (l_index = 0; l_index < corner_verts.
size(); l_index++) {
538 const int v_index = corner_verts[l_index];
540 sub_v3_v3v3(delta, rest_coords[v_index], smooth_vertex_coords[v_index]);
561 const bool force_delta_cache_update =
599 smooth_verts(csmd, mesh, dvert, defgrp_index, vertexCos);
615 "Bind vertex count mismatch: %u to %u",
630 if (me_numVerts != vertexCos.
size()) {
633 "Original vertex count mismatch: %u to %u",
643 force_delta_cache_update)
659 rest_coords = rest_coords_alloc;
662 const Mesh *object_mesh =
static_cast<const Mesh *
>(ob->
data);
663 rest_coords = object_mesh->vert_positions();
671 calc_deltas(csmd, mesh, dvert, defgrp_index, rest_coords);
688 smooth_verts(csmd, mesh, dvert, defgrp_index, vertexCos);
692 const float scale = csmd->
scale;
694 float(*tangent_spaces)[3][3] =
static_cast<float(*)[3][3]
>(
696 float *tangent_weights =
static_cast<float *
>(
698 float *tangent_weights_per_vertex =
static_cast<float *
>(
702 mesh, vertexCos, tangent_spaces, tangent_weights, tangent_weights_per_vertex);
705 const int v_index = corner_verts[l_index];
706 const float weight = tangent_weights[l_index] / tangent_weights_per_vertex[v_index];
767 "OBJECT_OT_correctivesmooth_bind");
816 N_(
"CorrectiveSmooth"),
817 "CorrectiveSmoothModifierData",
819 &RNA_CorrectiveSmoothModifier,
blender::Array< blender::float3 > BKE_editmesh_vert_coords_alloc_orco(BMEditMesh *em)
void BKE_modifier_copydata_generic(const ModifierData *md, ModifierData *md_dst, int flag)
@ eModifierTypeFlag_SupportsEditmode
@ eModifierTypeFlag_AcceptsMesh
ModifierData * BKE_modifier_get_original(const Object *object, ModifierData *md)
void BKE_modifier_set_error(const Object *ob, ModifierData *md, const char *format,...) ATTR_PRINTF_FORMAT(3
void unit_m3(float m[3][3])
bool invert_m3_m3(float inverse[3][3], const float mat[3][3])
void mul_v3_m3v3(float r[3], const float M[3][3], const float a[3])
void transpose_m3_m3(float R[3][3], const float M[3][3])
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
void copy_vn_fl(float *array_tar, int size, float val)
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE bool compare_v3v3(const float v1[3], const float v2[3], float limit) ATTR_WARN_UNUSED_RESULT
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float normalize_v3(float n[3])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
Platform independent time functions.
Utility defines for timing/benchmarks.
#define TIMEIT_START(var)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
void BLO_read_float3_array(BlendDataReader *reader, int array_size, float **ptr_p)
void BLO_write_float3_array(BlendWriter *writer, uint num, const float *data_ptr)
bool BLO_write_is_undo(BlendWriter *writer)
#define BLO_write_struct_at_address(writer, struct_name, address, data_ptr)
bool DEG_is_active(const Depsgraph *depsgraph)
#define ID_IS_LINKED(_id)
#define ID_IS_OVERRIDE_LIBRARY(_id)
#define CD_MASK_MDEFORMVERT
#define DNA_struct_default_get(struct_name)
@ eModifierFlag_OverrideLibrary_Local
@ MOD_CORRECTIVESMOOTH_ONLY_SMOOTH
@ MOD_CORRECTIVESMOOTH_PIN_BOUNDARY
@ MOD_CORRECTIVESMOOTH_INVERT_VGROUP
@ eModifierType_CorrectiveSmooth
@ MOD_CORRECTIVESMOOTH_RESTSOURCE_ORCO
@ MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND
struct CorrectiveSmoothModifierData CorrectiveSmoothModifierData
@ MOD_CORRECTIVESMOOTH_SMOOTH_LENGTH_WEIGHT
Object is a sort of wrapper for general info.
Read Guarded memory(de)allocation.
static void init_data(ModifierData *md)
static void freeBind(CorrectiveSmoothModifierData *csmd)
static void deform_verts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, blender::MutableSpan< blender::float3 > positions)
static void store_cache_settings(CorrectiveSmoothModifierData *csmd)
static void panel_register(ARegionType *region_type)
static void smooth_iter__length_weight(CorrectiveSmoothModifierData *csmd, Mesh *mesh, blender::MutableSpan< blender::float3 > vertexCos, const float *smooth_weights, uint iterations)
ModifierTypeInfo modifierType_CorrectiveSmooth
static void smooth_iter__simple(CorrectiveSmoothModifierData *csmd, Mesh *mesh, blender::MutableSpan< blender::float3 > vertexCos, const float *smooth_weights, uint iterations)
static void calc_deltas(CorrectiveSmoothModifierData *csmd, Mesh *mesh, const MDeformVert *dvert, const int defgrp_index, const blender::Span< blender::float3 > rest_coords)
static void free_data(ModifierData *md)
static void blend_read(BlendDataReader *reader, ModifierData *md)
static void calc_tangent_spaces(const Mesh *mesh, blender::Span< blender::float3 > vertexCos, float(*r_tangent_spaces)[3][3], float *r_tangent_weights, float *r_tangent_weights_per_vertex)
static void correctivesmooth_modifier_do(ModifierData *md, Depsgraph *depsgraph, Object *ob, Mesh *mesh, blender::MutableSpan< blender::float3 > vertexCos, BMEditMesh *em)
static void panel_draw(const bContext *, Panel *panel)
static bool calc_tangent_loop(const float v_dir_prev[3], const float v_dir_next[3], float r_tspace[3][3])
static void required_data_mask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
static void blend_write(BlendWriter *writer, const ID *id_owner, const ModifierData *md)
static void smooth_verts(CorrectiveSmoothModifierData *csmd, Mesh *mesh, const MDeformVert *dvert, const int defgrp_index, blender::MutableSpan< blender::float3 > vertexCos)
static void mesh_get_weights(const MDeformVert *dvert, const int defgrp_index, const uint verts_num, const bool use_invert_vgroup, float *smooth_weights)
static void smooth_iter(CorrectiveSmoothModifierData *csmd, Mesh *mesh, blender::MutableSpan< blender::float3 > vertexCos, const float *smooth_weights, uint iterations)
static bool cache_settings_equal(CorrectiveSmoothModifierData *csmd)
static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
static void mesh_get_boundaries(Mesh *mesh, float *smooth_weights)
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)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
constexpr int64_t size() const
constexpr T * data() const
constexpr int64_t size_in_bytes() const
constexpr Span slice(int64_t start, int64_t size) const
constexpr int64_t size() const
constexpr IndexRange index_range() const
const Depsgraph * depsgraph
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
void *(* MEM_dupallocN)(const void *vmemh)
static void error(const char *str)
float safe_acos_approx(float x)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
unsigned int bind_coords_num
CorrectiveSmoothDeltaCache delta_cache