[#29144] Snapping control points: can't choose which one to delete
authorMartin Poirier <theeth@yahoo.com>
Mon, 26 Dec 2011 20:23:07 +0000 (20:23 +0000)
committerMartin Poirier <theeth@yahoo.com>
Mon, 26 Dec 2011 20:23:07 +0000 (20:23 +0000)
Reported by Pep Ribal
You can now select which snap point to remove (with Alt-A) by moving the cursor over them.
Display colors are also used to indicate which snap points are active, selected or just there.

source/blender/editors/transform/transform.c
source/blender/editors/transform/transform.h
source/blender/editors/transform/transform_snap.c

index 8e6e5d08266b7d02c54d96e30d569af6ea2efd0b..30337551fe56b742709cf4bbad327d5f9708d96b 100644 (file)
@@ -585,6 +585,9 @@ int transformEvent(TransInfo *t, wmEvent *event)
                }
 
                applyMouseInput(t, &t->mouse, t->mval, t->values);
+
+               // Snapping mouse move events
+               t->redraw |= handleSnapping(t, event);
        }
 
        /* handle modal keymap first */
@@ -1027,7 +1030,7 @@ int transformEvent(TransInfo *t, wmEvent *event)
                // Numerical input events
                t->redraw |= handleNumInput(&(t->num), event);
 
-               // Snapping events
+               // Snapping key events
                t->redraw |= handleSnapping(t, event);
 
        }
index fcc285d52f099de4df281f1e2c2eeac7697fc531..2233aeda92ee02aa424c887f7d851357436c9e0d 100644 (file)
@@ -65,15 +65,6 @@ struct wmTimer;
 struct ARegion;
 struct ReportList;
 
-/*
-       The ctrl value has different meaning:
-               0                       : No value has been typed
-
-               otherwise, |value| - 1 is where the cursor is located after the period
-               Positive        : number is positive
-               Negative        : number is negative
-*/
-
 typedef struct TransSnapPoint {
        struct TransSnapPoint *next,*prev;
        float co[3];
@@ -94,6 +85,7 @@ typedef struct TransSnap {
        float   snapNormal[3];
        float   snapTangent[3];
        ListBase points;
+       TransSnapPoint  *selectedPoint;
        float   dist; // Distance from snapPoint to snapTarget
        double  last;
        void  (*applySnap)(struct TransInfo *, float *);
@@ -618,6 +610,7 @@ int validSnappingNormal(TransInfo *t);
 
 void getSnapPoint(TransInfo *t, float vec[3]);
 void addSnapPoint(TransInfo *t);
+int updateSelectedSnapPoint(TransInfo *t);
 void removeSnapPoint(TransInfo *t);
 
 /********************** Mouse Input ******************************/
index d341a21bc717baa5adc841835c8de4d1fb4884d0..ed3e949c8a02393bf65274251aca6b9850d8752a 100644 (file)
@@ -141,11 +141,16 @@ void drawSnapping(const struct bContext *C, TransInfo *t)
        if (validSnap(t) && activeSnap(t))
                {
                
-               unsigned char col[4];
+               unsigned char col[4], selectedCol[4], activeCol[4];
                UI_GetThemeColor3ubv(TH_TRANSFORM, col);
                col[3]= 128;
-               glColor4ubv(col);
                
+               UI_GetThemeColor3ubv(TH_SELECT, selectedCol);
+               selectedCol[3]= 128;
+
+               UI_GetThemeColor3ubv(TH_ACTIVE, activeCol);
+               activeCol[3]= 192;
+
                if (t->spacetype == SPACE_VIEW3D) {
                        TransSnapPoint *p;
                        View3D *v3d = CTX_wm_view3d(C);
@@ -160,16 +165,26 @@ void drawSnapping(const struct bContext *C, TransInfo *t)
                        invert_m4_m4(imat, rv3d->viewmat);
 
                        for (p = t->tsnap.points.first; p; p = p->next) {
-                               drawcircball(GL_LINE_LOOP, p->co, ED_view3d_pixel_size(rv3d, p->co) * size, imat);
+                               if (p == t->tsnap.selectedPoint) {
+                                       glColor4ubv(selectedCol);
+                               } else {
+                                       glColor4ubv(col);
+                               }
+
+                               drawcircball(GL_LINE_LOOP, p->co, ED_view3d_pixel_size(rv3d, p->co) * size * 0.75f, imat);
                        }
 
                        if (t->tsnap.status & POINT_INIT) {
+                               glColor4ubv(activeCol);
+
                                drawcircball(GL_LINE_LOOP, t->tsnap.snapPoint, ED_view3d_pixel_size(rv3d, t->tsnap.snapPoint) * size, imat);
                        }
                        
                        /* draw normal if needed */
                        if (usingSnappingNormal(t) && validSnappingNormal(t))
                        {
+                               glColor4ubv(activeCol);
+
                                glBegin(GL_LINES);
                                        glVertex3f(t->tsnap.snapPoint[0], t->tsnap.snapPoint[1], t->tsnap.snapPoint[2]);
                                        glVertex3f(     t->tsnap.snapPoint[0] + t->tsnap.snapNormal[0],
@@ -219,7 +234,7 @@ void drawSnapping(const struct bContext *C, TransInfo *t)
        }
 }
 
-int  handleSnapping(TransInfo *UNUSED(t), wmEvent *UNUSED(event))
+int  handleSnapping(TransInfo *t, wmEvent *event)
 {
        int status = 0;
 
@@ -232,6 +247,10 @@ int  handleSnapping(TransInfo *UNUSED(t), wmEvent *UNUSED(event))
                status = 1;
        }
 #endif
+       if (event->type == MOUSEMOVE)
+       {
+               status |= updateSelectedSnapPoint(t);
+       }
        
        return status;
 }
@@ -541,6 +560,8 @@ void addSnapPoint(TransInfo *t)
        if (t->tsnap.status & POINT_INIT) {
                TransSnapPoint *p = MEM_callocN(sizeof(TransSnapPoint), "SnapPoint");
 
+               t->tsnap.selectedPoint = p;
+
                copy_v3_v3(p->co, t->tsnap.snapPoint);
 
                BLI_addtail(&t->tsnap.points, p);
@@ -549,13 +570,55 @@ void addSnapPoint(TransInfo *t)
        }
 }
 
+int updateSelectedSnapPoint(TransInfo *t)
+{
+       int status = 0;
+       if (t->tsnap.status & MULTI_POINTS) {
+               TransSnapPoint *p, *closest_p = NULL;
+               int closest_dist = 0;
+               int screen_loc[2];
+
+               for( p = t->tsnap.points.first; p; p = p->next ) {
+                       int dx, dy;
+                       int dist;
+
+                       project_int(t->ar, p->co, screen_loc);
+
+                       dx = t->mval[0] - screen_loc[0];
+                       dy = t->mval[1] - screen_loc[1];
+
+                       dist = dx * dx + dy * dy;
+
+                       if (dist < 100 && (closest_p == NULL || closest_dist > dist)) {
+                               closest_p = p;
+                               closest_dist = dist;
+                       }
+               }
+
+               if (closest_p) {
+                       status = t->tsnap.selectedPoint == closest_p ? 0 : 1;
+                       t->tsnap.selectedPoint = closest_p;
+               }
+       }
+
+       return status;
+}
+
 void removeSnapPoint(TransInfo *t)
 {
        if (t->tsnap.status & MULTI_POINTS) {
-               BLI_freelinkN(&t->tsnap.points, t->tsnap.points.last);
+               updateSelectedSnapPoint(t);
+
+               if (t->tsnap.selectedPoint) {
+                       BLI_freelinkN(&t->tsnap.points, t->tsnap.selectedPoint);
+
+                       if (t->tsnap.points.first == NULL) {
+                               t->tsnap.status &= ~MULTI_POINTS;
+                       }
+
+                       t->tsnap.selectedPoint = NULL;
+               }
 
-               if (t->tsnap.points.first == NULL)
-                       t->tsnap.status &= ~MULTI_POINTS;
        }
 }