Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2013-09-06 09:44:18 +0400
committerCampbell Barton <ideasman42@gmail.com>2013-09-06 09:44:18 +0400
commit6439ae9d51dfe3a77ff778e35cf83909bbc93acc (patch)
treeb62a6cebe2dc88b4db4b1fe50924b5039c23dacf /source/blender/blenlib
parente045e324a47fcaf5c5fd13bbb165cabe9c1051bf (diff)
fix for barycentric_weights_v2_quad() divide by zero when the location we're checking the weight of touches one of the weighting coords exactly.
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r--source/blender/blenlib/intern/math_geom.c50
1 files changed, 29 insertions, 21 deletions
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 68f246e3982..cf1377f6627 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -2200,8 +2200,6 @@ void barycentric_weights_v2_quad(const float v1[2], const float v2[2], const flo
((_area = cross_v2v2(dirs[i1], dirs[i2])) != 0.0f ? \
fabsf(((lens[i1] * lens[i2]) - dot_v2v2(dirs[i1], dirs[i2])) / _area) : 0.0f)
- float wtot, area;
-
const float dirs[4][2] = {
{v1[0] - co[0], v1[1] - co[1]},
{v2[0] - co[0], v2[1] - co[1]},
@@ -2216,20 +2214,29 @@ void barycentric_weights_v2_quad(const float v1[2], const float v2[2], const flo
len_v2(dirs[3]),
};
- /* variable 'area' is just for storage,
- * the order its initialized doesn't matter */
+ /* avoid divide by zero */
+ if (UNLIKELY(lens[0] < FLT_EPSILON)) { w[0] = 1.0f; w[1] = w[2] = w[3] = 0.0f; }
+ else if (UNLIKELY(lens[1] < FLT_EPSILON)) { w[1] = 1.0f; w[0] = w[2] = w[3] = 0.0f; }
+ else if (UNLIKELY(lens[2] < FLT_EPSILON)) { w[2] = 1.0f; w[0] = w[1] = w[3] = 0.0f; }
+ else if (UNLIKELY(lens[3] < FLT_EPSILON)) { w[3] = 1.0f; w[0] = w[1] = w[2] = 0.0f;
+ }
+ else {
+ float wtot, area;
+
+ /* variable 'area' is just for storage,
+ * the order its initialized doesn't matter */
#ifdef __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wunsequenced"
#endif
- /* inline mean_value_half_tan four times here */
- float t[4] = {
- MEAN_VALUE_HALF_TAN_V2(area, 0, 1),
- MEAN_VALUE_HALF_TAN_V2(area, 1, 2),
- MEAN_VALUE_HALF_TAN_V2(area, 2, 3),
- MEAN_VALUE_HALF_TAN_V2(area, 3, 0),
- };
+ /* inline mean_value_half_tan four times here */
+ float t[4] = {
+ MEAN_VALUE_HALF_TAN_V2(area, 0, 1),
+ MEAN_VALUE_HALF_TAN_V2(area, 1, 2),
+ MEAN_VALUE_HALF_TAN_V2(area, 2, 3),
+ MEAN_VALUE_HALF_TAN_V2(area, 3, 0),
+ };
#ifdef __clang__
# pragma clang diagnostic pop
@@ -2237,18 +2244,19 @@ void barycentric_weights_v2_quad(const float v1[2], const float v2[2], const flo
#undef MEAN_VALUE_HALF_TAN_V2
- w[0] = (t[3] + t[0]) / lens[0];
- w[1] = (t[0] + t[1]) / lens[1];
- w[2] = (t[1] + t[2]) / lens[2];
- w[3] = (t[2] + t[3]) / lens[3];
+ w[0] = (t[3] + t[0]) / lens[0];
+ w[1] = (t[0] + t[1]) / lens[1];
+ w[2] = (t[1] + t[2]) / lens[2];
+ w[3] = (t[2] + t[3]) / lens[3];
- wtot = w[0] + w[1] + w[2] + w[3];
+ wtot = w[0] + w[1] + w[2] + w[3];
- if (wtot != 0.0f) {
- mul_v4_fl(w, 1.0f / wtot);
- }
- else { /* dummy values for zero area face */
- copy_v4_fl(w, 1.0f / 4.0f);
+ if (wtot != 0.0f) {
+ mul_v4_fl(w, 1.0f / wtot);
+ }
+ else { /* dummy values for zero area face */
+ copy_v4_fl(w, 1.0f / 4.0f);
+ }
}
}