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:
authorTon Roosendaal <ton@blender.org>2004-09-27 23:22:15 +0400
committerTon Roosendaal <ton@blender.org>2004-09-27 23:22:15 +0400
commitea84d29d909fe6849ec5ae432c341394768b1a4e (patch)
treed00d0b06eb3ac0d7f549f87a5820921a1d2e50f3 /source/blender/src/editmesh_mods.c
parentdbef53aa319a4a2643a01ccea13b1c13304f6026 (diff)
Faceloop select recoded, also nonmodal (no loop). It works by clicking with
ALT on an edge, in face-select mode. Holding shift again extends selection. Current UI access can need rethink though. But I also think the loop tools deserve to be accessible without menu, for speed/workflow. So what's good shortcuts! BTW: both tools don't do triangle meshes (yet)
Diffstat (limited to 'source/blender/src/editmesh_mods.c')
-rw-r--r--source/blender/src/editmesh_mods.c136
1 files changed, 124 insertions, 12 deletions
diff --git a/source/blender/src/editmesh_mods.c b/source/blender/src/editmesh_mods.c
index 38a98e7fb12..e8396fb69ac 100644
--- a/source/blender/src/editmesh_mods.c
+++ b/source/blender/src/editmesh_mods.c
@@ -290,12 +290,27 @@ int EM_zbuffer_edge_visible(float *v1, float *v2, short *val1, short *val2)
return 0;
}
+/* helper for findnearest edge */
+static float dist_mval_edge(short *mval, EditEdge *eed)
+{
+ float v1[2], v2[2], mval2[2];
+
+ mval2[0] = (float)mval[0];
+ mval2[1] = (float)mval[1];
+
+ v1[0] = eed->v1->xs;
+ v1[1] = eed->v1->ys;
+ v2[0] = eed->v2->xs;
+ v2[1] = eed->v2->ys;
+
+ return PdistVL2Dfl(mval2, v1, v2);
+}
+
EditEdge *findnearestedge(short *dist)
{
EditMesh *em = G.editMesh;
EditEdge *closest, *eed;
EditVert *eve;
- float v1[2], v2[2], mval2[2];
short mval[2], distance;
if(em->edges.first==NULL) return NULL;
@@ -312,21 +327,13 @@ EditEdge *findnearestedge(short *dist)
getmouseco_areawin(mval);
closest=NULL;
- mval2[0] = (float)mval[0];
- mval2[1] = (float)mval[1];
-
/*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->h==0){
- v1[0] = eed->v1->xs;
- v1[1] = eed->v1->ys;
- v2[0] = eed->v2->xs;
- v2[1] = eed->v2->ys;
-
- distance= (short)PdistVL2Dfl(mval2, v1, v2);
+ distance= dist_mval_edge(mval, eed);
if(distance < *dist) {
if(EM_zbuffer_edge_visible(eed->v1->co, eed->v2->co, &eed->v1->xs, &eed->v2->xs)) {
*dist= distance;
@@ -563,6 +570,77 @@ void EM_select_face_fgon(EditFace *efa, int val)
}
}
+/* **************** LOOP SELECTS *************** */
+
+/* selects quads in loop direction of indicated edge */
+/* only flush over edges with valence <= 2 */
+static void faceloop_select(EditEdge *startedge, int select)
+{
+ EditMesh *em = G.editMesh;
+ EditEdge *eed;
+ EditFace *efa;
+ int looking= 1;
+
+ /* in eed->f1 we put the valence (amount of faces in edge) */
+ /* in eed->f2 we put tagged flag as correct loop */
+ /* in efa->f1 we put tagged flag as correct to select */
+
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ eed->f1= 0;
+ eed->f2= 0;
+ }
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ efa->f1= 0;
+ if(efa->h==0) {
+ efa->e1->f1++;
+ efa->e2->f1++;
+ efa->e3->f1++;
+ if(efa->e4) efa->e4->f1++;
+ }
+ }
+
+ // tag startedge OK
+ startedge->f2= 1;
+
+ while(looking) {
+ looking= 0;
+
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ if(efa->e4 && efa->f1==0) { // not done quad
+ if(efa->e1->f1<=2 && efa->e2->f1<=2 && efa->e3->f1<=2 && efa->e4->f1<=2) { // valence ok
+
+ // if edge tagged, select opposing edge and mark face ok
+ if(efa->e1->f2) {
+ efa->e3->f2= 1;
+ efa->f1= 1;
+ looking= 1;
+ }
+ else if(efa->e2->f2) {
+ efa->e4->f2= 1;
+ efa->f1= 1;
+ looking= 1;
+ }
+ if(efa->e3->f2) {
+ efa->e1->f2= 1;
+ efa->f1= 1;
+ looking= 1;
+ }
+ if(efa->e4->f2) {
+ efa->e2->f2= 1;
+ efa->f1= 1;
+ looking= 1;
+ }
+ }
+ }
+ }
+ }
+
+ /* (de)select the faces */
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ if(efa->f1) EM_select_face(efa, select);
+ }
+}
+
/* helper for edgeloop_select, checks for eed->f2 tag in faces */
static int edge_not_in_tagged_face(EditEdge *eed)
{
@@ -653,6 +731,39 @@ static void edgeloop_select(EditEdge *starteed, int select)
}
}
+/* ***************** MAIN MOUSE SELECTION ************** */
+
+// just to have the functions nice together
+static void mouse_mesh_loop(void)
+{
+ EditEdge *eed;
+ short dist= 50;
+
+ eed= findnearestedge(&dist);
+ if(eed) {
+
+ if((G.qual & LR_SHIFTKEY)==0) EM_clear_flag_all(SELECT);
+
+ if((eed->f & SELECT)==0) EM_select_edge(eed, 1);
+ else if(G.qual & LR_SHIFTKEY) EM_select_edge(eed, 0);
+
+ if(G.scene->selectmode & SCE_SELECT_FACE) {
+ faceloop_select(eed, eed->f & SELECT);
+ }
+ else {
+ edgeloop_select(eed, eed->f & SELECT);
+ }
+
+ /* frontbuffer draw of last selected only */
+ unified_select_draw(NULL, eed, NULL);
+
+ countall();
+ EM_selectmode_flush();
+
+ allqueue(REDRAWVIEW3D, 0);
+ }
+}
+
/* here actual select happens */
void mouse_mesh(void)
@@ -661,11 +772,13 @@ void mouse_mesh(void)
EditEdge *eed;
EditFace *efa;
- if(unified_findnearest(&eve, &eed, &efa)) {
+ if(G.qual & LR_ALTKEY) mouse_mesh_loop();
+ else 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_fgon(efa, 1);
}
@@ -680,7 +793,6 @@ void mouse_mesh(void)
else if(G.qual & LR_SHIFTKEY) {
EM_select_edge(eed, 0);
}
- if(G.qual & LR_ALTKEY) edgeloop_select(eed, eed->f & SELECT);
}
else if(eve) {
if((eve->f & SELECT)==0) eve->f |= SELECT;