ok, apparently didn't commit this either. apparently includes a merge with trunk...
[blender-staging.git] / source / blender / editors / transform / transform.c
index 769395d4581dcfc3980a1123ba5bd6b38727d868..66ced74e1a8108f10f78ccdc1c79474c173ccabe 100644 (file)
@@ -555,7 +555,8 @@ void transform_modal_keymap(wmKeyConfig *keyconf)
        WM_modalkeymap_assign(keymap, "TFM_OT_shrink_fatten");
        WM_modalkeymap_assign(keymap, "TFM_OT_tilt");
        WM_modalkeymap_assign(keymap, "TFM_OT_trackball");
-       
+       WM_modalkeymap_assign(keymap, "TFM_OT_mirror");
+       WM_modalkeymap_assign(keymap, "TFM_OT_edge_slide");
 }
 
 
@@ -3929,11 +3930,179 @@ int BoneEnvelope(TransInfo *t, short mval[2])
 }
 
 /* ********************  Edge Slide   *************** */
+#if 1
+static int createSlideVerts(TransInfo *t) {
+#else
+static BMEdge *get_other_edge(BMesh *bm, BMVert *v, BMEdge *e)
+{
+       BMIter iter;
+       BMEdge *e2;
+
+       BM_ITER(e, &iter, bm, BM_EDGES_OF_VERT, v) {
+               if (BM_TestHFlag(e2, BM_SELECT) && e2 != e)
+                       return e;
+       }
+
+       return NULL;
+}
+
+static BMLoop *get_next_loop(BMesh *bm, BMVert *v, BMFace *f, 
+                             BMEdge *olde, BMEdge *nexte)
+{
+       BMIter iter;
+       BMLoop *l, firstl;
+
+       BM_ITER(l, &iter, bm, BM_LOOPS_OF_FACE, f) {
+               if (l->e == olde)
+                       break;
+       }
+
+       firstl = l;
+       do {
+               l = BM_OtherFaceLoop(l->e, l->f, v);
+               if (l->radial.next->data == l)
+                       return NULL;
+               
+               if (BM_OtherFaceLoop(l->e, l->f, v)->e == nexte)
+                       return BM_OtherFaceLoop(l->e, l->f, v);
+               
+               if (l->e == nexte)
+                       return l;
+
+               l = l->radial.next->data;
+       } while (l != firstl); 
+
+       return NULL;
+}
 
 static int createSlideVerts(TransInfo *t)
 {
        Mesh *me = t->obedit->data;
-       EditMesh *em = me->edit_mesh;
+       BMEditMesh *em = me->edit_btmesh;
+       BMIter iter, iter2;
+       BMEdge *e, *e1, *e2;
+       BMVert *v, *first;
+       BMLoop *l, *l1, *l2;
+       TransDataSlideVert *tempsv;
+       GHash **uvarray= NULL;
+       SlideData *sld = MEM_callocN(sizeof(*sld), "sld");
+       int  uvlay_tot= CustomData_number_of_layers(&em->fdata, CD_MTFACE);
+       int uvlay_idx;
+       TransDataSlideUv *slideuvs=NULL, *suv=NULL, *suv_last=NULL;
+       RegionView3D *v3d = t->ar->regiondata;
+       float projectMat[4][4];
+       float start[3] = {0.0f, 0.0f, 0.0f}, end[3] = {0.0f, 0.0f, 0.0f};
+       float vec[3], i, j;
+       float totvec=0.0;
+
+       if (!v3d) {
+               /*ok, let's try to survive this*/
+               unit_m4(projectMat);
+       } else {
+               view3d_get_object_project_mat(v3d, t->obedit, projectMat);
+       }
+       
+       /*ensure valid selection*/
+       BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
+               if (BM_TestHFlag(v, BM_SELECT)) {
+                       numsel = 0;
+                       BM_ITER(e, &iter2, em->bm, BM_EDGES_OF_VERT, v) {
+                               if (BM_TestHFlag(e, BM_SELECT)) {
+                                       /*BMESH_TODO: this is probably very evil,
+                                         set v->edge to a selected edge*/
+                                       v->edge = e;
+
+                                       numsel++;
+                               }
+                       }
+
+                       if (numsel > 2) {
+                               return 0; //invalid edge selection
+                       }
+               }
+       }
+
+       BM_ITER(e, &iter, em->bm, BM_EDGES_OF_MESH, NULL) {
+               if (BM_TestHFlag(e, BM_SELECT)) {
+                       if (BM_Edge_FaceCount(e) > 2)
+                               return 0; //can't handle more then 2 faces around an edge
+               }
+       }
+
+       j = 0;
+       BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
+               if (BM_TestHFlag(v, BM_SELECT)) {
+                       BMINDEX_SET(v, 1);
+                       j += 1;
+               } else BMINDEX_SET(v, 0);
+       }
+
+       if (!j)
+               return 0;
+
+       tempsv = MEM_callocN(sizeof(TransDataSlideVert)*j, "tempsv");
+
+       j = 0;
+       while (1) {
+               v = NULL;
+               BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
+                       if (BMINDEX_GET(v))
+                               break;
+
+               }
+
+               if (!v)
+                       break;
+
+               BMINDX_SET(v, 0);
+
+               if (!v->edge)
+                       continue
+               
+               first = v;
+
+               /*walk along the edge loop*/
+               e = v->edge;
+
+               /*first, rewind*/
+               numsel = 0;
+               do {
+                       e = get_other_edge(bm, v, e);
+                       if (!e) {
+                               e = v->edge;
+                               break;
+                       }
+
+                       v = BM_OtherEdgeVert(e, v);
+                       numsel += 1;
+               } while (e != v->edge);
+
+               l1 = l2 = l = NULL;
+
+               /*iterate over the loop*/
+               first = v;
+               do {
+                       TransDataSlideVert *sv = tempsv + j;
+
+                       sv->v = v;
+                       sv->origvert = *v;
+
+                       e = get_other_edge(bm, v, e);
+                       if (!e) {
+                               e = v->edge;
+                               break;
+                       }
+
+                       v = BM_OtherEdgeVert(e, v);
+                       j += 1
+               } while (e != v->edge);
+       }
+
+       MEM_freeN(tempsv);
+#endif
+#if 0
+       Mesh *me = t->obedit->data;
+       BMEditMesh *em = me->edit_btmesh;
        EditFace *efa;
        EditEdge *eed,*first=NULL,*last=NULL, *temp = NULL;
        EditVert *ev, *nearest = NULL;
@@ -4396,10 +4565,12 @@ static int createSlideVerts(TransInfo *t)
        t->customData = sld;
 
        return 1;
+#endif
 }
 
 void freeSlideVerts(TransInfo *t)
 {
+#if 0
        TransDataSlideUv *suv;
        SlideData *sld = t->customData;
        int uvlay_idx;
@@ -4428,6 +4599,7 @@ void freeSlideVerts(TransInfo *t)
 
        MEM_freeN(sld);
        t->customData = NULL;
+#endif
 }
 
 void initEdgeSlide(TransInfo *t)
@@ -4445,8 +4617,9 @@ void initEdgeSlide(TransInfo *t)
 
        t->customFree = freeSlideVerts;
 
-       initMouseInputMode(t, &t->mouse, INPUT_CUSTOM_RATIO);
+       /* set custom point first if you want value to be initialized by init */
        setCustomPoints(t, &t->mouse, sld->end, sld->start);
+       initMouseInputMode(t, &t->mouse, INPUT_CUSTOM_RATIO);
        
        t->idx_max = 0;
        t->num.idx_max = 0;
@@ -4459,6 +4632,7 @@ void initEdgeSlide(TransInfo *t)
 
 int doEdgeSlide(TransInfo *t, float perc)
 {
+#if 0
        Mesh *me= t->obedit->data;
        EditMesh *em = me->edit_mesh;
        SlideData *sld = t->customData;
@@ -4564,7 +4738,7 @@ int doEdgeSlide(TransInfo *t, float perc)
                }
 
        }
-
+#endif
        return 1;
 }