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:
Diffstat (limited to 'source/blender/src/editmesh_mods.c')
-rw-r--r--source/blender/src/editmesh_mods.c1899
1 files changed, 1032 insertions, 867 deletions
diff --git a/source/blender/src/editmesh_mods.c b/source/blender/src/editmesh_mods.c
index f711b90317b..595af2658e8 100644
--- a/source/blender/src/editmesh_mods.c
+++ b/source/blender/src/editmesh_mods.c
@@ -49,6 +49,7 @@ editmesh_mods.c, UI level access, no geometry changes
#endif
#include "MEM_guardedalloc.h"
+#include "MTC_matrixops.h"
#include "DNA_mesh_types.h"
#include "DNA_material_types.h"
@@ -74,9 +75,11 @@ editmesh_mods.c, UI level access, no geometry changes
#include "BIF_editmesh.h"
#include "BIF_resources.h"
#include "BIF_gl.h"
+#include "BIF_glutil.h"
#include "BIF_graphics.h"
#include "BIF_interface.h"
#include "BIF_mywindow.h"
+#include "BIF_resources.h"
#include "BIF_screen.h"
#include "BIF_space.h"
#include "BIF_toolbox.h"
@@ -93,280 +96,19 @@ editmesh_mods.c, UI level access, no geometry changes
#include "editmesh.h"
-/* **************************** MODS ************************* */
-
-void selectswap_mesh(void)
-{
- EditMesh *em = G.editMesh;
- EditVert *eve;
-
- eve= em->verts.first;
- while(eve) {
- if(eve->h==0) {
- if(eve->f & 1) eve->f&= ~1;
- else eve->f|= 1;
- }
- eve= eve->next;
- }
- countall();
- allqueue(REDRAWVIEW3D, 0);
-
-}
-
+/* ****************************** SELECTION ROUTINES **************** */
-void deselectall_mesh(void) /* toggle */
-{
- EditMesh *em = G.editMesh;
- EditVert *eve;
- int a;
-
- if(G.obedit->lay & G.vd->lay) {
- a= 0;
- eve= em->verts.first;
- while(eve) {
- if(eve->f & 1) {
- a= 1;
- break;
- }
- eve= eve->next;
- }
-
- if (a) undo_push_mesh("Deselect All");
- else undo_push_mesh("Select All");
-
- eve= em->verts.first;
- while(eve) {
- if(eve->h==0) {
- if(a) eve->f&= -2;
- else eve->f|= 1;
- }
- eve= eve->next;
- }
- }
- countall();
- allqueue(REDRAWVIEW3D, 0);
-}
-
-
-void righthandfaces(int select) /* makes faces righthand turning */
-{
- EditMesh *em = G.editMesh;
- EditEdge *eed, *ed1, *ed2, *ed3, *ed4;
- EditFace *efa, *startvl;
- float maxx, nor[3], cent[3];
- int totsel, found, foundone, direct, turn, tria_nr;
-
- /* based at a select-connected to witness loose objects */
-
- /* count per edge the amount of faces */
-
- /* find the ultimate left, front, upper face (not manhattan dist!!) */
- /* also evaluate both triangle cases in quad, since these can be non-flat */
-
- /* put normal to the outside, and set the first direction flags in edges */
-
- /* then check the object, and set directions / direction-flags: but only for edges with 1 or 2 faces */
- /* this is in fact the 'select connected' */
-
- /* in case (selected) faces were not done: start over with 'find the ultimate ...' */
-
- waitcursor(1);
-
- eed= em->edges.first;
- while(eed) {
- eed->f= 0;
- eed->f1= 0;
- eed= eed->next;
- }
-
- /* count faces and edges */
- totsel= 0;
- efa= em->faces.first;
- while(efa) {
- if(select==0 || faceselectedAND(efa, 1) ) {
- efa->f= 1;
- totsel++;
- efa->e1->f1++;
- efa->e2->f1++;
- efa->e3->f1++;
- if(efa->v4) efa->e4->f1++;
- }
- else efa->f= 0;
-
- efa= efa->next;
- }
-
- while(totsel>0) {
- /* from the outside to the inside */
-
- efa= em->faces.first;
- startvl= NULL;
- maxx= -1.0e10;
- tria_nr= 0;
-
- while(efa) {
- if(efa->f) {
- CalcCent3f(cent, efa->v1->co, efa->v2->co, efa->v3->co);
- cent[0]= cent[0]*cent[0] + cent[1]*cent[1] + cent[2]*cent[2];
-
- if(cent[0]>maxx) {
- maxx= cent[0];
- startvl= efa;
- tria_nr= 0;
- }
- if(efa->v4) {
- CalcCent3f(cent, efa->v1->co, efa->v3->co, efa->v4->co);
- cent[0]= cent[0]*cent[0] + cent[1]*cent[1] + cent[2]*cent[2];
-
- if(cent[0]>maxx) {
- maxx= cent[0];
- startvl= efa;
- tria_nr= 1;
- }
- }
- }
- efa= efa->next;
- }
-
- /* set first face correct: calc normal */
-
- if(tria_nr==1) {
- CalcNormFloat(startvl->v1->co, startvl->v3->co, startvl->v4->co, nor);
- CalcCent3f(cent, startvl->v1->co, startvl->v3->co, startvl->v4->co);
- } else {
- CalcNormFloat(startvl->v1->co, startvl->v2->co, startvl->v3->co, nor);
- CalcCent3f(cent, startvl->v1->co, startvl->v2->co, startvl->v3->co);
- }
- /* first normal is oriented this way or the other */
- if(select) {
- if(select==2) {
- if(cent[0]*nor[0]+cent[1]*nor[1]+cent[2]*nor[2] > 0.0) flipface(startvl);
- }
- else {
- if(cent[0]*nor[0]+cent[1]*nor[1]+cent[2]*nor[2] < 0.0) flipface(startvl);
- }
- }
- else if(cent[0]*nor[0]+cent[1]*nor[1]+cent[2]*nor[2] < 0.0) flipface(startvl);
-
-
- eed= startvl->e1;
- if(eed->v1==startvl->v1) eed->f= 1;
- else eed->f= 2;
-
- eed= startvl->e2;
- if(eed->v1==startvl->v2) eed->f= 1;
- else eed->f= 2;
-
- eed= startvl->e3;
- if(eed->v1==startvl->v3) eed->f= 1;
- else eed->f= 2;
-
- eed= startvl->e4;
- if(eed) {
- if(eed->v1==startvl->v4) eed->f= 1;
- else eed->f= 2;
- }
-
- startvl->f= 0;
- totsel--;
-
- /* test normals */
- found= 1;
- direct= 1;
- while(found) {
- found= 0;
- if(direct) efa= em->faces.first;
- else efa= em->faces.last;
- while(efa) {
- if(efa->f) {
- turn= 0;
- foundone= 0;
-
- ed1= efa->e1;
- ed2= efa->e2;
- ed3= efa->e3;
- ed4= efa->e4;
-
- if(ed1->f) {
- if(ed1->v1==efa->v1 && ed1->f==1) turn= 1;
- if(ed1->v2==efa->v1 && ed1->f==2) turn= 1;
- foundone= 1;
- }
- else if(ed2->f) {
- if(ed2->v1==efa->v2 && ed2->f==1) turn= 1;
- if(ed2->v2==efa->v2 && ed2->f==2) turn= 1;
- foundone= 1;
- }
- else if(ed3->f) {
- if(ed3->v1==efa->v3 && ed3->f==1) turn= 1;
- if(ed3->v2==efa->v3 && ed3->f==2) turn= 1;
- foundone= 1;
- }
- else if(ed4 && ed4->f) {
- if(ed4->v1==efa->v4 && ed4->f==1) turn= 1;
- if(ed4->v2==efa->v4 && ed4->f==2) turn= 1;
- foundone= 1;
- }
-
- if(foundone) {
- found= 1;
- totsel--;
- efa->f= 0;
-
- if(turn) {
- if(ed1->v1==efa->v1) ed1->f= 2;
- else ed1->f= 1;
- if(ed2->v1==efa->v2) ed2->f= 2;
- else ed2->f= 1;
- if(ed3->v1==efa->v3) ed3->f= 2;
- else ed3->f= 1;
- if(ed4) {
- if(ed4->v1==efa->v4) ed4->f= 2;
- else ed4->f= 1;
- }
-
- flipface(efa);
-
- }
- else {
- if(ed1->v1== efa->v1) ed1->f= 1;
- else ed1->f= 2;
- if(ed2->v1==efa->v2) ed2->f= 1;
- else ed2->f= 2;
- if(ed3->v1==efa->v3) ed3->f= 1;
- else ed3->f= 2;
- if(ed4) {
- if(ed4->v1==efa->v4) ed4->f= 1;
- else ed4->f= 2;
- }
- }
- }
- }
- if(direct) efa= efa->next;
- else efa= efa->prev;
- }
- direct= 1-direct;
- }
- }
-
- recalc_editnormals();
-
- makeDispList(G.obedit);
-
- waitcursor(0);
-}
-
-static EditVert *findnearestvert(short sel)
+static EditVert *findnearestvert(short *dist, short sel)
{
+ static EditVert *acto= NULL;
EditMesh *em = G.editMesh;
/* if sel==1 the vertices with flag==1 get a disadvantage */
- EditVert *eve,*act=0;
- static EditVert *acto=0;
- short dist=100,temp,mval[2];
+ EditVert *eve,*act=NULL;
+ short temp, mval[2];
- if(em->verts.first==0) return 0;
+ if(em->verts.first==NULL) return NULL;
/* do projection */
calc_meshverts_ext(); /* drawobject.c */
@@ -378,9 +120,7 @@ static EditVert *findnearestvert(short sel)
if(eve==acto) break;
eve= eve->next;
}
- if(eve==0) acto= em->verts.first;
-
- if(acto==0) return 0;
+ if(eve==NULL) acto= em->verts.first;
/* is there an indicated vertex? part 1 */
getmouseco_areawin(mval);
@@ -389,25 +129,25 @@ static EditVert *findnearestvert(short sel)
if(eve->h==0) {
temp= abs(mval[0]- eve->xs)+ abs(mval[1]- eve->ys);
if( (eve->f & 1)==sel ) temp+=5;
- if(temp<dist) {
+ if(temp< *dist) {
act= eve;
- dist= temp;
- if(dist<4) break;
+ *dist= temp;
+ if(*dist<4) break;
}
}
eve= eve->next;
}
/* is there an indicated vertex? part 2 */
- if(dist>3) {
+ if(*dist>3) {
eve= em->verts.first;
while(eve) {
if(eve->h==0) {
temp= abs(mval[0]- eve->xs)+ abs(mval[1]- eve->ys);
if( (eve->f & 1)==sel ) temp+=5;
- if(temp<dist) {
+ if(temp< *dist) {
act= eve;
if(temp<4) break;
- dist= temp;
+ *dist= temp;
}
if(eve== acto) break;
}
@@ -420,16 +160,16 @@ static EditVert *findnearestvert(short sel)
}
-EditEdge *findnearestedge()
+EditEdge *findnearestedge(short *dist)
{
EditMesh *em = G.editMesh;
EditEdge *closest, *eed;
EditVert *eve;
- short found=0, mval[2];
- float distance[2], v1[2], v2[2], mval2[2];
+ short mval[2], distance;
+ float v1[2], v2[2], mval2[2];
- if(em->edges.first==0) return NULL;
- else eed=em->edges.first;
+ if(em->edges.first==NULL) return NULL;
+ else eed= em->edges.first;
/* reset flags */
for(eve=em->verts.first; eve; eve=eve->next){
@@ -443,31 +183,21 @@ EditEdge *findnearestedge()
mval2[0] = (float)mval[0];
mval2[1] = (float)mval[1];
- eed=em->edges.first;
/*compare the distance to the rest of the edges and find the closest one*/
+ eed=em->edges.first;
while(eed) {
/* Are both vertices of the edge ofscreen or either of them hidden? then don't select the edge*/
- if( !((eed->v1->f & 2) && (eed->v2->f & 2)) && (eed->v1->h==0 && eed->v2->h==0)){
+ if( !((eed->v1->f & 2) && (eed->v2->f & 2)) && eed->h==0){
v1[0] = eed->v1->xs;
v1[1] = eed->v1->ys;
v2[0] = eed->v2->xs;
v2[1] = eed->v2->ys;
- distance[1] = PdistVL2Dfl(mval2, v1, v2);
+ distance= (short)PdistVL2Dfl(mval2, v1, v2);
- if(distance[1]<50){
- /*do we have to compare it to other distances? */
- if(found) {
- if (distance[1]<distance[0]){
- distance[0]=distance[1];
- /*save the current closest edge*/
- closest=eed;
- }
- } else {
- distance[0]=distance[1];
- closest=eed;
- found=1;
- }
+ if(distance < *dist) {
+ *dist= distance;
+ closest= eed;
}
}
eed= eed->next;
@@ -478,151 +208,237 @@ EditEdge *findnearestedge()
eve->f &= ~2;
}
- if(found) return closest;
- else return 0;
+ return closest;
}
-static void edge_select(void)
+
+static EditFace *findnearestface(short *dist)
{
+ static EditFace *acto= NULL;
EditMesh *em = G.editMesh;
- EditEdge *closest=0;
-
- closest=findnearestedge();
+ /* if selected the faces with flag==1 get a disadvantage */
+ EditFace *efa, *act=NULL;
+ short temp, mval[2];
+
+ if(em->faces.first==NULL) return NULL;
+
+ /* do projection */
+ calc_mesh_facedots_ext();
- if(closest){ /* Did we find anything that is selectable?*/
+ /* we count from acto->next to last, and from first to acto */
+ /* does acto exist? */
+ efa= em->faces.first;
+ while(efa) {
+ if(efa==acto) break;
+ efa= efa->next;
+ }
+ if(efa==NULL) acto= em->faces.first;
- if( (G.qual & LR_SHIFTKEY)==0) {
- EditVert *eve;
-
- undo_push_mesh("Select Edge");
- /* deselectall */
- for(eve= em->verts.first; eve; eve= eve->next) eve->f&= ~1;
-
- /* select edge */
- closest->v1->f |= 1;
- closest->v2->f |= 1;
- }
- else {
- /* both of the vertices are selected: deselect both*/
- if((closest->v1->f & 1) && (closest->v2->f & 1) ){
- closest->v1->f &= ~1;
- closest->v2->f &= ~1;
+ /* is there an indicated face? part 1 */
+ getmouseco_areawin(mval);
+ efa= acto->next;
+ while(efa) {
+ if(efa->h==0) {
+ temp= abs(mval[0]- efa->xs)+ abs(mval[1]- efa->ys);
+ if(temp< *dist) {
+ act= efa;
+ *dist= temp;
}
- else {
- /* select both */
- closest->v1->f |= 1;
- closest->v2->f |= 1;
+ }
+ efa= efa->next;
+ }
+ /* is there an indicated face? part 2 */
+ if(*dist>3) {
+ efa= em->faces.first;
+ while(efa) {
+ if(efa->h==0) {
+ temp= abs(mval[0]- efa->xs)+ abs(mval[1]- efa->ys);
+ if(temp< *dist) {
+ act= efa;
+ *dist= temp;
+ }
+ if(efa== acto) break;
}
+ efa= efa->next;
}
- countall();
- allqueue(REDRAWVIEW3D, 0);
}
+
+ acto= act;
+ return act;
}
-static void draw_vertices_special(int mode, EditVert *act) /* teken = draw */
+/* for interactivity, frontbuffer draw in current window */
+static void unified_select_draw(EditVert *eve, EditEdge *eed, EditFace *efa)
{
- /* (only this view, no other windows) */
- /* hackish routine for visual speed:
- * mode 0: deselect the selected ones, draw them, except act
- * mode 1: only draw act
- */
- EditMesh *em = G.editMesh;
- EditVert *eve;
- float size= BIF_GetThemeValuef(TH_VERTEX_SIZE);
- char col[3];
-
- glPointSize(size);
+
+ glDrawBuffer(GL_FRONT);
persp(PERSP_VIEW);
glPushMatrix();
mymultmatrix(G.obedit->obmat);
-
- if(mode==0) {
- BIF_ThemeColor(TH_VERTEX);
-
- /* set zbuffer on, its default off outside main drawloops */
- if(G.vd->drawtype > OB_WIRE) {
- G.zbuf= 1;
- glEnable(GL_DEPTH_TEST);
+
+ /* face selected */
+ if(efa) {
+ if(G.scene->selectmode & SCE_SELECT_VERTEX) {
+ glPointSize(BIF_GetThemeValuef(TH_VERTEX_SIZE));
+
+ if(efa->f & SELECT) BIF_ThemeColor(TH_VERTEX_SELECT);
+ else BIF_ThemeColor(TH_VERTEX);
+
+ bglBegin(GL_POINTS);
+ bglVertex3fv(efa->v1->co);
+ bglVertex3fv(efa->v2->co);
+ bglVertex3fv(efa->v3->co);
+ if(efa->v4) bglVertex3fv(efa->v4->co);
+ bglEnd();
}
- glBegin(GL_POINTS);
- eve= (EditVert *)em->verts.first;
- while(eve) {
- if(eve->h==0) {
- if(eve!=act && (eve->f & 1)) {
- eve->f -= 1;
- glVertex3fv(eve->co);
- }
- }
- eve= eve->next;
+ if(G.scene->selectmode & (SCE_SELECT_EDGE|SCE_SELECT_FACE)) {
+ if(efa->f & SELECT) BIF_ThemeColor(TH_EDGE_SELECT);
+ else BIF_ThemeColor(TH_WIRE);
+
+ glBegin(GL_LINE_LOOP);
+ glVertex3fv(efa->v1->co);
+ glVertex3fv(efa->v2->co);
+ glVertex3fv(efa->v3->co);
+ if(efa->v4) glVertex3fv(efa->v4->co);
+ glEnd();
}
- glEnd();
- glDisable(GL_DEPTH_TEST);
- G.zbuf= 0;
+ if(G.scene->selectmode & SCE_SELECT_FACE) {
+ glPointSize(BIF_GetThemeValuef(TH_FACEDOT_SIZE));
+
+ if(efa->f & SELECT) BIF_ThemeColor(TH_FACE_DOT);
+ else BIF_ThemeColor(TH_WIRE);
+
+ bglBegin(GL_POINTS);
+ bglVertex3fv(efa->cent);
+ bglEnd();
+ }
+ }
+ /* edge selected */
+ if(eed) {
+ if(G.scene->selectmode & (SCE_SELECT_EDGE|SCE_SELECT_FACE)) {
+ if(eed->f & SELECT) BIF_ThemeColor(TH_EDGE_SELECT);
+ else BIF_ThemeColor(TH_WIRE);
+
+ glBegin(GL_LINES);
+ glVertex3fv(eed->v1->co);
+ glVertex3fv(eed->v2->co);
+ glEnd();
+ }
+ if(G.scene->selectmode & SCE_SELECT_VERTEX) {
+ glPointSize(BIF_GetThemeValuef(TH_VERTEX_SIZE));
+
+ if(eed->f & SELECT) BIF_ThemeColor(TH_VERTEX_SELECT);
+ else BIF_ThemeColor(TH_VERTEX);
+
+ bglBegin(GL_POINTS);
+ bglVertex3fv(eed->v1->co);
+ bglVertex3fv(eed->v2->co);
+ bglEnd();
+ }
+ }
+ if(eve) {
+ if(G.scene->selectmode & SCE_SELECT_VERTEX) {
+ glPointSize(BIF_GetThemeValuef(TH_VERTEX_SIZE));
+
+ if(eve->f & SELECT) BIF_ThemeColor(TH_VERTEX_SELECT);
+ else BIF_ThemeColor(TH_VERTEX);
+
+ bglBegin(GL_POINTS);
+ bglVertex3fv(eve->co);
+ bglEnd();
+ }
}
-
- /* draw active vertex */
- if(act->f & 1) BIF_GetThemeColor3ubv(TH_VERTEX_SELECT, col);
- else BIF_GetThemeColor3ubv(TH_VERTEX, col);
-
- glColor3ub(col[0], col[1], col[2]);
- glBegin(GL_POINTS);
- glVertex3fv(act->co);
- glEnd();
-
glPointSize(1.0);
glPopMatrix();
-
+ glFlush();
+ glDrawBuffer(GL_BACK);
+
+ /* signal that frontbuf differs from back */
+ curarea->win_swap= WIN_FRONT_OK;
}
-void mouse_mesh(void)
-{
- EditVert *act=0;
- if(G.qual & LR_ALTKEY) {
- if (G.qual & LR_CTRLKEY) edge_select();
+/* best distance based on screen coords.
+ use g.scene->selectmode to define how to use
+ selected vertices and edges get disadvantage
+ return 1 if found one
+*/
+static int unified_findnearest(EditVert **eve, EditEdge **eed, EditFace **efa)
+{
+ short dist= 75;
+
+ *eve= NULL;
+ *eed= NULL;
+ *efa= NULL;
+
+ if(G.scene->selectmode & SCE_SELECT_VERTEX)
+ *eve= findnearestvert(&dist, SELECT);
+ if(G.scene->selectmode & SCE_SELECT_FACE)
+ *efa= findnearestface(&dist);
+
+ dist-= 20; // since edges select lines, we give dots advantage of 20 pix
+ if(G.scene->selectmode & SCE_SELECT_EDGE)
+ *eed= findnearestedge(&dist);
+
+ /* return only one of 3 pointers, for frontbuffer redraws */
+ if(*eed) {
+ *efa= NULL; *eve= NULL;
+ }
+ else if(*efa) {
+ *eve= NULL;
}
- else {
- act= findnearestvert(1);
- if(act) {
-
- glDrawBuffer(GL_FRONT);
-
- undo_push_mesh("Select Vertex");
-
- if( (act->f & 1)==0) act->f+= 1;
- else if(G.qual & LR_SHIFTKEY) act->f-= 1;
+ return (*eve || *eed || *efa);
+}
- if((G.qual & LR_SHIFTKEY)==0) {
- draw_vertices_special(0, act);
+/* here actual select happens */
+void mouse_mesh(void)
+{
+ EditVert *eve;
+ EditEdge *eed;
+ EditFace *efa;
+
+ if(unified_findnearest(&eve, &eed, &efa)) {
+
+ if((G.qual & LR_SHIFTKEY)==0) EM_clear_flag_all(SELECT);
+
+ if(efa) {
+ if( (efa->f & SELECT)==0 ) {
+ EM_select_face(efa, 1);
}
- else draw_vertices_special(1, act);
-
- countall();
-
- glFlush();
- glDrawBuffer(GL_BACK);
-
- /* signal that frontbuf differs from back */
- curarea->win_swap= WIN_FRONT_OK;
-
- if(G.f & (G_FACESELECT|G_DRAWFACES|G_DRAWEDGES)) {
- /* update full view later on */
- allqueue(REDRAWVIEW3D, 0);
+ else if(G.qual & LR_SHIFTKEY) {
+ EM_select_face(efa, 0);
+ }
+ }
+ else if(eed) {
+ if((eed->f & SELECT)==0) {
+ EM_select_edge(eed, 1);
+ }
+ else if(G.qual & LR_SHIFTKEY) {
+ EM_select_edge(eed, 0);
}
- else allqueue(REDRAWVIEW3D, curarea->win); // all windows except this one
}
+ else if(eve) {
+ if((eve->f & SELECT)==0) eve->f |= SELECT;
+ else if(G.qual & LR_SHIFTKEY) eve->f |= ~SELECT;
+ }
+
+ /* frontbuffer draw of last selected only */
+ unified_select_draw(eve, eed, efa);
- rightmouse_transform();
- }
-}
+ countall();
+ EM_selectmode_flush();
+ allqueue(REDRAWVIEW3D, 0);
+ }
+ rightmouse_transform();
+}
static void selectconnectedAll(void)
@@ -630,31 +446,31 @@ static void selectconnectedAll(void)
EditMesh *em = G.editMesh;
EditVert *v1,*v2;
EditEdge *eed;
- short flag=1,toggle=0;
+ short done=1, toggle=0;
if(em->edges.first==0) return;
- undo_push_mesh("Select Connected (All)");
-
- while(flag==1) {
- flag= 0;
+ while(done==1) {
+ done= 0;
+
toggle++;
if(toggle & 1) eed= em->edges.first;
else eed= em->edges.last;
+
while(eed) {
v1= eed->v1;
v2= eed->v2;
if(eed->h==0) {
- if(v1->f & 1) {
- if( (v2->f & 1)==0 ) {
- v2->f |= 1;
- flag= 1;
+ if(v1->f & SELECT) {
+ if( (v2->f & SELECT)==0 ) {
+ v2->f |= SELECT;
+ done= 1;
}
}
- else if(v2->f & 1) {
- if( (v1->f & 1)==0 ) {
- v1->f |= 1;
- flag= 1;
+ else if(v2->f & SELECT) {
+ if( (v1->f & SELECT)==0 ) {
+ v1->f |= SELECT;
+ done= 1;
}
}
}
@@ -662,18 +478,23 @@ static void selectconnectedAll(void)
else eed= eed->prev;
}
}
+
+ /* now use vertex select flag to select rest */
+ EM_select_flush();
+
countall();
allqueue(REDRAWVIEW3D, 0);
-
+ BIF_undo_push("Select Connected (All)");
}
void selectconnected_mesh(int qual)
{
EditMesh *em = G.editMesh;
- EditVert *eve,*v1,*v2,*act= 0;
+ EditVert *eve, *v1, *v2;
EditEdge *eed;
- short flag=1,sel,toggle=0;
+ EditFace *efa;
+ short done=1, sel, toggle=0;
if(em->edges.first==0) return;
@@ -682,308 +503,778 @@ void selectconnected_mesh(int qual)
return;
}
- sel= 3;
- if(qual & LR_SHIFTKEY) sel=2;
- act= findnearestvert(sel-2);
- if(act==0) {
+ if( unified_findnearest(&eve, &eed, &efa)==0 ) {
error("Nothing indicated ");
return;
}
- undo_push_mesh("Select Linked");
- /* clear test flags */
- eve= em->verts.first;
- while(eve) {
- eve->f&= ~2;
- eve= eve->next;
- }
- act->f= (act->f & ~3) | sel;
+ sel= 1;
+ if(qual & LR_SHIFTKEY) sel=0;
- while(flag==1) {
- flag= 0;
+ /* clear test flags */
+ for(v1= em->verts.first; v1; v1= v1->next) v1->f1= 0;
+
+ /* start vertex/face/edge */
+ if(eve) eve->f1= 1;
+ else if(eed) eed->v1->f1= eed->v2->f1= 1;
+ else efa->v1->f1= efa->v2->f1= efa->v3->f1= 1;
+
+ /* set flag f1 if affected */
+ while(done==1) {
+ done= 0;
toggle++;
+
if(toggle & 1) eed= em->edges.first;
else eed= em->edges.last;
+
while(eed) {
v1= eed->v1;
v2= eed->v2;
+
if(eed->h==0) {
- if(v1->f & 2) {
- if( (v2->f & 2)==0 ) {
- v2->f= (v2->f & ~3) | sel;
- flag= 1;
- }
+ if(v1->f1 && v2->f1==0) {
+ v2->f1= 1;
+ done= 1;
}
- else if(v2->f & 2) {
- if( (v1->f & 2)==0 ) {
- v1->f= (v1->f & ~3) | sel;
- flag= 1;
- }
+ else if(v1->f1==0 && v2->f1) {
+ v1->f1= 1;
+ done= 1;
}
}
+
if(toggle & 1) eed= eed->next;
else eed= eed->prev;
}
}
+
+ /* now use vertex f1 flag to select/deselect */
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ if(eed->v1->f1 && eed->v2->f1)
+ EM_select_edge(eed, sel);
+ }
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ if(efa->v1->f1 && efa->v2->f1 && efa->v3->f1 && (efa->v4 && efa->v4->f1))
+ EM_select_face(efa, sel);
+ }
+ /* no flush needed, connected geometry is done */
+
countall();
allqueue(REDRAWVIEW3D, 0);
+ BIF_undo_push("Select Linked");
+
}
-void vertexsmooth(void)
+
+/* swap is 0 or 1, if 1 it hides not selected */
+void hide_mesh(int swap)
{
EditMesh *em = G.editMesh;
EditVert *eve;
EditEdge *eed;
- float *adror, *adr, fac;
- float fvec[3];
- int teller=0;
-
+ EditFace *efa;
+
if(G.obedit==0) return;
- /* count */
- eve= em->verts.first;
- while(eve) {
- if(eve->f & 1) teller++;
- eve= eve->next;
- }
- if(teller==0) return;
+ /* hide happens on least dominant select mode */
- undo_push_mesh("Smooth");
-
- adr=adror= (float *)MEM_callocN(3*sizeof(float *)*teller, "vertsmooth");
- eve= em->verts.first;
- while(eve) {
- if(eve->f & 1) {
- eve->vn= (EditVert *)adr;
- eve->f1= 0;
- adr+= 3;
+ if(G.scene->selectmode & SCE_SELECT_VERTEX) {
+ for(eve= em->verts.first; eve; eve= eve->next) {
+ if((eve->f & SELECT)!=swap) {
+ eve->xs= 3200;
+ eve->f &= ~SELECT;
+ eve->h= 1;
+ }
}
- eve= eve->next;
- }
- eed= em->edges.first;
- while(eed) {
- if( (eed->v1->f & 1) || (eed->v2->f & 1) ) {
- fvec[0]= (eed->v1->co[0]+eed->v2->co[0])/2.0;
- fvec[1]= (eed->v1->co[1]+eed->v2->co[1])/2.0;
- fvec[2]= (eed->v1->co[2]+eed->v2->co[2])/2.0;
-
- if((eed->v1->f & 1) && eed->v1->f1<255) {
- eed->v1->f1++;
- VecAddf((float *)eed->v1->vn, (float *)eed->v1->vn, fvec);
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ if(eed->v1->h || eed->v2->h) {
+ eed->h= 1;
+ eed->f &= ~SELECT;
}
- if((eed->v2->f & 1) && eed->v2->f1<255) {
- eed->v2->f1++;
- VecAddf((float *)eed->v2->vn, (float *)eed->v2->vn, fvec);
+ else eed->h= 0;
+ }
+
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ if(efa->v1->h || efa->v2->h || efa->v3->h || (efa->v4 && efa->v4->h)) {
+ efa->h= 1;
+ efa->f &= ~SELECT;
}
+ else efa->h= 0;
}
- eed= eed->next;
}
+ else if(G.scene->selectmode & SCE_SELECT_EDGE) {
+
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ if((eed->f & SELECT)!=swap) {
+ eed->h= 1;
+ eed->v1->h= 1;
+ eed->v2->h= 1;
+ EM_select_edge(eed, 0);
+ }
+ }
- eve= em->verts.first;
- while(eve) {
- if(eve->f & 1) {
- if(eve->f1) {
- adr= (float *)eve->vn;
- fac= 0.5/(float)eve->f1;
-
- eve->co[0]= 0.5*eve->co[0]+fac*adr[0];
- eve->co[1]= 0.5*eve->co[1]+fac*adr[1];
- eve->co[2]= 0.5*eve->co[2]+fac*adr[2];
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ if(efa->e1->h || efa->e2->h || efa->e3->h || (efa->e4 && efa->e4->h)) {
+ efa->h= 1;
+ efa->f &= ~SELECT;
}
- eve->vn= 0;
+ else efa->h= 0;
}
- eve= eve->next;
}
- MEM_freeN(adror);
+ else {
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ if((efa->f & SELECT)!=swap) {
+ efa->h= 1;
+ efa->e1->h= efa->e2->h= efa->e3->h= 1;
+ if(efa->e4) efa->e4->h= 1;
+ efa->v1->h= efa->v2->h= efa->v3->h= 1;
+ if(efa->v4) efa->v4->h= 1;
+
+ EM_select_face(efa, 0);
+ }
+ }
+ }
+
allqueue(REDRAWVIEW3D, 0);
makeDispList(G.obedit);
+ BIF_undo_push("Hide");
}
-void vertexnoise(void)
+
+void reveal_mesh(void)
{
EditMesh *em = G.editMesh;
- extern float Tin;
- Material *ma;
- Tex *tex;
EditVert *eve;
- float b2, ofs, vec[3];
-
+ EditEdge *eed;
+ EditFace *efa;
+
if(G.obedit==0) return;
+
+ for(eve= em->verts.first; eve; eve= eve->next) {
+ if(eve->h) {
+ eve->h= 0;
+ eve->f |= SELECT;
+ }
+ }
+
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ if(eed->h) {
+ eed->h= 0;
+ eed->f |= SELECT;
+ }
+ }
+
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ if(efa->h) {
+ efa->h= 0;
+ efa->f |= SELECT;
+ }
+ }
- undo_push_mesh("Noise");
+ allqueue(REDRAWVIEW3D, 0);
+ makeDispList(G.obedit);
+ BIF_undo_push("Reveal");
+}
+
+void select_non_manifold(void)
+{
+ EditMesh *em = G.editMesh;
+ EditVert *eve;
+ EditEdge *eed;
+ EditFace *efa;
+
+ /* Selects isolated verts, and edges that do not have 2 neighboring
+ * faces
+ */
- ma= give_current_material(G.obedit, G.obedit->actcol);
- if(ma==0 || ma->mtex[0]==0 || ma->mtex[0]->tex==0) {
+ if(G.scene->selectmode==SCE_SELECT_FACE) {
+ error("Doesn't work in face selection mode");
return;
}
- tex= ma->mtex[0]->tex;
-
- ofs= tex->turbul/200.0;
-
- eve= (struct EditVert *)em->verts.first;
+
+ eve= em->verts.first;
while(eve) {
- if(eve->f & 1) {
-
- if(tex->type==TEX_STUCCI) {
-
- b2= BLI_hnoise(tex->noisesize, eve->co[0], eve->co[1], eve->co[2]);
- if(tex->stype) ofs*=(b2*b2);
- vec[0]= 0.2*(b2-BLI_hnoise(tex->noisesize, eve->co[0]+ofs, eve->co[1], eve->co[2]));
- vec[1]= 0.2*(b2-BLI_hnoise(tex->noisesize, eve->co[0], eve->co[1]+ofs, eve->co[2]));
- vec[2]= 0.2*(b2-BLI_hnoise(tex->noisesize, eve->co[0], eve->co[1], eve->co[2]+ofs));
-
- VecAddf(eve->co, eve->co, vec);
- }
- else {
-
- externtex(ma->mtex[0], eve->co);
-
- eve->co[2]+= 0.05*Tin;
- }
+ /* this will count how many edges are connected
+ * to this vert */
+ eve->f1= 0;
+ eve= eve->next;
+ }
+
+ eed= em->edges.first;
+ while(eed) {
+ /* this will count how many faces are connected to
+ * this edge */
+ eed->f1= 0;
+ /* increase edge count for verts */
+ ++eed->v1->f1;
+ ++eed->v2->f1;
+ eed= eed->next;
+ }
+
+ efa= em->faces.first;
+ while(efa) {
+ /* increase face count for edges */
+ ++efa->e1->f1;
+ ++efa->e2->f1;
+ ++efa->e3->f1;
+ if (efa->e4)
+ ++efa->e4->f1;
+ efa= efa->next;
+ }
+
+ /* select verts that are attached to an edge that does not
+ * have 2 neighboring faces */
+ eed= em->edges.first;
+ while(eed) {
+ if (eed->h==0 && eed->f1 != 2) {
+ EM_select_edge(eed, 1);
+ }
+ eed= eed->next;
+ }
+
+ /* select isolated verts */
+ eve= em->verts.first;
+ while(eve) {
+ if (eve->f1 == 0) {
+ if (!eve->h) eve->f |= SELECT;
}
eve= eve->next;
}
- allqueue(REDRAWVIEW3D, 0);
- makeDispList(G.obedit);
+ countall();
+ addqueue(curarea->win, REDRAW, 0);
+ BIF_undo_push("Select Non Manifold");
}
-void hide_mesh(int swap)
+void selectswap_mesh(void) /* UI level */
{
EditMesh *em = G.editMesh;
EditVert *eve;
EditEdge *eed;
+ EditFace *efa;
+
+ if(G.scene->selectmode & SCE_SELECT_VERTEX) {
- if(G.obedit==0) return;
-
- if(swap) {
- eve= em->verts.first;
- while(eve) {
- if((eve->f & 1)==0) {
- eve->xs= 3200;
- eve->h= 1;
+ for(eve= em->verts.first; eve; eve= eve->next) {
+ if(eve->h==0) {
+ if(eve->f & SELECT) eve->f &= ~SELECT;
+ else eve->f|= SELECT;
}
- eve= eve->next;
}
}
- else {
- eve= em->verts.first;
- while(eve) {
- if(eve->f & 1) {
- eve->f-=1;
- eve->xs= 3200;
- eve->h= 1;
+ else if(G.scene->selectmode & SCE_SELECT_EDGE) {
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ if(eed->h==0) {
+ EM_select_edge(eed, !(eed->f & SELECT));
}
- eve= eve->next;
}
}
- eed= em->edges.first;
- while(eed) {
- if(eed->v1->h || eed->v2->h) eed->h= 1;
- else eed->h= 0;
- eed= eed->next;
+ else {
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ if(efa->h==0) {
+ EM_select_face(efa, !(efa->f & SELECT));
+ }
+ }
}
+ EM_selectmode_flush();
+
+ countall();
allqueue(REDRAWVIEW3D, 0);
- makeDispList(G.obedit);
+
+ BIF_undo_push("Select Swap");
+
}
+void deselectall_mesh(void) /* this toggles!!!, UI level */
+{
+
+ if(G.obedit->lay & G.vd->lay) {
-void reveal_mesh(void)
+ if( EM_nvertices_selected() ) {
+ EM_clear_flag_all(SELECT);
+ BIF_undo_push("Deselect All");
+ }
+ else {
+ EM_set_flag_all(SELECT);
+ BIF_undo_push("Select All");
+ }
+
+ countall();
+ allqueue(REDRAWVIEW3D, 0);
+ }
+}
+
+void select_more(void)
{
EditMesh *em = G.editMesh;
EditVert *eve;
EditEdge *eed;
+ EditFace *efa;
+
+ for(eve= em->verts.first; eve; eve= eve->next) {
+ if(eve->f & SELECT) eve->f1= 1;
+ else eve->f1 = 0;
+ }
+
+ /* set f1 flags in vertices to select 'more' */
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ if(eed->h==0) {
+ if (eed->v1->f & SELECT)
+ eed->v2->f1 = 1;
+ if (eed->v2->f & SELECT)
+ eed->v1->f1 = 1;
+ }
+ }
- if(G.obedit==0) return;
+ /* new selected edges */
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ if(eed->h==0) {
+ if(eed->v1->f1 && eed->v2->f1) EM_select_edge(eed, 1);
+ }
+ }
- eve= em->verts.first;
- while(eve) {
- if(eve->h) {
- eve->h= 0;
- eve->f|=1;
+ /* new selected faces */
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ if(efa->h==0) {
+ if(efa->v1->f1 && efa->v2->f1 && efa->v3->f1 && (efa->v4 && efa->v4->f1))
+ EM_select_face(efa, 1);
}
- eve= eve->next;
}
- eed= em->edges.first;
- while(eed) {
- eed->h= 0;
- eed= eed->next;
+ countall();
+ addqueue(curarea->win, REDRAW, 0);
+ BIF_undo_push("Select More");
+}
+
+void select_less(void)
+{
+ EditMesh *em = G.editMesh;
+ EditVert *eve;
+ EditEdge *eed;
+ EditFace *efa;
+
+ /* eve->f1 & 1 => isolated */
+ /* eve->f1 & 2 => on an edge */
+ /* eve->f1 & 4 => shares edge with a deselected vert */
+ /* eve->f1 & 8 => at most one neighbor */
+
+ for(eve= em->verts.first; eve; eve= eve->next) {
+ /* assume vert is isolated unless proven otherwise, */
+ /* assume at most one neighbor too */
+ eve->f1 = 1 | 8;
}
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ eed->f1= 0;
+ if(eed->h==0) {
+ /* this will count how many faces are connected to
+ * this edge */
+
+ /* if vert wasn't isolated, it now has more than one neighbor */
+ if (~eed->v1->f1 & 1) eed->v1->f1 &= ~8;
+ if (~eed->v2->f1 & 1) eed->v2->f1 &= ~8;
+
+ /* verts on edge are clearly not isolated */
+ eed->v1->f1 &= ~1;
+ eed->v2->f1 &= ~1;
+
+ /* if one of the verts on the edge is deselected,
+ * deselect the other */
+ if ( (~eed->v1->f & SELECT) )
+ eed->v2->f1 |= 4;
+ if ( (~eed->v2->f & SELECT) )
+ eed->v1->f1 |= 4;
+ }
+ }
+
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ /* increase face count for edges */
+ if(efa->h==0) {
+ ++efa->e1->f1;
+ ++efa->e2->f1;
+ ++efa->e3->f1;
+ if (efa->e4) ++efa->e4->f1;
+ }
+ }
+
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ /* if the edge has only one neighboring face, then
+ * deselect attached verts */
+ if (eed->h==0 && eed->f1 == 1) {
+ eed->v1->f1 |= 2;
+ eed->v2->f1 |= 2;
+ }
+ }
+
+ /* deselect verts */
+ for(eve= em->verts.first; eve; eve= eve->next) {
+ if (eve->f1) {
+ eve->f &= ~SELECT;
+ }
+ }
+
+ /* now rebuild selection state for edges & faces */
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ if(eed->v1->f1 && eed->v2->f1) EM_select_edge(eed, 0);
+ }
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ if(efa->h==0) {
+ if(efa->v1->f1 && efa->v2->f1 && efa->v3->f1 && (efa->v4 && efa->v4->f1))
+ EM_select_face(efa, 0);
+ }
+ }
+
+ countall();
allqueue(REDRAWVIEW3D, 0);
- makeDispList(G.obedit);
}
-void vertices_to_sphere(void)
+void selectrandom_mesh(void) /* randomly selects a user-set % of vertices/edges/faces */
{
EditMesh *em = G.editMesh;
EditVert *eve;
- Object *ob= OBACT;
- float *curs, len, vec[3], cent[3], fac, facm, imat[3][3], bmat[3][3];
- int tot;
- short perc=100;
-
- if(ob==0) return;
- TEST_EDITMESH
+ EditEdge *eed;
+ EditFace *efa;
+ short randfac = 50;
+
+ if(G.obedit==NULL || (G.obedit->lay & G.vd->lay)==0) return;
+
+ /* Get the percentage of vertices to randomly select as 'randfac' */
+ if(button(&randfac,0, 100,"Percentage:")==0) return;
+
+ BLI_srand( BLI_rand() ); /* random seed */
- if(button(&perc, 1, 100, "Percentage:")==0) return;
+ if(G.scene->selectmode & SCE_SELECT_VERTEX) {
+ for(eve= em->verts.first; eve; eve= eve->next) {
+ if(eve->h==0) {
+ if ( (BLI_frand() * 100) < randfac)
+ eve->f |= SELECT;
+ }
+ }
+ }
+ else if(G.scene->selectmode & SCE_SELECT_EDGE) {
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ if(eed->h==0) {
+ if ( (BLI_frand() * 100) < randfac)
+ EM_select_edge(eed, 1);
+ }
+ }
+ }
+ else {
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ if(efa->h==0) {
+ if ( (BLI_frand() * 100) < randfac)
+ EM_select_face(efa, 1);
+ }
+ }
+ }
- undo_push_mesh("To Sphere");
+ EM_selectmode_flush();
+
+ countall();
+ allqueue(REDRAWVIEW3D, 0);
+}
+
+void editmesh_select_by_material(int index)
+{
+ EditMesh *em = G.editMesh;
+ EditFace *efa;
- fac= perc/100.0;
- facm= 1.0-fac;
+ for (efa=em->faces.first; efa; efa= efa->next) {
+ if (efa->mat_nr==index) {
+ EM_select_face(efa, 1);
+ }
+ }
+
+ EM_selectmode_flush();
+}
+
+void editmesh_deselect_by_material(int index)
+{
+ EditMesh *em = G.editMesh;
+ EditFace *efa;
- Mat3CpyMat4(bmat, ob->obmat);
- Mat3Inv(imat, bmat);
+ for (efa=em->faces.first; efa; efa= efa->next) {
+ if (efa->mat_nr==index) {
+ EM_select_face(efa, 0);
+ }
+ }
- /* centre */
- curs= give_cursor();
- cent[0]= curs[0]-ob->obmat[3][0];
- cent[1]= curs[1]-ob->obmat[3][1];
- cent[2]= curs[2]-ob->obmat[3][2];
- Mat3MulVecfl(imat, cent);
+ EM_selectmode_flush();
+}
- len= 0.0;
- tot= 0;
- eve= em->verts.first;
- while(eve) {
- if(eve->f & 1) {
- tot++;
- len+= VecLenf(cent, eve->co);
+/* ************************* SEAMS AND EDGES **************** */
+
+void editmesh_mark_seam(int clear)
+{
+ EditMesh *em= G.editMesh;
+ EditEdge *eed;
+ Mesh *me= G.obedit->data;
+
+ /* auto-enable seams drawing */
+ if(clear==0) {
+ if(!(G.f & G_DRAWSEAMS)) {
+ G.f |= G_DRAWSEAMS;
+ allqueue(REDRAWBUTSEDIT, 0);
}
- eve= eve->next;
+ if(!me->medge)
+ me->medge= MEM_callocN(sizeof(MEdge), "fake mesh edge");
}
- len/=tot;
+
+ if(clear) {
+ eed= em->edges.first;
+ while(eed) {
+ if((eed->h==0) && (eed->f & SELECT)) {
+ eed->seam = 0;
+ }
+ eed= eed->next;
+ }
+ }
+ else {
+ eed= em->edges.first;
+ while(eed) {
+ if((eed->h==0) && (eed->f & SELECT)) {
+ eed->seam = 1;
+ }
+ eed= eed->next;
+ }
+ }
+
+ allqueue(REDRAWVIEW3D, 0);
+}
+
+void Edge_Menu() {
+ short ret;
+
+ ret= pupmenu("Edge Specials%t|Mark Seam %x1|Clear Seam %x2|Rotate Edges %x3");
+
+ switch(ret)
+ {
+ case 1:
+ editmesh_mark_seam(0);
+ break;
+ case 2:
+ editmesh_mark_seam(1);
+ break;
+ case 3:
+ edge_rotate_selected();
+ break;
+ }
+}
+
+/* **************** NORMALS ************** */
+
+void righthandfaces(int select) /* makes faces righthand turning */
+{
+ EditMesh *em = G.editMesh;
+ EditEdge *eed, *ed1, *ed2, *ed3, *ed4;
+ EditFace *efa, *startvl;
+ float maxx, nor[3], cent[3];
+ int totsel, found, foundone, direct, turn, tria_nr;
+
+ /* based at a select-connected to witness loose objects */
+
+ /* count per edge the amount of faces */
+
+ /* find the ultimate left, front, upper face (not manhattan dist!!) */
+ /* also evaluate both triangle cases in quad, since these can be non-flat */
+
+ /* put normal to the outside, and set the first direction flags in edges */
+
+ /* then check the object, and set directions / direction-flags: but only for edges with 1 or 2 faces */
+ /* this is in fact the 'select connected' */
- if(len==0.0) len= 10.0;
+ /* in case (selected) faces were not done: start over with 'find the ultimate ...' */
+
+ waitcursor(1);
- eve= em->verts.first;
- while(eve) {
- if(eve->f & 1) {
- vec[0]= eve->co[0]-cent[0];
- vec[1]= eve->co[1]-cent[1];
- vec[2]= eve->co[2]-cent[2];
-
- Normalise(vec);
-
- eve->co[0]= fac*(cent[0]+vec[0]*len) + facm*eve->co[0];
- eve->co[1]= fac*(cent[1]+vec[1]*len) + facm*eve->co[1];
- eve->co[2]= fac*(cent[2]+vec[2]*len) + facm*eve->co[2];
-
+ eed= em->edges.first;
+ while(eed) {
+ eed->f2= 0; // edge direction
+ eed->f1= 0; // counter
+ eed= eed->next;
+ }
+
+ /* count faces and edges */
+ totsel= 0;
+ efa= em->faces.first;
+ while(efa) {
+ if(select==0 || (efa->f & SELECT) ) {
+ efa->f1= 1;
+ totsel++;
+ efa->e1->f1++;
+ efa->e2->f1++;
+ efa->e3->f1++;
+ if(efa->v4) efa->e4->f1++;
}
- eve= eve->next;
+ else efa->f1= 0;
+
+ efa= efa->next;
}
+
+ while(totsel>0) {
+ /* from the outside to the inside */
+
+ efa= em->faces.first;
+ startvl= NULL;
+ maxx= -1.0e10;
+ tria_nr= 0;
+
+ while(efa) {
+ if(efa->f1) {
+ CalcCent3f(cent, efa->v1->co, efa->v2->co, efa->v3->co);
+ cent[0]= cent[0]*cent[0] + cent[1]*cent[1] + cent[2]*cent[2];
+
+ if(cent[0]>maxx) {
+ maxx= cent[0];
+ startvl= efa;
+ tria_nr= 0;
+ }
+ if(efa->v4) {
+ CalcCent3f(cent, efa->v1->co, efa->v3->co, efa->v4->co);
+ cent[0]= cent[0]*cent[0] + cent[1]*cent[1] + cent[2]*cent[2];
+
+ if(cent[0]>maxx) {
+ maxx= cent[0];
+ startvl= efa;
+ tria_nr= 1;
+ }
+ }
+ }
+ efa= efa->next;
+ }
+
+ /* set first face correct: calc normal */
+
+ if(tria_nr==1) {
+ CalcNormFloat(startvl->v1->co, startvl->v3->co, startvl->v4->co, nor);
+ CalcCent3f(cent, startvl->v1->co, startvl->v3->co, startvl->v4->co);
+ } else {
+ CalcNormFloat(startvl->v1->co, startvl->v2->co, startvl->v3->co, nor);
+ CalcCent3f(cent, startvl->v1->co, startvl->v2->co, startvl->v3->co);
+ }
+ /* first normal is oriented this way or the other */
+ if(select) {
+ if(select==2) {
+ if(cent[0]*nor[0]+cent[1]*nor[1]+cent[2]*nor[2] > 0.0) flipface(startvl);
+ }
+ else {
+ if(cent[0]*nor[0]+cent[1]*nor[1]+cent[2]*nor[2] < 0.0) flipface(startvl);
+ }
+ }
+ else if(cent[0]*nor[0]+cent[1]*nor[1]+cent[2]*nor[2] < 0.0) flipface(startvl);
+
+
+ eed= startvl->e1;
+ if(eed->v1==startvl->v1) eed->f2= 1;
+ else eed->f2= 2;
+
+ eed= startvl->e2;
+ if(eed->v1==startvl->v2) eed->f2= 1;
+ else eed->f2= 2;
+
+ eed= startvl->e3;
+ if(eed->v1==startvl->v3) eed->f2= 1;
+ else eed->f2= 2;
+
+ eed= startvl->e4;
+ if(eed) {
+ if(eed->v1==startvl->v4) eed->f2= 1;
+ else eed->f2= 2;
+ }
+
+ startvl->f1= 0;
+ totsel--;
+
+ /* test normals */
+ found= 1;
+ direct= 1;
+ while(found) {
+ found= 0;
+ if(direct) efa= em->faces.first;
+ else efa= em->faces.last;
+ while(efa) {
+ if(efa->f1) {
+ turn= 0;
+ foundone= 0;
+
+ ed1= efa->e1;
+ ed2= efa->e2;
+ ed3= efa->e3;
+ ed4= efa->e4;
+
+ if(ed1->f2) {
+ if(ed1->v1==efa->v1 && ed1->f2==1) turn= 1;
+ if(ed1->v2==efa->v1 && ed1->f2==2) turn= 1;
+ foundone= 1;
+ }
+ else if(ed2->f2) {
+ if(ed2->v1==efa->v2 && ed2->f2==1) turn= 1;
+ if(ed2->v2==efa->v2 && ed2->f2==2) turn= 1;
+ foundone= 1;
+ }
+ else if(ed3->f2) {
+ if(ed3->v1==efa->v3 && ed3->f2==1) turn= 1;
+ if(ed3->v2==efa->v3 && ed3->f2==2) turn= 1;
+ foundone= 1;
+ }
+ else if(ed4 && ed4->f2) {
+ if(ed4->v1==efa->v4 && ed4->f2==1) turn= 1;
+ if(ed4->v2==efa->v4 && ed4->f2==2) turn= 1;
+ foundone= 1;
+ }
+
+ if(foundone) {
+ found= 1;
+ totsel--;
+ efa->f1= 0;
+
+ if(turn) {
+ if(ed1->v1==efa->v1) ed1->f2= 2;
+ else ed1->f2= 1;
+ if(ed2->v1==efa->v2) ed2->f2= 2;
+ else ed2->f2= 1;
+ if(ed3->v1==efa->v3) ed3->f2= 2;
+ else ed3->f2= 1;
+ if(ed4) {
+ if(ed4->v1==efa->v4) ed4->f2= 2;
+ else ed4->f2= 1;
+ }
+
+ flipface(efa);
+
+ }
+ else {
+ if(ed1->v1== efa->v1) ed1->f2= 1;
+ else ed1->f2= 2;
+ if(ed2->v1==efa->v2) ed2->f2= 1;
+ else ed2->f2= 2;
+ if(ed3->v1==efa->v3) ed3->f2= 1;
+ else ed3->f2= 2;
+ if(ed4) {
+ if(ed4->v1==efa->v4) ed4->f2= 1;
+ else ed4->f2= 2;
+ }
+ }
+ }
+ }
+ if(direct) efa= efa->next;
+ else efa= efa->prev;
+ }
+ direct= 1-direct;
+ }
+ }
+
+ recalc_editnormals();
- allqueue(REDRAWVIEW3D, 0);
makeDispList(G.obedit);
+
+ waitcursor(0);
}
@@ -1078,7 +1369,7 @@ void faceselect_align_view_to_selected(View3D *v3d, Mesh *me, int axis)
void editmesh_align_view_to_selected(View3D *v3d, int axis)
{
EditMesh *em = G.editMesh;
- int nselverts= editmesh_nvertices_selected();
+ int nselverts= EM_nvertices_selected();
if (nselverts<3) {
if (nselverts==0) {
@@ -1086,7 +1377,7 @@ void editmesh_align_view_to_selected(View3D *v3d, int axis)
} else {
error("At least one face or three vertices must be selected.");
}
- } else if (editmesh_nfaces_selected()) {
+ } else if (EM_nfaces_selected()) {
float norm[3];
EditFace *efa;
@@ -1135,313 +1426,187 @@ void editmesh_align_view_to_selected(View3D *v3d, int axis)
}
}
+/* **************** VERTEX DEFORMS *************** */
-void select_non_manifold(void)
+void vertexsmooth(void)
{
EditMesh *em = G.editMesh;
EditVert *eve;
EditEdge *eed;
- EditFace *efa;
-
- /* Selects isolated verts, and edges that do not have 2 neighboring
- * faces
- */
+ float *adror, *adr, fac;
+ float fvec[3];
+ int teller=0;
+ if(G.obedit==0) return;
+ /* count */
eve= em->verts.first;
while(eve) {
- /* this will count how many edges are connected
- * to this vert */
- eve->f1= 0;
+ if(eve->f & SELECT) teller++;
eve= eve->next;
}
-
- eed= em->edges.first;
- while(eed) {
- /* this will count how many faces are connected to
- * this edge */
- eed->f1= 0;
- /* increase edge count for verts */
- ++eed->v1->f1;
- ++eed->v2->f1;
- eed= eed->next;
- }
-
- efa= em->faces.first;
- while(efa) {
- /* increase face count for edges */
- ++efa->e1->f1;
- ++efa->e2->f1;
- ++efa->e3->f1;
- if (efa->e4)
- ++efa->e4->f1;
- efa= efa->next;
- }
-
- /* select verts that are attached to an edge that does not
- * have 2 neighboring faces */
- eed= em->edges.first;
- while(eed) {
- if (eed->f1 != 2) {
- if (!eed->v1->h) eed->v1->f |= 1;
- if (!eed->v2->h) eed->v2->f |= 1;
- }
- eed= eed->next;
- }
-
- /* select isolated verts */
+ if(teller==0) return;
+
+ adr=adror= (float *)MEM_callocN(3*sizeof(float *)*teller, "vertsmooth");
eve= em->verts.first;
while(eve) {
- if (eve->f1 == 0) {
- if (!eve->h) eve->f |= 1;
+ if(eve->f & SELECT) {
+ eve->vn= (EditVert *)adr;
+ eve->f1= 0;
+ adr+= 3;
}
eve= eve->next;
}
-
- countall();
- addqueue(curarea->win, REDRAW, 0);
-
-}
-
-void select_more(void)
-{
- EditMesh *em = G.editMesh;
- EditVert *eve;
- EditEdge *eed;
-
- eve= em->verts.first;
- while(eve) {
- eve->f1 = 0;
- eve= eve->next;
- }
-
+
eed= em->edges.first;
while(eed) {
- if (eed->v1->f & 1)
- eed->v2->f1 = 1;
- if (eed->v2->f & 1)
- eed->v1->f1 = 1;
-
+ if( (eed->v1->f & SELECT) || (eed->v2->f & SELECT) ) {
+ fvec[0]= (eed->v1->co[0]+eed->v2->co[0])/2.0;
+ fvec[1]= (eed->v1->co[1]+eed->v2->co[1])/2.0;
+ fvec[2]= (eed->v1->co[2]+eed->v2->co[2])/2.0;
+
+ if((eed->v1->f & SELECT) && eed->v1->f1<255) {
+ eed->v1->f1++;
+ VecAddf((float *)eed->v1->vn, (float *)eed->v1->vn, fvec);
+ }
+ if((eed->v2->f & SELECT) && eed->v2->f1<255) {
+ eed->v2->f1++;
+ VecAddf((float *)eed->v2->vn, (float *)eed->v2->vn, fvec);
+ }
+ }
eed= eed->next;
}
eve= em->verts.first;
while(eve) {
- if (eve->f1 == 1)
- if (!eve->h) eve->f |= 1;
-
+ if(eve->f & SELECT) {
+ if(eve->f1) {
+ adr= (float *)eve->vn;
+ fac= 0.5/(float)eve->f1;
+
+ eve->co[0]= 0.5*eve->co[0]+fac*adr[0];
+ eve->co[1]= 0.5*eve->co[1]+fac*adr[1];
+ eve->co[2]= 0.5*eve->co[2]+fac*adr[2];
+ }
+ eve->vn= 0;
+ }
eve= eve->next;
}
+ MEM_freeN(adror);
- countall();
- addqueue(curarea->win, REDRAW, 0);
+ allqueue(REDRAWVIEW3D, 0);
+ makeDispList(G.obedit);
+ BIF_undo_push("Vertex Smooth");
}
-void select_less(void)
+void vertexnoise(void)
{
EditMesh *em = G.editMesh;
+ extern float Tin;
+ Material *ma;
+ Tex *tex;
EditVert *eve;
- EditEdge *eed;
- EditFace *efa;
-
- /* eve->f1 & 1 => isolated */
- /* eve->f1 & 2 => on an edge */
- /* eve->f1 & 4 => shares edge with a deselected vert */
- /* eve->f1 & 8 => at most one neighbor */
-
- eve= em->verts.first;
- while(eve) {
- /* assume vert is isolated unless proven otherwise, */
- /* assume at most one neighbor too */
- eve->f1 = 1 | 8;
-
- eve= eve->next;
- }
-
- eed= em->edges.first;
- while(eed) {
- /* this will count how many faces are connected to
- * this edge */
- eed->f1= 0;
-
- /* if vert wasn't isolated, it now has more than one neighbor */
- if (~eed->v1->f1 & 1) eed->v1->f1 &= ~8;
- if (~eed->v2->f1 & 1) eed->v2->f1 &= ~8;
-
- /* verts on edge are clearly not isolated */
- eed->v1->f1 &= ~1;
- eed->v2->f1 &= ~1;
-
- /* if one of the verts on the edge is deselected,
- * deselect the other */
- if ( !(eed->v1->h) && (~eed->v1->f & 1) )
- eed->v2->f1 |= 4;
- if ( !(eed->v2->h) && (~eed->v2->f & 1) )
- eed->v1->f1 |= 4;
-
- eed= eed->next;
- }
-
- efa= em->faces.first;
- while(efa) {
- /* increase face count for edges */
- ++efa->e1->f1;
- ++efa->e2->f1;
- ++efa->e3->f1;
- if (efa->e4)
- ++efa->e4->f1;
-
- efa= efa->next;
- }
-
- eed= em->edges.first;
- while(eed) {
- /* if the edge has only one neighboring face, then
- * deselect attached verts */
- if (eed->f1 == 1) {
- eed->v1->f1 |= 2;
- eed->v2->f1 |= 2;
- }
+ float b2, ofs, vec[3];
- eed= eed->next;
+ if(G.obedit==0) return;
+
+ ma= give_current_material(G.obedit, G.obedit->actcol);
+ if(ma==0 || ma->mtex[0]==0 || ma->mtex[0]->tex==0) {
+ return;
}
-
- /* deselect verts */
- eve= em->verts.first;
+ tex= ma->mtex[0]->tex;
+
+ ofs= tex->turbul/200.0;
+
+ eve= (struct EditVert *)em->verts.first;
while(eve) {
- if (eve->f1) {
- eve->f &= ~1;
+ if(eve->f & SELECT) {
+
+ if(tex->type==TEX_STUCCI) {
+
+ b2= BLI_hnoise(tex->noisesize, eve->co[0], eve->co[1], eve->co[2]);
+ if(tex->stype) ofs*=(b2*b2);
+ vec[0]= 0.2*(b2-BLI_hnoise(tex->noisesize, eve->co[0]+ofs, eve->co[1], eve->co[2]));
+ vec[1]= 0.2*(b2-BLI_hnoise(tex->noisesize, eve->co[0], eve->co[1]+ofs, eve->co[2]));
+ vec[2]= 0.2*(b2-BLI_hnoise(tex->noisesize, eve->co[0], eve->co[1], eve->co[2]+ofs));
+
+ VecAddf(eve->co, eve->co, vec);
+ }
+ else {
+
+ externtex(ma->mtex[0], eve->co);
+
+ eve->co[2]+= 0.05*Tin;
+ }
}
-
eve= eve->next;
}
- countall();
allqueue(REDRAWVIEW3D, 0);
+ makeDispList(G.obedit);
+ BIF_undo_push("Vertex Noise");
}
-
-void selectrandom_mesh(void) /* randomly selects a user-set % of vertices */
+void vertices_to_sphere(void)
{
EditMesh *em = G.editMesh;
EditVert *eve;
- int newsel = 0; /* to decide whether to redraw or not */
- short randfac = 50;
-
- if(G.obedit==0) return;
-
- /* Get the percentage of vertices to randomly select as 'randfac' */
- if(button(&randfac,0, 100,"Percentage:")==0) return;
-
- if(G.obedit->lay & G.vd->lay) {
- eve= em->verts.first;
- while(eve) {
- BLI_srand( BLI_rand() ); /* random seed */
- if ( (BLI_frand() * 100) < randfac) {
- eve->f |= SELECT;
- newsel = 1;
- } else {
- /* Deselect other vertices
- *
- * - Commenting this out makes it add to the selection,
- * rather than replace it.
- * eve->f &= ~SELECT;
- */
- }
- eve= eve->next;
- }
- countall();
- allqueue(REDRAWVIEW3D, 0);
- }
-}
-
-
-
-void editmesh_select_by_material(int index)
-{
- EditMesh *em = G.editMesh;
- EditFace *efa;
+ Object *ob= OBACT;
+ float *curs, len, vec[3], cent[3], fac, facm, imat[3][3], bmat[3][3];
+ int tot;
+ short perc=100;
- for (efa=em->faces.first; efa; efa= efa->next) {
- if (efa->mat_nr==index) {
- if(efa->v1->h==0) efa->v1->f |= 1;
- if(efa->v2->h==0) efa->v2->f |= 1;
- if(efa->v3->h==0) efa->v3->f |= 1;
- if(efa->v4 && efa->v4->h==0) efa->v4->f |= 1;
- }
- }
-}
-
-void editmesh_deselect_by_material(int index)
-{
- EditMesh *em = G.editMesh;
- EditFace *efa;
+ if(ob==0) return;
+ TEST_EDITMESH
- for (efa=em->faces.first; efa; efa= efa->next) {
- if (efa->mat_nr==index) {
- if(efa->v1->h==0) efa->v1->f &= ~1;
- if(efa->v2->h==0) efa->v2->f &= ~1;
- if(efa->v3->h==0) efa->v3->f &= ~1;
- if(efa->v4 && efa->v4->h==0) efa->v4->f &= ~1;
- }
- }
-}
-
-void editmesh_mark_seam(int clear)
-{
- EditMesh *em= G.editMesh;
- EditEdge *eed;
- Mesh *me= G.obedit->data;
+ if(button(&perc, 1, 100, "Percentage:")==0) return;
+
+ fac= perc/100.0;
+ facm= 1.0-fac;
+
+ Mat3CpyMat4(bmat, ob->obmat);
+ Mat3Inv(imat, bmat);
- /* auto-enable seams drawing */
- if(clear==0) {
- if(!(G.f & G_DRAWSEAMS)) {
- G.f |= G_DRAWSEAMS;
- allqueue(REDRAWBUTSEDIT, 0);
- }
- if(!me->medge)
- me->medge= MEM_callocN(sizeof(MEdge), "fake mesh edge");
- }
+ /* centre */
+ curs= give_cursor();
+ cent[0]= curs[0]-ob->obmat[3][0];
+ cent[1]= curs[1]-ob->obmat[3][1];
+ cent[2]= curs[2]-ob->obmat[3][2];
+ Mat3MulVecfl(imat, cent);
- if(clear) {
- eed= em->edges.first;
- while(eed) {
- if((eed->h==0) && (eed->v1->f & 1) && (eed->v2->f & 1)) {
- eed->seam = 0;
- }
- eed= eed->next;
+ len= 0.0;
+ tot= 0;
+ eve= em->verts.first;
+ while(eve) {
+ if(eve->f & SELECT) {
+ tot++;
+ len+= VecLenf(cent, eve->co);
}
+ eve= eve->next;
}
- else {
- eed= em->edges.first;
- while(eed) {
- if((eed->h==0) && (eed->v1->f & 1) && (eed->v2->f & 1)) {
- eed->seam = 1;
- }
- eed= eed->next;
+ len/=tot;
+
+ if(len==0.0) len= 10.0;
+
+ eve= em->verts.first;
+ while(eve) {
+ if(eve->f & SELECT) {
+ vec[0]= eve->co[0]-cent[0];
+ vec[1]= eve->co[1]-cent[1];
+ vec[2]= eve->co[2]-cent[2];
+
+ Normalise(vec);
+
+ eve->co[0]= fac*(cent[0]+vec[0]*len) + facm*eve->co[0];
+ eve->co[1]= fac*(cent[1]+vec[1]*len) + facm*eve->co[1];
+ eve->co[2]= fac*(cent[2]+vec[2]*len) + facm*eve->co[2];
+
}
+ eve= eve->next;
}
-
+
allqueue(REDRAWVIEW3D, 0);
+ makeDispList(G.obedit);
+ BIF_undo_push("To Sphere");
}
-void Edge_Menu() {
- short ret;
-
- ret= pupmenu("Edge Specials%t|Mark Seam %x1|Clear Seam %x2|Rotate Edges %x3");
-
- switch(ret)
- {
- case 1:
- editmesh_mark_seam(0);
- break;
- case 2:
- editmesh_mark_seam(1);
- break;
- case 3:
- edge_rotate_selected();
- break;
- }
-}
-
-