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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2007-01-09 00:20:18 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2007-01-09 00:20:18 +0300
commit5bb658dd699aba235788be06368eff2b5421b125 (patch)
treede87138d9e762e7e459d822f208756bd2bd78cac /source/blender/src/editmesh_tools.c
parentfb176639884ced162aeed03cf44bb00d97068e60 (diff)
Fix for bug and #5449 and #5423:
Crashes using flip triangle edges or beauty fill. The cause was edges being marked for deletion and deleted that are still in use by faces. This could happen if the edge was part of a quad or unselected triangle, or if the edge was marked for deletion, but then needed again because of another flip.
Diffstat (limited to 'source/blender/src/editmesh_tools.c')
-rw-r--r--source/blender/src/editmesh_tools.c132
1 files changed, 59 insertions, 73 deletions
diff --git a/source/blender/src/editmesh_tools.c b/source/blender/src/editmesh_tools.c
index 15978191f2c..3f0df4f2155 100644
--- a/source/blender/src/editmesh_tools.c
+++ b/source/blender/src/editmesh_tools.c
@@ -111,8 +111,7 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise
/* local prototypes ---------------*/
void bevel_menu(void);
-static void free_tagged_edgelist(EditEdge *eed);
-static void free_tagged_facelist(EditFace *efa);
+static void free_tagged_edges_faces(EditEdge *eed, EditFace *efa);
/********* qsort routines *********/
@@ -2609,9 +2608,7 @@ void esubdivideflag(int flag, float rad, int beauty, int numcuts, int seltype)
}
}
- // Delete Old Faces
- free_tagged_facelist(em->faces.first);
- //Delete Old Edges
+ // Delete Old Edges and Faces
for(eed = em->edges.first;eed;eed = eed->next) {
if(BLI_ghash_haskey(gh,eed)) {
eed->f1 = SELECT;
@@ -2619,7 +2616,7 @@ void esubdivideflag(int flag, float rad, int beauty, int numcuts, int seltype)
eed->f1 = 0;
}
}
- free_tagged_edgelist(em->edges.first);
+ free_tagged_edges_faces(em->edges.first, em->faces.first);
if(seltype == SUBDIV_SELECT_ORIG && G.qual != LR_CTRLKEY) {
for(eed = em->edges.first;eed;eed = eed->next) {
@@ -2735,35 +2732,40 @@ static int collect_quadedges(EVPTuple *efaa, EditEdge *eed, EditFace *efa)
while(efa) {
efa->f1= 0;
- if(efa->v4==0) { /* if triangle */
- if(efa->f & SELECT) {
-
- e1= efa->e1;
- e2= efa->e2;
- e3= efa->e3;
- if(e1->f2<3 && e1->tmp.p) {
- if(e1->f2<2) {
- evp= (EVPtr *) e1->tmp.p;
- evp[(int)e1->f2] = efa;
- }
- e1->f2+= 1;
+ if(efa->v4==0 && (efa->f & SELECT)) { /* if selected triangle */
+ e1= efa->e1;
+ e2= efa->e2;
+ e3= efa->e3;
+ if(e1->f2<3 && e1->tmp.p) {
+ if(e1->f2<2) {
+ evp= (EVPtr *) e1->tmp.p;
+ evp[(int)e1->f2] = efa;
}
- if(e2->f2<3 && e2->tmp.p) {
- if(e2->f2<2) {
- evp= (EVPtr *) e2->tmp.p;
- evp[(int)e2->f2]= efa;
- }
- e2->f2+= 1;
+ e1->f2+= 1;
+ }
+ if(e2->f2<3 && e2->tmp.p) {
+ if(e2->f2<2) {
+ evp= (EVPtr *) e2->tmp.p;
+ evp[(int)e2->f2]= efa;
}
- if(e3->f2<3 && e3->tmp.p) {
- if(e3->f2<2) {
- evp= (EVPtr *) e3->tmp.p;
- evp[(int)e3->f2]= efa;
- }
- e3->f2+= 1;
+ e2->f2+= 1;
+ }
+ if(e3->f2<3 && e3->tmp.p) {
+ if(e3->f2<2) {
+ evp= (EVPtr *) e3->tmp.p;
+ evp[(int)e3->f2]= efa;
}
+ e3->f2+= 1;
}
}
+ else {
+ /* set to 3 to make sure these are not flipped or joined */
+ efa->e1->f2= 3;
+ efa->e2->f2= 3;
+ efa->e3->f2= 3;
+ if (efa->e4) efa->e4->f2= 3;
+ }
+
efa= efa->next;
}
return i;
@@ -2831,31 +2833,17 @@ static void givequadverts(EditFace *efa, EditFace *efa1, EditVert **v1, EditVert
/* Helper functions for edge/quad edit features*/
static void untag_edges(EditFace *f)
{
- f->e1->f2 = 0;
- f->e2->f2 = 0;
- if (f->e3) f->e3->f2 = 0;
- if (f->e4) f->e4->f2 = 0;
+ f->e1->f1 = 0;
+ f->e2->f1 = 0;
+ f->e3->f1 = 0;
+ if (f->e4) f->e4->f1 = 0;
}
-/** remove and free list of tagged edges */
-static void free_tagged_edgelist(EditEdge *eed)
+/** remove and free list of tagged edges and faces */
+static void free_tagged_edges_faces(EditEdge *eed, EditFace *efa)
{
+ EditMesh *em= G.editMesh;
EditEdge *nexted;
-
- while(eed) {
- nexted= eed->next;
- if(eed->f1) {
- remedge(eed);
- free_editedge(eed);
- }
- eed= nexted;
- }
-}
-/** remove and free list of tagged faces */
-
-static void free_tagged_facelist(EditFace *efa)
-{
- EditMesh *em = G.editMesh;
EditFace *nextvl;
while(efa) {
@@ -2864,8 +2852,20 @@ static void free_tagged_facelist(EditFace *efa)
BLI_remlink(&em->faces, efa);
free_editface(efa);
}
+ else
+ /* avoid deleting edges that are still in use */
+ untag_edges(efa);
efa= nextvl;
}
+
+ while(eed) {
+ nexted= eed->next;
+ if(eed->f1) {
+ remedge(eed);
+ free_editedge(eed);
+ }
+ eed= nexted;
+ }
}
/* note; the EM_selectmode_set() calls here illustrate how badly constructed it all is... from before the
@@ -3024,8 +3024,7 @@ void beauty_fill(void)
eed= nexted;
}
- free_tagged_edgelist(em->edges.first);
- free_tagged_facelist(em->faces.first);
+ free_tagged_edges_faces(em->edges.first, em->faces.first);
if(onedone==0) break;
@@ -3185,7 +3184,6 @@ static int fplcmp(const void *v1, const void *v2)
#define T2QDELETE 1
#define T2QCOMPLEX 2
#define T2QJOIN 4
-#define T2QPAIR 8
void join_triangles(void)
{
EditMesh *em=G.editMesh;
@@ -3231,26 +3229,17 @@ void join_triangles(void)
/*clear tmp.l flag and store number of faces that are selected and coincident to current face here.*/
for(eed=em->edges.first; eed; eed=eed->next){
+ /* eed->f2 is 2 only if this edge is part of exactly two
+ triangles, and both are selected, and it has EVPTuple assigned */
if(eed->f2 == 2){
- eed->f1 |= T2QPAIR; /*tells us that an EVPtuple has been assigned for this face.*/
efaa= (EVPtr *) eed->tmp.p;
efaa[0]->tmp.l++;
efaa[1]->tmp.l++;
}
- eed->f2 = 0; /*needed to store actual face count, not just selected*/
- }
-
- /*count actual number of edges for each face.*/
- for(efa=em->faces.first; efa; efa=efa->next){
- efa->e1->f2++;
- efa->e2->f2++;
- efa->e3->f2++;
- if(efa->v4)
- efa->e4->f2++;
}
for(eed=em->edges.first; eed; eed=eed->next){
- if(eed->f2 == 2 && (eed->f1 & T2QPAIR)){
+ if(eed->f2 == 2){
efaa= (EVPtr *) eed->tmp.p;
v1 = v2 = v3 = v4 = NULL;
givequadverts(efaa[0], efaa[1], &v1, &v2, &v3, &v4, vindex);
@@ -3350,8 +3339,7 @@ void join_triangles(void)
if(eed->f1 & T2QDELETE) eed->f1 = 1;
else eed->f1 = 0;
}
- free_tagged_facelist(em->faces.first);
- free_tagged_edgelist(em->edges.first);
+ free_tagged_edges_faces(em->edges.first, em->faces.first);
if(efaar) MEM_freeN(efaar);
if(edsortblock) MEM_freeN(edsortblock);
@@ -3437,14 +3425,12 @@ void edge_flip(void)
vindex[1], 4+vindex[2], -1);
EM_select_face(w, 1);
- untag_edges(w);
/* outch this may break seams */
w= EM_face_from_faces(efaa[0], efaa[1], vindex[0],
4+vindex[2], 4+vindex[3], -1);
EM_select_face(w, 1);
- untag_edges(w);
}
/* tag as to-be-removed */
FACE_MARKCLEAR(efaa[1]);
@@ -3459,8 +3445,7 @@ void edge_flip(void)
}
/* clear tagged edges and faces: */
- free_tagged_edgelist(em->edges.first);
- free_tagged_facelist(em->faces.first);
+ free_tagged_edges_faces(em->edges.first, em->faces.first);
MEM_freeN(efaar);
@@ -6480,4 +6465,5 @@ void loop_to_region(void)
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
allqueue(REDRAWVIEW3D, 0);
BIF_undo_push("Edge Loop to Face Region");
-} \ No newline at end of file
+}
+