Merge branch 'master' into blender2.8
authorCampbell Barton <ideasman42@gmail.com>
Thu, 15 Jun 2017 15:29:20 +0000 (01:29 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Thu, 15 Jun 2017 15:29:20 +0000 (01:29 +1000)
1  2 
source/blender/blenlib/BLI_math_vector.h
source/blender/blenlib/intern/math_vector.c
source/blender/editors/mesh/editmesh_knife.c
source/blender/editors/transform/transform.c

index c1e5c1177cce034677ddb1851abae2f9337ea6d3,43f414f376a3b546ca18ec7a3b4ae51f6ee2e610..120f3bb5ac3d4e8c21bc4c8d9b9be0ac8e8535ef
@@@ -123,7 -123,7 +123,7 @@@ MINLINE void mul_v4_fl(float r[4], floa
  MINLINE void mul_v4_v4fl(float r[3], const float a[3], float f);
  MINLINE void mul_v2_v2_cw(float r[2], const float mat[2], const float vec[2]);
  MINLINE void mul_v2_v2_ccw(float r[2], const float mat[2], const float vec[2]);
 -MINLINE float mul_project_m4_v3_zfac(float mat[4][4], const float co[3]) ATTR_WARN_UNUSED_RESULT;
 +MINLINE float mul_project_m4_v3_zfac(const float mat[4][4], const float co[3]) ATTR_WARN_UNUSED_RESULT;
  MINLINE float dot_m3_v3_row_x(float M[3][3], const float a[3]) ATTR_WARN_UNUSED_RESULT;
  MINLINE float dot_m3_v3_row_y(float M[3][3], const float a[3]) ATTR_WARN_UNUSED_RESULT;
  MINLINE float dot_m3_v3_row_z(float M[3][3], const float a[3]) ATTR_WARN_UNUSED_RESULT;
@@@ -151,7 -151,6 +151,7 @@@ MINLINE void negate_v3_short(short r[3]
  MINLINE void negate_v3_db(double r[3]);
  
  MINLINE void invert_v2(float r[2]);
 +MINLINE void invert_v3(float r[3]);
  
  MINLINE void abs_v2(float r[2]);
  MINLINE void abs_v2_v2(float r[2], const float a[2]);
@@@ -287,6 -286,8 +287,8 @@@ float angle_v3v3(const float a[3], cons
  float angle_v3v3v3(const float a[3], const float b[3], const float c[3]) ATTR_WARN_UNUSED_RESULT;
  float cos_v3v3v3(const float p1[3], const float p2[3], const float p3[3]) ATTR_WARN_UNUSED_RESULT;
  float cos_v2v2v2(const float p1[2], const float p2[2], const float p3[2]) ATTR_WARN_UNUSED_RESULT;
+ float angle_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3]) ATTR_WARN_UNUSED_RESULT;
+ float angle_signed_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3]) ATTR_WARN_UNUSED_RESULT;
  float angle_normalized_v3v3(const float v1[3], const float v2[3]) ATTR_WARN_UNUSED_RESULT;
  float angle_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3]) ATTR_WARN_UNUSED_RESULT;
  float angle_signed_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3]) ATTR_WARN_UNUSED_RESULT;
@@@ -300,13 -301,14 +302,15 @@@ void project_v2_v2v2(float out[2], cons
  void project_v3_v3v3(float out[3], const float p[3], const float v_proj[3]);
  void project_plane_v3_v3v3(float out[3], const float p[3], const float v_plane[3]);
  void project_plane_v2_v2v2(float out[2], const float p[2], const float v_plane[2]);
+ void project_plane_normalized_v3_v3v3(float out[3], const float p[3], const float v_plane[3]);
+ void project_plane_normalized_v2_v2v2(float out[2], const float p[2], const float v_plane[2]);
  void project_v3_plane(float out[3], const float plane_no[3], const float plane_co[3]);
  void reflect_v3_v3v3(float out[3], const float vec[3], const float normal[3]);
  void ortho_basis_v3v3_v3(float r_n1[3], float r_n2[3], const float n[3]);
  void ortho_v3_v3(float out[3], const float v[3]);
  void ortho_v2_v2(float out[2], const float v[2]);
  void bisect_v3_v3v3v3(float r[3], const float a[3], const float b[3], const float c[3]);
 +void rotate_v2_v2fl(float r[2], const float p[2], const float angle);
  void rotate_v3_v3v3fl(float v[3], const float p[3], const float axis[3], const float angle);
  void rotate_normalized_v3_v3v3fl(float out[3], const float p[3], const float axis[3], const float angle);
  
@@@ -322,7 -324,6 +326,7 @@@ void print_vn(const char *str, const fl
  #define print_v4_id(v) print_v4(STRINGIFY(v), v)
  #define print_vn_id(v, n) print_vn(STRINGIFY(v), v, n)
  
 +MINLINE void normal_float_to_short_v2(short r[2], const float n[2]);
  MINLINE void normal_short_to_float_v3(float r[3], const short n[3]);
  MINLINE void normal_float_to_short_v3(short r[3], const float n[3]);
  
index b45137fd7f750160e7d387daccfe0e7f02590c89,c6e9b8229ba3fc8b0fe172ab75c06198fb4c57ac..40a78adcefe157fa3d2661fdcd5d843a253e81bc
@@@ -518,38 -518,27 +518,27 @@@ float angle_normalized_v2v2(const floa
  }
  
  /**
-  * angle between 2 vectors defined by 3 coords, about an axis. */
- float angle_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3])
+  * Angle between 2 vectors, about an axis (axis can be considered a plane).
+  */
+ float angle_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3])
  {
-       float v1_proj[3], v2_proj[3], tproj[3];
-       sub_v3_v3v3(v1_proj, v1, v2);
-       sub_v3_v3v3(v2_proj, v3, v2);
+       float v1_proj[3], v2_proj[3];
  
        /* project the vectors onto the axis */
-       project_v3_v3v3(tproj, v1_proj, axis);
-       sub_v3_v3(v1_proj, tproj);
-       project_v3_v3v3(tproj, v2_proj, axis);
-       sub_v3_v3(v2_proj, tproj);
+       project_plane_normalized_v3_v3v3(v1_proj, v1, axis);
+       project_plane_normalized_v3_v3v3(v2_proj, v2, axis);
  
        return angle_v3v3(v1_proj, v2_proj);
  }
  
- float angle_signed_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3])
+ float angle_signed_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3])
  {
        float v1_proj[3], v2_proj[3], tproj[3];
        float angle;
  
-       sub_v3_v3v3(v1_proj, v1, v2);
-       sub_v3_v3v3(v2_proj, v3, v2);
        /* project the vectors onto the axis */
-       project_v3_v3v3(tproj, v1_proj, axis);
-       sub_v3_v3(v1_proj, tproj);
-       project_v3_v3v3(tproj, v2_proj, axis);
-       sub_v3_v3(v2_proj, tproj);
+       project_plane_normalized_v3_v3v3(v1_proj, v1, axis);
+       project_plane_normalized_v3_v3v3(v2_proj, v2, axis);
  
        angle = angle_v3v3(v1_proj, v2_proj);
  
        return angle;
  }
  
+ /**
+  * Angle between 2 vectors defined by 3 coords, about an axis (axis can be considered a plane).
+  */
+ float angle_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3])
+ {
+       float vec1[3], vec2[3];
+       sub_v3_v3v3(vec1, v1, v2);
+       sub_v3_v3v3(vec2, v3, v2);
+       return angle_on_axis_v3v3_v3(vec1, vec2, axis);
+ }
+ float angle_signed_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3])
+ {
+       float vec1[3], vec2[3];
+       sub_v3_v3v3(vec1, v1, v2);
+       sub_v3_v3v3(vec2, v3, v2);
+       return angle_signed_on_axis_v3v3_v3(vec1, vec2, axis);
+ }
  void angle_tri_v3(float angles[3], const float v1[3], const float v2[3], const float v3[3])
  {
        float ed1[3], ed2[3], ed3[3];
@@@ -669,6 -681,25 +681,25 @@@ void project_plane_v2_v2v2(float out[2]
        out[1] = p[1] - (mul * v_plane[1]);
  }
  
+ void project_plane_normalized_v3_v3v3(float out[3], const float p[3], const float v_plane[3])
+ {
+       BLI_ASSERT_UNIT_V3(v_plane);
+       const float mul = dot_v3v3(p, v_plane);
+       out[0] = p[0] - (mul * v_plane[0]);
+       out[1] = p[1] - (mul * v_plane[1]);
+       out[2] = p[2] - (mul * v_plane[2]);
+ }
+ void project_plane_normalized_v2_v2v2(float out[2], const float p[2], const float v_plane[2])
+ {
+       BLI_ASSERT_UNIT_V2(v_plane);
+       const float mul = dot_v2v2(p, v_plane);
+       out[0] = p[0] - (mul * v_plane[0]);
+       out[1] = p[1] - (mul * v_plane[1]);
+ }
  /* project a vector on a plane defined by normal and a plane point p */
  void project_v3_plane(float out[3], const float plane_no[3], const float plane_co[3])
  {
@@@ -793,20 -824,6 +824,20 @@@ void ortho_v2_v2(float out[2], const fl
        out[1] =  v[0];
  }
  
 +/**
 + * Rotate a point \a p by \a angle around origin (0, 0)
 + */
 +void rotate_v2_v2fl(float r[2], const float p[2], const float angle)
 +{
 +      const float co = cosf(angle);
 +      const float si = sinf(angle);
 +
 +      BLI_assert(r != p);
 +
 +      r[0] = co * p[0] - si * p[1];
 +      r[1] = si * p[0] + co * p[1];
 +}
 +
  /**
   * Rotate a point \a p by \a angle around an arbitrary unit length \a axis.
   * http://local.wasp.uwa.edu.au/~pbourke/geometry/
index 3fe7c1d1c99cdd64b58467fafb50da9e17bda3fd,5e44509e10a6f9fd36ab8e9bb01cadf16b3d47f2..530faffdac115f84ea2b47a425f9b2fbbd65df27
@@@ -54,8 -54,8 +54,8 @@@
  #include "BKE_editmesh_bvh.h"
  #include "BKE_report.h"
  
 -#include "BIF_gl.h"
 -#include "BIF_glutil.h" /* for paint cursor */
 +#include "GPU_immediate.h"
 +#include "GPU_matrix.h"
  
  #include "ED_screen.h"
  #include "ED_space_api.h"
@@@ -1002,18 -1002,12 +1002,18 @@@ static void knifetool_draw_angle_snappi
                copy_v3_v3(v2, ray_hit_best[1]);
        }
  
 -      UI_ThemeColor(TH_TRANSFORM);
 +      unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
 +
 +      immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
 +      immUniformThemeColor(TH_TRANSFORM);
        glLineWidth(2.0);
 -      glBegin(GL_LINES);
 -      glVertex3fv(v1);
 -      glVertex3fv(v2);
 -      glEnd();
 +
 +      immBegin(PRIM_LINES, 2);
 +      immVertex3fv(pos, v1);
 +      immVertex3fv(pos, v2);
 +      immEnd();
 +
 +      immUnbindProgram();
  }
  
  static void knife_init_colors(KnifeColors *colors)
@@@ -1041,69 -1035,66 +1041,69 @@@ static void knifetool_draw(const bConte
  
        glPolygonOffset(1.0f, 1.0f);
  
 -      glPushMatrix();
 -      glMultMatrixf(kcd->ob->obmat);
 +      gpuPushMatrix();
 +      gpuMultMatrix(kcd->ob->obmat);
 +
 +      unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
 +
 +      immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
  
        if (kcd->mode == MODE_DRAGGING) {
                if (kcd->is_angle_snapping)
                        knifetool_draw_angle_snapping(kcd);
  
 -              glColor3ubv(kcd->colors.line);
 -              
 +              immUniformColor3ubv(kcd->colors.line);
                glLineWidth(2.0);
  
 -              glBegin(GL_LINES);
 -              glVertex3fv(kcd->prev.cage);
 -              glVertex3fv(kcd->curr.cage);
 -              glEnd();
 +              immBegin(PRIM_LINES, 2);
 +              immVertex3fv(pos, kcd->prev.cage);
 +              immVertex3fv(pos, kcd->curr.cage);
 +              immEnd();
        }
  
        if (kcd->prev.vert) {
 -              glColor3ubv(kcd->colors.point);
 +              immUniformColor3ubv(kcd->colors.point);
                glPointSize(11);
  
 -              glBegin(GL_POINTS);
 -              glVertex3fv(kcd->prev.cage);
 -              glEnd();
 +              immBegin(PRIM_POINTS, 1);
 +              immVertex3fv(pos, kcd->prev.cage);
 +              immEnd();
        }
  
        if (kcd->prev.bmface) {
 -              glColor3ubv(kcd->colors.curpoint);
 +              immUniformColor3ubv(kcd->colors.curpoint);
                glPointSize(9);
  
 -              glBegin(GL_POINTS);
 -              glVertex3fv(kcd->prev.cage);
 -              glEnd();
 +              immBegin(PRIM_POINTS, 1);
 +              immVertex3fv(pos, kcd->prev.cage);
 +              immEnd();
        }
  
        if (kcd->curr.edge) {
 -              glColor3ubv(kcd->colors.edge);
 +              immUniformColor3ubv(kcd->colors.edge);
                glLineWidth(2.0);
  
 -              glBegin(GL_LINES);
 -              glVertex3fv(kcd->curr.edge->v1->cageco);
 -              glVertex3fv(kcd->curr.edge->v2->cageco);
 -              glEnd();
 +              immBegin(PRIM_LINES, 2);
 +              immVertex3fv(pos, kcd->curr.edge->v1->cageco);
 +              immVertex3fv(pos, kcd->curr.edge->v2->cageco);
 +              immEnd();
        }
        else if (kcd->curr.vert) {
 -              glColor3ubv(kcd->colors.point);
 +              immUniformColor3ubv(kcd->colors.point);
                glPointSize(11);
  
 -              glBegin(GL_POINTS);
 -              glVertex3fv(kcd->curr.cage);
 -              glEnd();
 +              immBegin(PRIM_POINTS, 1);
 +              immVertex3fv(pos, kcd->curr.cage);
 +              immEnd();
        }
  
        if (kcd->curr.bmface) {
 -              glColor3ubv(kcd->colors.curpoint);
 +              immUniformColor3ubv(kcd->colors.curpoint);
                glPointSize(9);
  
 -              glBegin(GL_POINTS);
 -              glVertex3fv(kcd->curr.cage);
 -              glEnd();
 +              immBegin(PRIM_POINTS, 1);
 +              immVertex3fv(pos, kcd->curr.cage);
 +              immEnd();
        }
  
        if (kcd->totlinehit > 0) {
                glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  
                /* draw any snapped verts first */
 -              glColor4ubv(kcd->colors.point_a);
 +              immUniformColor4ubv(kcd->colors.point_a);
                glPointSize(11);
 -              glBegin(GL_POINTS);
 +
 +              immBeginAtMost(PRIM_POINTS, kcd->totlinehit);
 +
                lh = kcd->linehits;
                for (i = 0; i < kcd->totlinehit; i++, lh++) {
 -                      if (lh->v)
 -                              glVertex3fv(lh->cagehit);
 +                      if (lh->v) {
 +                              immVertex3fv(pos, lh->cagehit);
 +                      }
                }
 -              glEnd();
 +
 +              immEnd();
  
                /* now draw the rest */
 -              glColor4ubv(kcd->colors.curpoint_a);
 +              immUniformColor4ubv(kcd->colors.curpoint_a);
                glPointSize(7);
 -              glBegin(GL_POINTS);
 +
 +              immBeginAtMost(PRIM_POINTS, kcd->totlinehit);
 +
                lh = kcd->linehits;
                for (i = 0; i < kcd->totlinehit; i++, lh++) {
 -                      if (!lh->v)
 -                              glVertex3fv(lh->cagehit);
 +                      if (!lh->v) {
 +                              immVertex3fv(pos, lh->cagehit);
 +                      }
                }
 -              glEnd();
 +
 +              immEnd();
 +
                glDisable(GL_BLEND);
        }
  
                BLI_mempool_iter iter;
                KnifeEdge *kfe;
  
 +              immUniformColor3ubv(kcd->colors.line);
                glLineWidth(1.0);
 -              glBegin(GL_LINES);
 +
 +              immBeginAtMost(PRIM_LINES, BLI_mempool_count(kcd->kedges) * 2);
  
                BLI_mempool_iternew(kcd->kedges, &iter);
                for (kfe = BLI_mempool_iterstep(&iter); kfe; kfe = BLI_mempool_iterstep(&iter)) {
                        if (!kfe->is_cut)
                                continue;
  
 -                      glColor3ubv(kcd->colors.line);
 -
 -                      glVertex3fv(kfe->v1->cageco);
 -                      glVertex3fv(kfe->v2->cageco);
 +                      immVertex3fv(pos, kfe->v1->cageco);
 +                      immVertex3fv(pos, kfe->v2->cageco);
                }
  
 -              glEnd();
 +              immEnd();
        }
  
        if (kcd->totkvert > 0) {
                BLI_mempool_iter iter;
                KnifeVert *kfv;
  
 +              immUniformColor3ubv(kcd->colors.point);
                glPointSize(5.0);
  
 -              glBegin(GL_POINTS);
 +              immBeginAtMost(PRIM_POINTS, BLI_mempool_count(kcd->kverts));
 +
                BLI_mempool_iternew(kcd->kverts, &iter);
                for (kfv = BLI_mempool_iterstep(&iter); kfv; kfv = BLI_mempool_iterstep(&iter)) {
                        if (!kfv->is_cut)
                                continue;
  
 -                      glColor3ubv(kcd->colors.point);
 -
 -                      glVertex3fv(kfv->cageco);
 +                      immVertex3fv(pos, kfv->cageco);
                }
  
 -              glEnd();
 +              immEnd();
        }
  
 -      glPopMatrix();
 +      immUnbindProgram();
 +
 +      gpuPopMatrix();
  
        if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
  }
@@@ -1416,7 -1396,7 +1416,7 @@@ static bool bm_ray_cast_cb_elem_not_in_
   * intersecting faces matching this face (or connected when an vert/edge) will be ignored.
   */
  static bool point_is_visible(
 -        KnifeTool_OpData *kcd, const float p[3], const float s[2], bglMats *mats,
 +        KnifeTool_OpData *kcd, const float p[3], const float s[2],
          BMElem *ele_test)
  {
        BMFace *f_hit;
                float view[3], p_ofs[3];
  
                /* TODO: I think there's a simpler way to get the required raycast ray */
 -              ED_view3d_unproject(mats, view, s[0], s[1], 0.0f);
 +              ED_view3d_unproject(kcd->vc.ar, s[0], s[1], 0.0f, view);
  
                mul_m4_v3(kcd->ob->imat, view);
  
@@@ -1492,7 -1472,7 +1492,7 @@@ static void clip_to_ortho_planes(float 
  
        /* could be v1 or v2 */
        sub_v3_v3(v1, center);
-       project_plane_v3_v3v3(closest, v1, dir);
+       project_plane_normalized_v3_v3v3(closest, v1, dir);
        add_v3_v3(closest, center);
  
        madd_v3_v3v3fl(v1, closest, dir,  d);
@@@ -1507,6 -1487,7 +1507,6 @@@ static void set_linehit_depth(KnifeTool
  /* Finds visible (or all, if cutting through) edges that intersects the current screen drag line */
  static void knife_find_line_hits(KnifeTool_OpData *kcd)
  {
 -      bglMats mats;
        SmallHash faces, kfes, kfvs;
        float v1[3], v2[3], v3[3], v4[3], s1[2], s2[2];
        BVHTree *planetree, *tree;
        const bool use_hit_prev = true;
        const bool use_hit_curr = (kcd->is_drag_hold == false);
  
 -      bgl_get_mats(&mats);
 -
        if (kcd->linehits) {
                MEM_freeN(kcd->linehits);
                kcd->linehits = NULL;
                knife_project_v2(kcd, v->cageco, s);
                d = dist_squared_to_line_segment_v2(s, s1, s2);
                if ((d <= vert_tol_sq) &&
 -                  (point_is_visible(kcd, v->cageco, s, &mats, bm_elem_from_knife_vert(v, &kfe_hit))))
 +                  (point_is_visible(kcd, v->cageco, s, bm_elem_from_knife_vert(v, &kfe_hit))))
                {
                        memset(&hit, 0, sizeof(hit));
                        hit.v = v;
                                 * Need to find 3d intersection of ray through sint */
                                knife_input_ray_segment(kcd, sint, 1.0f, r1, r2);
                                isect_kind = isect_line_line_v3(kfe->v1->cageco, kfe->v2->cageco, r1, r2, p_cage, p_cage_tmp);
 -                              if (isect_kind >= 1 && point_is_visible(kcd, p_cage, sint, &mats, bm_elem_from_knife_edge(kfe))) {
 +                              if (isect_kind >= 1 && point_is_visible(kcd, p_cage, sint, bm_elem_from_knife_edge(kfe))) {
                                        memset(&hit, 0, sizeof(hit));
                                        if (kcd->snap_midpoints) {
                                                /* choose intermediate point snap too */
                float p[3], p_cage[3];
  
                if (use_hit_prev && knife_ray_intersect_face(kcd, s1, v1, v3, f, face_tol_sq, p, p_cage)) {
 -                      if (point_is_visible(kcd, p_cage, s1, &mats, (BMElem *)f)) {
 +                      if (point_is_visible(kcd, p_cage, s1, (BMElem *)f)) {
                                memset(&hit, 0, sizeof(hit));
                                hit.f = f;
                                copy_v3_v3(hit.hit, p);
                }
  
                if (use_hit_curr && knife_ray_intersect_face(kcd, s2, v2, v4, f, face_tol_sq, p, p_cage)) {
 -                      if (point_is_visible(kcd, p_cage, s2, &mats, (BMElem *)f)) {
 +                      if (point_is_visible(kcd, p_cage, s2, (BMElem *)f)) {
                                memset(&hit, 0, sizeof(hit));
                                hit.f = f;
                                copy_v3_v3(hit.hit, p);
  static void knife_input_ray_segment(KnifeTool_OpData *kcd, const float mval[2], const float ofs,
                                      float r_origin[3], float r_origin_ofs[3])
  {
 -      bglMats mats;
 -
 -      bgl_get_mats(&mats);
 -
        /* unproject to find view ray */
 -      ED_view3d_unproject(&mats, r_origin,     mval[0], mval[1], 0.0f);
 -      ED_view3d_unproject(&mats, r_origin_ofs, mval[0], mval[1], ofs);
 +      ED_view3d_unproject(kcd->vc.ar, mval[0], mval[1], 0.0f, r_origin);
 +      ED_view3d_unproject(kcd->vc.ar, mval[0], mval[1], ofs,  r_origin_ofs);
  
        /* transform into object space */
        invert_m4_m4(kcd->ob->imat, kcd->ob->obmat); 
@@@ -3005,6 -2992,7 +3005,6 @@@ static bool edbm_mesh_knife_point_isect
  void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_through)
  {
        KnifeTool_OpData *kcd;
 -      bglMats mats;
  
        view3d_operator_needs_opengl(C);
  
                if (use_tag) {
                        BM_mesh_elem_hflag_enable_all(kcd->em->bm, BM_EDGE, BM_ELEM_TAG, false);
                }
 -
 -              if (kcd->cut_through == false) {
 -                      bgl_get_mats(&mats);
 -              }
        }
  
        /* execute */
                                                        float cent[3], cent_ss[2];
                                                        BM_face_calc_point_in_face(f, cent);
                                                        knife_project_v2(kcd, cent, cent_ss);
 -                                                      if ((kcd->cut_through || point_is_visible(kcd, cent, cent_ss, &mats, (BMElem *)f)) &&
 +                                                      if ((kcd->cut_through || point_is_visible(kcd, cent, cent_ss, (BMElem *)f)) &&
                                                            edbm_mesh_knife_point_isect(polys, cent_ss))
                                                        {
                                                                BM_elem_flag_enable(f, BM_ELEM_TAG);
index 1bcb03d71db542ae0626b3a094eac687c4dae0b9,4686ff0523eb412482930b3c158379181d40b794..4727986fdb4d970c5e6bbe65febf19dcceca28c4
@@@ -43,7 -43,6 +43,7 @@@
  #include "DNA_mask_types.h"
  #include "DNA_movieclip_types.h"
  #include "DNA_scene_types.h"  /* PET modes */
 +#include "DNA_workspace_types.h"
  
  #include "BLI_alloca.h"
  #include "BLI_utildefines.h"
  #include "BKE_unit.h"
  #include "BKE_mask.h"
  #include "BKE_report.h"
 +#include "BKE_workspace.h"
  
 -#include "BIF_gl.h"
  #include "BIF_glutil.h"
  
 +#include "GPU_immediate.h"
 +#include "GPU_immediate_util.h"
 +#include "GPU_matrix.h"
 +
  #include "ED_image.h"
  #include "ED_keyframing.h"
  #include "ED_screen.h"
@@@ -1603,16 -1598,8 +1603,16 @@@ typedef enum 
        LEFT,
        RIGHT
  } ArrowDirection;
 +
 +#define POS_INDEX 0
 +/* NOTE: this --^ is a bit hackish, but simplifies VertexFormat usage among functions
 + * private to this file  - merwin
 + */
 +
  static void drawArrow(ArrowDirection d, short offset, short length, short size)
  {
 +      immBegin(PRIM_LINES, 6);
 +
        switch (d) {
                case LEFT:
                        offset = -offset;
                        size = -size;
                        ATTR_FALLTHROUGH;
                case RIGHT:
 -                      glBegin(GL_LINES);
 -                      glVertex2s(offset, 0);
 -                      glVertex2s(offset + length, 0);
 -                      glVertex2s(offset + length, 0);
 -                      glVertex2s(offset + length - size, -size);
 -                      glVertex2s(offset + length, 0);
 -                      glVertex2s(offset + length - size,  size);
 -                      glEnd();
 +                      immVertex2f(POS_INDEX, offset, 0);
 +                      immVertex2f(POS_INDEX, offset + length, 0);
 +                      immVertex2f(POS_INDEX, offset + length, 0);
 +                      immVertex2f(POS_INDEX, offset + length - size, -size);
 +                      immVertex2f(POS_INDEX, offset + length, 0);
 +                      immVertex2f(POS_INDEX, offset + length - size,  size);
                        break;
  
                case DOWN:
                        size = -size;
                        ATTR_FALLTHROUGH;
                case UP:
 -                      glBegin(GL_LINES);
 -                      glVertex2s(0, offset);
 -                      glVertex2s(0, offset + length);
 -                      glVertex2s(0, offset + length);
 -                      glVertex2s(-size, offset + length - size);
 -                      glVertex2s(0, offset + length);
 -                      glVertex2s(size, offset + length - size);
 -                      glEnd();
 +                      immVertex2f(POS_INDEX, 0, offset);
 +                      immVertex2f(POS_INDEX, 0, offset + length);
 +                      immVertex2f(POS_INDEX, 0, offset + length);
 +                      immVertex2f(POS_INDEX, -size, offset + length - size);
 +                      immVertex2f(POS_INDEX, 0, offset + length);
 +                      immVertex2f(POS_INDEX, size, offset + length - size);
                        break;
        }
 +
 +      immEnd();
  }
  
  static void drawArrowHead(ArrowDirection d, short size)
  {
 +      immBegin(PRIM_LINES, 4);
 +
        switch (d) {
                case LEFT:
                        size = -size;
                        ATTR_FALLTHROUGH;
                case RIGHT:
 -                      glBegin(GL_LINES);
 -                      glVertex2s(0, 0);
 -                      glVertex2s(-size, -size);
 -                      glVertex2s(0, 0);
 -                      glVertex2s(-size,  size);
 -                      glEnd();
 +                      immVertex2f(POS_INDEX, 0, 0);
 +                      immVertex2f(POS_INDEX, -size, -size);
 +                      immVertex2f(POS_INDEX, 0, 0);
 +                      immVertex2f(POS_INDEX, -size,  size);
                        break;
  
                case DOWN:
                        size = -size;
                        ATTR_FALLTHROUGH;
                case UP:
 -                      glBegin(GL_LINES);
 -                      glVertex2s(0, 0);
 -                      glVertex2s(-size, -size);
 -                      glVertex2s(0, 0);
 -                      glVertex2s(size, -size);
 -                      glEnd();
 +                      immVertex2f(POS_INDEX, 0, 0);
 +                      immVertex2f(POS_INDEX, -size, -size);
 +                      immVertex2f(POS_INDEX, 0, 0);
 +                      immVertex2f(POS_INDEX, size, -size);
                        break;
        }
 +
 +      immEnd();
  }
  
  static void drawArc(float size, float angle_start, float angle_end, int segments)
        float angle;
        int a;
  
 -      glBegin(GL_LINE_STRIP);
 +      immBegin(PRIM_LINE_STRIP, segments + 1);
  
        for (angle = angle_start, a = 0; a < segments; angle += delta, a++) {
 -              glVertex2f(cosf(angle) * size, sinf(angle) * size);
 +              immVertex2f(POS_INDEX, cosf(angle) * size, sinf(angle) * size);
        }
 -      glVertex2f(cosf(angle_end) * size, sinf(angle_end) * size);
 +      immVertex2f(POS_INDEX, cosf(angle_end) * size, sinf(angle_end) * size);
  
 -      glEnd();
 +      immEnd();
  }
  
  static int helpline_poll(bContext *C)
@@@ -1704,9 -1693,12 +1704,9 @@@ static void drawHelpline(bContext *UNUS
  {
        TransInfo *t = (TransInfo *)customdata;
  
 -      if (t->helpline != HLP_NONE && !(t->flag & T_USES_MANIPULATOR)) {
 +      if (t->helpline != HLP_NONE) {
                float vecrot[3], cent[2];
 -              int mval[2];
 -
 -              mval[0] = x;
 -              mval[1] = y;
 +              float mval[3] = { x, y, 0.0f };
  
                copy_v3_v3(vecrot, t->center);
                if (t->flag & T_EDIT) {
  
                projectFloatViewEx(t, vecrot, cent, V3D_PROJ_TEST_CLIP_ZERO);
  
 -              glPushMatrix();
 +              gpuPushMatrix();
 +
 +              /* Dashed lines first. */
 +              if (ELEM(t->helpline, HLP_SPRING, HLP_ANGLE)) {
 +                      const uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
 +
 +                      UNUSED_VARS_NDEBUG(shdr_pos); /* silence warning */
 +                      BLI_assert(shdr_pos == POS_INDEX);
 +
 +                      glLineWidth(1.0f);
 +
 +                      immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_COLOR);
 +
 +                      float viewport_size[4];
 +                      glGetFloatv(GL_VIEWPORT, viewport_size);
 +                      immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
 +
 +                      immUniform1i("num_colors", 0);  /* "simple" mode */
 +                      immUniformThemeColor(TH_VIEW_OVERLAY);
 +                      immUniform1f("dash_width", 6.0f);
 +                      immUniform1f("dash_factor", 0.5f);
 +
 +                      immBegin(PRIM_LINES, 2);
 +                      immVertex2fv(POS_INDEX, cent);
 +                      immVertex2f(POS_INDEX, (float)t->mval[0], (float)t->mval[1]);
 +                      immEnd();
 +
 +                      immUnbindProgram();
 +              }
 +
 +              /* And now, solid lines. */
 +              unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
 +              UNUSED_VARS_NDEBUG(pos); /* silence warning */
 +              BLI_assert(pos == POS_INDEX);
 +              immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
  
                switch (t->helpline) {
                        case HLP_SPRING:
 -                              UI_ThemeColor(TH_VIEW_OVERLAY);
 +                              immUniformThemeColor(TH_VIEW_OVERLAY);
  
 -                              setlinestyle(3);
 -                              glLineWidth(1);
 -                              glBegin(GL_LINES);
 -                              glVertex2iv(t->mval);
 -                              glVertex2fv(cent);
 -                              glEnd();
 +                              gpuTranslate3fv(mval);
 +                              gpuRotateAxis(-RAD2DEGF(atan2f(cent[0] - t->mval[0], cent[1] - t->mval[1])), 'Z');
  
 -                              glTranslate2iv(mval);
 -                              glRotatef(-RAD2DEGF(atan2f(cent[0] - t->mval[0], cent[1] - t->mval[1])), 0, 0, 1);
 -
 -                              setlinestyle(0);
 -                              glLineWidth(3.0);
 +                              glLineWidth(3.0f);
                                drawArrow(UP, 5, 10, 5);
                                drawArrow(DOWN, 5, 10, 5);
                                break;
                        case HLP_HARROW:
 -                              UI_ThemeColor(TH_VIEW_OVERLAY);
 -
 -                              glTranslate2iv(mval);
 +                              immUniformThemeColor(TH_VIEW_OVERLAY);
 +                              gpuTranslate3fv(mval);
  
 -                              glLineWidth(3.0);
 +                              glLineWidth(3.0f);
                                drawArrow(RIGHT, 5, 10, 5);
                                drawArrow(LEFT, 5, 10, 5);
                                break;
                        case HLP_VARROW:
 -                              UI_ThemeColor(TH_VIEW_OVERLAY);
 +                              immUniformThemeColor(TH_VIEW_OVERLAY);
  
 -                              glTranslate2iv(mval);
 +                              gpuTranslate3fv(mval);
  
 -                              glLineWidth(3.0);
 +                              glLineWidth(3.0f);
                                drawArrow(UP, 5, 10, 5);
                                drawArrow(DOWN, 5, 10, 5);
                                break;
                                float dist = hypotf(dx, dy);
                                float delta_angle = min_ff(15.0f / dist, (float)M_PI / 4.0f);
                                float spacing_angle = min_ff(5.0f / dist, (float)M_PI / 12.0f);
 -                              UI_ThemeColor(TH_VIEW_OVERLAY);
  
 -                              setlinestyle(3);
 -                              glLineWidth(1);
 -                              glBegin(GL_LINES);
 -                              glVertex2iv(t->mval);
 -                              glVertex2fv(cent);
 -                              glEnd();
 +                              immUniformThemeColor(TH_VIEW_OVERLAY);
  
 -                              glTranslatef(cent[0] - t->mval[0] + mval[0], cent[1] - t->mval[1] + mval[1], 0);
 +                              gpuTranslate3f(cent[0] - t->mval[0] + mval[0], cent[1] - t->mval[1] + mval[1], 0);
  
 -                              setlinestyle(0);
 -                              glLineWidth(3.0);
 +                              glLineWidth(3.0f);
                                drawArc(dist, angle - delta_angle, angle - spacing_angle, 10);
                                drawArc(dist, angle + spacing_angle, angle + delta_angle, 10);
  
 -                              glPushMatrix();
 +                              gpuPushMatrix();
  
 -                              glTranslatef(cosf(angle - delta_angle) * dist, sinf(angle - delta_angle) * dist, 0);
 -                              glRotatef(RAD2DEGF(angle - delta_angle), 0, 0, 1);
 +                              gpuTranslate3f(cosf(angle - delta_angle) * dist, sinf(angle - delta_angle) * dist, 0);
 +                              gpuRotateAxis(RAD2DEGF(angle - delta_angle), 'Z');
  
                                drawArrowHead(DOWN, 5);
  
 -                              glPopMatrix();
 +                              gpuPopMatrix();
  
 -                              glTranslatef(cosf(angle + delta_angle) * dist, sinf(angle + delta_angle) * dist, 0);
 -                              glRotatef(RAD2DEGF(angle + delta_angle), 0, 0, 1);
 +                              gpuTranslate3f(cosf(angle + delta_angle) * dist, sinf(angle + delta_angle) * dist, 0);
 +                              gpuRotateAxis(RAD2DEGF(angle + delta_angle), 'Z');
  
                                drawArrowHead(UP, 5);
                                break;
                                unsigned char col[3], col2[3];
                                UI_GetThemeColor3ubv(TH_GRID, col);
  
 -                              glTranslate2iv(mval);
 +                              gpuTranslate3fv(mval);
  
 -                              glLineWidth(3.0);
 +                              glLineWidth(3.0f);
  
                                UI_make_axis_color(col, col2, 'X');
 -                              glColor3ubv((GLubyte *)col2);
 +                              immUniformColor3ubv((GLubyte *)col2);
  
                                drawArrow(RIGHT, 5, 10, 5);
                                drawArrow(LEFT, 5, 10, 5);
  
                                UI_make_axis_color(col, col2, 'Y');
 -                              glColor3ubv((GLubyte *)col2);
 +                              immUniformColor3ubv((GLubyte *)col2);
  
                                drawArrow(UP, 5, 10, 5);
                                drawArrow(DOWN, 5, 10, 5);
                        }
                }
  
 -              glPopMatrix();
 +              immUnbindProgram();
 +              gpuPopMatrix();
        }
  }
  
@@@ -1848,7 -1821,7 +1848,7 @@@ static void drawTransformView(const str
  {
        TransInfo *t = arg;
        
 -      glLineWidth(1.0);
 +      glLineWidth(1.0f);
  
        drawConstraint(t);
        drawPropCircle(C, t);
@@@ -1868,9 -1841,8 +1868,9 @@@ static void drawAutoKeyWarning(TransInf
        int xco, yco;
  
        ED_region_visible_rect(ar, &rect);
 -      
 -      BLF_width_and_height_default(printable, BLF_DRAW_STR_DUMMY_MAX, &printable_size[0], &printable_size[1]);
 +
 +      const int font_id = BLF_default();
 +      BLF_width_and_height(font_id, printable, BLF_DRAW_STR_DUMMY_MAX, &printable_size[0], &printable_size[1]);
        
        xco = (rect.xmax - U.widget_unit) - (int)printable_size[0];
        yco = (rect.ymax - U.widget_unit);
        /* warning text (to clarify meaning of overlays)
         * - original color was red to match the icon, but that clashes badly with a less nasty border
         */
 -      UI_ThemeColorShade(TH_TEXT_HI, -50);
 +      unsigned char color[3];
 +      UI_GetThemeColorShade3ubv(TH_TEXT_HI, -50, color);
 +      BLF_color3ubv(font_id, color);
  #ifdef WITH_INTERNATIONAL
        BLF_draw_default(xco, yco, 0.0f, printable, BLF_DRAW_STR_DUMMY_MAX);
  #else
@@@ -1903,8 -1873,7 +1903,8 @@@ static void drawTransformPixel(const st
  {     
        TransInfo *t = arg;
        Scene *scene = t->scene;
 -      Object *ob = OBACT;
 +      SceneLayer *sl = t->scene_layer;
 +      Object *ob = OBACT_NEW;
        
        /* draw autokeyframing hint in the corner 
         * - only draw if enabled (advanced users may be distracted/annoyed), 
@@@ -2015,8 -1984,6 +2015,8 @@@ void saveTransform(bContext *C, TransIn
                                View3D *v3d = t->view;
  
                                v3d->twmode = t->current_orientation;
 +                              BLI_assert(BKE_workspace_transform_orientation_get_index(CTX_wm_workspace(C), t->custom_orientation)
 +                                         == v3d->custom_orientation_index);
                        }
                }
        }
        }
  
        if ((prop = RNA_struct_find_property(op->ptr, "constraint_axis"))) {
 -              /* constraint orientation can be global, event if user selects something else
 -               * so use the orientation in the constraint if set
 -               * */
 -              if (t->con.mode & CON_APPLY) {
 -                      RNA_enum_set(op->ptr, "constraint_orientation", t->con.orientation);
 -              }
 -              else {
 -                      RNA_enum_set(op->ptr, "constraint_orientation", t->current_orientation);
 +              /* constraint orientation can be global, even if user selects something else
 +               * so use the orientation in the constraint if set */
 +              short orientation = (t->con.mode & CON_APPLY) ? t->con.orientation : t->current_orientation;
 +
 +              if (orientation == V3D_MANIP_CUSTOM) {
 +                      WorkSpace *workspace = CTX_wm_workspace(C);
 +                      const int custom_orientation_index = BKE_workspace_transform_orientation_get_index(
 +                                                             workspace, t->custom_orientation);
 +
 +                      /* Maybe we need a t->con.custom_orientation? Seems like it would always match t->custom_orientation. */
 +                      orientation = V3D_MANIP_CUSTOM + custom_orientation_index;
 +                      BLI_assert(orientation >= V3D_MANIP_CUSTOM);
                }
 +              RNA_enum_set(op->ptr, "constraint_orientation", orientation);
  
                if (t->con.mode & CON_APPLY) {
                        if (t->con.mode & CON_AXIS0) {
@@@ -3438,7 -3400,7 +3438,7 @@@ static void ElementResize(TransInfo *t
        constraintTransLim(t, td);
  }
  
 -static void applyResize(TransInfo *t, const int mval[2])
 +static void applyResize(TransInfo *t, const int UNUSED(mval[2]))
  {
        TransData *td;
        float mat[3][3];
                copy_v3_v3(t->values, t->auto_values);
        }
        else {
 -              float ratio;
 -
 -              /* for manipulator, center handle, the scaling can't be done relative to center */
 -              if ((t->flag & T_USES_MANIPULATOR) && t->con.mode == 0) {
 -                      ratio = 1.0f - ((t->mouse.imval[0] - mval[0]) + (t->mouse.imval[1] - mval[1])) / 100.0f;
 -              }
 -              else {
 -                      ratio = t->values[0];
 -              }
 +              float ratio = t->values[0];
  
                copy_v3_fl(t->values, ratio);
  
@@@ -5277,14 -5247,23 +5277,14 @@@ static void ElementBoneSize(TransInfo *
        td->loc[1] = oldy;
  }
  
 -static void applyBoneSize(TransInfo *t, const int mval[2])
 +static void applyBoneSize(TransInfo *t, const int UNUSED(mval[2]))
  {
        TransData *td = t->data;
        float size[3], mat[3][3];
 -      float ratio;
 +      float ratio = t->values[0];
        int i;
        char str[UI_MAX_DRAW_STR];
 -      
 -      // TRANSFORM_FIX_ME MOVE TO MOUSE INPUT
 -      /* for manipulator, center handle, the scaling can't be done relative to center */
 -      if ((t->flag & T_USES_MANIPULATOR) && t->con.mode == 0) {
 -              ratio = 1.0f - ((t->mouse.imval[0] - mval[0]) + (t->mouse.imval[1] - mval[1])) / 100.0f;
 -      }
 -      else {
 -              ratio = t->values[0];
 -      }
 -      
 +
        copy_v3_fl(size, ratio);
        
        snapGridIncrement(t, size);
@@@ -5580,7 -5559,7 +5580,7 @@@ static void slide_origdata_interp_data_
        float v_proj[3][3];
  
        if (do_loop_weight || do_loop_mdisps) {
-               project_plane_v3_v3v3(v_proj[1], sv->co_orig_3d, v_proj_axis);
+               project_plane_normalized_v3_v3v3(v_proj[1], sv->co_orig_3d, v_proj_axis);
        }
  
        // BM_ITER_ELEM (l, &liter, sv->v, BM_LOOPS_OF_VERT) {
                        /* In the unlikely case that we're next to a zero length edge - walk around the to the next.
                         * Since we only need to check if the vertex is in this corner,
                         * its not important _which_ loop - as long as its not overlapping 'sv->co_orig_3d', see: T45096. */
-                       project_plane_v3_v3v3(v_proj[0], co_prev, v_proj_axis);
+                       project_plane_normalized_v3_v3v3(v_proj[0], co_prev, v_proj_axis);
                        while (UNLIKELY(((co_prev_ok = (len_squared_v3v3(v_proj[1], v_proj[0]) > eps)) == false) &&
                                        ((l_prev = l_prev->prev) != l->next)))
                        {
                                co_prev = slide_origdata_orig_vert_co(sod, l_prev->v);
-                               project_plane_v3_v3v3(v_proj[0], co_prev, v_proj_axis);
+                               project_plane_normalized_v3_v3v3(v_proj[0], co_prev, v_proj_axis);
                        }
-                       project_plane_v3_v3v3(v_proj[2], co_next, v_proj_axis);
+                       project_plane_normalized_v3_v3v3(v_proj[2], co_next, v_proj_axis);
                        while (UNLIKELY(((co_next_ok = (len_squared_v3v3(v_proj[1], v_proj[2]) > eps)) == false) &&
                                        ((l_next = l_next->next) != l->prev)))
                        {
                                co_next = slide_origdata_orig_vert_co(sod, l_next->v);
-                               project_plane_v3_v3v3(v_proj[2], co_next, v_proj_axis);
+                               project_plane_normalized_v3_v3v3(v_proj[2], co_next, v_proj_axis);
                        }
  
                        if (co_prev_ok && co_next_ok) {
@@@ -6876,12 -6855,10 +6876,12 @@@ static void drawEdgeSlide(TransInfo *t
                        glEnable(GL_BLEND);
                        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  
 -                      glPushAttrib(GL_CURRENT_BIT | GL_LINE_BIT | GL_POINT_BIT);
 -                      glPushMatrix();
 +                      gpuPushMatrix();
 +                      gpuMultMatrix(t->obedit->obmat);
 +
 +                      unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
  
 -                      glMultMatrixf(t->obedit->obmat);
 +                      immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
  
                        if (sld->use_even == true) {
                                float co_a[3], co_b[3], co_mark[3];
                                add_v3_v3v3(co_b, curr_sv->v_co_orig, curr_sv->dir_side[1]);
  
                                glLineWidth(line_size);
 -                              UI_ThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
 -                              glBegin(GL_LINES);
 +                              immUniformThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
 +                              immBeginAtMost(PRIM_LINES, 4);
                                if (curr_sv->v_side[0]) {
 -                                      glVertex3fv(curr_sv->v_side[0]->co);
 -                                      glVertex3fv(curr_sv->v_co_orig);
 +                                      immVertex3fv(pos, curr_sv->v_side[0]->co);
 +                                      immVertex3fv(pos, curr_sv->v_co_orig);
                                }
                                if (curr_sv->v_side[1]) {
 -                                      glVertex3fv(curr_sv->v_side[1]->co);
 -                                      glVertex3fv(curr_sv->v_co_orig);
 +                                      immVertex3fv(pos, curr_sv->v_side[1]->co);
 +                                      immVertex3fv(pos, curr_sv->v_co_orig);
                                }
 -                              glEnd();
 +                              immEnd();
  
 -                              UI_ThemeColorShadeAlpha(TH_SELECT, -30, alpha_shade);
 +                              immUniformThemeColorShadeAlpha(TH_SELECT, -30, alpha_shade);
                                glPointSize(ctrl_size);
 -                              glBegin(GL_POINTS);
 +                              immBegin(PRIM_POINTS, 1);
                                if (sld->flipped) {
 -                                      if (curr_sv->v_side[1]) glVertex3fv(curr_sv->v_side[1]->co);
 +                                      if (curr_sv->v_side[1]) immVertex3fv(pos, curr_sv->v_side[1]->co);
                                }
                                else {
 -                                      if (curr_sv->v_side[0]) glVertex3fv(curr_sv->v_side[0]->co);
 +                                      if (curr_sv->v_side[0]) immVertex3fv(pos, curr_sv->v_side[0]->co);
                                }
 -                              glEnd();
 +                              immEnd();
  
 -                              UI_ThemeColorShadeAlpha(TH_SELECT, 255, alpha_shade);
 +                              immUniformThemeColorShadeAlpha(TH_SELECT, 255, alpha_shade);
                                glPointSize(guide_size);
 -                              glBegin(GL_POINTS);
 -#if 0
 -                              interp_v3_v3v3(co_mark, co_b, co_a, fac);
 -                              glVertex3fv(co_mark);
 -#endif
 +                              immBegin(PRIM_POINTS, 1);
                                interp_line_v3_v3v3v3(co_mark, co_b, curr_sv->v_co_orig, co_a, fac);
 -                              glVertex3fv(co_mark);
 -                              glEnd();
 +                              immVertex3fv(pos, co_mark);
 +                              immEnd();
                        }
                        else {
                                if (is_clamp == false) {
                                        const int alpha_shade = -160;
  
                                        glLineWidth(line_size);
 -                                      UI_ThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
 -                                      glBegin(GL_LINES);
 +                                      immUniformThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
 +                                      immBegin(PRIM_LINES, sld->totsv * 2);
  
                                        sv = sld->sv;
                                        for (i = 0; i < sld->totsv; i++, sv++) {
                                                add_v3_v3(a, sv->v_co_orig);
                                                add_v3_v3(b, sv->v_co_orig);
  
 -                                              glVertex3fv(a);
 -                                              glVertex3fv(b);
 +                                              immVertex3fv(pos, a);
 +                                              immVertex3fv(pos, b);
                                        }
 -                                      glEnd();
 +                                      immEnd();
                                }
                                else {
                                        BLI_assert(0);
                                }
                        }
  
 -                      glPopMatrix();
 -                      glPopAttrib();
 +                      immUnbindProgram();
 +
 +                      gpuPopMatrix();
  
                        glDisable(GL_BLEND);
  
@@@ -7488,22 -7468,19 +7488,22 @@@ static void drawVertSlide(TransInfo *t
                        glEnable(GL_BLEND);
                        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  
 -                      glPushAttrib(GL_CURRENT_BIT | GL_LINE_BIT | GL_POINT_BIT);
 -                      glPushMatrix();
 -
 -                      glMultMatrixf(t->obedit->obmat);
 +                      gpuPushMatrix();
 +                      gpuMultMatrix(t->obedit->obmat);
  
                        glLineWidth(line_size);
 -                      UI_ThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
 -                      glBegin(GL_LINES);
 +
 +                      const uint shdr_pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
 +                       
 +                      immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
 +                      immUniformThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
 +
 +                      immBegin(PRIM_LINES, sld->totsv * 2);
                        if (is_clamp) {
                                sv = sld->sv;
                                for (i = 0; i < sld->totsv; i++, sv++) {
 -                                      glVertex3fv(sv->co_orig_3d);
 -                                      glVertex3fv(sv->co_link_orig_3d[sv->co_link_curr]);
 +                                      immVertex3fv(shdr_pos, sv->co_orig_3d);
 +                                      immVertex3fv(shdr_pos, sv->co_link_orig_3d[sv->co_link_curr]);
                                }
                        }
                        else {
                                        add_v3_v3(a, sv->co_orig_3d);
                                        add_v3_v3(b, sv->co_orig_3d);
  
 -                                      glVertex3fv(a);
 -                                      glVertex3fv(b);
 +                                      immVertex3fv(shdr_pos, a);
 +                                      immVertex3fv(shdr_pos, b);
                                }
                        }
 -                      glEnd();
 +                      immEnd();
  
                        glPointSize(ctrl_size);
  
 -                      glBegin(GL_POINTS);
 -                      glVertex3fv((sld->flipped && sld->use_even) ?
 +                      immBegin(PRIM_POINTS, 1);
 +                      immVertex3fv(shdr_pos, (sld->flipped && sld->use_even) ?
                                    curr_sv->co_link_orig_3d[curr_sv->co_link_curr] :
                                    curr_sv->co_orig_3d);
 -                      glEnd();
 +                      immEnd();
  
 -                      glDisable(GL_BLEND);
 +                      immUnbindProgram();
  
                        /* direction from active vertex! */
                        if ((t->mval[0] != t->mouse.imval[0]) ||
  
                                add_v3_v3(co_dest_3d, curr_sv->co_orig_3d);
  
 -                              glLineWidth(1);
 -                              setlinestyle(1);
 +                              glLineWidth(1.0f);
 +
 +                              immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_COLOR);
 +
 +                              float viewport_size[4];
 +                              glGetFloatv(GL_VIEWPORT, viewport_size);
 +                              immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
 +
 +                              immUniform1i("num_colors", 0);  /* "simple" mode */
 +                              immUniformColor4f(1.0f, 1.0f, 1.0f, 1.0f);
 +                              immUniform1f("dash_width", 6.0f);
 +                              immUniform1f("dash_factor", 0.5f);
  
 -                              cpack(0xffffff);
 -                              glBegin(GL_LINES);
 -                              glVertex3fv(curr_sv->co_orig_3d);
 -                              glVertex3fv(co_dest_3d);
 +                              immBegin(PRIM_LINES, 2);
 +                              immVertex3fv(shdr_pos, curr_sv->co_orig_3d);
 +                              immVertex3fv(shdr_pos, co_dest_3d);
 +                              immEnd();
  
 -                              glEnd();
 +                              immUnbindProgram();
                        }
  
 -                      glPopMatrix();
 -                      glPopAttrib();
 +                      gpuPopMatrix();
  
                        if (v3d && v3d->zbuf)
                                glEnable(GL_DEPTH_TEST);