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 int edge : corner_edges.
slice(
faces[
i])) {
134 uint8_t *e_value = &boundaries[edge];
135 *e_value |= uint8_t((*e_value) + 1);
140 if (boundaries[
i] == 1) {
141 smooth_weights[edges[
i][0]] = 0.0f;
142 smooth_weights[edges[
i][1]] = 0.0f;
157 const float *smooth_weights,
160 const float lambda = csmd->
lambda;
166 struct SmoothingData_Simple {
170 size_t(vertexCos.
size()), __func__);
175 for (
i = 0;
i < edges_num;
i++) {
176 vertex_edge_count_div[edges[
i][0]] += 1.0f;
177 vertex_edge_count_div[edges[
i][1]] += 1.0f;
182 if (smooth_weights ==
nullptr) {
183 for (
i = 0;
i < vertexCos.
size();
i++) {
184 vertex_edge_count_div[
i] = lambda * (vertex_edge_count_div[
i] ?
185 (1.0f / vertex_edge_count_div[
i]) :
190 for (
i = 0;
i < vertexCos.
size();
i++) {
191 vertex_edge_count_div[
i] = smooth_weights[
i] * lambda *
192 (vertex_edge_count_div[
i] ? (1.0f / vertex_edge_count_div[
i]) :
200 while (iterations--) {
201 for (
i = 0;
i < edges_num;
i++) {
202 SmoothingData_Simple *sd_v1;
203 SmoothingData_Simple *sd_v2;
206 sub_v3_v3v3(edge_dir, vertexCos[edges[
i][1]], vertexCos[edges[
i][0]]);
208 sd_v1 = &smooth_data[edges[
i][0]];
209 sd_v2 = &smooth_data[edges[
i][1]];
215 for (
i = 0;
i < vertexCos.
size();
i++) {
216 SmoothingData_Simple *sd = &smooth_data[
i];
219 memset(sd, 0,
sizeof(*sd));
233 const float *smooth_weights,
236 const float eps = FLT_EPSILON * 10.0f;
240 const float lambda = csmd->
lambda * 2.0f;
244 struct SmoothingData_Weighted {
246 float edge_length_sum;
249 size_t(vertexCos.
size()), __func__);
253 for (
i = 0;
i < edges_num;
i++) {
254 vertex_edge_count[edges[
i][0]] += 1.0f;
255 vertex_edge_count[edges[
i][1]] += 1.0f;
261 while (iterations--) {
262 for (
i = 0;
i < edges_num;
i++) {
263 SmoothingData_Weighted *sd_v1;
264 SmoothingData_Weighted *sd_v2;
268 sub_v3_v3v3(edge_dir, vertexCos[edges[
i][1]], vertexCos[edges[
i][0]]);
269 edge_dist =
len_v3(edge_dir);
274 sd_v1 = &smooth_data[edges[
i][0]];
275 sd_v2 = &smooth_data[edges[
i][1]];
280 sd_v1->edge_length_sum += edge_dist;
281 sd_v2->edge_length_sum += edge_dist;
284 if (smooth_weights ==
nullptr) {
286 for (
i = 0;
i < vertexCos.
size();
i++) {
287 SmoothingData_Weighted *sd = &smooth_data[
i];
290 const float div = sd->edge_length_sum * vertex_edge_count[
i];
303 memset(sd, 0,
sizeof(*sd));
307 for (
i = 0;
i < vertexCos.
size();
i++) {
308 SmoothingData_Weighted *sd = &smooth_data[
i];
309 const float div = sd->edge_length_sum * vertex_edge_count[
i];
311 const float lambda_w = lambda * smooth_weights[
i];
315 memset(sd, 0,
sizeof(*sd));
327 const float *smooth_weights,
345 const int defgrp_index,
348 float *smooth_weights =
nullptr;
372 if (smooth_weights) {
382 const float v_dir_next[3],
383 float r_tspace[3][3])
419 float (*r_tangent_spaces)[3][3],
420 float *r_tangent_weights,
421 float *r_tangent_weights_per_vertex)
427 if (r_tangent_weights_per_vertex !=
nullptr) {
428 copy_vn_fl(r_tangent_weights_per_vertex,
int(mvert_num), 0.0f);
433 int next_corner = int(face.
start());
434 int term_corner = next_corner + int(face.
size());
435 int prev_corner = term_corner - 2;
436 int curr_corner = term_corner - 1;
439 float v_dir_prev[3], v_dir_next[3];
443 v_dir_prev, vertexCos[corner_verts[prev_corner]], vertexCos[corner_verts[curr_corner]]);
446 for (; next_corner != term_corner;
447 prev_corner = curr_corner, curr_corner = next_corner, next_corner++)
449 float(*ts)[3] = r_tangent_spaces[curr_corner];
454 v_dir_prev, vertexCos[corner_verts[prev_corner]], vertexCos[corner_verts[curr_corner]]);
458 v_dir_next, vertexCos[corner_verts[curr_corner]], vertexCos[corner_verts[next_corner]]);
462 if (r_tangent_weights !=
nullptr) {
463 const float weight =
fabsf(
465 r_tangent_weights[curr_corner] = weight;
466 r_tangent_weights_per_vertex[corner_verts[curr_corner]] += weight;
470 if (r_tangent_weights !=
nullptr) {
471 r_tangent_weights[curr_corner] = 0;
504 const int defgrp_index,
526 smooth_verts(csmd, mesh, dvert, defgrp_index, smooth_vertex_coords);
532 for (l_index = 0; l_index < corner_verts.
size(); l_index++) {
533 const int v_index = corner_verts[l_index];
535 sub_v3_v3v3(delta, rest_coords[v_index], smooth_vertex_coords[v_index]);
556 const bool force_delta_cache_update =
593 smooth_verts(csmd, mesh, dvert, defgrp_index, vertexCos);
609 "Bind vertex count mismatch: %u to %u",
624 if (me_numVerts != vertexCos.
size()) {
627 "Original vertex count mismatch: %u to %u",
637 force_delta_cache_update)
653 rest_coords = rest_coords_alloc;
656 const Mesh *object_mesh =
static_cast<const Mesh *
>(ob->
data);
657 rest_coords = object_mesh->vert_positions();
665 calc_deltas(csmd, mesh, dvert, defgrp_index, rest_coords);
682 smooth_verts(csmd, mesh, dvert, defgrp_index, vertexCos);
686 const float scale = csmd->
scale;
695 mesh, vertexCos, tangent_spaces, tangent_weights, tangent_weights_per_vertex);
698 const int v_index = corner_verts[l_index];
699 const float weight = tangent_weights[l_index] / tangent_weights_per_vertex[v_index];
757 layout->
op(
"OBJECT_OT_correctivesmooth_bind",
808 N_(
"CorrectiveSmooth"),
809 "CorrectiveSmoothModifierData",
811 &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, int64_t array_size, float **ptr_p)
void BLO_write_float3_array(BlendWriter *writer, int64_t 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 DNA_struct_default_get(struct_name)
@ eModifierFlag_OverrideLibrary_Local
@ MOD_CORRECTIVESMOOTH_RESTSOURCE_ORCO
@ MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND
@ eModifierType_CorrectiveSmooth
@ MOD_CORRECTIVESMOOTH_SMOOTH_LENGTH_WEIGHT
@ MOD_CORRECTIVESMOOTH_ONLY_SMOOTH
@ MOD_CORRECTIVESMOOTH_PIN_BOUNDARY
@ MOD_CORRECTIVESMOOTH_INVERT_VGROUP
Object is a sort of wrapper for general info.
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 blend_read(BlendDataReader *, ModifierData *md)
static void panel_draw(const bContext *, Panel *panel)
static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
static void free_data(ModifierData *md)
static void blend_write(BlendWriter *writer, const ID *, const ModifierData *md)
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_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)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
BPy_StructRNA * depsgraph
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
constexpr int64_t size() const
constexpr int64_t start() const
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
#define CD_MASK_MDEFORMVERT
#define ID_IS_LINKED(_id)
#define ID_IS_OVERRIDE_LIBRARY(_id)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_dupallocN(const void *vmemh)
void MEM_freeN(void *vmemh)
static void error(const char *str)
float safe_acos_approx(float x)
VecBase< float, 3 > float3
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
PointerRNA op(wmOperatorType *ot, std::optional< blender::StringRef > name, int icon, wmOperatorCallContext context, eUI_Item_Flag flag)
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)