diff --git a/source/blender/include/BDR_editface.h b/source/blender/include/BDR_editface.h index 41efb4fa4c5..e9e2edd5c4f 100644 --- a/source/blender/include/BDR_editface.h +++ b/source/blender/include/BDR_editface.h @@ -51,7 +51,8 @@ void face_borderselect(void); float CalcNormUV(float *a, float *b, float *c); void uv_autocalc_tface(void); void set_faceselect(void); -void face_draw(void); +void face_draw(void); +void get_same_uv(void); #endif /* BDR_EDITFACE_H */ diff --git a/source/blender/include/BIF_editmesh.h b/source/blender/include/BIF_editmesh.h index 8a72a63f323..3e545ac4507 100644 --- a/source/blender/include/BIF_editmesh.h +++ b/source/blender/include/BIF_editmesh.h @@ -95,7 +95,11 @@ void adduplicateflag(int flag); void extrude_mesh(void); void adduplicate_mesh(void); void split_mesh(void); + +void separatemenu(void); void separate_mesh(void); +void separate_mesh_loose(void); + void extrude_repeat_mesh(int steps, float offs); void spin_mesh(int steps,int degr,float *dvec, int mode); void screw_mesh(int steps,int turns); diff --git a/source/blender/src/editface.c b/source/blender/src/editface.c index bf4d030d00b..290c9b2aa9e 100644 --- a/source/blender/src/editface.c +++ b/source/blender/src/editface.c @@ -1362,4 +1362,70 @@ void face_draw() allqueue(REDRAWIMAGE, 0); allqueue(REDRAWHEADERS, 0); } + + /* Selects all faces which have the same uv-texture as the active face + * @author Roel Spruit + * @return Void + * Errors: - Active object not in this layer + * - No active face or active face has no UV-texture + */ +void get_same_uv(void) +{ + Object *ob; + Mesh *me; + TFace *tface; + short a, foundtex=0; + Image *ima; + char uvname[160]; + + ob = OBACT; + if (!(ob->lay & G.vd->lay)) { + error("Active object not in this layer!"); + return; + } + me = get_mesh(ob); + + + /* Search for the active face with a UV-Texture */ + tface = me->tface; + a = me->totface; + while (a--) { + if(tface->flag & TF_ACTIVE){ + ima=tface->tpage; + if(ima && ima->name){ + strcpy(uvname,ima->name); + a=0; + foundtex=1; + } + } + tface++; + } + + if(!foundtex) { + error("No active face or active face has no UV-texture"); + return; + } + + /* select everything with the same texture */ + tface = me->tface; + a = me->totface; + while (a--) { + ima=tface->tpage; + if(ima && ima->name){ + if(!strcmp(ima->name, uvname)){ + tface->flag |= TF_SELECT; + } + else tface->flag &= ~TF_SELECT; + } + else tface->flag &= ~TF_SELECT; + tface++; + } + + + + /* image window redraw */ + allqueue(REDRAWIMAGE, 0); + allqueue(REDRAWBUTSGAME, 0); + allqueue(REDRAWVIEW3D, 0); +} #endif /* NAN_TPT */ diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c index 69c94c4d842..dabf440cfb8 100644 --- a/source/blender/src/editmesh.c +++ b/source/blender/src/editmesh.c @@ -3607,6 +3607,25 @@ void split_mesh(void) makeDispList(G.obedit); } + +void separatemenu(void) +{ + short event; + + event = pupmenu("Separate %t|Selected%x1|All loose parts%x2"); + + switch (event) { + + case 1: + separate_mesh(); + break; + case 2: + separate_mesh_loose(); + break; + } +} + + void separate_mesh(void) { EditVert *eve, *v1; @@ -3619,9 +3638,7 @@ void separate_mesh(void) float trans[9]; int ok, flag; - TEST_EDITMESH - - if(okee("Separate")==0) return; + TEST_EDITMESH waitcursor(1); @@ -3744,6 +3761,203 @@ void separate_mesh(void) } +void separate_mesh_loose(void) +{ + EditVert *eve, *v1; + EditEdge *eed, *e1; + EditVlak *evl, *vl1; + Object *oldob; + Mesh *me, *men; + Base *base, *oldbase; + ListBase edve, eded, edvl; + float trans[9]; + int ok, vertsep=0, flag; + short sel,toggle=0, done=0, check=1, loop=0; + + TEST_EDITMESH + waitcursor(1); + + /* we are going to abuse the system as follows: + * 1. add a duplicate object: this will be the new one, we remember old pointer + * 2: then do a split if needed. + * 3. put apart: all NOT selected verts, edges, faces + * 4. call loadobeditdata(): this will be the new object + * 5. freelist en oude verts, eds, vlakken weer terughalen + */ + + + + while(!done){ + vertsep=check=1; + + countall(); + + me= get_mesh(G.obedit); + if(me->key) { + error("Can't separate with vertex keys"); + return; + } + + /* make only obedit selected */ + base= FIRSTBASE; + while(base) { + if(base->lay & G.vd->lay) { + if(base->object==G.obedit) base->flag |= SELECT; + else base->flag &= ~SELECT; + } + base= base->next; + } + + /*--------- Select connected-----------*/ + //sel= 3; + /* clear test flags */ + eve= G.edve.first; + while(eve) { + eve->f&= ~1; + eve= eve->next; + } + + /* Select a random vert to start with */ + eve= G.edve.first; + eve->f |= 1; + + while(check==1) { + check= 0; + eed= G.eded.first; + while(eed) { + if(eed->h==0) { + if(eed->v1->f & 1) { + if( (eed->v2->f & 1)==0 ) { + eed->v2->f |= 1; + vertsep++; + check= 1; + } + } + else if(eed->v2->f & 1) { + if( (eed->v1->f & 1)==0 ) { + eed->v1->f |= 1; + vertsep++; + check= 1; + } + } + } + eed= eed->next; + } + } + /*----------End of select connected--------*/ + + + /* If the amount of vertices that is about to be split == the total amount + of verts in the mesh, it means that there is only 1 unconnected object, so we don't have to separate + */ + if(G.totvert==vertsep)done=1; + else{ + /* Test for splitting: Separate selected */ + ok= 0; + eed= G.eded.first; + while(eed) { + flag= (eed->v1->f & 1)+(eed->v2->f & 1); + if(flag==1) { + ok= 1; + break; + } + eed= eed->next; + } + if(ok) { + /* SPLIT: first make duplicate */ + adduplicateflag(1); + /* SPLIT: old faces have 3x flag 128 set, delete these ones */ + delvlakflag(128); + } + + + + /* set apart: everything that is not selected */ + edve.first= edve.last= eded.first= eded.last= edvl.first= edvl.last= 0; + eve= G.edve.first; + while(eve) { + v1= eve->next; + if((eve->f & 1)==0) { + BLI_remlink(&G.edve, eve); + BLI_addtail(&edve, eve); + } + eve= v1; + } + eed= G.eded.first; + while(eed) { + e1= eed->next; + if( (eed->v1->f & 1)==0 || (eed->v2->f & 1)==0 ) { + BLI_remlink(&G.eded, eed); + BLI_addtail(&eded, eed); + } + eed= e1; + } + evl= G.edvl.first; + while(evl) { + vl1= evl->next; + if( (evl->v1->f & 1)==0 || (evl->v2->f & 1)==0 || (evl->v3->f & 1)==0 ) { + BLI_remlink(&G.edvl, evl); + BLI_addtail(&edvl, evl); + } + evl= vl1; + } + + oldob= G.obedit; + oldbase= BASACT; + + trans[0]=trans[1]=trans[2]=trans[3]=trans[4]=trans[5]= 0.0; + trans[6]=trans[7]=trans[8]= 1.0; + G.qual |= LR_ALTKEY; /* patch to make sure we get a linked duplicate */ + adduplicate(trans); + G.qual &= ~LR_ALTKEY; + + G.obedit= BASACT->object; /* basact was set in adduplicate() */ + + men= copy_mesh(me); + set_mesh(G.obedit, men); + /* because new mesh is a copy: reduce user count */ + men->id.us--; + + load_editMesh(); + + BASACT->flag &= ~SELECT; + + makeDispList(G.obedit); + free_editMesh(); + + G.edve= edve; + G.eded= eded; + G.edvl= edvl; + + /* hashedges are freed now, make new! */ + eed= G.eded.first; + while(eed) { + if( findedgelist(eed->v1, eed->v2)==NULL ) + insert_hashedge(eed); + eed= eed->next; + } + + G.obedit= oldob; + BASACT= oldbase; + BASACT->flag |= SELECT; + + } + } + + /* unselect the vertices that we (ab)used for the separation*/ + eve= G.edve.first; + while(eve) { + eve->f&= ~1; + eve= eve->next; + } + + waitcursor(0); + countall(); + allqueue(REDRAWVIEW3D, 0); + makeDispList(G.obedit); +} + + void extrude_repeat_mesh(int steps, float offs) { float dvec[3], tmat[3][3], bmat[3][3]; diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index fcaf29d5190..19666e70934 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -140,6 +140,7 @@ #include "BDR_editobject.h" #include "BDR_drawobject.h" #include "BDR_editcurve.h" +#include "BDR_editface.h" #include "render.h" #include @@ -1396,7 +1397,7 @@ void special_editmenu(void) if(me==0 || me->tface==0) return; - nr= pupmenu("Specials%t|Set Tex%x1| Shared%x2| Light%x3| Invisible%x4| Collision%x5|Clr Tex%x6| Shared%x7| Light%x8| Invisible%x9| Collision%x10"); + nr= pupmenu("Specials%t|Set Tex%x1| Shared%x2| Light%x3| Invisible%x4| Collision%x5|Clr Tex%x6| Shared%x7| Light%x8| Invisible%x9| Collision%x10|Sel Same UV%x11"); for(a=me->totface, tface= me->tface; a>0; a--, tface++) { if(tface->flag & SELECT) { @@ -1423,6 +1424,8 @@ void special_editmenu(void) tface->mode &= ~TF_INVISIBLE; break; case 10: tface->mode &= ~TF_DYNAMIC; break; + case 11: + get_same_uv(); break; } } } diff --git a/source/blender/src/space.c b/source/blender/src/space.c index ff1b5746b23..c289f8275ae 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -1054,7 +1054,7 @@ void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) if(G.qual) { if(G.qual & LR_CTRLKEY) make_parent(); } - else if(G.obedit->type==OB_MESH) separate_mesh(); + else if(G.obedit->type==OB_MESH) separatemenu(); else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) separate_nurb(); } else if(G.qual & LR_CTRLKEY) make_parent();