diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-05-08 18:33:02 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-05-08 18:33:02 +0400 |
commit | 0ee45c9301fa100624479255b3928945ded4042e (patch) | |
tree | c8747edeed599f8d45db9a91dfa241776dffce2b /source | |
parent | f25e7d62b3023812eb594250d22e142c02533482 (diff) |
more optimal method of calculating the normal for the solidify modifier.
When adding 2 unit length vectors, the length can be used to calculate the angle.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenlib/BLI_math_vector.h | 3 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_vector.c | 51 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_polygon.c | 5 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_solidify.c | 10 |
4 files changed, 61 insertions, 8 deletions
diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index 9b2d6a5ead6..17c69d22337 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -182,6 +182,9 @@ void mid_v3_v3v3(float r[3], const float a[3], const float b[3]); void mid_v2_v2v2(float r[2], const float a[2], const float b[2]); void mid_v3_v3v3v3(float v[3], const float v1[3], const float v2[3], const float v3[3]); +void mid_v3_v3v3_angle_weighted(float r[3], const float a[3], const float b[3]); +void mid_v3_angle_weighted(float r[3]); + void flip_v4_v4v4(float v[4], const float v1[4], const float v2[4]); void flip_v3_v3v3(float v[3], const float v1[3], const float v2[3]); void flip_v2_v2v2(float v[2], const float v1[2], const float v2[2]); diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c index 24b5d2af3db..82b295d39b2 100644 --- a/source/blender/blenlib/intern/math_vector.c +++ b/source/blender/blenlib/intern/math_vector.c @@ -130,6 +130,57 @@ void mid_v3_v3v3v3(float v[3], const float v1[3], const float v2[3], const float } /** + * Specialized function for calculating normals. + * fastpath for: + * +* \code{.c} + * add_v3_v3v3(r, a, b); + * normalize_v3(r) + * mul_v3_fl(r, angle_normalized_v3v3(a, b) / M_PI_2); + * \endcode + * + * We can use the length of (a + b) to calculate the angle. + */ +void mid_v3_v3v3_angle_weighted(float r[3], const float a[3], const float b[3]) +{ + /* trick, we want the middle of 2 normals as well as the angle between them + * avoid multiple calculations by */ + float angle; + + /* double check they are normalized */ + BLI_ASSERT_UNIT_V3(a); + BLI_ASSERT_UNIT_V3(b); + + add_v3_v3v3(r, a, b); + angle = ((float)(1.0 / (M_PI / 2.0)) * + /* normally we would only multiply by 2, + * but instead of an angle make this 0-1 factor */ + 2.0f) * + acosf(normalize_v3(r) / 2.0f); + mul_v3_fl(r, angle); +} +/** + * Same as mid_v3_v3v3_angle_weighted + * but \a r is assumed to be accumulated normals, divided by their total. + */ +void mid_v3_angle_weighted(float r[3]) +{ + /* trick, we want the middle of 2 normals as well as the angle between them + * avoid multiple calculations by */ + float angle; + + /* double check they are normalized */ + BLI_assert(len_squared_v3(r) <= 1.0f + FLT_EPSILON); + + angle = ((float)(1.0 / (M_PI / 2.0)) * + /* normally we would only multiply by 2, + * but instead of an angle make this 0-1 factor */ + 2.0f) * + acosf(normalize_v3(r)); + mul_v3_fl(r, angle); +} + +/** * Equivalent to: * interp_v3_v3v3(v, v1, v2, -1.0f); */ diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index 0886edc5b85..a6cad4a6ead 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -534,11 +534,6 @@ void BM_face_normal_update(BMFace *f) normal_tri_v3(f->no, co1, co2, co3); break; } - case 0: - { - zero_v3(f->no); - break; - } default: { bm_face_calc_poly_normal(f); diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index 660e5912388..3148273886b 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -142,15 +142,19 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) if (edge_ref->f2 != -1) { /* We have 2 faces using this edge, calculate the edges normal * using the angle between the 2 faces as a weighting */ +#if 0 add_v3_v3v3(edge_normal, face_nors[edge_ref->f1], face_nors[edge_ref->f2]); normalize_v3(edge_normal); + mul_v3_fl(edge_normal, angle_normalized_v3v3(face_nors[edge_ref->f1], face_nors[edge_ref->f2])); +#else + mid_v3_v3v3_angle_weighted(edge_normal, face_nors[edge_ref->f1], face_nors[edge_ref->f2]); +#endif } else { /* only one face attached to that edge */ - /* an edge without another attached- the weight on this is - * undefined, M_PI/2 is 90d in radians and that seems good enough */ - mul_v3_v3fl(edge_normal, face_nors[edge_ref->f1], M_PI / 2); + /* an edge without another attached- the weight on this is undefined */ + copy_v3_v3(edge_normal, face_nors[edge_ref->f1]); } add_v3_v3(temp_nors[ed_v1], edge_normal); add_v3_v3(temp_nors[ed_v2], edge_normal); |