diff options
author | Geoffrey Bantle <hairbat@yahoo.com> | 2006-02-14 01:49:46 +0300 |
---|---|---|
committer | Geoffrey Bantle <hairbat@yahoo.com> | 2006-02-14 01:49:46 +0300 |
commit | 1f21e2eea708ee73491b508c29b159ae170fe713 (patch) | |
tree | a4a3e84cb6c88a13c3848f7692e94734d9c1cf3c | |
parent | 9104862f48b0caf3131f583a382fcce3b4b7c289 (diff) |
Modified Files:
source/blender/blenlib/BLI_editVert.h
source/blender/include/BIF_editmesh.h
source/blender/src/edit.c source/blender/src/editmesh.c
source/blender/src/editmesh_lib.c
source/blender/src/editmesh_mods.c
source/blender/src/editmesh_tools.c
source/blender/src/header_view3d.c
Log:
Commit of the 'upgraded merge tools' (Patch #3345) and 'inclusive selection mode conversion' (Patch #3768).
-rw-r--r-- | source/blender/blenlib/BLI_editVert.h | 3 | ||||
-rw-r--r-- | source/blender/include/BIF_editmesh.h | 4 | ||||
-rw-r--r-- | source/blender/src/edit.c | 76 | ||||
-rw-r--r-- | source/blender/src/editmesh.c | 47 | ||||
-rw-r--r-- | source/blender/src/editmesh_lib.c | 65 | ||||
-rw-r--r-- | source/blender/src/editmesh_mods.c | 20 | ||||
-rw-r--r-- | source/blender/src/editmesh_tools.c | 379 | ||||
-rw-r--r-- | source/blender/src/header_view3d.c | 18 |
8 files changed, 588 insertions, 24 deletions
diff --git a/source/blender/blenlib/BLI_editVert.h b/source/blender/blenlib/BLI_editVert.h index 315498bab4c..57fe08e5305 100644 --- a/source/blender/blenlib/BLI_editVert.h +++ b/source/blender/blenlib/BLI_editVert.h @@ -130,6 +130,9 @@ typedef struct EditMesh EditEdge *alledges, *curedge; EditFace *allfaces, *curface; + /*for improved merge code*/ + EditVert *lastvert, *firstvert; + /* DerivedMesh caches... note that derived cage can be equivalent * to derived final, care should be taken on release. */ diff --git a/source/blender/include/BIF_editmesh.h b/source/blender/include/BIF_editmesh.h index b1620ec58a6..8c5fa1660ce 100644 --- a/source/blender/include/BIF_editmesh.h +++ b/source/blender/include/BIF_editmesh.h @@ -202,5 +202,9 @@ int editface_containsEdge(struct EditFace *efa, struct EditEdge *eed); void shape_copy_select_from(void); void shape_propagate(void); +int collapseEdges(void); +int collapseFaces(void); +int merge_firstlast(int first); + #endif diff --git a/source/blender/src/edit.c b/source/blender/src/edit.c index 355aee6e6c9..6ee71832651 100644 --- a/source/blender/src/edit.c +++ b/source/blender/src/edit.c @@ -66,6 +66,7 @@ #include "BLI_blenlib.h" #include "BLI_arithb.h" #include "BLI_editVert.h" +#include "BLI_linklist.h" #include "BKE_action.h" #include "BKE_armature.h" @@ -600,6 +601,17 @@ void countall() G.totface++; if(efa->f & SELECT) G.totfacesel++; } + + /*for keeping track of last & first vertex selected*/ + /*lastvert and first must be cleared in two circumstances.....*/ + // 1: if last/first vert exists but is NOT selected, get rid of it. + // 2: if totvertsel = 0, get rid of last/first vert + + if((G.editMesh->lastvert) && ( !(G.editMesh->lastvert->f&SELECT) )) G.editMesh->lastvert = NULL; + else if(G.totvertsel == 0) G.editMesh->lastvert = NULL; + + if((G.editMesh->firstvert) && ( !(G.editMesh->firstvert->f&SELECT) )) G.editMesh->firstvert = NULL; + else if(G.totvertsel == 0) G.editMesh->firstvert = NULL; } else if (G.obedit->type==OB_ARMATURE){ for (ebo=G.edbo.first;ebo;ebo=ebo->next){ @@ -1552,25 +1564,61 @@ void snapmenu() } +#define MERGELIMIT 0.001 void mergemenu(void) -{ - short event; - - event = pupmenu("Merge %t|At Center%x1|At Cursor%x2"); - - if (event==-1) return; /* Return if the menu is closed without any choices */ - - if (event==1) - snap_to_center(); /*Merge at Center*/ - else - snap_sel_to_curs(); /*Merge at Cursor*/ +{ - notice("Removed %d Vertices", removedoublesflag(1, G.scene->toolsettings->doublimit)); + short event; + int remCount; + if(G.scene->selectmode == SCE_SELECT_VERTEX) + if(G.editMesh->firstvert && G.editMesh->lastvert) event = pupmenu("Merge %t|At First %x6|At Last%x1|At Center%x3|At Cursor%x4"); + else if (G.editMesh->firstvert) event = pupmenu("Merge %t|At First %x6|At Center%x3|At Cursor%x4"); + else if (G.editMesh->lastvert) event = pupmenu("Merge %t|At Last %x1|At Center%x3|At Cursor%x4"); + else event = pupmenu("Merge %t|At Center%x3|At Cursor%x4"); + + else if(G.scene->selectmode == SCE_SELECT_EDGE) + event = pupmenu("Merge %t|Collapse Edges%x2|At Center%x3|At Cursor%x4"); + + else if(G.scene->selectmode == SCE_SELECT_FACE) + event = pupmenu("Merge %t|Collapse Faces%x5|At Center%x3|At Cursor%x4"); + else event = pupmenu("Merge %t|At Center%x3|At Cursor%x4"); + switch (event) + { + case -1: + return; + case 3: + snap_to_center(); + remCount = removedoublesflag(1,MERGELIMIT); + BIF_undo_push("Merge at center"); + break; + case 4: + snap_sel_to_curs(); + remCount = removedoublesflag(1,MERGELIMIT); + BIF_undo_push("Merge at cursor"); + break; + case 1: + remCount = merge_firstlast(0); + BIF_undo_push("Merge at last selected"); + break; + case 6: + remCount = merge_firstlast(1); + BIF_undo_push("Merge at first selected"); + break; + case 2: + remCount = collapseEdges(); + BIF_undo_push("Collapse Edges"); + break; + case 5: + remCount = collapseFaces(); + BIF_undo_push("Collapse Faces"); + break; + } + notice("Removed %d Vertices", remCount); allqueue(REDRAWVIEW3D, 0); countall(); - BIF_undo_push("Merge"); /* push the mesh down the undo pipe */ - } +#undef MERGELIMIT + void delete_context_selected(void) { diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c index e54bb0c156d..fefec0b460d 100644 --- a/source/blender/src/editmesh.c +++ b/source/blender/src/editmesh.c @@ -1575,6 +1575,8 @@ typedef struct UndoMesh { EditFaceC *faces; TFace *tfaces; int totvert, totedge, totface; + int lastvert, firstvert; /*index for last and first selected vert. -1 if no first/last vert exists (nasty)*/ + short selectmode; } UndoMesh; @@ -1609,9 +1611,30 @@ static void *editMesh_to_undoMesh(void) EditEdgeC *eedc=NULL; EditFaceC *efac=NULL; TFace *tface= NULL; - int a=0; + int i, a=0; um= MEM_callocN(sizeof(UndoMesh), "undomesh"); + + um->selectmode = G.scene->selectmode; + um->lastvert = -1; + um->firstvert = -1; + + if(em->lastvert){ + for (i=0,eve=G.editMesh->verts.first; eve; i++,eve=eve->next){ + if(eve == em->lastvert){ + um->lastvert = i; + break; + } + } + } + if(em->firstvert){ + for (i=0,eve=G.editMesh->verts.first; eve; i++,eve=eve->next){ + if(eve == em->firstvert){ + um->firstvert = i; + break; + } + } + } for(eve=em->verts.first; eve; eve= eve->next) um->totvert++; for(eed=em->edges.first; eed; eed= eed->next) um->totedge++; @@ -1678,7 +1701,7 @@ static void *editMesh_to_undoMesh(void) static void undoMesh_to_editMesh(void *umv) { - UndoMesh *um= umv; + UndoMesh *um= (UndoMesh*)umv; EditMesh *em= G.editMesh; EditVert *eve, **evar=NULL; EditEdge *eed; @@ -1689,11 +1712,15 @@ static void undoMesh_to_editMesh(void *umv) TFace *tface; int a=0; + G.scene->selectmode = um->selectmode; + free_editMesh(G.editMesh); /* malloc blocks */ memset(em, 0, sizeof(EditMesh)); + + init_editmesh_fastmalloc(em, um->totvert, um->totedge, um->totface); /* now copy vertices */ @@ -1743,6 +1770,22 @@ static void undoMesh_to_editMesh(void *umv) end_editmesh_fastmalloc(); if(evar) MEM_freeN(evar); + + /*restore last and first selected vertex pointers*/ + + G.totvert = um->totvert; + if(um->lastvert != -1 || um-> firstvert != -1){ + + EM_init_index_arrays(1,0,0); + if(um->lastvert != -1) em->lastvert = EM_get_vert_for_index(um->lastvert); + else em->lastvert = NULL; + + if(um->firstvert != -1) em->firstvert = EM_get_vert_for_index(um->firstvert); + else em->firstvert = NULL; + + EM_free_index_arrays(); + } + } diff --git a/source/blender/src/editmesh_lib.c b/source/blender/src/editmesh_lib.c index fecd6efecce..8c57120021b 100644 --- a/source/blender/src/editmesh_lib.c +++ b/source/blender/src/editmesh_lib.c @@ -392,6 +392,70 @@ void EM_selectmode_flush(void) } +void EM_convertsel(short oldmode, short selectmode) +{ + EditMesh *em = G.editMesh; + EditVert *eve; + EditEdge *eed; + EditFace *efa; + /*clear flags*/ + for(eve= em->verts.first; eve; eve= eve->next) eve->f1 = 0; + for(eed= em->edges.first; eed; eed= eed->next) eed->f1 = 0; + for(efa= em->faces.first; efa; efa= efa->next) efa->f1 = 0; + + /*have to find out what the selectionmode was previously*/ + if(oldmode == SCE_SELECT_VERTEX) { + if(selectmode == SCE_SELECT_EDGE){ + /*select all edges associated with every selected vertex*/ + for(eed= em->edges.first; eed; eed= eed->next){ + if(eed->v1->f&SELECT) eed->f1 = 1; + else if(eed->v2->f&SELECT) eed->f1 = 1; + } + + for(eed= em->edges.first; eed; eed= eed->next){ + if(eed->f1 == 1) EM_select_edge(eed,1); + } + } + else if(selectmode == SCE_SELECT_FACE){ + /*select all faces associated with every selected vertex*/ + for(efa= em->faces.first; efa; efa= efa->next){ + if(efa->v1->f&SELECT) efa->f1 = 1; + else if(efa->v2->f&SELECT) efa->f1 = 1; + else if(efa->v3->f&SELECT) efa->f1 = 1; + else{ + if(efa->v4){ + if(efa->v4->f&SELECT) efa->f1 =1; + } + } + + } + for(efa= em->faces.first; efa; efa= efa->next){ + if(efa->f1 == 1) EM_select_face(efa,1); + } + check_fgons_selection(); + countall(); + } + } + + if(oldmode == SCE_SELECT_EDGE){ + if(selectmode == SCE_SELECT_FACE){ + for(efa= em->faces.first; efa; efa= efa->next){ + if(efa->e1->f&SELECT) efa->f1 = 1; + else if(efa->e2->f&SELECT) efa->f1 = 1; + else if(efa->e3->f&SELECT) efa->f1 = 1; + else if(efa->e4){ + if(efa->e4->f&SELECT) efa->f1 = 1; + } + } + for(efa= em->faces.first; efa; efa= efa->next){ + if(efa->f1 == 1) EM_select_face(efa,1); + } + check_fgons_selection(); + countall(); + } + } +} + /* when switching select mode, makes sure selection is consistant for editing */ /* also for paranoia checks to make sure edge or face mode works */ void EM_selectmode_set(void) @@ -424,6 +488,7 @@ void EM_selectmode_set(void) for(efa= em->faces.first; efa; efa= efa->next) if(efa->f & SELECT) EM_select_face(efa, 1); } + BIF_undo_push("Selectmode Set"); } /* paranoia check, actually only for entering editmode. rule: diff --git a/source/blender/src/editmesh_mods.c b/source/blender/src/editmesh_mods.c index aa3353046a8..7179543c695 100644 --- a/source/blender/src/editmesh_mods.c +++ b/source/blender/src/editmesh_mods.c @@ -1052,7 +1052,11 @@ void mouse_mesh(void) } } else if(eve) { - if((eve->f & SELECT)==0) eve->f |= SELECT; + if((eve->f & SELECT)==0) { + eve->f |= SELECT; + if((G.qual & LR_SHIFTKEY)==0) G.editMesh->firstvert = eve; + else G.editMesh->lastvert = eve; + } else if(G.qual & LR_SHIFTKEY) eve->f &= ~SELECT; } @@ -1937,10 +1941,20 @@ void EM_selectmode_menu(void) else pupmenu_set_active(3); val= pupmenu("Select Mode%t|Vertices|Edges|Faces"); + + if(val>0) { if(val==1) G.scene->selectmode= SCE_SELECT_VERTEX; - else if(val==2) G.scene->selectmode= SCE_SELECT_EDGE; - else G.scene->selectmode= SCE_SELECT_FACE; + + else if(val==2){ + if((G.qual==LR_CTRLKEY)) EM_convertsel(G.scene->selectmode, SCE_SELECT_EDGE); + G.scene->selectmode= SCE_SELECT_EDGE; + } + + else{ + if((G.qual==LR_CTRLKEY)) EM_convertsel(G.scene->selectmode, SCE_SELECT_FACE); + G.scene->selectmode= SCE_SELECT_FACE; + } EM_selectmode_set(); // when mode changes allqueue(REDRAWVIEW3D, 1); diff --git a/source/blender/src/editmesh_tools.c b/source/blender/src/editmesh_tools.c index c244f1d249c..3bc528e7702 100644 --- a/source/blender/src/editmesh_tools.c +++ b/source/blender/src/editmesh_tools.c @@ -5565,4 +5565,383 @@ void shape_copy_select_from() return; } +/* Collection Routines|Currently used by the improved merge code*/ +/* both buildEdge_collection() and buildFace_collection() create a series of lists*/ +/* these lists are filled with edges or faces that are topologically connected.*/ + +#define MERGELIMIT 0.001 + +LinkNode *build_edgecollection(LinkNode *allCollections) +{ + EditEdge *eed; + + LinkNode *edgeCollection, *currEdge; + + edgeCollection = NULL; + currEdge = NULL; + allCollections = NULL; + + int currTag, lowtag; + + short ebalanced = 0; + short listfound; + + currTag = 1; + + for (eed=G.editMesh->edges.first; eed; eed = eed->next) + { + eed->tmp.l = 0; + eed->v1->tmp.l = 0; + eed->v2->tmp.l = 0; + } + + /*1st pass*/ + for(eed=G.editMesh->edges.first; eed; eed=eed->next) + { + if(eed->f&SELECT) + { + + eed->v1->tmp.l = currTag; + eed->v2->tmp.l = currTag; + + currTag +=1; + } + } + + /*2nd pass - Brute force. Loop through selected faces until there are no 'unbalanced' edges left (those with both vertices 'tmp.l' tag matching */ + while(ebalanced == 0) + { + ebalanced = 1; + for(eed=G.editMesh->edges.first; eed; eed = eed->next) + { + if(eed->f&SELECT) + { + if(eed->v1->tmp.l != eed->v2->tmp.l) /*unbalanced*/ + { + if(eed->v1->tmp.l > eed->v2->tmp.l && eed->v2->tmp.l !=0) eed->v1->tmp.l = eed->v2->tmp.l; + else if(eed->v1 != 0) eed->v2->tmp.l = eed->v1->tmp.l; + ebalanced = 0; + } + } + } + } + + /*3rd pass, set all the edge flags (unnessecary?)*/ + for(eed=G.editMesh->edges.first; eed; eed = eed->next) + { + if(eed->f&SELECT) eed->tmp.l = eed->v1->tmp.l; + } + + /*build our list of lists - Needs to be in a seperate function, identical to build_facecollection()!*/ + for(eed=G.editMesh->edges.first; eed; eed=eed->next) + { + if(eed->f&SELECT) + { + if(allCollections) /*allCollections is NOT NULL*/ + { + for(edgeCollection = allCollections; edgeCollection; edgeCollection=edgeCollection->next) + { + currEdge = edgeCollection->link; + if(((EditEdge*)currEdge->link)->tmp.l == eed->tmp.l) + { + BLI_linklist_append(&currEdge,eed); + listfound = 1; + break; + } + else listfound = 0; + } + + if(!listfound) + { + /*add a new faceCollection to the Collections list*/ + edgeCollection = NULL; + BLI_linklist_prepend(&edgeCollection, eed); + BLI_linklist_append(allCollections, edgeCollection); + + } + } + else /*allCollections is a 'zero length list'*/ + { + edgeCollection = NULL; + BLI_linklist_prepend(&edgeCollection, eed); + BLI_linklist_prepend(&allCollections, edgeCollection); /*this actually looks like it is correct*/ + } + } + } + return allCollections; + +} + +LinkNode *build_facecollection(LinkNode *allCollections) /*Builds a collection of lists of connected faces from the currently selected set*/ +{ + EditFace *efa; + + LinkNode *faceCollection, *currFace; + + faceCollection = NULL; + currFace = NULL; + allCollections = NULL; + + int currTag, lowtag; + short listfound,aCount; + int tagArray[3]; /*used to pull the tags out of faces vertices. an entry of -1 means no vertex exists....*/ + currTag = 1; /*don't start with zero since f1 is cleared to that in editvert and editface structs already*/ + + for (efa=G.editMesh->faces.first; efa; efa=efa->next){ + + efa->tmp.l = 0; + efa->v1->tmp.l = 0; + efa->v2->tmp.l = 0; + efa->v3->tmp.l = 0; + if(efa->v4) efa->v4->tmp.l = 0; + + } + + /*1st pass*/ + for (efa=G.editMesh->faces.first; efa; efa=efa->next) + { + + if(efa->f&SELECT) + { /*face has no vertices that have been visited before since all the f1 tags are zero*/ + if((efa->v1->tmp.l + efa->v2->tmp.l + efa->v3->tmp.l + ((efa->v4) ? efa->v4->tmp.l : 0)) == 0) + { + efa->v1->tmp.l = currTag; + efa->v2->tmp.l = currTag; + efa->v3->tmp.l = currTag; + if(efa->v4) efa->v4->tmp.l = currTag; + } + else + { /*the face has some vert tagged allready as a result of another face that it shares verts with being already visited*/ + lowtag = currTag+1; /* plus one? why? this makes little sense!*/ + + /*test to find the lowest tag....*/ + if(efa->v1->tmp.l < lowtag && efa->v1->tmp.l != 0 && efa->v1->tmp.l != -1) lowtag = efa->v1->tmp.l; + if(efa->v2->tmp.l < lowtag && efa->v2->tmp.l != 0 && efa->v2->tmp.l != -1) lowtag = efa->v2->tmp.l; + if(efa->v3->tmp.l < lowtag && efa->v3->tmp.l != 0 && efa->v3->tmp.l != -1) lowtag = efa->v3->tmp.l; + + if(efa->v4){ + if(efa->v4->tmp.l < lowtag && efa->v4->tmp.l != 0 && efa->v4->tmp.l != -1) lowtag = efa->v4->tmp.l; + } + + /*set all vertices to lowest tag*/ + efa->v1->tmp.l = lowtag; + efa->v2->tmp.l = lowtag; + efa->v3->tmp.l = lowtag; + if(efa->v4) efa->v4->tmp.l = lowtag; + } + currTag += 1; + } + } + + /*2nd pass - Nessecary because of faces connected only by a single vertex*/ + + for (efa=G.editMesh->faces.first; efa; efa=efa->next) + { + + lowtag = currTag+1; /*plus one? why? this makes little sense!*/ + if(efa->f&SELECT) + { + tagArray[0] = efa->v1->tmp.l; + tagArray[1] = efa->v2->tmp.l; + tagArray[2] = efa->v3->tmp.l; + tagArray[3] = (efa->v4) ? efa->v4->tmp.l : -1; /*could be a triangle, have to test*/ + + if(efa->v1->tmp.l < lowtag && efa->v1->tmp.l != 0 && efa->v1->tmp.l != -1) lowtag = efa->v1->tmp.l; + if(efa->v2->tmp.l < lowtag && efa->v2->tmp.l != 0 && efa->v2->tmp.l != -1) lowtag = efa->v2->tmp.l; + if(efa->v3->tmp.l < lowtag && efa->v3->tmp.l != 0 && efa->v3->tmp.l != -1) lowtag = efa->v3->tmp.l; + + if(efa->v4){ + if(efa->v4->tmp.l < lowtag && efa->v4->tmp.l != 0 && efa->v4->tmp.l != -1) lowtag = efa->v4->tmp.l; + } + + + efa->tmp.l = lowtag; /*actually tag the face now with lowtag*/ + } + } + + /*build our list of lists*/ + for(efa=G.editMesh->faces.first; efa; efa=efa->next) + { + if(efa->f&SELECT) + { + if(allCollections) /*allCollections is NOT NULL*/ + { + for(faceCollection = allCollections; faceCollection; faceCollection=faceCollection->next) + { + currFace = faceCollection->link; + if(((EditFace*)currFace->link)->tmp.l == efa->tmp.l) /*put efa into this list.........*/ + { + BLI_linklist_append(&currFace,efa); + listfound = 1; + break; + } + else listfound = 0; + } + + if(!listfound) + { + /*add a new faceCollection to the Collections list*/ + faceCollection = NULL; + BLI_linklist_prepend(&faceCollection, efa); + BLI_linklist_append(allCollections, faceCollection); + + } + } + else /*allCollections is a 'zero length list'*/ + { + faceCollection = NULL; + BLI_linklist_prepend(&faceCollection, efa); + BLI_linklist_prepend(&allCollections, faceCollection); /*this actually looks like it is correct*/ + } + } + } + return allCollections; + } + +void freeCollections(LinkNode *allCollections) +{ + LinkNode *Collection; + Collection = NULL; + + for(Collection = allCollections; Collection; Collection = Collection->next) + { + BLI_linklist_free((LinkNode*)Collection->link,NULL); + } + + BLI_linklist_free(allCollections,NULL); +} + +int collapseEdges(void) +{ + LinkNode *allCollections, *edgeCollection, *currEdge; + + int totEdges, groupCount, mergecount,vCount; + float avgCount[3]; + + mergecount = 0; + + allCollections = build_edgecollection(allCollections); + groupCount = BLI_linklist_length(allCollections); + + + for(edgeCollection = allCollections; edgeCollection; edgeCollection = edgeCollection->next) + { + totEdges = BLI_linklist_length(edgeCollection->link); + mergecount += totEdges; + avgCount[0] = 0; avgCount[1] = 0; avgCount[2] = 0; + vCount = 0; + + for(currEdge = edgeCollection->link; currEdge; currEdge = currEdge->next) + { + avgCount[0] += ((EditEdge*)currEdge->link)->v1->co[0]; + avgCount[1] += ((EditEdge*)currEdge->link)->v1->co[1]; + avgCount[2] += ((EditEdge*)currEdge->link)->v1->co[2]; + + avgCount[0] += ((EditEdge*)currEdge->link)->v2->co[0]; + avgCount[1] += ((EditEdge*)currEdge->link)->v2->co[1]; + avgCount[2] += ((EditEdge*)currEdge->link)->v2->co[2]; + + vCount +=2; + } + + avgCount[0] /= vCount; avgCount[1] /=vCount; avgCount[2] /= vCount; + + for(currEdge = edgeCollection->link; currEdge; currEdge = currEdge->next) + { + VECCOPY(((EditEdge*)currEdge->link)->v1->co,avgCount); + VECCOPY(((EditEdge*)currEdge->link)->v2->co,avgCount); + } + } + freeCollections(allCollections); + removedoublesflag(1, MERGELIMIT); + /*get rid of this!*/ + countall(); + return mergecount; + + +} + +int collapseFaces(void) +{ + LinkNode *allCollections, *faceCollection, *currFace; + + int groupCount; + int vCount,totFaces,mergecount; + float avgCount[3]; + + mergecount = 0; + allCollections = build_facecollection(allCollections); + groupCount = BLI_linklist_length(allCollections); + + for(faceCollection = allCollections; faceCollection; faceCollection = faceCollection->next) + { + totFaces = BLI_linklist_length(faceCollection->link); + mergecount += totFaces; + avgCount[0] = 0; avgCount[1] = 0; avgCount[2] = 0; + vCount = 0; + for(currFace = faceCollection->link; currFace; currFace = currFace->next) + { + avgCount[0] += ((EditFace*)currFace->link)->v1->co[0]; + avgCount[1] += ((EditFace*)currFace->link)->v1->co[1]; + avgCount[2] += ((EditFace*)currFace->link)->v1->co[2]; + + avgCount[0] += ((EditFace*)currFace->link)->v2->co[0]; + avgCount[1] += ((EditFace*)currFace->link)->v2->co[1]; + avgCount[2] += ((EditFace*)currFace->link)->v2->co[2]; + + avgCount[0] += ((EditFace*)currFace->link)->v3->co[0]; + avgCount[1] += ((EditFace*)currFace->link)->v3->co[1]; + avgCount[2] += ((EditFace*)currFace->link)->v3->co[2]; + + vCount+= 3; + + if(((EditFace*)currFace->link)->v4) + { + avgCount[0] += ((EditFace*)currFace->link)->v3->co[0]; + avgCount[1] += ((EditFace*)currFace->link)->v3->co[1]; + avgCount[2] += ((EditFace*)currFace->link)->v3->co[2]; + vCount+=1; + } + + } + + avgCount[0] /= vCount; avgCount[1] /=vCount; avgCount[2] /= vCount; + + for(currFace = faceCollection->link; currFace; currFace = currFace->next) + { + VECCOPY(((EditFace*)currFace->link)->v1->co,avgCount); + VECCOPY(((EditFace*)currFace->link)->v2->co,avgCount); + VECCOPY(((EditFace*)currFace->link)->v3->co,avgCount); + if(((EditFace*)currFace->link)->v4) VECCOPY(((EditFace*)currFace->link)->v4->co, avgCount); + } + } + freeCollections(allCollections); + removedoublesflag(1, MERGELIMIT); + /*get rid of this!*/ + countall(); + return mergecount; +} + +int merge_firstlast(int first) +{ + EditVert *ev,*mergevert; + + if(first == 0) mergevert=G.editMesh->lastvert; + else mergevert=G.editMesh->firstvert; + + if(mergevert->f&SELECT){ + for (ev=G.editMesh->verts.first; ev; ev=ev->next) + { + if (ev->f&SELECT) + VECCOPY(ev->co,mergevert->co); + } + } + + countall(); + +return removedoublesflag(1,MERGELIMIT); +} +#undef MERGELIMIT + + diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c index a1120e9ed5d..03788e848f7 100644 --- a/source/blender/src/header_view3d.c +++ b/source/blender/src/header_view3d.c @@ -4093,17 +4093,25 @@ void do_view3d_buttons(short event) allqueue(REDRAWVIEW3D, 1); break; case B_SEL_EDGE: - if( (G.qual & LR_SHIFTKEY)==0 || G.scene->selectmode==0) - G.scene->selectmode= SCE_SELECT_EDGE; + if( (G.qual & LR_SHIFTKEY)==0 || G.scene->selectmode==0){ + if( (G.scene->selectmode ^ SCE_SELECT_EDGE) == SCE_SELECT_VERTEX){ + if(G.qual==LR_CTRLKEY) EM_convertsel(SCE_SELECT_VERTEX,SCE_SELECT_EDGE); + } + G.scene->selectmode = SCE_SELECT_EDGE; + } EM_selectmode_set(); allqueue(REDRAWVIEW3D, 1); break; case B_SEL_FACE: - if( (G.qual & LR_SHIFTKEY)==0 || G.scene->selectmode==0) - G.scene->selectmode= SCE_SELECT_FACE; + if( (G.qual & LR_SHIFTKEY)==0 || G.scene->selectmode==0){ + if( ((G.scene->selectmode ^ SCE_SELECT_FACE) == SCE_SELECT_VERTEX) || ((G.scene->selectmode ^ SCE_SELECT_FACE) == SCE_SELECT_EDGE)){ + if(G.qual==LR_CTRLKEY) EM_convertsel((G.scene->selectmode ^ SCE_SELECT_FACE),SCE_SELECT_FACE); + } + G.scene->selectmode = SCE_SELECT_FACE; + } EM_selectmode_set(); allqueue(REDRAWVIEW3D, 1); - break; + break; case B_MAN_TRANS: if( (G.qual & LR_SHIFTKEY)==0 || G.vd->twtype==0) |