merge with trunk at r31523
[blender.git] / source / blender / editors / transform / transform.c
index de50861259d1c55e4db1c20e8c31cde1c93240fc..8c08b71eacd279d4a92d7af02e43a6d1f2cd6f1b 100644 (file)
@@ -4185,11 +4185,332 @@ int BoneEnvelope(TransInfo *t, short mval[2])
 }
 
 /* ********************  Edge Slide   *************** */
+#if 0
+static int createSlideVerts(TransInfo *t) {
+#else
+static BMEdge *get_other_edge(BMesh *bm, BMVert *v, BMEdge *e)
+{
+       BMIter iter;
+       BMEdge *e2;
+
+       BM_ITER(e2, &iter, bm, BM_EDGES_OF_VERT, v) {
+               if (BM_TestHFlag(e2, BM_SELECT) && e2 != e)
+                       return e2;
+       }
+
+       return NULL;
+}
+
+static BMLoop *get_next_loop(BMesh *bm, BMVert *v, BMLoop *l, 
+                             BMEdge *olde, BMEdge *nexte, float vec[3])
+{
+       BMLoop *firstl;
+       float a[3] = {0.0f, 0.0f, 0.0f}, n[3] = {0.0f, 0.0f, 0.0f};
+       int i=0;
+
+       firstl = l;
+       do {
+               l = BM_OtherFaceLoop(l->e, l->f, v);
+               if (l->radial_next == l)
+                       return NULL;
+               
+               if (l->e == nexte) {
+                       if (i) {
+                               mul_v3_fl(a, 1.0f / (float)i);
+                       } else {
+                               float f1[3], f2[3], f3[3], n[3];
+
+                               sub_v3_v3v3(f1, BM_OtherEdgeVert(olde, v)->co, v->co);
+                               sub_v3_v3v3(f2, BM_OtherEdgeVert(nexte, v)->co, v->co);
+
+                               cross_v3_v3v3(f3, f1, l->f->no);
+                               cross_v3_v3v3(a, f2, l->f->no);
+                               mul_v3_fl(a, -1.0f);
+
+                               add_v3_v3(a, f3);
+                               mul_v3_fl(a, 0.5f);
+                       }
+                       
+                       VECCOPY(vec, a);
+                       return l;
+               } else {
+                       sub_v3_v3v3(n, BM_OtherEdgeVert(l->e, v)->co, v->co);
+                       add_v3_v3v3(a, a, n);
+                       i += 1;
+               }
+
+               if (BM_OtherFaceLoop(l->e, l->f, v)->e == nexte) {
+                       if (i)
+                               mul_v3_fl(a, 1.0f / (float)i);
+                       
+                       VECCOPY(vec, a);
+                       return BM_OtherFaceLoop(l->e, l->f, v);
+               }
+               
+               l = l->radial_next;
+       } while (l != firstl); 
+
+       if (i)
+               mul_v3_fl(a, 1.0f / (float)i);
+       
+       VECCOPY(vec, a);
+       
+       return NULL;
+}
 
 static int createSlideVerts(TransInfo *t)
 {
        Mesh *me = t->obedit->data;
-       EditMesh *em = me->edit_mesh;
+       BMEditMesh *em = me->edit_btmesh;
+       BMesh *bm = em->bm;
+       BMIter iter, iter2;
+       BMEdge *e, *e1, *e2;
+       BMVert *v, *v2, *first;
+       BMLoop *l, *l1, *l2;
+       TransDataSlideVert *tempsv, *sv;
+       GHash **uvarray= NULL;
+       SlideData *sld = MEM_callocN(sizeof(*sld), "sld");
+       TransDataSlideUv *slideuvs=NULL, *suv=NULL, *suv_last=NULL;
+       RegionView3D *v3d = t->ar->regiondata;
+       ARegion *ar = t->ar;
+       float projectMat[4][4];
+       float start[3] = {0.0f, 0.0f, 0.0f}, end[3] = {0.0f, 0.0f, 0.0f};
+       float vec[3], vec2[3], size, dis=0.0, z;
+       float totvec=0.0;
+       int uvlay_tot= CustomData_number_of_layers(&em->bm->pdata, CD_MTFACE);
+       int uvlay_idx, numsel, i, j;
+
+       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->e to a selected edge*/
+                                       v->e = 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 || BM_Edge_FaceCount(e) == 0)
+                               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;
+
+               if (!v->e)
+                       continue;
+               
+               first = v;
+
+               /*walk along the edge loop*/
+               e = v->e;
+
+               /*first, rewind*/
+               numsel = 0;
+               do {
+                       e = get_other_edge(bm, v, e);
+                       if (!e) {
+                               e = v->e;
+                               break;
+                       }
+
+                       numsel += 1;
+
+                       if (!BMINDEX_GET(BM_OtherEdgeVert(e, v)))
+                               break;
+
+                       v = BM_OtherEdgeVert(e, v);
+               } while (e != first->e);
+
+               BMINDEX_SET(v, 0);
+
+               l1 = l2 = l = NULL;
+               l1 = e->l;
+               l2 = e->l->radial_next;
+
+               l = BM_OtherFaceLoop(l1->e, l1->f, v);
+               sub_v3_v3v3(vec, BM_OtherEdgeVert(l->e, v)->co, v->co);
+
+               if (l2 != l1) {
+                       l = BM_OtherFaceLoop(l2->e, l2->f, v);
+                       sub_v3_v3v3(vec2, BM_OtherEdgeVert(l->e, v)->co, v->co);
+               } else {
+                       l2 = NULL;
+               }
+
+               /*iterate over the loop*/
+               first = v;
+               j = 0;
+               do {
+                       TransDataSlideVert *sv = tempsv + j;
+
+                       sv->v = v;
+                       sv->origvert = *v;
+                       VECCOPY(sv->upvec, vec);
+                       if (l2)
+                               VECCOPY(sv->downvec, vec2);
+
+                       l = BM_OtherFaceLoop(l1->e, l1->f, v);
+                       sv->up = BM_OtherEdgeVert(l->e, v);
+
+                       if (l2) {
+                               l = BM_OtherFaceLoop(l2->e, l2->f, v);
+                               sv->down = BM_OtherEdgeVert(l->e, v);
+                       }
+
+                       v2=v, v = BM_OtherEdgeVert(e, v);
+
+                       e1 = e;
+                       e = get_other_edge(bm, v, e);
+                       if (!e) {
+                               //v2=v, v = BM_OtherEdgeVert(l1->e, v);
+
+                               sv = tempsv + j + 1;
+                               sv->v = v;
+                               sv->origvert = *v;
+                               
+                               l = BM_OtherFaceLoop(l1->e, l1->f, v);
+                               sv->up = BM_OtherEdgeVert(l->e, v);
+                               sub_v3_v3v3(sv->upvec, BM_OtherEdgeVert(l->e, v)->co, v->co);
+
+                               if (l2) {
+                                       l = BM_OtherFaceLoop(l2->e, l2->f, v);
+                                       sv->down = BM_OtherEdgeVert(l->e, v);
+                                       sub_v3_v3v3(sv->downvec, BM_OtherEdgeVert(l->e, v)->co, v->co);
+                               }
+
+                               BMINDEX_SET(v, 0);
+                               BMINDEX_SET(v2, 0);
+                               
+                               j += 2;
+                               break;
+                       }
+
+                       l1 = get_next_loop(bm, v, l1, e1, e, vec);
+                       l2 = l2 ? get_next_loop(bm, v, l2, e1, e, vec2) : NULL;
+
+                       j += 1;
+
+                       BMINDEX_SET(v, 0);
+                       BMINDEX_SET(v2, 0);
+               } while (e != first->e && l1);
+       }
+
+       //EDBM_clear_flag_all(em, BM_SELECT);
+
+       sld->sv = tempsv;
+       sld->totsv = j;
+       
+       /*find mouse vector*/
+       dis = z = 10000.0f;
+       size = 50.0;
+       BM_ITER(e, &iter, em->bm, BM_EDGES_OF_MESH, NULL) {
+               if (BM_TestHFlag(e, BM_SELECT)) {
+                       BMIter iter2;
+                       BMEdge *e2;
+                       float vec1[3], vec2[3], dir[3], vec[3], mval[2] = {t->mval[0], t->mval[1]}, d, z2;
+                       
+                       for (i=0; i<2; i++) {
+                               BM_ITER(e2, &iter2, em->bm, BM_EDGES_OF_VERT, i?e->v1:e->v2) {
+                                       if (BM_TestHFlag(e2, BM_SELECT))
+                                               continue;
+
+                                       view3d_project_float_v3(ar, e2->v1->co, vec1, projectMat);
+                                       view3d_project_float_v3(ar, e2->v2->co, vec2, projectMat);
+                                       
+                                       add_v3_v3v3(vec, vec1, vec2);
+                                       mul_v3_fl(vec, 0.5);
+                                       z2 = vec[2];
+
+                                       d = dist_to_line_segment_v2(mval, vec1, vec2);
+                                       if (d < dis || (d < 15 && z2 < z)) {
+                                               dis = d;
+                                               size = len_v3v3(vec1, vec2);
+                                       }
+                               }
+                       }
+                       view3d_project_float(ar, e->v1->co, vec1, projectMat);
+                       view3d_project_float(ar, e->v2->co, vec2, projectMat);
+
+                       sub_v3_v3v3(vec, vec1, vec2);
+                       normalize_v3(vec);
+
+                       if (dot_v3v3(dir, dir) != 0.0f) {
+                               copy_v3_v3(dir, start);
+                               normalize_v3(dir);
+                               
+                               if (dot_v3v3(dir, vec) < 0.0) {
+                                       mul_v3_fl(dir, -1.0);
+                               }
+                       }
+
+                       add_v3_v3(start, dir);
+               }
+       }
+       
+       normalize_v3(start);
+       mul_v3_fl(start, size);
+
+       end[0] = start[1];
+       end[1] = -start[0];
+
+       SWAP(float, start[0], start[1]);
+
+       sld->start[0] = t->mval[0] + start[0];
+       sld->start[1] = t->mval[1] + start[1];
+
+       sld->end[0] = t->mval[0] + end[0];
+       sld->end[1] = t->mval[1] + end[1];
+       
+       t->customData = sld;
+
+       return 1;
+#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;
@@ -4652,10 +4973,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;
@@ -4684,6 +5007,7 @@ void freeSlideVerts(TransInfo *t)
 
        MEM_freeN(sld);
        t->customData = NULL;
+#endif
 }
 
 void initEdgeSlide(TransInfo *t)
@@ -4718,6 +5042,26 @@ void initEdgeSlide(TransInfo *t)
 
 int doEdgeSlide(TransInfo *t, float perc)
 {
+       SlideData *sld = t->customData;
+       TransDataSlideVert *svlist = sld->sv, *sv;
+       float vec[3];
+       int i;
+
+       sv = svlist;
+       for (i=0; i<sld->totsv; i++, sv++) {
+               if (perc > 0.0f) {
+                       VECCOPY(vec, sv->upvec);
+                       mul_v3_fl(vec, perc);
+                       add_v3_v3v3(sv->v->co, sv->origvert.co, vec);
+               } else {
+                       VECCOPY(vec, sv->downvec);
+                       mul_v3_fl(vec, -perc);
+                       add_v3_v3v3(sv->v->co, sv->origvert.co, vec);
+               }
+       }
+
+       return 1;
+#if 0
        Mesh *me= t->obedit->data;
        EditMesh *em = me->edit_mesh;
        SlideData *sld = t->customData;
@@ -4826,6 +5170,7 @@ int doEdgeSlide(TransInfo *t, float perc)
        }
 
        return 1;
+#endif
 }
 
 int EdgeSlide(TransInfo *t, short mval[2])