From 5ea45a1385a2bc71be572fd7923c508edb70eaa2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 18 Oct 2007 21:47:55 +0000 Subject: Mesh edit option 'AutoMerge' - access from the mesh menu, basically runs remove doubles after transform. but only merges unselected verts into selected verts, so it wont merge verts your not editing. --- source/blender/include/BIF_editmesh.h | 2 +- source/blender/include/editmesh.h | 1 + source/blender/makesdna/DNA_scene_types.h | 2 + source/blender/python/api2_2x/Mesh.c | 4 +- source/blender/src/buttons_editing.c | 2 +- source/blender/src/editmesh_add.c | 2 +- source/blender/src/editmesh_mods.c | 14 +++- source/blender/src/editmesh_tools.c | 112 +++++++++++++++++++---------- source/blender/src/editobject.c | 4 +- source/blender/src/header_view3d.c | 20 +++++- source/blender/src/transform_conversions.c | 7 +- 11 files changed, 122 insertions(+), 48 deletions(-) (limited to 'source/blender') diff --git a/source/blender/include/BIF_editmesh.h b/source/blender/include/BIF_editmesh.h index 7ad3fd480a3..42d581ee758 100644 --- a/source/blender/include/BIF_editmesh.h +++ b/source/blender/include/BIF_editmesh.h @@ -206,7 +206,7 @@ extern short sharesFace(struct EditEdge* e1, struct EditEdge* e2); #define SUBDIV_SELECT_LOOPCUT 3 extern void convert_to_triface(int direction); -extern int removedoublesflag(short flag, float limit); +extern int removedoublesflag(short flag, short automerge, float limit); extern void xsortvert_flag(int flag); extern void hashvert_flag(int flag); diff --git a/source/blender/include/editmesh.h b/source/blender/include/editmesh.h index ba96dff5aca..1b2d91e22b8 100644 --- a/source/blender/include/editmesh.h +++ b/source/blender/include/editmesh.h @@ -90,6 +90,7 @@ extern int convex(float *v1, float *v2, float *v3, float *v4); /* ******************* editmesh_mods.c */ extern EditEdge *findnearestedge(int *dist); +extern void EM_automerge(int update); /** * findnearestvert diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 51ec3a9e133..2ba5ef5437c 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -418,8 +418,10 @@ typedef struct Scene { float editbutsize; /* size of normals */ short selectmode; short proportional, prop_mode; + short automerge, pad5, pad6, pad7; short use_nodes; + struct bNodeTree *nodetree; void *ed; /* sequence editor data is allocated here */ diff --git a/source/blender/python/api2_2x/Mesh.c b/source/blender/python/api2_2x/Mesh.c index 659ecd79d81..494a1250728 100644 --- a/source/blender/python/api2_2x/Mesh.c +++ b/source/blender/python/api2_2x/Mesh.c @@ -3526,7 +3526,7 @@ static PyObject *MEdgeSeq_collapse( BPy_MEdgeSeq * self, PyObject *args ) basact = BASACT; BASACT = base; - removedoublesflag( 1, 0.0 ); + removedoublesflag( 1, 0, 0.0 ); /* make mesh's object active, enter mesh edit mode */ G.obedit = object; @@ -7214,7 +7214,7 @@ static PyObject *Mesh_Tools( BPy_Mesh * self, int type, void **args ) esubdivideflag( 1, 0.0, *((int *)args[0]), 1, 0 ); break; case MESH_TOOL_REMDOUB: - result = removedoublesflag( 1, *((float *)args[0]) ); + result = removedoublesflag( 1, 0, *((float *)args[0]) ); attr = PyInt_FromLong( result ); if( !attr ) diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index c389c2ddc7e..86d518f5467 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -4226,7 +4226,7 @@ void do_meshbuts(unsigned short event) G.f -= G_DISABLE_OK; break; case B_REMDOUB: - count= removedoublesflag(1, G.scene->toolsettings->doublimit); + count= removedoublesflag(1, 1, G.scene->toolsettings->doublimit); notice("Removed: %d", count); if (count) { /* only undo and redraw if an action is taken */ countall (); diff --git a/source/blender/src/editmesh_add.c b/source/blender/src/editmesh_add.c index 49913b345ed..ccd8b58c47e 100644 --- a/source/blender/src/editmesh_add.c +++ b/source/blender/src/editmesh_add.c @@ -960,7 +960,7 @@ void make_prim(int type, float imat[3][3], int tot, int seg, rotateflag(2, v1->co, cmat); } - removedoublesflag(4, 0.0001); + removedoublesflag(4, 0, 0.0001); /* and now do imat */ eve= em->verts.first; diff --git a/source/blender/src/editmesh_mods.c b/source/blender/src/editmesh_mods.c index a8c71824ef1..a0c864de016 100644 --- a/source/blender/src/editmesh_mods.c +++ b/source/blender/src/editmesh_mods.c @@ -131,6 +131,18 @@ void EM_select_mirrored(void) } } +void EM_automerge(int update) { + if (G.scene->automerge) { + if (G.obedit && G.obedit->type==OB_MESH) { + if (removedoublesflag(1, 1, G.scene->toolsettings->doublimit)) { + if (update) { + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); + } + } + } + } +} + /* ****************************** SELECTION ROUTINES **************** */ unsigned int em_solidoffs=0, em_wireoffs=0, em_vertoffs=0; /* set in drawobject.c ... for colorindices */ @@ -3331,7 +3343,7 @@ void Vertex_Menu() { switch(ret) { case 1: - notice("Removed %d Vertices", removedoublesflag(1, G.scene->toolsettings->doublimit)); + notice("Removed %d Vertices", removedoublesflag(1, 0, G.scene->toolsettings->doublimit)); BIF_undo_push("Remove Doubles"); break; case 2: diff --git a/source/blender/src/editmesh_tools.c b/source/blender/src/editmesh_tools.c index 2afac79be1d..56db0ea7016 100644 --- a/source/blender/src/editmesh_tools.c +++ b/source/blender/src/editmesh_tools.c @@ -195,8 +195,15 @@ void convert_to_triface(int direction) } -int removedoublesflag(short flag, float limit) /* return amount */ +int removedoublesflag(short flag, short automerge, float limit) /* return amount */ { + /* + flag - Test with vert->flags + weld - Alternative operation, merge unselected into selected. + Used for "Auto Weld" mode. warning. + limit - Quick manhattan distance between verts. + */ + EditMesh *em = G.editMesh; /* all verts with (flag & 'flag') are being evaluated */ EditVert *eve, *v1, *nextve; @@ -209,12 +216,15 @@ int removedoublesflag(short flag, float limit) /* return amount */ if(multires_test()) return 0; + /* flag 128 is cleared, count */ + + /* Normal non weld operation */ eve= em->verts.first; amount= 0; while(eve) { eve->f &= ~128; - if(eve->h==0 && (eve->f & flag)) amount++; + if(eve->h==0 && (automerge || (eve->f & flag))) amount++; eve= eve->next; } if(amount==0) return 0; @@ -223,7 +233,7 @@ int removedoublesflag(short flag, float limit) /* return amount */ sb= sortblock= MEM_mallocN(sizeof(xvertsort)*amount,"sortremovedoub"); eve= em->verts.first; while(eve) { - if(eve->h==0 && (eve->f & flag)) { + if(eve->h==0 && (automerge || (eve->f & flag))) { sb->x= eve->co[0]+eve->co[1]+eve->co[2]; sb->v1= eve; sb++; @@ -232,44 +242,72 @@ int removedoublesflag(short flag, float limit) /* return amount */ } qsort(sortblock, amount, sizeof(xvertsort), vergxco); + /* test for doubles */ - sb= sortblock; - for(a=0; av1; - if( (eve->f & 128)==0 ) { - sb1= sb+1; - for(b=a+1; bx - sb->x; - if(dist > limit) break; - - /* second test: is vertex allowed */ - v1= sb1->v1; - if( (v1->f & 128)==0 ) { + sb= sortblock; + if (automerge) { + for(a=0; av1; + if( (eve->f & 128)==0 ) { + sb1= sb+1; + for(b=a+1; bf & 128)==0; b++, sb1++) { + if(sb1->x - sb->x > limit) break; - dist= (float)fabs(v1->co[0]-eve->co[0]); - if(dist<=limit) { - dist= (float)fabs(v1->co[1]-eve->co[1]); - if(dist<=limit) { - dist= (float)fabs(v1->co[2]-eve->co[2]); - if(dist<=limit) { + /* when welding, only allow selected-> unselected*/ + v1= sb1->v1; + if( (v1->f & 128)==0 ) { + if ((eve->f & flag)==0 && (v1->f & flag)==1) { + if( (float)fabs(v1->co[0]-eve->co[0])<=limit && + (float)fabs(v1->co[1]-eve->co[1])<=limit && + (float)fabs(v1->co[2]-eve->co[2])<=limit) + { /* unique bit */ + eve->f|= 128; + eve->tmp.v = v1; + } + } else if( (eve->f & flag)==1 && (v1->f & flag)==0 ) { + if( (float)fabs(v1->co[0]-eve->co[0])<=limit && + (float)fabs(v1->co[1]-eve->co[1])<=limit && + (float)fabs(v1->co[2]-eve->co[2])<=limit) + { /* unique bit */ v1->f|= 128; v1->tmp.v = eve; } } } } - sb1++; } } - sb++; + } else { + for(a=0; av1; + if( (eve->f & 128)==0 ) { + sb1= sb+1; + for(b=a+1; bx - sb->x > limit) break; + v1= sb1->v1; + + /* second test: is vertex allowed */ + if( (v1->f & 128)==0 ) { + if( (float)fabs(v1->co[0]-eve->co[0])<=limit && + (float)fabs(v1->co[1]-eve->co[1])<=limit && + (float)fabs(v1->co[2]-eve->co[2])<=limit) + { + v1->f|= 128; + v1->tmp.v = eve; + } + } + } + } + } } MEM_freeN(sortblock); - - for(eve = em->verts.first; eve; eve=eve->next) - if((eve->f & flag) && (eve->f & 128)) - EM_data_interp_from_verts(eve, eve->tmp.v, eve->tmp.v, 0.5f); - + + if (!automerge) + for(eve = em->verts.first; eve; eve=eve->next) + if((eve->f & flag) && (eve->f & 128)) + EM_data_interp_from_verts(eve, eve->tmp.v, eve->tmp.v, 0.5f); + /* test edges and insert again */ eed= em->edges.first; while(eed) { @@ -445,7 +483,7 @@ int removedoublesflag(short flag, float limit) /* return amount */ eve= (struct EditVert *)em->verts.first; while(eve) { nextve= eve->next; - if(eve->f & flag) { + if(automerge || eve->f & flag) { if(eve->f & 128) { a++; BLI_remlink(&em->verts, eve); @@ -4023,7 +4061,7 @@ static void bevel_mesh(float bsize, int allfaces) waitcursor(1); - removedoublesflag(1, limit); + removedoublesflag(1, 0, limit); /* tag all original faces */ efa= em->faces.first; @@ -4378,7 +4416,7 @@ static void bevel_mesh(float bsize, int allfaces) allqueue(REDRAWVIEW3D, 0); DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); - removedoublesflag(1, limit); + removedoublesflag(1, 0, limit); /* flush selected vertices to edges/faces */ EM_select_flush(); @@ -4531,7 +4569,7 @@ int EdgeLoopDelete(void) { return 0; } select_more(); - removedoublesflag(1,0.001); + removedoublesflag(1,0, 0.001); EM_select_flush(); DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); return 1; @@ -5079,6 +5117,8 @@ int EdgeSlide(short immediate, float imperc) } force_draw(0); + + EM_automerge(0); DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); scrarea_queue_winredraw(curarea); @@ -6113,7 +6153,7 @@ int collapseEdges(void) } freecollections(&allcollections); - removedoublesflag(1, MERGELIMIT); + removedoublesflag(1, 0, MERGELIMIT); /*get rid of this!*/ countall(); DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); @@ -6157,7 +6197,7 @@ int merge_firstlast(int first, int uvmerge) } countall(); - return removedoublesflag(1,MERGELIMIT); + return removedoublesflag(1, 0, MERGELIMIT); } int merge_target(int target, int uvmerge) @@ -6180,7 +6220,7 @@ int merge_target(int target, int uvmerge) countall(); DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); - return removedoublesflag(1,MERGELIMIT); + return removedoublesflag(1, 0, MERGELIMIT); } #undef MERGELIMIT diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index 33b6dbfe664..6d63e0ad230 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -2424,12 +2424,12 @@ void special_editmenu(void) esubdivideflag(1, fac, G.scene->toolsettings->editbutflag | B_SMOOTH, 1, 0); BIF_undo_push("Subdivide Smooth"); break; - + case 4: mergemenu(); break; case 5: - notice("Removed %d Vertices", removedoublesflag(1, G.scene->toolsettings->doublimit)); + notice("Removed %d Vertices", removedoublesflag(1, 1, G.scene->toolsettings->doublimit)); BIF_undo_push("Remove Doubles"); break; case 6: diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c index 105ac97f335..d64f8a8d169 100644 --- a/source/blender/src/header_view3d.c +++ b/source/blender/src/header_view3d.c @@ -2536,7 +2536,7 @@ void do_view3d_edit_mesh_verticesmenu(void *arg, int event) make_parent(); break; case 1: /* remove doubles */ - count= removedoublesflag(1, G.scene->toolsettings->doublimit); + count= removedoublesflag(1, 0, G.scene->toolsettings->doublimit); notice("Removed: %d", count); if (count) { /* only undo and redraw if an action is taken */ DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); @@ -2978,8 +2978,12 @@ static void do_view3d_edit_meshmenu(void *arg, int event) if(G.scene->proportional) G.scene->proportional= 0; else G.scene->proportional= 1; break; + case 13: /* automerge edit (toggle) */ + if(G.scene->automerge) G.scene->automerge= 0; + else G.scene->automerge= 1; + break; #ifdef WITH_VERSE - case 13: + case 14: if(session_list.first != session_list.last) session = session_menu(); else session = session_list.first; if(session) b_verse_push_object(session, G.obedit); @@ -3001,7 +3005,7 @@ static uiBlock *view3d_edit_meshmenu(void *arg_unused) #ifdef WITH_VERSE if((session_list.first != NULL) && (!G.obedit->vnode)) { uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Share at Verse Server", - 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, ""); + 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 14, ""); uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); } #endif @@ -3037,6 +3041,8 @@ static uiBlock *view3d_edit_meshmenu(void *arg_unused) uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); + + if(G.scene->proportional) { uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Proportional Editing|O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, ""); } else { @@ -3046,6 +3052,14 @@ static uiBlock *view3d_edit_meshmenu(void *arg_unused) uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); + if(G.scene->automerge) { + uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "AutoMarge Editing", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, ""); + } else { + uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "AutoMarge Editing", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, ""); + } + + uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); + uiDefIconTextBlockBut(block, view3d_edit_mesh_showhidemenu, NULL, ICON_RIGHTARROW_THIN, "Show/Hide Vertices", 0, yco-=20, 120, 19, ""); uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c index 7cb4c9b38c4..3e1f08c82a3 100644 --- a/source/blender/src/transform_conversions.c +++ b/source/blender/src/transform_conversions.c @@ -125,6 +125,8 @@ #include "BLI_blenlib.h" #include "BLI_editVert.h" +#include "editmesh.h" + #include "blendef.h" #include "mydevice.h" @@ -2732,7 +2734,10 @@ void special_aftertrans_update(TransInfo *t) Base *base; short redrawipo=0, resetslowpar=1; int cancelled= (t->state == TRANS_CANCEL); - + + if (t->spacetype==SPACE_VIEW3D) + EM_automerge(1); + if(t->spacetype == SPACE_ACTION) { void *data; short datatype; -- cgit v1.2.3