[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [16851] trunk/blender/source/blender/ blenkernel/intern/modifier.c: Fix for bug #17691: edgesplit was crashing on windows on large meshes
Brecht Van Lommel
brecht at blender.org
Tue Sep 30 19:06:58 CEST 2008
Revision: 16851
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16851
Author: blendix
Date: 2008-09-30 19:06:41 +0200 (Tue, 30 Sep 2008)
Log Message:
-----------
Fix for bug #17691: edgesplit was crashing on windows on large meshes
due to stack overflow.
Modified Paths:
--------------
trunk/blender/source/blender/blenkernel/intern/modifier.c
Modified: trunk/blender/source/blender/blenkernel/intern/modifier.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/modifier.c 2008-09-30 12:30:56 UTC (rev 16850)
+++ trunk/blender/source/blender/blenkernel/intern/modifier.c 2008-09-30 17:06:41 UTC (rev 16851)
@@ -2139,6 +2139,8 @@
DerivedMesh *dm;
float threshold; /* the cosine of the smoothing angle */
int flags;
+ MemArena *arena;
+ ListBase propagatestack, reusestack;
} SmoothMesh;
static SmoothVert *smoothvert_copy(SmoothVert *vert, SmoothMesh *mesh)
@@ -2221,6 +2223,9 @@
for(i = 0; i < mesh->num_edges; ++i)
BLI_linklist_free(mesh->edges[i].faces, NULL);
+
+ if(mesh->arena)
+ BLI_memarena_free(mesh->arena);
MEM_freeN(mesh->verts);
MEM_freeN(mesh->edges);
@@ -2872,6 +2877,49 @@
face_replace_vert(face, &repdata);
}
+typedef struct PropagateEdge {
+ struct PropagateEdge *next, *prev;
+ SmoothEdge *edge;
+ SmoothVert *vert;
+} PropagateEdge;
+
+static void push_propagate_stack(SmoothEdge *edge, SmoothVert *vert, SmoothMesh *mesh)
+{
+ PropagateEdge *pedge = mesh->reusestack.first;
+
+ if(pedge) {
+ BLI_remlink(&mesh->reusestack, pedge);
+ }
+ else {
+ if(!mesh->arena) {
+ mesh->arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
+ BLI_memarena_use_calloc(mesh->arena);
+ }
+
+ pedge = BLI_memarena_alloc(mesh->arena, sizeof(PropagateEdge));
+ }
+
+ pedge->edge = edge;
+ pedge->vert = vert;
+ BLI_addhead(&mesh->propagatestack, pedge);
+}
+
+static void pop_propagate_stack(SmoothEdge **edge, SmoothVert **vert, SmoothMesh *mesh)
+{
+ PropagateEdge *pedge = mesh->propagatestack.first;
+
+ if(pedge) {
+ *edge = pedge->edge;
+ *vert = pedge->vert;
+ BLI_remlink(&mesh->propagatestack, pedge);
+ BLI_addhead(&mesh->reusestack, pedge);
+ }
+ else {
+ *edge = NULL;
+ *vert = NULL;
+ }
+}
+
static void split_edge(SmoothEdge *edge, SmoothVert *vert, SmoothMesh *mesh);
static void propagate_split(SmoothEdge *edge, SmoothVert *vert,
@@ -2949,7 +2997,7 @@
if(!edge2) {
/* didn't find a sharp or loose edge, so try the other vert */
vert2 = other_vert(edge, vert);
- propagate_split(edge, vert2, mesh);
+ push_propagate_stack(edge, vert2, mesh);
} else if(!edge_is_loose(edge2)) {
/* edge2 is not loose, so it must be sharp */
SmoothEdge *copy_edge = smoothedge_copy(edge, mesh);
@@ -2978,11 +3026,11 @@
/* all copying and replacing is done; the mesh should be consistent.
* now propagate the split to the vertices at either end
*/
- propagate_split(copy_edge, other_vert(copy_edge, vert2), mesh);
- propagate_split(copy_edge2, other_vert(copy_edge2, vert2), mesh);
+ push_propagate_stack(copy_edge, other_vert(copy_edge, vert2), mesh);
+ push_propagate_stack(copy_edge2, other_vert(copy_edge2, vert2), mesh);
if(smoothedge_has_vert(edge, vert))
- propagate_split(edge, vert, mesh);
+ push_propagate_stack(edge, vert, mesh);
} else {
/* edge2 is loose */
SmoothEdge *copy_edge = smoothedge_copy(edge, mesh);
@@ -3005,10 +3053,10 @@
/* copying and replacing is done; the mesh should be consistent.
* now propagate the split to the vertex at the other end
*/
- propagate_split(copy_edge, other_vert(copy_edge, vert2), mesh);
+ push_propagate_stack(copy_edge, other_vert(copy_edge, vert2), mesh);
if(smoothedge_has_vert(edge, vert))
- propagate_split(edge, vert, mesh);
+ push_propagate_stack(edge, vert, mesh);
}
BLI_linklist_free(visited_faces, NULL);
@@ -3080,6 +3128,7 @@
static void split_sharp_edges(SmoothMesh *mesh, float split_angle, int flags)
{
+ SmoothVert *vert;
int i;
/* if normal1 dot normal2 < threshold, angle is greater, so split */
/* FIXME not sure if this always works */
@@ -3092,10 +3141,16 @@
for(i = 0; i < mesh->num_edges; i++) {
SmoothEdge *edge = &mesh->edges[i];
- if(edge_is_sharp(edge, flags, mesh->threshold))
+ if(edge_is_sharp(edge, flags, mesh->threshold)) {
split_edge(edge, edge->verts[0], mesh);
+
+ do {
+ pop_propagate_stack(&edge, &vert, mesh);
+ if(edge && smoothedge_has_vert(edge, vert))
+ propagate_split(edge, vert, mesh);
+ } while(edge);
+ }
}
-
}
static int count_bridge_verts(SmoothMesh *mesh)
More information about the Bf-blender-cvs
mailing list