37 #include "RNA_prototypes.h"
55 #define USE_TANGENT_CALC_INLINE
113 const int defgrp_index,
114 const uint verts_num,
115 const bool use_invert_vgroup,
116 float *smooth_weights)
120 for (i = 0; i < verts_num; i++, dvert++) {
123 if (use_invert_vgroup ==
false) {
124 smooth_weights[i] =
w;
127 smooth_weights[i] = 1.0f -
w;
137 uint mpoly_num, medge_num, i;
146 for (i = 0; i < mpoly_num; i++) {
147 const MPoly *p = &mpoly[i];
148 const int totloop = p->
totloop;
150 for (j = 0; j < totloop; j++) {
155 for (i = 0; i < medge_num; i++) {
156 if (boundaries[i] == 1) {
157 smooth_weights[medge[i].
v1] = 0.0f;
158 smooth_weights[medge[i].v2] = 0.0f;
172 float (*vertexCos)[3],
174 const float *smooth_weights,
177 const float lambda = csmd->
lambda;
182 float *vertex_edge_count_div;
184 struct SmoothingData_Simple {
191 for (i = 0; i < edges_num; i++) {
192 vertex_edge_count_div[edges[i].v1] += 1.0f;
193 vertex_edge_count_div[edges[i].v2] += 1.0f;
198 if (smooth_weights ==
NULL) {
199 for (i = 0; i < verts_num; i++) {
200 vertex_edge_count_div[i] = lambda * (vertex_edge_count_div[i] ?
201 (1.0f / vertex_edge_count_div[i]) :
206 for (i = 0; i < verts_num; i++) {
207 vertex_edge_count_div[i] = smooth_weights[i] * lambda *
208 (vertex_edge_count_div[i] ? (1.0f / vertex_edge_count_div[i]) :
216 while (iterations--) {
217 for (i = 0; i < edges_num; i++) {
218 struct SmoothingData_Simple *sd_v1;
219 struct SmoothingData_Simple *sd_v2;
224 sd_v1 = &smooth_data[edges[i].v1];
225 sd_v2 = &smooth_data[edges[i].v2];
231 for (i = 0; i < verts_num; i++) {
232 struct SmoothingData_Simple *sd = &smooth_data[i];
233 madd_v3_v3fl(vertexCos[i], sd->delta, vertex_edge_count_div[i]);
235 memset(sd, 0,
sizeof(*sd));
248 float (*vertexCos)[3],
250 const float *smooth_weights,
253 const float eps = FLT_EPSILON * 10.0f;
257 const float lambda = csmd->
lambda * 2.0f;
259 float *vertex_edge_count;
262 struct SmoothingData_Weighted {
264 float edge_length_sum;
269 for (i = 0; i < edges_num; i++) {
270 vertex_edge_count[edges[i].v1] += 1.0f;
271 vertex_edge_count[edges[i].v2] += 1.0f;
277 while (iterations--) {
278 for (i = 0; i < edges_num; i++) {
279 struct SmoothingData_Weighted *sd_v1;
280 struct SmoothingData_Weighted *sd_v2;
285 edge_dist =
len_v3(edge_dir);
290 sd_v1 = &smooth_data[edges[i].v1];
291 sd_v2 = &smooth_data[edges[i].v2];
296 sd_v1->edge_length_sum += edge_dist;
297 sd_v2->edge_length_sum += edge_dist;
300 if (smooth_weights ==
NULL) {
302 for (i = 0; i < verts_num; i++) {
303 struct SmoothingData_Weighted *sd = &smooth_data[i];
306 const float div = sd->edge_length_sum * vertex_edge_count[i];
319 memset(sd, 0,
sizeof(*sd));
323 for (i = 0; i < verts_num; i++) {
324 struct SmoothingData_Weighted *sd = &smooth_data[i];
325 const float div = sd->edge_length_sum * vertex_edge_count[i];
327 const float lambda_w = lambda * smooth_weights[i];
331 memset(sd, 0,
sizeof(*sd));
342 float (*vertexCos)[3],
344 const float *smooth_weights,
362 const int defgrp_index,
363 float (*vertexCos)[3],
366 float *smooth_weights =
NULL;
380 copy_vn_fl(smooth_weights, (
int)verts_num, 1.0f);
390 if (smooth_weights) {
400 float v_tan_a[3], v_tan_b[3];
401 float t_vec_a[3], t_vec_b[3];
429 const float v_dir_next[3],
430 float r_tspace[3][3])
434 if (
compare_v3v3(v_dir_prev, v_dir_next, FLT_EPSILON * 10.0f) ==
false) {
453 const uint mvert_num = (
uint)dm->getNumVerts(dm);
459 for (i = 0; i < mpoly_num; i++) {
460 const MPoly *mp = &mpoly[i];
463 const MLoop *l_prev = l_term - 2;
464 const MLoop *l_curr = l_term - 1;
467 float v_dir_prev[3], v_dir_next[3];
470 sub_v3_v3v3(v_dir_prev, vertexCos[l_prev->
v], vertexCos[l_curr->
v]);
473 for (; l_next != l_term; l_prev = l_curr, l_curr = l_next, l_next++) {
474 float(*ts)[3] = r_tangent_spaces[l_curr->
v];
478 sub_v3_v3v3(v_dir_prev, vertexCos[l_prev->
v], vertexCos[l_curr->
v]);
481 sub_v3_v3v3(v_dir_next, vertexCos[l_curr->
v], vertexCos[l_next->
v]);
491 #ifndef USE_TANGENT_CALC_INLINE
492 for (i = 0; i < mvert_num; i++) {
493 float(*ts)[3] = r_tangent_spaces[i];
523 const int defgrp_index,
524 const float (*rest_coords)[3],
528 float(*tangent_spaces)[3][3];
543 smooth_verts(csmd,
mesh, dvert, defgrp_index, smooth_vertex_coords, verts_num);
547 for (i = 0; i < verts_num; i++) {
548 float imat[3][3], delta[3];
550 #ifdef USE_TANGENT_CALC_INLINE
554 sub_v3_v3v3(delta, rest_coords[i], smooth_vertex_coords[i]);
569 float (*vertexCos)[3],
575 const bool force_delta_cache_update =
621 ob, md,
"Bind vertex count mismatch: %u to %u", csmd->
bind_coords_num, verts_num);
634 if (me_numVerts != verts_num) {
636 ob, md,
"Original vertex count mismatch: %u to %u", me_numVerts, verts_num);
644 force_delta_cache_update) {
645 const float(*rest_coords)[3];
646 bool is_rest_coords_alloc =
false;
661 is_rest_coords_alloc =
true;
673 if (is_rest_coords_alloc) {
693 float(*tangent_spaces)[3][3];
694 const float scale = csmd->
scale;
700 for (i = 0; i < verts_num; i++) {
703 #ifdef USE_TANGENT_CALC_INLINE
729 float (*vertexCos)[3],
747 float (*vertexCos)[3],
754 if (mesh_src !=
NULL) {
790 "OBJECT_OT_correctivesmooth_bind");
838 N_(
"CorrectiveSmooth"),
839 "CorrectiveSmoothModifierData",
841 &RNA_CorrectiveSmoothModifier,
typedef float(TangentPoint)[2]
float(* BKE_editmesh_vert_coords_alloc_orco(BMEditMesh *em, int *r_vert_len))[3]
void BKE_id_free(struct Main *bmain, void *idv)
float(* BKE_mesh_vert_coords_alloc(const struct Mesh *mesh, int *r_vert_len))[3]
void BKE_mesh_wrapper_ensure_mdata(struct Mesh *me)
struct ModifierData * BKE_modifier_get_original(const struct Object *object, struct ModifierData *md)
@ eModifierTypeFlag_SupportsEditmode
@ eModifierTypeFlag_AcceptsMesh
void BKE_modifier_copydata_generic(const struct ModifierData *md, struct ModifierData *md_dst, int flag)
@ eModifierTypeType_OnlyDeform
void BKE_modifier_set_error(const struct Object *ob, struct ModifierData *md, const char *format,...) ATTR_PRINTF_FORMAT(3
bool invert_m3_m3(float R[3][3], const float A[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 bool compare_v3v3(const float a[3], const float b[3], float limit) ATTR_WARN_UNUSED_RESULT
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE float normalize_v3(float r[3])
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 add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
Strict compiler flags for areas of code we want to ensure don't do conversions without us knowing abo...
#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)
struct Depsgraph Depsgraph
bool DEG_is_active(const struct 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_RESTSOURCE_ORCO
@ MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND
@ MOD_CORRECTIVESMOOTH_SMOOTH_LENGTH_WEIGHT
@ MOD_CORRECTIVESMOOTH_ONLY_SMOOTH
@ MOD_CORRECTIVESMOOTH_PIN_BOUNDARY
@ MOD_CORRECTIVESMOOTH_INVERT_VGROUP
@ eModifierType_CorrectiveSmooth
struct CorrectiveSmoothModifierData CorrectiveSmoothModifierData
Object is a sort of wrapper for general info.
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
Read Guarded memory(de)allocation.
static void freeBind(CorrectiveSmoothModifierData *csmd)
static void smooth_iter__length_weight(CorrectiveSmoothModifierData *csmd, Mesh *mesh, float(*vertexCos)[3], uint verts_num, const float *smooth_weights, uint iterations)
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
static void store_cache_settings(CorrectiveSmoothModifierData *csmd)
static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, float(*vertexCos)[3], int verts_num)
static void smooth_iter(CorrectiveSmoothModifierData *csmd, Mesh *mesh, float(*vertexCos)[3], uint verts_num, const float *smooth_weights, uint iterations)
static void deformVertsEM(ModifierData *md, const ModifierEvalContext *ctx, struct BMEditMesh *editData, Mesh *mesh, float(*vertexCos)[3], int verts_num)
static void correctivesmooth_modifier_do(ModifierData *md, Depsgraph *depsgraph, Object *ob, Mesh *mesh, float(*vertexCos)[3], uint verts_num, struct BMEditMesh *em)
#define USE_TANGENT_CALC_INLINE
ModifierTypeInfo modifierType_CorrectiveSmooth
static void blendRead(BlendDataReader *reader, ModifierData *md)
static void smooth_iter__simple(CorrectiveSmoothModifierData *csmd, Mesh *mesh, float(*vertexCos)[3], uint verts_num, const float *smooth_weights, uint iterations)
static void calc_tangent_loop_accum(const float v_dir_prev[3], const float v_dir_next[3], float r_tspace[3][3])
static void mesh_get_weights(MDeformVert *dvert, const int defgrp_index, const uint verts_num, const bool use_invert_vgroup, float *smooth_weights)
static void smooth_verts(CorrectiveSmoothModifierData *csmd, Mesh *mesh, MDeformVert *dvert, const int defgrp_index, float(*vertexCos)[3], uint verts_num)
static void calc_deltas(CorrectiveSmoothModifierData *csmd, Mesh *mesh, MDeformVert *dvert, const int defgrp_index, const float(*rest_coords)[3], uint verts_num)
static void calc_tangent_ortho(float ts[3][3])
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
static void initData(ModifierData *md)
static void panelRegister(ARegionType *region_type)
static bool cache_settings_equal(CorrectiveSmoothModifierData *csmd)
static void calc_tangent_spaces(Mesh *mesh, float(*vertexCos)[3], float(*r_tangent_spaces)[3][3])
static void mesh_get_boundaries(Mesh *mesh, float *smooth_weights)
static void freeData(ModifierData *md)
static void blendWrite(BlendWriter *writer, const ID *id_owner, const ModifierData *md)
static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
void modifier_panel_end(uiLayout *layout, PointerRNA *ptr)
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
void modifier_vgroup_ui(uiLayout *layout, PointerRNA *ptr, PointerRNA *ob_ptr, const char *vgroup_prop, const char *invert_vgroup_prop, const char *text)
Mesh * MOD_deform_mesh_eval_get(Object *ob, struct BMEditMesh *em, Mesh *mesh, const float(*vertexCos)[3], const int verts_num, const bool use_normals, const bool use_orco)
void MOD_get_vgroup(Object *ob, struct Mesh *mesh, const char *name, MDeformVert **dvert, int *defgrp_index)
Platform independent time functions.
Utility defines for timing/benchmarks.
#define TIMEIT_START(var)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
const Depsgraph * depsgraph
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
void(* MEM_freeN)(void *vmemh)
void *(* MEM_dupallocN)(const void *vmemh)
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
static void error(const char *str)
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
struct Depsgraph * depsgraph