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.
This commit is contained in:
@@ -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]);
|
||||
|
@@ -129,6 +129,57 @@ void mid_v3_v3v3v3(float v[3], const float v1[3], const float v2[3], const float
|
||||
v[2] = (v1[2] + v2[2] + v3[2]) / 3.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user