33#include "RNA_prototypes.hh"
105 const int defgrp_index,
106 const uint verts_num,
107 const bool use_invert_vgroup,
108 float *smooth_weights)
112 for (
i = 0;
i < verts_num;
i++, dvert++) {
115 if (use_invert_vgroup ==
false) {
116 smooth_weights[
i] =
w;
119 smooth_weights[
i] = 1.0f -
w;
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);
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;
167 struct SmoothingData_Simple {
171 size_t(vertexCos.
size()), __func__);
176 for (
i = 0;
i < edges_num;
i++) {
177 vertex_edge_count_div[edges[
i][0]] += 1.0f;
178 vertex_edge_count_div[edges[
i][1]] += 1.0f;
183 if (smooth_weights ==
nullptr) {
184 for (
i = 0;
i < vertexCos.
size();
i++) {
185 vertex_edge_count_div[
i] = lambda * (vertex_edge_count_div[
i] ?
186 (1.0f / vertex_edge_count_div[
i]) :
191 for (
i = 0;
i < vertexCos.
size();
i++) {
192 vertex_edge_count_div[
i] = smooth_weights[
i] * lambda *
193 (vertex_edge_count_div[
i] ? (1.0f / vertex_edge_count_div[
i]) :
201 while (iterations--) {
202 for (
i = 0;
i < edges_num;
i++) {
203 SmoothingData_Simple *sd_v1;
204 SmoothingData_Simple *sd_v2;
207 sub_v3_v3v3(edge_dir, vertexCos[edges[
i][1]], vertexCos[edges[
i][0]]);
209 sd_v1 = &smooth_data[edges[
i][0]];
210 sd_v2 = &smooth_data[edges[
i][1]];
216 for (
i = 0;
i < vertexCos.
size();
i++) {
217 SmoothingData_Simple *sd = &smooth_data[
i];
220 memset(sd, 0,
sizeof(*sd));
234 const float *smooth_weights,
237 const float eps = FLT_EPSILON * 10.0f;
241 const float lambda = csmd->
lambda * 2.0f;
245 struct SmoothingData_Weighted {
247 float edge_length_sum;
250 size_t(vertexCos.
size()), __func__);
254 for (
i = 0;
i < edges_num;
i++) {
255 vertex_edge_count[edges[
i][0]] += 1.0f;
256 vertex_edge_count[edges[
i][1]] += 1.0f;
262 while (iterations--) {
263 for (
i = 0;
i < edges_num;
i++) {
264 SmoothingData_Weighted *sd_v1;
265 SmoothingData_Weighted *sd_v2;
269 sub_v3_v3v3(edge_dir, vertexCos[edges[
i][1]], vertexCos[edges[
i][0]]);
270 edge_dist =
len_v3(edge_dir);
275 sd_v1 = &smooth_data[edges[
i][0]];
276 sd_v2 = &smooth_data[edges[
i][1]];
281 sd_v1->edge_length_sum += edge_dist;
282 sd_v2->edge_length_sum += edge_dist;
285 if (smooth_weights ==
nullptr) {
287 for (
i = 0;
i < vertexCos.
size();
i++) {
288 SmoothingData_Weighted *sd = &smooth_data[
i];
291 const float div = sd->edge_length_sum * vertex_edge_count[
i];
304 memset(sd, 0,
sizeof(*sd));
308 for (
i = 0;
i < vertexCos.
size();
i++) {
309 SmoothingData_Weighted *sd = &smooth_data[
i];
310 const float div = sd->edge_length_sum * vertex_edge_count[
i];
312 const float lambda_w = lambda * smooth_weights[
i];
316 memset(sd, 0,
sizeof(*sd));
328 const float *smooth_weights,
346 const int defgrp_index,
349 float *smooth_weights =
nullptr;
373 if (smooth_weights) {
383 const float v_dir_next[3],
384 float r_tspace[3][3])
420 float (*r_tangent_spaces)[3][3],
421 float *r_tangent_weights,
422 float *r_tangent_weights_per_vertex)
428 if (r_tangent_weights_per_vertex !=
nullptr) {
429 copy_vn_fl(r_tangent_weights_per_vertex,
int(mvert_num), 0.0f);
434 int next_corner = int(face.
start());
435 int term_corner = next_corner + int(face.
size());
436 int prev_corner = term_corner - 2;
437 int curr_corner = term_corner - 1;
440 float v_dir_prev[3], v_dir_next[3];
444 v_dir_prev, vertexCos[corner_verts[prev_corner]], vertexCos[corner_verts[curr_corner]]);
447 for (; next_corner != term_corner;
448 prev_corner = curr_corner, curr_corner = next_corner, next_corner++)
450 float (*ts)[3] = r_tangent_spaces[curr_corner];
455 v_dir_prev, vertexCos[corner_verts[prev_corner]], vertexCos[corner_verts[curr_corner]]);
459 v_dir_next, vertexCos[corner_verts[curr_corner]], vertexCos[corner_verts[next_corner]]);
463 if (r_tangent_weights !=
nullptr) {
464 const float weight =
fabsf(
466 r_tangent_weights[curr_corner] = weight;
467 r_tangent_weights_per_vertex[corner_verts[curr_corner]] += weight;
471 if (r_tangent_weights !=
nullptr) {
472 r_tangent_weights[curr_corner] = 0;
505 const int defgrp_index,
527 smooth_verts(csmd, mesh, dvert, defgrp_index, smooth_vertex_coords);
533 for (l_index = 0; l_index < corner_verts.
size(); l_index++) {
534 const int v_index = corner_verts[l_index];
536 sub_v3_v3v3(delta, rest_coords[v_index], smooth_vertex_coords[v_index]);
558 const bool force_delta_cache_update =
601 smooth_verts(csmd, mesh, dvert, defgrp_index, vertexCos);
617 "Bind vertex count mismatch: %u to %u",
632 if (me_numVerts != vertexCos.
size()) {
635 "Original vertex count mismatch: %u to %u",
645 force_delta_cache_update)
661 rest_coords = rest_coords_alloc;
664 const Mesh *object_mesh =
static_cast<const Mesh *
>(ob->
data);
665 rest_coords = object_mesh->vert_positions();
673 calc_deltas(csmd, mesh, dvert, defgrp_index, rest_coords);
690 smooth_verts(csmd, mesh, dvert, defgrp_index, vertexCos);
694 const float scale = csmd->
scale;
703 mesh, vertexCos, tangent_spaces, tangent_weights, tangent_weights_per_vertex);
706 const int v_index = corner_verts[l_index];
707 const float weight = tangent_weights[l_index] / tangent_weights_per_vertex[v_index];
765 layout->
op(
"OBJECT_OT_correctivesmooth_bind",
801 BLO_write_float3_array(
802 writer, csmd.bind_coords_num, (const float *)csmd.bind_coords);
815 BLO_read_float3_array(reader, int(csmd->bind_coords_num), (float **)&csmd->bind_coords);
816 return blender::implicit_sharing::info_for_mem_free(csmd->bind_coords);
827 N_(
"CorrectiveSmooth"),
828 "CorrectiveSmoothModifierData",
830 &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)
bool BLO_write_is_undo(BlendWriter *writer)
void BLO_write_shared(BlendWriter *writer, const void *data, size_t approximate_size_in_bytes, const blender::ImplicitSharingInfo *sharing_info, blender::FunctionRef< void()> write_fn)
const blender::ImplicitSharingInfo * BLO_read_shared(BlendDataReader *reader, T **data_ptr, blender::FunctionRef< const blender::ImplicitSharingInfo *()> read_fn)
#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_SMOOTH_LENGTH_WEIGHT
@ MOD_CORRECTIVESMOOTH_RESTSOURCE_ORCO
@ MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND
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)
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
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_freeN(void *vmemh)
static void error(const char *str)
void copy_shared_pointer(T *src_ptr, const ImplicitSharingInfo *src_sharing_info, T **r_dst_ptr, const ImplicitSharingInfo **r_dst_sharing_info)
const ImplicitSharingInfo * info_for_mem_free(void *data)
void free_shared_data(T **data, const ImplicitSharingInfo **sharing_info)
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
const ImplicitSharingInfoHandle * bind_coords_sharing_info
PointerRNA op(wmOperatorType *ot, std::optional< blender::StringRef > name, int icon, blender::wm::OpCallContext context, eUI_Item_Flag flag)
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)