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>2014-02-25 16:01:50 +0400
committerCampbell Barton <ideasman42@gmail.com>2014-02-25 16:03:26 +0400
commitca2b4323a8b20e20c8b5ffe980d27da58d7b2b07 (patch)
tree373de975c507b4ff36428b1b62b06808ee7a6274 /source/blender/modifiers/intern/MOD_skin.c
parentdbf653acb763392c92a30e7576fb4693fe167926 (diff)
Fix T38003: Skin modifier crash with long edges
Diffstat (limited to 'source/blender/modifiers/intern/MOD_skin.c')
-rw-r--r--source/blender/modifiers/intern/MOD_skin.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c
index fa239cedb02..07be90b9ce1 100644
--- a/source/blender/modifiers/intern/MOD_skin.c
+++ b/source/blender/modifiers/intern/MOD_skin.c
@@ -753,10 +753,13 @@ static EMat *build_edge_mats(const MVertSkin *vs,
static int calc_edge_subdivisions(const MVert *mvert, const MVertSkin *nodes,
const MEdge *e, int *degree)
{
+ /* prevent memory errors [#38003] */
+#define NUM_SUBDIVISIONS_MAX 128
+
const MVertSkin *evs[2] = {&nodes[e->v1], &nodes[e->v2]};
- float edge_len, avg[2];
- int v1_branch = degree[e->v1] > 2;
- int v2_branch = degree[e->v2] > 2;
+ float avg_radius;
+ const bool v1_branch = degree[e->v1] > 2;
+ const bool v2_branch = degree[e->v2] > 2;
int num_subdivisions;
/* If either end is a branch node marked 'loose', don't subdivide
@@ -770,15 +773,23 @@ static int calc_edge_subdivisions(const MVert *mvert, const MVertSkin *nodes,
return 0;
}
- edge_len = len_v3v3(mvert[e->v1].co, mvert[e->v2].co);
-
- avg[0] = half_v2(evs[0]->radius);
- avg[1] = half_v2(evs[1]->radius);
+ avg_radius = half_v2(evs[0]->radius) + half_v2(evs[1]->radius);
- if (avg[0] + avg[1] == 0.0f)
+ if (avg_radius != 0.0f) {
+ /* possible (but unlikely) that we overflow INT_MAX */
+ float num_subdivisions_fl;
+ const float edge_len = len_v3v3(mvert[e->v1].co, mvert[e->v2].co);
+ num_subdivisions_fl = (edge_len / avg_radius);
+ if (num_subdivisions_fl < NUM_SUBDIVISIONS_MAX) {
+ num_subdivisions = (int)num_subdivisions_fl;
+ }
+ else {
+ num_subdivisions = NUM_SUBDIVISIONS_MAX;
+ }
+ }
+ else {
num_subdivisions = 0;
- else
- num_subdivisions = (int)((float)edge_len / (avg[0] + avg[1]));
+ }
/* If both ends are branch nodes, two intermediate nodes are
* required */
@@ -786,6 +797,8 @@ static int calc_edge_subdivisions(const MVert *mvert, const MVertSkin *nodes,
num_subdivisions = 2;
return num_subdivisions;
+
+#undef NUM_SUBDIVISIONS_MAX
}
/* Take a DerivedMesh and subdivide its edges to keep skin nodes