Merge branch 'master' into blender2.8
[blender.git] / source / blender / editors / space_view3d / drawobject.c
index cb45a04..7de7aa7 100644 (file)
@@ -54,6 +54,7 @@
 #include "BKE_camera.h"
 #include "BKE_colortools.h"
 #include "BKE_constraint.h"  /* for the get_constraint_target function */
+#include "BKE_context.h"
 #include "BKE_curve.h"
 #include "BKE_DerivedMesh.h"
 #include "BKE_deform.h"
@@ -62,6 +63,7 @@
 #include "BKE_global.h"
 #include "BKE_image.h"
 #include "BKE_key.h"
+#include "BKE_layer.h"
 #include "BKE_lattice.h"
 #include "BKE_main.h"
 #include "BKE_mesh.h"
@@ -80,6 +82,9 @@
 
 #include "BKE_editmesh.h"
 
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
 #include "IMB_imbuf.h"
 #include "IMB_imbuf_types.h"
 
 #include "GPU_select.h"
 #include "GPU_basic_shader.h"
 #include "GPU_shader.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_batch.h"
+#include "GPU_matrix.h"
 
 #include "ED_mesh.h"
 #include "ED_particle.h"
 
 #include "view3d_intern.h"  /* bad level include */
 
-/* Workaround for sequencer scene render mode.
- *
- * Strips doesn't use DAG to update objects or so, which
- * might lead to situations when object is drawing without
- * curve cache ready.
- *
- * Ideally we don't want to evaluate objects from drawing,
- * but it'll require some major sequencer re-design. So
- * for now just fallback to legacy behavior with calling
- * display ist creating from draw().
- */
-#define SEQUENCER_DAG_WORKAROUND
-
-typedef enum eWireDrawMode {
-       OBDRAW_WIRE_OFF = 0,
-       OBDRAW_WIRE_ON = 1,
-       OBDRAW_WIRE_ON_DEPTH = 2
-} eWireDrawMode;
-
-typedef struct drawDMVerts_userData {
-       BMesh *bm;
-
-       BMVert *eve_act;
-       char sel;
-
-       /* cached theme values */
-       unsigned char th_editmesh_active[4];
-       unsigned char th_vertex_select[4];
-       unsigned char th_vertex[4];
-       unsigned char th_skin_root[4];
-
-       /* for skin node drawing */
-       int cd_vskin_offset;
-       float imat[4][4];
-} drawDMVerts_userData;
-
-typedef struct drawDMEdgesSel_userData {
-       BMesh *bm;
-
-       unsigned char *baseCol, *selCol, *actCol;
-       BMEdge *eed_act;
-} drawDMEdgesSel_userData;
-
-typedef struct drawDMEdgesSelInterp_userData {
-       BMesh *bm;
-
-       unsigned char *baseCol, *selCol;
-       unsigned char *lastCol;
-} drawDMEdgesSelInterp_userData;
-
-typedef struct drawDMEdgesWeightInterp_userData {
-       BMesh *bm;
-
-       int cd_dvert_offset;
-       int defgroup_tot;
-       int vgroup_index;
-       char weight_user;
-       float alert_color[3];
-
-} drawDMEdgesWeightInterp_userData;
-
-typedef struct drawDMFacesSel_userData {
-#ifdef WITH_FREESTYLE
-       unsigned char *cols[4];
-#else
-       unsigned char *cols[3];
-#endif
-
-       DerivedMesh *dm;
-       BMesh *bm;
-
-       BMFace *efa_act;
-       const int *orig_index_mp_to_orig;
-} drawDMFacesSel_userData;
-
-typedef struct drawDMNormal_userData {
-       BMesh *bm;
-       int uniform_scale;
-       float normalsize;
-       float tmat[3][3];
-       float imat[3][3];
-} drawDMNormal_userData;
-
-typedef struct drawMVertOffset_userData {
-       MVert *mvert;
-       int offset;
-} drawMVertOffset_userData;
-
-typedef struct drawDMLayer_userData {
-       BMesh *bm;
-       int cd_layer_offset;
-} drawDMLayer_userData;
-
-typedef struct drawBMOffset_userData {
-       BMesh *bm;
-       int offset;
-} drawBMOffset_userData;
-
-typedef struct drawBMSelect_userData {
-       BMesh *bm;
-       bool select;
-} drawBMSelect_userData;
-
-static void draw_bounding_volume(Object *ob, char type);
-
-static void drawcube_size(float size);
-static void drawcircle_size(float size);
-static void draw_empty_sphere(float size);
-static void draw_empty_cone(float size);
-static void draw_box(const float vec[8][3], bool solid);
-
-static void ob_wire_color_blend_theme_id(const unsigned char ob_wire_col[4], const int theme_id, float fac)
-{
-       float col_wire[3], col_bg[3], col[3];
-
-       rgb_uchar_to_float(col_wire, ob_wire_col);
-
-       UI_GetThemeColor3fv(theme_id, col_bg);
-       interp_v3_v3v3(col, col_bg, col_wire, fac);
-       glColor3fv(col);
-}
+#include "../../draw/intern/draw_cache_impl.h"  /* bad level include (temporary) */
 
 int view3d_effective_drawtype(const struct View3D *v3d)
 {
@@ -235,42 +124,6 @@ int view3d_effective_drawtype(const struct View3D *v3d)
        return v3d->drawtype;
 }
 
-/* this condition has been made more complex since editmode can draw textures */
-bool check_object_draw_texture(Scene *scene, View3D *v3d, const char drawtype)
-{
-       const int v3d_drawtype = view3d_effective_drawtype(v3d);
-       /* texture and material draw modes */
-       if (ELEM(v3d_drawtype, OB_TEXTURE, OB_MATERIAL) && drawtype > OB_SOLID) {
-               return true;
-       }
-
-       /* textured solid */
-       if ((v3d_drawtype == OB_SOLID) &&
-           (v3d->flag2 & V3D_SOLID_TEX) &&
-           (BKE_scene_use_new_shading_nodes(scene) == false))
-       {
-               return true;
-       }
-
-       if (v3d->flag2 & V3D_SHOW_SOLID_MATCAP) {
-               return true;
-       }
-
-       return false;
-}
-
-static bool check_object_draw_editweight(Mesh *me, DerivedMesh *finalDM)
-{
-       if (me->drawflag & ME_DRAWEIGHT) {
-               /* editmesh handles its own weight drawing */
-               if (finalDM->type != DM_TYPE_EDITBMESH) {
-                       return true;
-               }
-       }
-
-       return false;
-}
-
 static bool check_ob_drawface_dot(Scene *sce, View3D *vd, char dt)
 {
        if ((sce->toolsettings->selectmode & SCE_SELECT_FACE) == 0)
@@ -292,49 +145,6 @@ static bool check_ob_drawface_dot(Scene *sce, View3D *vd, char dt)
        return true;
 }
 
-/* ************************ */
-
-/* check for glsl drawing */
-
-bool draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, const char dt)
-{
-       if (G.f & G_PICKSEL)
-               return false;
-       if (!check_object_draw_texture(scene, v3d, dt))
-               return false;
-       if (ob == OBACT && (ob && ob->mode & OB_MODE_WEIGHT_PAINT))
-               return false;
-
-       if (v3d->flag2 & V3D_SHOW_SOLID_MATCAP)
-               return true;
-
-       if (v3d->drawtype == OB_TEXTURE)
-               return (scene->gm.matmode == GAME_MAT_GLSL && !BKE_scene_use_new_shading_nodes(scene));
-       else if (v3d->drawtype == OB_MATERIAL && dt > OB_SOLID)
-               return true;
-       else
-               return false;
-}
-
-static bool check_alpha_pass(Base *base)
-{
-       if (base->flag & OB_FROMDUPLI)
-               return false;
-
-       if (G.f & G_PICKSEL)
-               return false;
-
-       if (base->object->mode & OB_MODE_ALL_PAINT)
-               return false;
-
-       return (base->object->dtx & OB_DRAWTRANSP);
-}
-
-/***/
-static const unsigned int colortab[] = {
-       0x0, 0x403000, 0xFFFF88
-};
-
 /* ----------------- OpenGL Circle Drawing - Tables for Optimized Drawing Speed ------------------ */
 /* 32 values of sin function (still same result!) */
 #define CIRCLE_RESOL 32
@@ -363,7856 +173,89 @@ static const float sinval[CIRCLE_RESOL] = {
        -0.79077573,
        -0.89780453,
        -0.96807711,
-       -0.99871650,
-       -0.98846832,
-       -0.93775213,
-       -0.84864425,
-       -0.72479278,
-       -0.57126821,
-       -0.39435585,
-       -0.20129852,
-       0.00000000
-};
-
-/* 32 values of cos function (still same result!) */
-static const float cosval[CIRCLE_RESOL] = {
-       1.00000000,
-       0.97952994,
-       0.91895781,
-       0.82076344,
-       0.68896691,
-       0.52896401,
-       0.34730525,
-       0.15142777,
-       -0.05064916,
-       -0.25065253,
-       -0.44039415,
-       -0.61210598,
-       -0.75875812,
-       -0.87434661,
-       -0.95413925,
-       -0.99486932,
-       -0.99486932,
-       -0.95413925,
-       -0.87434661,
-       -0.75875812,
-       -0.61210598,
-       -0.44039415,
-       -0.25065253,
-       -0.05064916,
-       0.15142777,
-       0.34730525,
-       0.52896401,
-       0.68896691,
-       0.82076344,
-       0.91895781,
-       0.97952994,
-       1.00000000
-};
-
-/**
- * \param viewmat_local_unit is typically the 'rv3d->viewmatob'
- * copied into a 3x3 matrix and normalized.
- */
-static void draw_xyz_wire(const float viewmat_local_unit[3][3], const float c[3], float size, int axis)
-{
-       int line_type;
-       float buffer[4][3];
-       int n = 0;
-
-       float v1[3] = {0.0f, 0.0f, 0.0f}, v2[3] = {0.0f, 0.0f, 0.0f};
-       float dim = size * 0.1f;
-       float dx[3], dy[3];
-
-       dx[0] = dim;  dx[1] = 0.0f; dx[2] = 0.0f;
-       dy[0] = 0.0f; dy[1] = dim;  dy[2] = 0.0f;
-
-       switch (axis) {
-               case 0:     /* x axis */
-                       line_type = GL_LINES;
-
-                       /* bottom left to top right */
-                       negate_v3_v3(v1, dx);
-                       sub_v3_v3(v1, dy);
-                       copy_v3_v3(v2, dx);
-                       add_v3_v3(v2, dy);
-
-                       copy_v3_v3(buffer[n++], v1);
-                       copy_v3_v3(buffer[n++], v2);
-
-                       /* top left to bottom right */
-                       mul_v3_fl(dy, 2.0f);
-                       add_v3_v3(v1, dy);
-                       sub_v3_v3(v2, dy);
-
-                       copy_v3_v3(buffer[n++], v1);
-                       copy_v3_v3(buffer[n++], v2);
-
-                       break;
-               case 1:     /* y axis */
-                       line_type = GL_LINES;
-
-                       /* bottom left to top right */
-                       mul_v3_fl(dx, 0.75f);
-                       negate_v3_v3(v1, dx);
-                       sub_v3_v3(v1, dy);
-                       copy_v3_v3(v2, dx);
-                       add_v3_v3(v2, dy);
-
-                       copy_v3_v3(buffer[n++], v1);
-                       copy_v3_v3(buffer[n++], v2);
-
-                       /* top left to center */
-                       mul_v3_fl(dy, 2.0f);
-                       add_v3_v3(v1, dy);
-                       zero_v3(v2);
-
-                       copy_v3_v3(buffer[n++], v1);
-                       copy_v3_v3(buffer[n++], v2);
-
-                       break;
-               case 2:     /* z axis */
-                       line_type = GL_LINE_STRIP;
-
-                       /* start at top left */
-                       negate_v3_v3(v1, dx);
-                       add_v3_v3(v1, dy);
-
-                       copy_v3_v3(buffer[n++], v1);
-
-                       mul_v3_fl(dx, 2.0f);
-                       add_v3_v3(v1, dx);
-
-                       copy_v3_v3(buffer[n++], v1);
-
-                       mul_v3_fl(dy, 2.0f);
-                       sub_v3_v3(v1, dx);
-                       sub_v3_v3(v1, dy);
-
-                       copy_v3_v3(buffer[n++], v1);
-
-                       add_v3_v3(v1, dx);
-
-                       copy_v3_v3(buffer[n++], v1);
-
-                       break;
-               default:
-                       BLI_assert(0);
-                       return;
-       }
-
-       for (int i = 0; i < n; i++) {
-               mul_transposed_m3_v3((float (*)[3])viewmat_local_unit, buffer[i]);
-               add_v3_v3(buffer[i], c);
-       }
-
-       glEnableClientState(GL_VERTEX_ARRAY);
-       glVertexPointer(3, GL_FLOAT, 0, buffer);
-       glDrawArrays(line_type, 0, n);
-       glDisableClientState(GL_VERTEX_ARRAY);
-}
-
-void drawaxes(const float viewmat_local[4][4], float size, char drawtype)
-{
-       int axis;
-       float v1[3] = {0.0, 0.0, 0.0};
-       float v2[3] = {0.0, 0.0, 0.0};
-       float v3[3] = {0.0, 0.0, 0.0};
-
-       glLineWidth(1);
-
-       switch (drawtype) {
-
-               case OB_PLAINAXES:
-                       for (axis = 0; axis < 3; axis++) {
-                               glBegin(GL_LINES);
-
-                               v1[axis] = size;
-                               v2[axis] = -size;
-                               glVertex3fv(v1);
-                               glVertex3fv(v2);
-
-                               /* reset v1 & v2 to zero */
-                               v1[axis] = v2[axis] = 0.0f;
-
-                               glEnd();
-                       }
-                       break;
-               case OB_SINGLE_ARROW:
-
-                       glBegin(GL_LINES);
-                       /* in positive z direction only */
-                       v1[2] = size;
-                       glVertex3fv(v1);
-                       glVertex3fv(v2);
-                       glEnd();
-
-                       /* square pyramid */
-                       glBegin(GL_TRIANGLES);
-
-                       v2[0] = size * 0.035f; v2[1] = size * 0.035f;
-                       v3[0] = size * -0.035f; v3[1] = size * 0.035f;
-                       v2[2] = v3[2] = size * 0.75f;
-
-                       for (axis = 0; axis < 4; axis++) {
-                               if (axis % 2 == 1) {
-                                       v2[0] = -v2[0];
-                                       v3[1] = -v3[1];
-                               }
-                               else {
-                                       v2[1] = -v2[1];
-                                       v3[0] = -v3[0];
-                               }
-
-                               glVertex3fv(v1);
-                               glVertex3fv(v2);
-                               glVertex3fv(v3);
-
-                       }
-                       glEnd();
-
-                       break;
-               case OB_CUBE:
-                       drawcube_size(size);
-                       break;
-
-               case OB_CIRCLE:
-                       drawcircle_size(size);
-                       break;
-
-               case OB_EMPTY_SPHERE:
-                       draw_empty_sphere(size);
-                       break;
-
-               case OB_EMPTY_CONE:
-                       draw_empty_cone(size);
-                       break;
-
-               case OB_ARROWS:
-               default:
-               {
-                       float viewmat_local_unit[3][3];
-
-                       copy_m3_m4(viewmat_local_unit, (float (*)[4])viewmat_local);
-                       normalize_m3(viewmat_local_unit);
-
-                       for (axis = 0; axis < 3; axis++) {
-                               const int arrow_axis = (axis == 0) ? 1 : 0;
-
-                               glBegin(GL_LINES);
-
-                               v2[axis] = size;
-                               glVertex3fv(v1);
-                               glVertex3fv(v2);
-
-                               v1[axis] = size * 0.85f;
-                               v1[arrow_axis] = -size * 0.08f;
-                               glVertex3fv(v1);
-                               glVertex3fv(v2);
-
-                               v1[arrow_axis] = size * 0.08f;
-                               glVertex3fv(v1);
-                               glVertex3fv(v2);
-
-                               glEnd();
-
-                               v2[axis] += size * 0.125f;
-
-                               draw_xyz_wire(viewmat_local_unit, v2, size, axis);
-
-
-                               /* reset v1 & v2 to zero */
-                               v1[arrow_axis] = v1[axis] = v2[axis] = 0.0f;
-                       }
-                       break;
-               }
-       }
-}
-
-
-/* Function to draw an Image on an empty Object */
-static void draw_empty_image(Object *ob, const short dflag, const unsigned char ob_wire_col[4], eStereoViews sview)
-{
-       Image *ima = ob->data;
-       ImBuf *ibuf;
-       ImageUser iuser = *ob->iuser;
-
-       /* Support multi-view */
-       if (ima && (sview == STEREO_RIGHT_ID)) {
-               iuser.multiview_eye = sview;
-               iuser.flag |= IMA_SHOW_STEREO;
-               BKE_image_multiview_index(ima, &iuser);
-       }
-
-       ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
-
-       if (ibuf && (ibuf->rect == NULL) && (ibuf->rect_float != NULL)) {
-               IMB_rect_from_float(ibuf);
-       }
-
-       int ima_x, ima_y;
-
-       /* Get the buffer dimensions so we can fallback to fake ones */
-       if (ibuf && ibuf->rect) {
-               ima_x = ibuf->x;
-               ima_y = ibuf->y;
-       }
-       else {
-               ima_x = 1;
-               ima_y = 1;
-       }
-
-       float sca_x = 1.0f;
-       float sca_y = 1.0f;
-
-       /* Get the image aspect even if the buffer is invalid */
-       if (ima) {
-               if (ima->aspx > ima->aspy) {
-                       sca_y = ima->aspy / ima->aspx;
-               }
-               else if (ima->aspx < ima->aspy) {
-                       sca_x = ima->aspx / ima->aspy;
-               }
-       }
-
-       /* Calculate the scale center based on object's origin */
-       float ofs_x = ob->ima_ofs[0] * ima_x;
-       float ofs_y = ob->ima_ofs[1] * ima_y;
-
-       glMatrixMode(GL_MODELVIEW);
-       glPushMatrix();
-
-       /* Calculate Image scale */
-       float scale = ob->empty_drawsize / max_ff((float)ima_x * sca_x, (float)ima_y * sca_y);
-
-       /* Set the object scale */
-       glScalef(scale * sca_x, scale * sca_y, 1.0f);
-
-       if (ibuf && ibuf->rect) {
-               const bool use_clip = (U.glalphaclip != 1.0f);
-               int zoomfilter = (U.gameflags & USER_DISABLE_MIPMAP) ? GL_NEAREST : GL_LINEAR;
-               /* Setup GL params */
-               glEnable(GL_BLEND);
-               glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
-               if (use_clip) {
-                       glEnable(GL_ALPHA_TEST);
-                       glAlphaFunc(GL_GREATER, U.glalphaclip);
-               }
-
-               /* Use the object color and alpha */
-               glColor4fv(ob->col);
-
-               /* Draw the Image on the screen */
-               glaDrawPixelsTex(ofs_x, ofs_y, ima_x, ima_y, GL_RGBA, GL_UNSIGNED_BYTE, zoomfilter, ibuf->rect);
-
-               glDisable(GL_BLEND);
-
-               if (use_clip) {
-                       glDisable(GL_ALPHA_TEST);
-                       glAlphaFunc(GL_ALWAYS, 0.0f);
-               }
-       }
-
-       if ((dflag & DRAW_CONSTCOLOR) == 0) {
-               glColor3ubv(ob_wire_col);
-       }
-
-       /* Calculate the outline vertex positions */
-       glBegin(GL_LINE_LOOP);
-       glVertex2f(ofs_x, ofs_y);
-       glVertex2f(ofs_x + ima_x, ofs_y);
-       glVertex2f(ofs_x + ima_x, ofs_y + ima_y);
-       glVertex2f(ofs_x, ofs_y + ima_y);
-       glEnd();
-
-       /* Reset GL settings */
-       glPopMatrix();
-
-       BKE_image_release_ibuf(ima, ibuf, NULL);
-}
-
-static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3], float rad, const float tmat[4][4])
-{
-       float vx[3], vy[3];
-       float *viter = (float *)verts;
-
-       mul_v3_v3fl(vx, tmat[0], rad);
-       mul_v3_v3fl(vy, tmat[1], rad);
-
-       for (unsigned int a = 0; a < CIRCLE_RESOL; a++, viter += 3) {
-               viter[0] = cent[0] + sinval[a] * vx[0] + cosval[a] * vy[0];
-               viter[1] = cent[1] + sinval[a] * vx[1] + cosval[a] * vy[1];
-               viter[2] = cent[2] + sinval[a] * vx[2] + cosval[a] * vy[2];
-       }
-}
-
-void drawcircball(int mode, const float cent[3], float rad, const float tmat[4][4])
-{
-       float verts[CIRCLE_RESOL][3];
-
-       circball_array_fill(verts, cent, rad, tmat);
-
-       glEnableClientState(GL_VERTEX_ARRAY);
-       glVertexPointer(3, GL_FLOAT, 0, verts);
-       glDrawArrays(mode, 0, CIRCLE_RESOL);
-       glDisableClientState(GL_VERTEX_ARRAY);
-}
-
-/* circle for object centers, special_color is for library or ob users */
-static void drawcentercircle(View3D *v3d, RegionView3D *rv3d, const float co[3], int selstate, bool special_color)
-{
-       const float size = ED_view3d_pixel_size(rv3d, co) * (float)U.obcenter_dia * 0.5f;
-       float verts[CIRCLE_RESOL][3];
-
-       /* using glDepthFunc guarantees that it does write z values,
-        * but not checks for it, so centers remain visible independent of draw order */
-       if (v3d->zbuf) glDepthFunc(GL_ALWAYS);
-       /* write to near buffer always */
-       glDepthRange(0.0, 0.0);
-       glEnable(GL_BLEND);
-
-       if (special_color) {
-               if (selstate == ACTIVE || selstate == SELECT) glColor4ub(0x88, 0xFF, 0xFF, 155);
-               else glColor4ub(0x55, 0xCC, 0xCC, 155);
-       }
-       else {
-               if (selstate == ACTIVE) UI_ThemeColorShadeAlpha(TH_ACTIVE, 0, -80);
-               else if (selstate == SELECT) UI_ThemeColorShadeAlpha(TH_SELECT, 0, -80);
-               else if (selstate == DESELECT) UI_ThemeColorShadeAlpha(TH_TRANSFORM, 0, -80);
-       }
-
-       circball_array_fill(verts, co, size, rv3d->viewinv);
-
-       /* enable vertex array */
-       glEnableClientState(GL_VERTEX_ARRAY);
-       glVertexPointer(3, GL_FLOAT, 0, verts);
-
-       /* 1. draw filled, blended polygon */
-       glDrawArrays(GL_POLYGON, 0, CIRCLE_RESOL);
-
-       /* 2. draw outline */
-       glLineWidth(1);
-       UI_ThemeColorShadeAlpha(TH_WIRE, 0, -30);
-       glDrawArrays(GL_LINE_LOOP, 0, CIRCLE_RESOL);
-
-       /* finish up */
-       glDisableClientState(GL_VERTEX_ARRAY);
-
-       glDepthRange(0.0, 1.0);
-       glDisable(GL_BLEND);
-
-       if (v3d->zbuf) glDepthFunc(GL_LEQUAL);
-}
-
-/* *********** text drawing for object/particles/armature ************* */
-
-typedef struct ViewCachedString {
-       struct ViewCachedString *next;
-       float vec[3];
-       union {
-               unsigned char ub[4];
-               int pack;
-       } col;
-       short sco[2];
-       short xoffs;
-       short flag;
-       int str_len;
-
-       /* str is allocated past the end */
-       char str[0];
-} ViewCachedString;
-
-/* one arena for all 3 string lists */
-static MemArena         *g_v3d_strings_arena = NULL;
-static ViewCachedString *g_v3d_strings[3] = {NULL, NULL, NULL};
-static int g_v3d_string_level = -1;
-
-void view3d_cached_text_draw_begin(void)
-{
-       g_v3d_string_level++;
-
-       BLI_assert(g_v3d_string_level >= 0);
-
-       if (g_v3d_string_level == 0) {
-               BLI_assert(g_v3d_strings_arena == NULL);
-       }
-}
-
-void view3d_cached_text_draw_add(const float co[3],
-                                 const char *str, const size_t str_len,
-                                 short xoffs, short flag,
-                                 const unsigned char col[4])
-{
-       int alloc_len = str_len + 1;
-       ViewCachedString *vos;
-
-       BLI_assert(str_len == strlen(str));
-
-       if (g_v3d_strings_arena == NULL) {
-               g_v3d_strings_arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 14), __func__);
-       }
-
-       vos = BLI_memarena_alloc(g_v3d_strings_arena, sizeof(ViewCachedString) + alloc_len);
-
-       BLI_LINKS_PREPEND(g_v3d_strings[g_v3d_string_level], vos);
-
-       copy_v3_v3(vos->vec, co);
-       copy_v4_v4_uchar(vos->col.ub, col);
-       vos->xoffs = xoffs;
-       vos->flag = flag;
-       vos->str_len = str_len;
-
-       /* allocate past the end */
-       memcpy(vos->str, str, alloc_len);
-}
-
-void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, bool depth_write)
-{
-       RegionView3D *rv3d = ar->regiondata;
-       ViewCachedString *vos;
-       int tot = 0;
-
-       BLI_assert(g_v3d_string_level >= 0 && g_v3d_string_level <= 2);
-
-       /* project first and test */
-       for (vos = g_v3d_strings[g_v3d_string_level]; vos; vos = vos->next) {
-               if (ED_view3d_project_short_ex(ar,
-                                              (vos->flag & V3D_CACHE_TEXT_GLOBALSPACE) ? rv3d->persmat : rv3d->persmatob,
-                                              (vos->flag & V3D_CACHE_TEXT_LOCALCLIP) != 0,
-                                              vos->vec, vos->sco,
-                                              V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
-               {
-                       tot++;
-               }
-               else {
-                       vos->sco[0] = IS_CLIPPED;
-               }
-       }
-
-       if (tot) {
-               int col_pack_prev = 0;
-
-#if 0
-               bglMats mats; /* ZBuffer depth vars */
-               double ux, uy, uz;
-               float depth;
-
-               if (v3d->zbuf)
-                       bgl_get_mats(&mats);
-#endif
-               if (rv3d->rflag & RV3D_CLIPPING) {
-                       ED_view3d_clipping_disable();
-               }
-
-               glMatrixMode(GL_PROJECTION);
-               glPushMatrix();
-               glMatrixMode(GL_MODELVIEW);
-               glPushMatrix();
-               wmOrtho2_region_pixelspace(ar);
-               glLoadIdentity();
-
-               if (depth_write) {
-                       if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
-               }
-               else {
-                       glDepthMask(0);
-               }
-
-               for (vos = g_v3d_strings[g_v3d_string_level]; vos; vos = vos->next) {
-                       if (vos->sco[0] != IS_CLIPPED) {
-                               if (col_pack_prev != vos->col.pack) {
-                                       glColor3ubv(vos->col.ub);
-                                       col_pack_prev = vos->col.pack;
-                               }
-
-                               ((vos->flag & V3D_CACHE_TEXT_ASCII) ? BLF_draw_default_ascii : BLF_draw_default)(
-                                       (float)(vos->sco[0] + vos->xoffs),
-                                       (float)(vos->sco[1]),
-                                       (depth_write) ? 0.0f : 2.0f,
-                                       vos->str,
-                                       vos->str_len);
-                       }
-               }
-
-               if (depth_write) {
-                       if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
-               }
-               else {
-                       glDepthMask(1);
-               }
-
-               glMatrixMode(GL_PROJECTION);
-               glPopMatrix();
-               glMatrixMode(GL_MODELVIEW);
-               glPopMatrix();
-
-               if (rv3d->rflag & RV3D_CLIPPING) {
-                       ED_view3d_clipping_enable();
-               }
-       }
-
-       g_v3d_strings[g_v3d_string_level] = NULL;
-
-       if (g_v3d_string_level == 0) {
-               if (g_v3d_strings_arena) {
-                       BLI_memarena_free(g_v3d_strings_arena);
-                       g_v3d_strings_arena = NULL;
-               }
-       }
-
-       g_v3d_string_level--;
-}
-
-/* ******************** primitive drawing ******************* */
-
-/* draws a cube given the scaling of the cube, assuming that
- * all required matrices have been set (used for drawing empties)
- */
-static void drawcube_size(float size)
-{
-       const GLfloat pos[8][3] = {
-               {-size, -size, -size},
-               {-size, -size,  size},
-               {-size,  size, -size},
-               {-size,  size,  size},
-               { size, -size, -size},
-               { size, -size,  size},
-               { size,  size, -size},
-               { size,  size,  size}
-       };
-
-       const GLubyte indices[24] = {0, 1, 1, 3, 3, 2, 2, 0, 0, 4, 4, 5, 5, 7, 7, 6, 6, 4, 1, 5, 3, 7, 2, 6};
-
-       glEnableClientState(GL_VERTEX_ARRAY);
-       glVertexPointer(3, GL_FLOAT, 0, pos);
-       glDrawRangeElements(GL_LINES, 0, 7, 24, GL_UNSIGNED_BYTE, indices);
-       glDisableClientState(GL_VERTEX_ARRAY);
-}
-
-static void drawshadbuflimits(Lamp *la, float mat[4][4])
-{
-       float sta[3], end[3], lavec[3];
-
-       negate_v3_v3(lavec, mat[2]);
-       normalize_v3(lavec);
-
-       madd_v3_v3v3fl(sta, mat[3], lavec, la->clipsta);
-       madd_v3_v3v3fl(end, mat[3], lavec, la->clipend);
-
-       glBegin(GL_LINES);
-       glVertex3fv(sta);
-       glVertex3fv(end);
-       glEnd();
-
-       glPointSize(3.0);
-       glBegin(GL_POINTS);
-       glVertex3fv(sta);
-       glVertex3fv(end);
-       glEnd();
-}
-
-static void spotvolume(float lvec[3], float vvec[3], const float inp)
-{
-       /* camera is at 0,0,0 */
-       float temp[3], plane[3], mat1[3][3], mat2[3][3], mat3[3][3], mat4[3][3], q[4], co, si, angle;
-
-       normalize_v3(lvec);
-       normalize_v3(vvec);             /* is this the correct vector ? */
-
-       cross_v3_v3v3(temp, vvec, lvec);      /* equation for a plane through vvec and lvec */
-       cross_v3_v3v3(plane, lvec, temp);     /* a plane perpendicular to this, parallel with lvec */
-
-       /* vectors are exactly aligned, use the X axis, this is arbitrary */
-       if (normalize_v3(plane) == 0.0f)
-               plane[1] = 1.0f;
-
-       /* now we've got two equations: one of a cone and one of a plane, but we have
-        * three unknowns. We remove one unknown by rotating the plane to z=0 (the plane normal) */
-
-       /* rotate around cross product vector of (0,0,1) and plane normal, dot product degrees */
-       /* according definition, we derive cross product is (plane[1],-plane[0],0), en cos = plane[2]);*/
-
-       /* translating this comment to english didnt really help me understanding the math! :-) (ton) */
-
-       q[1] =  plane[1];
-       q[2] = -plane[0];
-       q[3] =  0;
-       normalize_v3(&q[1]);
-
-       angle = saacos(plane[2]) / 2.0f;
-       co = cosf(angle);
-       si = sqrtf(1 - co * co);
-
-       q[0] =  co;
-       q[1] *= si;
-       q[2] *= si;
-       q[3] =  0;
-
-       quat_to_mat3(mat1, q);
-
-       /* rotate lamp vector now over acos(inp) degrees */
-       copy_v3_v3(vvec, lvec);
-
-       unit_m3(mat2);
-       co = inp;
-       si = sqrtf(1.0f - inp * inp);
-
-       mat2[0][0] =  co;
-       mat2[1][0] = -si;
-       mat2[0][1] =  si;
-       mat2[1][1] =  co;
-       mul_m3_m3m3(mat3, mat2, mat1);
-
-       mat2[1][0] =  si;
-       mat2[0][1] = -si;
-       mul_m3_m3m3(mat4, mat2, mat1);
-       transpose_m3(mat1);
-
-       mul_m3_m3m3(mat2, mat1, mat3);
-       mul_m3_v3(mat2, lvec);
-       mul_m3_m3m3(mat2, mat1, mat4);
-       mul_m3_v3(mat2, vvec);
-}
-
-static void draw_spot_cone(Lamp *la, float x, float z)
-{
-       z = fabsf(z);
-
-       glBegin(GL_TRIANGLE_FAN);
-       glVertex3f(0.0f, 0.0f, -x);
-
-       if (la->mode & LA_SQUARE) {
-               glVertex3f(z, z, 0);
-               glVertex3f(-z, z, 0);
-               glVertex3f(-z, -z, 0);
-               glVertex3f(z, -z, 0);
-               glVertex3f(z, z, 0);
-       }
-       else {
-               for (int a = 0; a < 33; a++) {
-                       float angle = a * M_PI * 2 / (33 - 1);
-                       glVertex3f(z * cosf(angle), z * sinf(angle), 0);
-               }
-       }
-
-       glEnd();
-}
-
-static void draw_transp_spot_volume(Lamp *la, float x, float z)
-{
-       glEnable(GL_CULL_FACE);
-       glEnable(GL_BLEND);
-       glDepthMask(0);
-
-       /* draw backside darkening */
-       glCullFace(GL_FRONT);
-
-       glBlendFunc(GL_ZERO, GL_SRC_ALPHA);
-       glColor4f(0.0f, 0.0f, 0.0f, 0.4f);
-
-       draw_spot_cone(la, x, z);
-
-       /* draw front side lighting */
-       glCullFace(GL_BACK);
-
-       glBlendFunc(GL_ONE, GL_ONE);
-       glColor4f(0.2f, 0.2f, 0.2f, 1.0f);
-
-       draw_spot_cone(la, x, z);
-
-       /* restore state */
-       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-       glDisable(GL_BLEND);
-       glDepthMask(1);
-       glDisable(GL_CULL_FACE);
-       glCullFace(GL_BACK);
-}
-
-#ifdef WITH_GAMEENGINE
-static void draw_transp_sun_volume(Lamp *la)
-{
-       float box[8][3];
-
-       /* construct box */
-       box[0][0] = box[1][0] = box[2][0] = box[3][0] = -la->shadow_frustum_size;
-       box[4][0] = box[5][0] = box[6][0] = box[7][0] = +la->shadow_frustum_size;
-       box[0][1] = box[1][1] = box[4][1] = box[5][1] = -la->shadow_frustum_size;
-       box[2][1] = box[3][1] = box[6][1] = box[7][1] = +la->shadow_frustum_size;
-       box[0][2] = box[3][2] = box[4][2] = box[7][2] = -la->clipend;
-       box[1][2] = box[2][2] = box[5][2] = box[6][2] = -la->clipsta;
-
-       /* draw edges */
-       draw_box(box, false);
-
-       /* draw faces */
-       glEnable(GL_CULL_FACE);
-       glEnable(GL_BLEND);
-       glDepthMask(0);
-
-       /* draw backside darkening */
-       glCullFace(GL_FRONT);
-
-       glBlendFunc(GL_ZERO, GL_SRC_ALPHA);
-       glColor4f(0.0f, 0.0f, 0.0f, 0.4f);
-
-       draw_box(box, true);
-
-       /* draw front side lighting */
-       glCullFace(GL_BACK);
-
-       glBlendFunc(GL_ONE, GL_ONE);
-       glColor4f(0.2f, 0.2f, 0.2f, 1.0f);
-
-       draw_box(box, true);
-
-       /* restore state */
-       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-       glDisable(GL_BLEND);
-       glDepthMask(1);
-       glDisable(GL_CULL_FACE);
-       glCullFace(GL_BACK);
-}
-#endif
-
-static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
-                     const char dt, const short dflag, const unsigned char ob_wire_col[4], const bool is_obact)
-{
-       Object *ob = base->object;
-       const float pixsize = ED_view3d_pixel_size(rv3d, ob->obmat[3]);
-       Lamp *la = ob->data;
-       float vec[3], lvec[3], vvec[3], circrad;
-       float lampsize;
-       float imat[4][4];
-
-       unsigned char curcol[4];
-       unsigned char col[4];
-       /* cone can't be drawn for duplicated lamps, because duplilist would be freed */
-       /* the moment of view3d_draw_transp() call */
-       const bool is_view = (rv3d->persp == RV3D_CAMOB && v3d->camera == base->object);
-       const bool drawcone = ((dt > OB_WIRE) &&
-                              !(G.f & G_PICKSEL) &&
-                              (la->type == LA_SPOT) &&
-                              (la->mode & LA_SHOW_CONE) &&
-                              !(base->flag & OB_FROMDUPLI) &&
-                              !is_view);
-
-#ifdef WITH_GAMEENGINE
-       const bool drawshadowbox = (
-               (rv3d->rflag & RV3D_IS_GAME_ENGINE) &&
-               (dt > OB_WIRE) &&
-               !(G.f & G_PICKSEL) &&
-               (la->type == LA_SUN) &&
-               ((la->mode & LA_SHAD_BUF) ||
-               (la->mode & LA_SHAD_RAY)) &&
-               (la->mode & LA_SHOW_SHADOW_BOX) &&
-               !(base->flag & OB_FROMDUPLI) &&
-               !is_view);
-#else
-       const bool drawshadowbox = false;
-#endif
-
-       if ((drawcone || drawshadowbox) && !v3d->transp) {
-               /* in this case we need to draw delayed */
-               ED_view3d_after_add(v3d->xray ? &v3d->afterdraw_xraytransp : &v3d->afterdraw_transp, base, dflag);
-               return;
-       }
-
-       /* we first draw only the screen aligned & fixed scale stuff */
-       glPushMatrix();
-       glLoadMatrixf(rv3d->viewmat);
-
-       /* lets calculate the scale: */
-       lampsize = pixsize * ((float)U.obcenter_dia * 0.5f);
-
-       /* and view aligned matrix: */
-       copy_m4_m4(imat, rv3d->viewinv);
-       normalize_v3(imat[0]);
-       normalize_v3(imat[1]);
-
-       /* lamp center */
-       copy_v3_v3(vec, ob->obmat[3]);
-
-       if ((dflag & DRAW_CONSTCOLOR) == 0) {
-               /* for AA effects */
-               curcol[0] = ob_wire_col[0];
-               curcol[1] = ob_wire_col[1];
-               curcol[2] = ob_wire_col[2];
-               curcol[3] = 154;
-               glColor4ubv(curcol);
-       }
-
-       glLineWidth(1);
-
-       if (lampsize > 0.0f) {
-
-               if ((dflag & DRAW_CONSTCOLOR) == 0) {
-                       if (ob->id.us > 1) {
-                               if (is_obact || (ob->flag & SELECT)) {
-                                       glColor4ub(0x88, 0xFF, 0xFF, 155);
-                               }
-                               else {
-                                       glColor4ub(0x77, 0xCC, 0xCC, 155);
-                               }
-                       }
-               }
-
-               /* Inner Circle */
-               glEnable(GL_BLEND);
-               drawcircball(GL_LINE_LOOP, vec, lampsize, imat);
-               glDisable(GL_BLEND);
-               drawcircball(GL_POLYGON, vec, lampsize, imat);
-
-               /* restore */
-               if ((dflag & DRAW_CONSTCOLOR) == 0) {
-                       if (ob->id.us > 1)
-                               glColor4ubv(curcol);
-               }
-
-               /* Outer circle */
-               circrad = 3.0f * lampsize;
-               setlinestyle(3);
-
-               drawcircball(GL_LINE_LOOP, vec, circrad, imat);
-
-               /* draw dashed outer circle if shadow is on. remember some lamps can't have certain shadows! */
-               if (la->type != LA_HEMI) {
-                       if ((la->mode & LA_SHAD_RAY) || ((la->mode & LA_SHAD_BUF) && (la->type == LA_SPOT))) {
-                               drawcircball(GL_LINE_LOOP, vec, circrad + 3.0f * pixsize, imat);
-                       }
-               }
-       }
-       else {
-               setlinestyle(3);
-               circrad = 0.0f;
-       }
-
-       /* draw the pretty sun rays */
-       if (la->type == LA_SUN) {
-               float v1[3], v2[3], mat[3][3];
-               short axis;
-
-               /* setup a 45 degree rotation matrix */
-               axis_angle_normalized_to_mat3_ex(mat, imat[2], M_SQRT1_2, M_SQRT1_2);
-
-               /* vectors */
-               mul_v3_v3fl(v1, imat[0], circrad * 1.2f);
-               mul_v3_v3fl(v2, imat[0], circrad * 2.5f);
-
-               /* center */
-               glTranslate3fv(vec);
-
-               setlinestyle(3);
-
-               glBegin(GL_LINES);
-               for (axis = 0; axis < 8; axis++) {
-                       glVertex3fv(v1);
-                       glVertex3fv(v2);
-                       mul_m3_v3(mat, v1);
-                       mul_m3_v3(mat, v2);
-               }
-               glEnd();
-
-               glTranslatef(-vec[0], -vec[1], -vec[2]);
-
-       }
-
-       if (la->type == LA_LOCAL) {
-               if (la->mode & LA_SPHERE) {
-                       drawcircball(GL_LINE_LOOP, vec, la->dist, imat);
-               }
-       }
-
-       glPopMatrix();  /* back in object space */
-       zero_v3(vec);
-
-       if (is_view) {
-               /* skip drawing extra info */
-       }
-       else if (la->type == LA_SPOT) {
-               float x, y, z, z_abs;
-               copy_v3_fl3(lvec, 0.0f, 0.0f, 1.0f);
-               copy_v3_fl3(vvec, rv3d->persmat[0][2], rv3d->persmat[1][2], rv3d->persmat[2][2]);
-               mul_transposed_mat3_m4_v3(ob->obmat, vvec);
-
-               x = -la->dist;
-               y = cosf(la->spotsize * 0.5f);
-               z = x * sqrtf(1.0f - y * y);
-
-               spotvolume(lvec, vvec, y);
-               mul_v3_fl(lvec, x);
-               mul_v3_fl(vvec, x);
-
-               x *= y;
-
-               z_abs = fabsf(z);
-
-               if (la->mode & LA_SQUARE) {
-                       /* draw pyramid */
-                       const float vertices[5][3] = {
-                           /* 5 of vertex coords of pyramid */
-                           {0.0f, 0.0f, 0.0f},
-                           {z_abs, z_abs, x},
-                           {-z_abs, -z_abs, x},
-                           {z_abs, -z_abs, x},
-                           {-z_abs, z_abs, x},
-                       };
-                       const unsigned char indices[] = {
-                           0, 1, 3,
-                           0, 3, 2,
-                           0, 2, 4,
-                           0, 1, 4,
-                       };
-
-                       /* Draw call:
-                        * activate and specify pointer to vertex array */
-                       glEnableClientState(GL_VERTEX_ARRAY);
-                       glVertexPointer(3, GL_FLOAT, 0, vertices);
-                       /* draw the pyramid */
-                       glDrawElements(GL_LINE_STRIP, 12, GL_UNSIGNED_BYTE, indices);
-
-                       /* deactivate vertex arrays after drawing */
-                       glDisableClientState(GL_VERTEX_ARRAY);
-
-                       glTranslatef(0.0f, 0.0f, x);
-
-                       /* draw the square representing spotbl */
-                       if (la->type == LA_SPOT) {
-                               float blend = z_abs * (1.0f - pow2f(la->spotblend));
-
-                               /* hide line if it is zero size or overlaps with outer border,
-                                * previously it adjusted to always to show it but that seems
-                                * confusing because it doesn't show the actual blend size */
-                               if (blend != 0.0f && blend != z_abs) {
-                                       fdrawbox(blend, -blend, -blend, blend);
-                               }
-                       }
-               }
-               else {
-
-                       /* draw the angled sides of the cone */
-                       glBegin(GL_LINE_STRIP);
-                       glVertex3fv(vvec);
-                       glVertex3fv(vec);
-                       glVertex3fv(lvec);
-                       glEnd();
-
-                       /* draw the circle at the end of the cone */
-                       glTranslatef(0.0f, 0.0f, x);
-                       circ(0.0f, 0.0f, z_abs);
-
-                       /* draw the circle representing spotbl */
-                       if (la->type == LA_SPOT) {
-                               float blend = z_abs * (1.0f - pow2f(la->spotblend));
-
-                               /* hide line if it is zero size or overlaps with outer border,
-                                * previously it adjusted to always to show it but that seems
-                                * confusing because it doesn't show the actual blend size */
-                               if (blend != 0.0f && blend != z_abs) {
-                                       circ(0.0f, 0.0f, blend);
-                               }
-                       }
-               }
-
-               if (drawcone)
-                       draw_transp_spot_volume(la, x, z);
-
-               /* draw clip start, useful for wide cones where its not obvious where the start is */
-               glTranslatef(0.0, 0.0, -x);  /* reverse translation above */
-               glBegin(GL_LINES);
-               if (la->type == LA_SPOT && (la->mode & LA_SHAD_BUF)) {
-                       float lvec_clip[3];
-                       float vvec_clip[3];
-                       float clipsta_fac = la->clipsta / -x;
-
-                       interp_v3_v3v3(lvec_clip, vec, lvec, clipsta_fac);
-                       interp_v3_v3v3(vvec_clip, vec, vvec, clipsta_fac);
-
-                       glVertex3fv(lvec_clip);
-                       glVertex3fv(vvec_clip);
-               }
-               /* Else, draw spot direction (using distance as end limit, same as for Area lamp). */
-               else {
-                       glVertex3f(0.0, 0.0, -circrad);
-                       glVertex3f(0.0, 0.0, -la->dist);
-               }
-               glEnd();
-       }
-       else if (ELEM(la->type, LA_HEMI, LA_SUN)) {
-
-               /* draw the line from the circle along the dist */
-               glBegin(GL_LINES);
-               vec[2] = -circrad;
-               glVertex3fv(vec);
-               vec[2] = -la->dist;
-               glVertex3fv(vec);
-               glEnd();
-
-               if (la->type == LA_HEMI) {
-                       /* draw the hemisphere curves */
-                       short axis, steps, dir;
-                       float outdist, zdist, mul;
-                       zero_v3(vec);
-                       outdist = 0.14; mul = 1.4; dir = 1;
-
-                       setlinestyle(4);
-                       /* loop over the 4 compass points, and draw each arc as a LINE_STRIP */
-                       for (axis = 0; axis < 4; axis++) {
-                               float v[3] = {0.0, 0.0, 0.0};
-                               zdist = 0.02;
-
-                               glBegin(GL_LINE_STRIP);
-
-                               for (steps = 0; steps < 6; steps++) {
-                                       if (axis == 0 || axis == 1) {       /* x axis up, x axis down */
-                                               /* make the arcs start at the edge of the energy circle */
-                                               if (steps == 0) v[0] = dir * circrad;
-                                               else v[0] = v[0] + dir * (steps * outdist);
-                                       }
-                                       else if (axis == 2 || axis == 3) {      /* y axis up, y axis down */
-                                               /* make the arcs start at the edge of the energy circle */
-                                               v[1] = (steps == 0) ? (dir * circrad) : (v[1] + dir * (steps * outdist));
-                                       }
-
-                                       v[2] = v[2] - steps * zdist;
-
-                                       glVertex3fv(v);
-
-                                       zdist = zdist * mul;
-                               }
-
-                               glEnd();
-                               /* flip the direction */
-                               dir = -dir;
-                       }
-               }
-
-#ifdef WITH_GAMEENGINE
-               if (drawshadowbox) {
-                       draw_transp_sun_volume(la);
-               }
-#endif
-
-       }
-       else if (la->type == LA_AREA) {
-               setlinestyle(3);
-               if (la->area_shape == LA_AREA_SQUARE)
-                       fdrawbox(-la->area_size * 0.5f, -la->area_size * 0.5f, la->area_size * 0.5f, la->area_size * 0.5f);
-               else if (la->area_shape == LA_AREA_RECT)
-                       fdrawbox(-la->area_size * 0.5f, -la->area_sizey * 0.5f, la->area_size * 0.5f, la->area_sizey * 0.5f);
-
-               glBegin(GL_LINES);
-               glVertex3f(0.0, 0.0, -circrad);
-               glVertex3f(0.0, 0.0, -la->dist);
-               glEnd();
-       }
-
-       /* and back to viewspace */
-       glPushMatrix();
-       glLoadMatrixf(rv3d->viewmat);
-       copy_v3_v3(vec, ob->obmat[3]);
-
-       setlinestyle(0);
-
-       if ((la->type == LA_SPOT) && (la->mode & LA_SHAD_BUF) && (is_view == false)) {
-               drawshadbuflimits(la, ob->obmat);
-       }
-
-       if ((dflag & DRAW_CONSTCOLOR) == 0) {
-               UI_GetThemeColor4ubv(TH_LAMP, col);
-               glColor4ubv(col);
-       }
-
-       glEnable(GL_BLEND);
-
-       if (vec[2] > 0) vec[2] -= circrad;
-       else vec[2] += circrad;
-
-       glBegin(GL_LINES);
-       glVertex3fv(vec);
-       vec[2] = 0;
-       glVertex3fv(vec);
-       glEnd();
-
-       glPointSize(2.0);
-       glBegin(GL_POINTS);
-       glVertex3fv(vec);
-       glEnd();
-
-       glDisable(GL_BLEND);
-
-       if ((dflag & DRAW_CONSTCOLOR) == 0) {
-               /* restore for drawing extra stuff */
-               glColor3ubv(ob_wire_col);
-       }
-       /* and finally back to org object space! */
-       glPopMatrix();
-}
-
-static void draw_limit_line(float sta, float end, const short dflag, const unsigned char col[3])
-{
-       glBegin(GL_LINES);
-       glVertex3f(0.0, 0.0, -sta);
-       glVertex3f(0.0, 0.0, -end);
-       glEnd();
-
-       if (!(dflag & DRAW_PICKING)) {
-               glPointSize(3.0);
-               glBegin(GL_POINTS);
-               if ((dflag & DRAW_CONSTCOLOR) == 0) {
-                       glColor3ubv(col);
-               }
-               glVertex3f(0.0, 0.0, -sta);
-               glVertex3f(0.0, 0.0, -end);
-               glEnd();
-       }
-}
-
-
-/* yafray: draw camera focus point (cross, similar to aqsis code in tuhopuu) */
-/* qdn: now also enabled for Blender to set focus point for defocus composite node */
-static void draw_focus_cross(float dist, float size)
-{
-       glBegin(GL_LINES);
-       glVertex3f(-size, 0.0f, -dist);
-       glVertex3f(size, 0.0f, -dist);
-       glVertex3f(0.0f, -size, -dist);
-       glVertex3f(0.0f, size, -dist);
-       glEnd();
-}
-
-#ifdef VIEW3D_CAMERA_BORDER_HACK
-unsigned char view3d_camera_border_hack_col[3];
-bool view3d_camera_border_hack_test = false;
-#endif
-
-/* ****************** draw clip data *************** */
-
-static void draw_bundle_sphere(void)
-{
-       static GLuint displist = 0;
-
-       if (displist == 0) {
-               GLUquadricObj *qobj;
-
-               displist = glGenLists(1);
-               glNewList(displist, GL_COMPILE);
-               qobj = gluNewQuadric();
-               gluQuadricDrawStyle(qobj, GLU_FILL);
-               gluSphere(qobj, 0.05, 8, 8);
-               gluDeleteQuadric(qobj);
-
-               glEndList();
-       }
-
-       glCallList(displist);
-}
-
-static void draw_viewport_object_reconstruction(
-        Scene *scene, Base *base, const View3D *v3d, const RegionView3D *rv3d,
-        MovieClip *clip, MovieTrackingObject *tracking_object,
-        const short dflag, const unsigned char ob_wire_col[4],
-        int *global_track_index, bool draw_selected)
-{
-       MovieTracking *tracking = &clip->tracking;
-       MovieTrackingTrack *track;
-       float mat[4][4], imat[4][4];
-       unsigned char col_unsel[4], col_sel[4];
-       int tracknr = *global_track_index;
-       ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, tracking_object);
-       float camera_size[3];
-
-       UI_GetThemeColor4ubv(TH_TEXT, col_unsel);
-       UI_GetThemeColor4ubv(TH_SELECT, col_sel);
-
-       BKE_tracking_get_camera_object_matrix(scene, base->object, mat);
-
-       /* we're compensating camera size for bundles size,
-        * to make it so bundles are always displayed with the same size */
-       copy_v3_v3(camera_size, base->object->size);
-       if ((tracking_object->flag & TRACKING_OBJECT_CAMERA) == 0)
-               mul_v3_fl(camera_size, tracking_object->scale);
-
-       glPushMatrix();
-
-       if (tracking_object->flag & TRACKING_OBJECT_CAMERA) {
-               /* current ogl matrix is translated in camera space, bundles should
-                * be rendered in world space, so camera matrix should be "removed"
-                * from current ogl matrix */
-               invert_m4_m4(imat, base->object->obmat);
-
-               glMultMatrixf(imat);
-               glMultMatrixf(mat);
-       }
-       else {
-               float obmat[4][4];
-               int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, scene->r.cfra);
-
-               BKE_tracking_camera_get_reconstructed_interpolate(tracking, tracking_object, framenr, obmat);
-
-               invert_m4_m4(imat, obmat);
-               glMultMatrixf(imat);
-       }
-
-       for (track = tracksbase->first; track; track = track->next) {
-               bool selected = TRACK_SELECTED(track);
-
-               if (draw_selected && !selected)
-                       continue;
-
-               if ((track->flag & TRACK_HAS_BUNDLE) == 0)
-                       continue;
-
-               if (dflag & DRAW_PICKING)
-                       GPU_select_load_id(base->selcol + (tracknr << 16));
-
-               glPushMatrix();
-               glTranslate3fv(track->bundle_pos);
-               glScalef(v3d->bundle_size / 0.05f / camera_size[0],
-                        v3d->bundle_size / 0.05f / camera_size[1],
-                        v3d->bundle_size / 0.05f / camera_size[2]);
-
-               const int v3d_drawtype = view3d_effective_drawtype(v3d);
-               if (v3d_drawtype == OB_WIRE) {
-                       if ((dflag & DRAW_CONSTCOLOR) == 0) {
-                               if (selected && (track->flag & TRACK_CUSTOMCOLOR) == 0) {
-                                       glColor3ubv(ob_wire_col);
-                               }
-                               else {
-                                       glColor3fv(track->color);
-                               }
-                       }
-
-                       drawaxes(rv3d->viewmatob, 0.05f, v3d->bundle_drawtype);
-               }
-               else if (v3d_drawtype > OB_WIRE) {
-                       if (v3d->bundle_drawtype == OB_EMPTY_SPHERE) {
-                               /* selection outline */
-                               if (selected) {
-                                       if ((dflag & DRAW_CONSTCOLOR) == 0) {
-                                               glColor3ubv(ob_wire_col);
-                                       }
-
-                                       glLineWidth(2.0f);
-                                       glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-
-                                       draw_bundle_sphere();
-
-                                       glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-                               }
-
-                               if ((dflag & DRAW_CONSTCOLOR) == 0) {
-                                       if (track->flag & TRACK_CUSTOMCOLOR) glColor3fv(track->color);
-                                       else UI_ThemeColor(TH_BUNDLE_SOLID);
-                               }
-
-                               draw_bundle_sphere();
-                       }
-                       else {
-                               if ((dflag & DRAW_CONSTCOLOR) == 0) {
-                                       if (selected) {
-                                               glColor3ubv(ob_wire_col);
-                                       }
-                                       else {
-                                               if (track->flag & TRACK_CUSTOMCOLOR) glColor3fv(track->color);
-                                               else UI_ThemeColor(TH_WIRE);
-                                       }
-                               }
-
-                               drawaxes(rv3d->viewmatob, 0.05f, v3d->bundle_drawtype);
-                       }
-               }
-
-               glPopMatrix();
-
-               if ((dflag & DRAW_PICKING) == 0 && (v3d->flag2 & V3D_SHOW_BUNDLENAME)) {
-                       float pos[3];
-
-                       mul_v3_m4v3(pos, mat, track->bundle_pos);
-                       view3d_cached_text_draw_add(pos,
-                                                   track->name, strlen(track->name),
-                                                   10, V3D_CACHE_TEXT_GLOBALSPACE,
-                                                   selected ? col_sel : col_unsel);
-               }
-
-               tracknr++;
-       }
-
-       if ((dflag & DRAW_PICKING) == 0) {
-               if ((v3d->flag2 & V3D_SHOW_CAMERAPATH) && (tracking_object->flag & TRACKING_OBJECT_CAMERA)) {
-                       MovieTrackingReconstruction *reconstruction;
-                       reconstruction = BKE_tracking_object_get_reconstruction(tracking, tracking_object);
-
-                       if (reconstruction->camnr) {
-                               MovieReconstructedCamera *camera = reconstruction->cameras;
-
-                               UI_ThemeColor(TH_CAMERA_PATH);
-                               glLineWidth(2.0f);
-
-                               glBegin(GL_LINE_STRIP);
-                               for (int a = 0; a < reconstruction->camnr; a++, camera++) {
-                                       glVertex3fv(camera->mat[3]);
-                               }
-                               glEnd();
-                       }
-               }
-       }
-
-       glPopMatrix();
-
-       *global_track_index = tracknr;
-}
-
-static void draw_viewport_reconstruction(
-        Scene *scene, Base *base, const View3D *v3d, const RegionView3D *rv3d, MovieClip *clip,
-        const short dflag, const unsigned char ob_wire_col[4],
-        const bool draw_selected)
-{
-       MovieTracking *tracking = &clip->tracking;
-       MovieTrackingObject *tracking_object;
-       int global_track_index = 1;
-
-       if ((v3d->flag2 & V3D_SHOW_RECONSTRUCTION) == 0)
-               return;
-
-       if (v3d->flag2 & V3D_RENDER_OVERRIDE)
-               return;
-
-       GPU_basic_shader_colors(NULL, NULL, 0, 1.0f);
-       GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR);
-
-       tracking_object = tracking->objects.first;
-       while (tracking_object) {
-               draw_viewport_object_reconstruction(
-                       scene, base, v3d, rv3d, clip, tracking_object,
-                       dflag, ob_wire_col, &global_track_index, draw_selected);
-
-               tracking_object = tracking_object->next;
-       }
-
-       /* restore */
-       GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
-
-       if ((dflag & DRAW_CONSTCOLOR) == 0) {
-               glColor3ubv(ob_wire_col);
-       }
-
-       if (dflag & DRAW_PICKING)
-               GPU_select_load_id(base->selcol);
-}
-
-static void drawcamera_volume(float near_plane[4][3], float far_plane[4][3], const GLenum mode)
-{
-       glBegin(mode);
-       glVertex3fv(near_plane[0]);
-       glVertex3fv(far_plane[0]);
-       glVertex3fv(far_plane[1]);
-       glVertex3fv(near_plane[1]);
-       glEnd();
-
-       glBegin(mode);
-       glVertex3fv(near_plane[1]);
-       glVertex3fv(far_plane[1]);
-       glVertex3fv(far_plane[2]);
-       glVertex3fv(near_plane[2]);
-       glEnd();
-
-       glBegin(mode);
-       glVertex3fv(near_plane[2]);
-       glVertex3fv(far_plane[2]);
-       glVertex3fv(far_plane[3]);
-       glVertex3fv(near_plane[3]);
-       glEnd();
-
-       glBegin(mode);
-       glVertex3fv(far_plane[3]);
-       glVertex3fv(near_plane[3]);
-       glVertex3fv(near_plane[0]);
-       glVertex3fv(far_plane[0]);
-       glEnd();
-}
-
-/* camera frame */
-static void drawcamera_frame(float vec[4][3], const GLenum mode)
-{
-       glBegin(mode);
-       glVertex3fv(vec[0]);
-       glVertex3fv(vec[1]);
-       glVertex3fv(vec[2]);
-       glVertex3fv(vec[3]);
-       glEnd();
-}
-
-/* center point to camera frame */
-static void drawcamera_framelines(float vec[4][3], float origin[3])
-{
-       glBegin(GL_LINE_STRIP);
-       glVertex3fv(vec[1]);
-       glVertex3fv(origin);
-       glVertex3fv(vec[0]);
-       glVertex3fv(vec[3]);
-       glVertex3fv(origin);
-       glVertex3fv(vec[2]);
-       glEnd();
-}
-
-static bool drawcamera_is_stereo3d(Scene *scene, View3D *v3d, Object *ob)
-{
-       return (ob == v3d->camera) &&
-               (scene->r.scemode & R_MULTIVIEW) != 0 &&
-               (v3d->stereo3d_flag);
-}
-
-static void drawcamera_stereo3d(
-        Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, const Camera *cam,
-        float vec[4][3], float drawsize, const float scale[3])
-{
-       float obmat[4][4];
-       float vec_lr[2][4][3];
-       const float fac = (cam->stereo.pivot == CAM_S3D_PIVOT_CENTER) ? 2.0f : 1.0f;
-       float origin[2][3] = {{0}};
-       float tvec[3];
-       const Camera *cam_lr[2];
-       const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
-
-       const bool is_stereo3d_cameras = (v3d->stereo3d_flag & V3D_S3D_DISPCAMERAS) && (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D);
-       const bool is_stereo3d_plane = (v3d->stereo3d_flag & V3D_S3D_DISPPLANE) && (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D);
-       const bool is_stereo3d_volume = (v3d->stereo3d_flag & V3D_S3D_DISPVOLUME);
-
-       zero_v3(tvec);
-
-       glPushMatrix();
-
-       for (int i = 0; i < 2; i++) {
-               ob = BKE_camera_multiview_render(scene, ob, names[i]);
-               cam_lr[i] = ob->data;
-
-               glLoadMatrixf(rv3d->viewmat);
-               BKE_camera_multiview_model_matrix(&scene->r, ob, names[i], obmat);
-               glMultMatrixf(obmat);
-
-               copy_m3_m3(vec_lr[i], vec);
-               copy_v3_v3(vec_lr[i][3], vec[3]);
-
-               if (cam->stereo.convergence_mode == CAM_S3D_OFFAXIS) {
-                       const float shift_x =
-                               ((BKE_camera_multiview_shift_x(&scene->r, ob, names[i]) - cam->shiftx) *
-                                (drawsize * scale[0] * fac));
-
-                       for (int j = 0; j < 4; j++) {
-                               vec_lr[i][j][0] += shift_x;
-                       }
-               }
-
-               if (is_stereo3d_cameras) {
-                       /* camera frame */
-                       drawcamera_frame(vec_lr[i], GL_LINE_LOOP);
-
-                       /* center point to camera frame */
-                       drawcamera_framelines(vec_lr[i], tvec);
-               }
-
-               /* connecting line */
-               mul_m4_v3(obmat, origin[i]);
-
-               /* convergence plane */
-               if (is_stereo3d_plane || is_stereo3d_volume) {
-                       for (int j = 0; j < 4; j++) {
-                               mul_m4_v3(obmat, vec_lr[i][j]);
-                       }
-               }
-       }
-
-
-       /* the remaining drawing takes place in the view space */
-       glLoadMatrixf(rv3d->viewmat);
-
-       if (is_stereo3d_cameras) {
-               /* draw connecting lines */
-               GPU_basic_shader_bind_enable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE);
-               GPU_basic_shader_line_stipple(2, 0xAAAA);
-
-               glBegin(GL_LINES);
-               glVertex3fv(origin[0]);
-               glVertex3fv(origin[1]);
-               glEnd();
-
-               GPU_basic_shader_bind_disable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE);
-       }
-
-       /* draw convergence plane */
-       if (is_stereo3d_plane) {
-               float axis_center[3], screen_center[3];
-               float world_plane[4][3];
-               float local_plane[4][3];
-               float offset;
-
-               mid_v3_v3v3(axis_center, origin[0], origin[1]);
-
-               for (int i = 0; i < 4; i++) {
-                       mid_v3_v3v3(world_plane[i], vec_lr[0][i], vec_lr[1][i]);
-                       sub_v3_v3v3(local_plane[i], world_plane[i], axis_center);
-               }
-
-               mid_v3_v3v3(screen_center, world_plane[0], world_plane[2]);
-               offset = cam->stereo.convergence_distance / len_v3v3(screen_center, axis_center);
-
-               for (int i = 0; i < 4; i++) {
-                       mul_v3_fl(local_plane[i], offset);
-                       add_v3_v3(local_plane[i], axis_center);
-               }
-
-               glColor3f(0.0f, 0.0f, 0.0f);
-
-               /* camera frame */
-               drawcamera_frame(local_plane, GL_LINE_LOOP);
-
-               if (v3d->stereo3d_convergence_alpha > 0.0f) {
-                       glEnable(GL_BLEND);
-                       glDepthMask(0);  /* disable write in zbuffer, needed for nice transp */
-
-                       glColor4f(0.0f, 0.0f, 0.0f, v3d->stereo3d_convergence_alpha);
-
-                       drawcamera_frame(local_plane, GL_QUADS);
-
-                       glDisable(GL_BLEND);
-                       glDepthMask(1);  /* restore write in zbuffer */
-               }
-       }
-
-       /* draw convergence plane */
-       if (is_stereo3d_volume) {
-               float screen_center[3];
-               float near_plane[4][3], far_plane[4][3];
-
-               for (int i = 0; i < 2; i++) {
-                       mid_v3_v3v3(screen_center, vec_lr[i][0], vec_lr[i][2]);
-
-                       float offset = len_v3v3(screen_center, origin[i]);
-
-                       for (int j = 0; j < 4; j++) {
-                               sub_v3_v3v3(near_plane[j], vec_lr[i][j], origin[i]);
-                               mul_v3_fl(near_plane[j], cam_lr[i]->clipsta / offset);
-                               add_v3_v3(near_plane[j], origin[i]);
-
-                               sub_v3_v3v3(far_plane[j], vec_lr[i][j], origin[i]);
-                               mul_v3_fl(far_plane[j], cam_lr[i]->clipend / offset);
-                               add_v3_v3(far_plane[j], origin[i]);
-                       }
-
-                       /* camera frame */
-                       glColor3f(0.0f, 0.0f, 0.0f);
-
-                       drawcamera_frame(near_plane, GL_LINE_LOOP);
-                       drawcamera_frame(far_plane, GL_LINE_LOOP);
-                       drawcamera_volume(near_plane, far_plane, GL_LINE_LOOP);
-
-                       if (v3d->stereo3d_volume_alpha > 0.0f) {
-                               glEnable(GL_BLEND);
-                               glDepthMask(0);  /* disable write in zbuffer, needed for nice transp */
-
-                               if (i == 0)
-                                       glColor4f(0.0f, 1.0f, 1.0f, v3d->stereo3d_volume_alpha);
-                               else
-                                       glColor4f(1.0f, 0.0f, 0.0f, v3d->stereo3d_volume_alpha);
-
-                               drawcamera_frame(near_plane, GL_QUADS);
-                               drawcamera_frame(far_plane, GL_QUADS);
-                               drawcamera_volume(near_plane, far_plane, GL_QUADS);
-
-                               glDisable(GL_BLEND);
-                               glDepthMask(1);  /* restore write in zbuffer */
-                       }
-               }
-       }
-
-       glPopMatrix();
-}
-
-/* flag similar to draw_object() */
-static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
-                       const short dflag, const unsigned char ob_wire_col[4])
-{
-       /* a standing up pyramid with (0,0,0) as top */
-       Camera *cam;
-       Object *ob = base->object;
-       float tvec[3];
-       float vec[4][3], asp[2], shift[2], scale[3];
-       MovieClip *clip = BKE_object_movieclip_get(scene, base->object, false);
-
-       const bool is_active = (ob == v3d->camera);
-       const bool is_view = (rv3d->persp == RV3D_CAMOB && is_active);
-       const bool is_multiview = (scene->r.scemode & R_MULTIVIEW) != 0;
-       const bool is_stereo3d = drawcamera_is_stereo3d(scene, v3d, ob);
-       const bool is_stereo3d_view = (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D);
-       const bool is_stereo3d_cameras = (ob == scene->camera) &&
-                                        is_multiview &&
-                                        is_stereo3d_view &&
-                                        (v3d->stereo3d_flag & V3D_S3D_DISPCAMERAS);
-       const bool is_selection_camera_stereo = (G.f & G_PICKSEL) &&
-                                               is_view && is_multiview &&
-                                               is_stereo3d_view;
-
-       /* draw data for movie clip set as active for scene */
-       if (clip) {
-               draw_viewport_reconstruction(scene, base, v3d, rv3d, clip, dflag, ob_wire_col, false);
-               draw_viewport_reconstruction(scene, base, v3d, rv3d, clip, dflag, ob_wire_col, true);
-       }
-
-#ifdef VIEW3D_CAMERA_BORDER_HACK
-       if (is_view && !(G.f & G_PICKSEL)) {
-               if ((dflag & DRAW_CONSTCOLOR) == 0) {
-                       view3d_camera_border_hack_col[0] = ob_wire_col[0];
-                       view3d_camera_border_hack_col[1] = ob_wire_col[1];
-                       view3d_camera_border_hack_col[2] = ob_wire_col[2];
-               }
-               else {
-                       float col[4];
-                       glGetFloatv(GL_CURRENT_COLOR, col);
-                       rgb_float_to_uchar(view3d_camera_border_hack_col, col);
-               }
-               view3d_camera_border_hack_test = true;
-               return;
-       }
-#endif
-
-       cam = ob->data;
-
-       /* BKE_camera_multiview_model_matrix already accounts for scale, don't do it here */
-       if (is_selection_camera_stereo) {
-               scale[0] = 1.0f;
-               scale[1] = 1.0f;
-               scale[2] = 1.0f;
-       }
-       else {
-               scale[0] = 1.0f / len_v3(ob->obmat[0]);
-               scale[1] = 1.0f / len_v3(ob->obmat[1]);
-               scale[2] = 1.0f / len_v3(ob->obmat[2]);
-       }
-
-       float drawsize;
-       BKE_camera_view_frame_ex(scene, cam, cam->drawsize, is_view, scale,
-                                asp, shift, &drawsize, vec);
-
-       glDisable(GL_CULL_FACE);
-       glLineWidth(1);
-
-       /* camera frame */
-       if (!is_stereo3d_cameras) {
-               /* make sure selection uses the same matrix for camera as the one used while viewing */
-               if (is_selection_camera_stereo) {
-                       float obmat[4][4];
-                       bool is_left = v3d->multiview_eye == STEREO_LEFT_ID;
-
-                       glPushMatrix();
-                       glLoadMatrixf(rv3d->viewmat);
-                       BKE_camera_multiview_model_matrix(&scene->r, ob, is_left ? STEREO_LEFT_NAME : STEREO_RIGHT_NAME, obmat);
-                       glMultMatrixf(obmat);
-
-                       drawcamera_frame(vec, GL_LINE_LOOP);
-                       glPopMatrix();
-               }
-               else {
-                       drawcamera_frame(vec, GL_LINE_LOOP);
-               }
-       }
-
-       if (is_view)
-               return;
-
-       zero_v3(tvec);
-
-       /* center point to camera frame */
-       if (!is_stereo3d_cameras)
-               drawcamera_framelines(vec, tvec);
-
-       /* arrow on top */
-       tvec[2] = vec[1][2]; /* copy the depth */
-
-       /* draw an outline arrow for inactive cameras and filled
-        * for active cameras. We actually draw both outline+filled
-        * for active cameras so the wire can be seen side-on */
-       for (int i = 0; i < 2; i++) {
-               if (i == 0) glBegin(GL_LINE_LOOP);
-               else if (i == 1 && is_active) glBegin(GL_TRIANGLES);
-               else break;
-
-               tvec[0] = shift[0] + ((-0.7f * drawsize) * scale[0]);
-               tvec[1] = shift[1] + ((drawsize * (asp[1] + 0.1f)) * scale[1]);
-               glVertex3fv(tvec); /* left */
-
-               tvec[0] = shift[0] + ((0.7f * drawsize) * scale[0]);
-               glVertex3fv(tvec); /* right */
-
-               tvec[0] = shift[0];
-               tvec[1] = shift[1] + ((1.1f * drawsize * (asp[1] + 0.7f)) * scale[1]);
-               glVertex3fv(tvec); /* top */
-
-               glEnd();
-       }
-
-       if ((dflag & DRAW_SCENESET) == 0) {
-               if (cam->flag & (CAM_SHOWLIMITS | CAM_SHOWMIST)) {
-                       float nobmat[4][4];
-
-                       /* draw in normalized object matrix space */
-                       copy_m4_m4(nobmat, ob->obmat);
-                       normalize_m4(nobmat);
-
-                       glPushMatrix();
-                       glLoadMatrixf(rv3d->viewmat);
-                       glMultMatrixf(nobmat);
-
-                       if (cam->flag & CAM_SHOWLIMITS) {
-                               const unsigned char col[3] = {128, 128, 60}, col_hi[3] = {255, 255, 120};
-
-                               draw_limit_line(cam->clipsta, cam->clipend, dflag, (is_active ? col_hi : col));
-                               /* qdn: was yafray only, now also enabled for Blender to be used with defocus composite node */
-                               draw_focus_cross(BKE_camera_object_dof_distance(ob), cam->drawsize);
-                       }
-
-                       if (cam->flag & CAM_SHOWMIST) {
-                               World *world = scene->world;
-                               const unsigned char col[3] = {128, 128, 128}, col_hi[3] = {255, 255, 255};
-
-                               if (world) {
-                                       draw_limit_line(world->miststa, world->miststa + world->mistdist,
-                                                       dflag, (is_active ? col_hi : col));
-                               }
-                       }
-                       glPopMatrix();
-               }
-       }
-
-       /* stereo cameras drawing */
-       if (is_stereo3d) {
-               drawcamera_stereo3d(scene, v3d, rv3d, ob, cam, vec, drawsize, scale);
-       }
-}
-
-/* flag similar to draw_object() */
-static void drawspeaker(Scene *UNUSED(scene), View3D *UNUSED(v3d), RegionView3D *UNUSED(rv3d),
-                        Object *UNUSED(ob), int UNUSED(flag))
-{
-       float vec[3];
-
-       glEnable(GL_BLEND);
-       glLineWidth(1);
-
-       for (int j = 0; j < 3; j++) {
-               vec[2] = 0.25f * j - 0.125f;
-
-               glBegin(GL_LINE_LOOP);
-               for (int i = 0; i < 16; i++) {
-                       vec[0] = cosf((float)M_PI * i / 8.0f) * (j == 0 ? 0.5f : 0.25f);
-                       vec[1] = sinf((float)M_PI * i / 8.0f) * (j == 0 ? 0.5f : 0.25f);
-                       glVertex3fv(vec);
-               }
-               glEnd();
-       }
-
-       for (int j = 0; j < 4; j++) {
-               vec[0] = (((j + 1) % 2) * (j - 1)) * 0.5f;
-               vec[1] = ((j % 2) * (j - 2)) * 0.5f;
-               glBegin(GL_LINE_STRIP);
-               for (int i = 0; i < 3; i++) {
-                       if (i == 1) {
-                               vec[0] *= 0.5f;
-                               vec[1] *= 0.5f;
-                       }
-
-                       vec[2] = 0.25f * i - 0.125f;
-                       glVertex3fv(vec);
-               }
-               glEnd();
-       }
-
-       glDisable(GL_BLEND);
-}
-
-static void lattice_draw_verts(Lattice *lt, DispList *dl, BPoint *actbp, short sel)
-{
-       BPoint *bp = lt->def;
-       const float *co = dl ? dl->verts : NULL;
-
-       const int color = sel ? TH_VERTEX_SELECT : TH_VERTEX;
-       UI_ThemeColor(color);
-
-       glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
-       glBegin(GL_POINTS);
-
-       for (int w = 0; w < lt->pntsw; w++) {
-               int wxt = (w == 0 || w == lt->pntsw - 1);
-               for (int v = 0; v < lt->pntsv; v++) {
-                       int vxt = (v == 0 || v == lt->pntsv - 1);
-                       for (int u = 0; u < lt->pntsu; u++, bp++, co += 3) {
-                               int uxt = (u == 0 || u == lt->pntsu - 1);
-                               if (!(lt->flag & LT_OUTSIDE) || uxt || vxt || wxt) {
-                                       if (bp->hide == 0) {
-                                               /* check for active BPoint and ensure selected */
-                                               if ((bp == actbp) && (bp->f1 & SELECT)) {
-                                                       UI_ThemeColor(TH_ACTIVE_VERT);
-                                                       glVertex3fv(dl ? co : bp->vec);
-                                                       UI_ThemeColor(color);
-                                               }
-                                               else if ((bp->f1 & SELECT) == sel) {
-                                                       glVertex3fv(dl ? co : bp->vec);
-                                               }
-                                       }
-                               }
-                       }
-               }
-       }
-
-       glEnd();
-}
-
-static void drawlattice__point(Lattice *lt, DispList *dl, int u, int v, int w, int actdef_wcol)
-{
-       int index = ((w * lt->pntsv + v) * lt->pntsu) + u;
-
-       if (actdef_wcol) {
-               float col[3];
-               MDeformWeight *mdw = defvert_find_index(lt->dvert + index, actdef_wcol - 1);
-
-               weight_to_rgb(col, mdw ? mdw->weight : 0.0f);
-               glColor3fv(col);
-
-       }
-
-       if (dl) {
-               glVertex3fv(&dl->verts[index * 3]);
-       }
-       else {
-               glVertex3fv(lt->def[index].vec);
-       }
-}
-
-#ifdef SEQUENCER_DAG_WORKAROUND
-static void ensure_curve_cache(Scene *scene, Object *object)
-{
-       bool need_recalc = object->curve_cache == NULL;
-       /* Render thread might have freed the curve cache if the
-        * object is not visible. If the object is also used for
-        * particles duplication, then render thread might have
-        * also created curve_cache with only bevel and path
-        * filled in.
-        *
-        * So check for curve_cache != NULL is not fully correct
-        * here, we also need to check whether display list is
-        * empty or not.
-        *
-        * The trick below tries to optimize calls to displist
-        * creation for cases curve is empty. Meaning, if the curve
-        * is empty (without splines) bevel list would also be empty.
-        * And the thing is, render thread always leaves bevel list
-        * in a proper state. So if bevel list is here and display
-        * list is not we need to make display list.
-        */
-       if (need_recalc == false) {
-               need_recalc = object->curve_cache->disp.first == NULL &&
-                             object->curve_cache->bev.first != NULL;
-       }
-       if (need_recalc) {
-               switch (object->type) {
-                       case OB_CURVE:
-                       case OB_SURF:
-                       case OB_FONT:
-                               BKE_displist_make_curveTypes(scene, object, false);
-                               break;
-                       case OB_MBALL:
-                               BKE_displist_make_mball(G.main->eval_ctx, scene, object);
-                               break;
-                       case OB_LATTICE:
-                               BKE_lattice_modifiers_calc(scene, object);
-                               break;
-               }
-       }
-}
-#endif
-
-/* lattice color is hardcoded, now also shows weightgroup values in edit mode */
-static void drawlattice(View3D *v3d, Object *ob)
-{
-       Lattice *lt = ob->data;
-       DispList *dl;
-       int u, v, w;
-       int actdef_wcol = 0;
-       const bool is_edit = (lt->editlatt != NULL);
-
-       dl = BKE_displist_find(&ob->curve_cache->disp, DL_VERTS);
-
-       if (is_edit) {
-               lt = lt->editlatt->latt;
-
-               UI_ThemeColor(TH_WIRE_EDIT);
-
-               if (ob->defbase.first && lt->dvert) {
-                       actdef_wcol = ob->actdef;
-               }
-       }
-
-       glLineWidth(1);
-       glBegin(GL_LINES);
-       for (w = 0; w < lt->pntsw; w++) {
-               int wxt = (w == 0 || w == lt->pntsw - 1);
-               for (v = 0; v < lt->pntsv; v++) {
-                       int vxt = (v == 0 || v == lt->pntsv - 1);
-                       for (u = 0; u < lt->pntsu; u++) {
-                               int uxt = (u == 0 || u == lt->pntsu - 1);
-
-                               if (w && ((uxt || vxt) || !(lt->flag & LT_OUTSIDE))) {
-                                       drawlattice__point(lt, dl, u, v, w - 1, actdef_wcol);
-                                       drawlattice__point(lt, dl, u, v, w, actdef_wcol);
-                               }
-                               if (v && ((uxt || wxt) || !(lt->flag & LT_OUTSIDE))) {
-                                       drawlattice__point(lt, dl, u, v - 1, w, actdef_wcol);
-                                       drawlattice__point(lt, dl, u, v, w, actdef_wcol);
-                               }
-                               if (u && ((vxt || wxt) || !(lt->flag & LT_OUTSIDE))) {
-                                       drawlattice__point(lt, dl, u - 1, v, w, actdef_wcol);
-                                       drawlattice__point(lt, dl, u, v, w, actdef_wcol);
-                               }
-                       }
-               }
-       }
-       glEnd();
-
-       if (is_edit) {
-               BPoint *actbp = BKE_lattice_active_point_get(lt);
-
-               if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
-
-               lattice_draw_verts(lt, dl, actbp, 0);
-               lattice_draw_verts(lt, dl, actbp, 1);
-
-               if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
-       }
-}
-
-/* ***************** ******************** */
-
-/* draw callback */
-
-typedef struct drawDMVertSel_userData {
-       MVert *mvert;
-       int active;
-       unsigned char *col[3];  /* (base, sel, act) */
-       char sel_prev;
-} drawDMVertSel_userData;
-
-static void drawSelectedVertices__mapFunc(void *userData, int index, const float co[3],
-                                          const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
-{
-       drawDMVertSel_userData *data = userData;
-       MVert *mv = &data->mvert[index];
-
-       if (!(mv->flag & ME_HIDE)) {
-               const char sel = (index == data->active) ? 2 : (mv->flag & SELECT);
-               if (sel != data->sel_prev) {
-                       glColor3ubv(data->col[sel]);
-                       data->sel_prev = sel;
-               }
-
-               glVertex3fv(co);
-       }
-}
-
-static void drawSelectedVertices(DerivedMesh *dm, Mesh *me)
-{
-       drawDMVertSel_userData data;
-
-       /* TODO define selected color */
-       unsigned char base_col[3] = {0x0, 0x0, 0x0};
-       unsigned char sel_col[3] = {0xd8, 0xb8, 0x0};
-       unsigned char act_col[3] = {0xff, 0xff, 0xff};
-
-       data.mvert = me->mvert;
-       data.active = BKE_mesh_mselect_active_get(me, ME_VSEL);
-       data.sel_prev = 0xff;
-
-       data.col[0] = base_col;
-       data.col[1] = sel_col;
-       data.col[2] = act_col;
-
-       glBegin(GL_POINTS);
-       dm->foreachMappedVert(dm, drawSelectedVertices__mapFunc, &data, DM_FOREACH_NOP);
-       glEnd();
-}
-
-/* ************** DRAW MESH ****************** */
-
-/* First section is all the "simple" draw routines,
- * ones that just pass some sort of primitive to GL,
- * with perhaps various options to control lighting,
- * color, etc.
- *
- * These routines should not have user interface related
- * logic!!!
- */
-
-static void calcDrawDMNormalScale(Object *ob, drawDMNormal_userData *data)
-{
-       float obmat[3][3];
-
-       copy_m3_m4(obmat, ob->obmat);
-
-       data->uniform_scale = is_uniform_scaled_m3(obmat);
-
-       if (!data->uniform_scale) {
-               /* inverted matrix */
-               invert_m3_m3(data->imat, obmat);
-
-               /* transposed inverted matrix */
-               transpose_m3_m3(data->tmat, data->imat);
-       }
-}
-
-static void draw_dm_face_normals__mapFunc(void *userData, int index, const float cent[3], const float no[3])
-{
-       drawDMNormal_userData *data = userData;
-       BMFace *efa = BM_face_at_index(data->bm, index);
-       float n[3];
-
-       if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
-               if (!data->uniform_scale) {
-                       mul_v3_m3v3(n, data->tmat, no);
-                       normalize_v3(n);
-                       mul_m3_v3(data->imat, n);
-               }
-               else {
-                       copy_v3_v3(n, no);
-               }
-
-               glVertex3fv(cent);
-               glVertex3f(cent[0] + n[0] * data->normalsize,
-                          cent[1] + n[1] * data->normalsize,
-                          cent[2] + n[2] * data->normalsize);
-       }
-}
-
-static void draw_dm_face_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm)
-{
-       drawDMNormal_userData data;
-
-       data.bm = em->bm;
-       data.normalsize = scene->toolsettings->normalsize;
-
-       calcDrawDMNormalScale(ob, &data);
-
-       glBegin(GL_LINES);
-       dm->foreachMappedFaceCenter(dm, draw_dm_face_normals__mapFunc, &data, DM_FOREACH_USE_NORMAL);
-       glEnd();
-}
-
-static void draw_dm_face_centers__mapFunc(void *userData, int index, const float cent[3], const float UNUSED(no[3]))
-{
-       drawBMSelect_userData *data = userData;
-       BMFace *efa = BM_face_at_index(data->bm, index);
-
-       if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) &&
-           (BM_elem_flag_test(efa, BM_ELEM_SELECT) == data->select))
-       {
-               glVertex3fv(cent);
-       }
-}
-static void draw_dm_face_centers(BMEditMesh *em, DerivedMesh *dm, bool select)
-{
-       drawBMSelect_userData data = {em->bm, select};
-
-       glBegin(GL_POINTS);
-       dm->foreachMappedFaceCenter(dm, draw_dm_face_centers__mapFunc, &data, DM_FOREACH_NOP);
-       glEnd();
-}
-
-static void draw_dm_vert_normals__mapFunc(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3])
-{
-       drawDMNormal_userData *data = userData;
-       BMVert *eve = BM_vert_at_index(data->bm, index);
-
-       if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
-               float no[3], n[3];
-
-               if (no_f) {
-                       copy_v3_v3(no, no_f);
-               }
-               else {
-                       normal_short_to_float_v3(no, no_s);
-               }
-
-               if (!data->uniform_scale) {
-                       mul_v3_m3v3(n, data->tmat, no);
-                       normalize_v3(n);
-                       mul_m3_v3(data->imat, n);
-               }
-               else {
-                       copy_v3_v3(n, no);
-               }
-
-               glVertex3fv(co);
-               glVertex3f(co[0] + n[0] * data->normalsize,
-                          co[1] + n[1] * data->normalsize,
-                          co[2] + n[2] * data->normalsize);
-       }
-}
-
-static void draw_dm_vert_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm)
-{
-       drawDMNormal_userData data;
-
-       data.bm = em->bm;
-       data.normalsize = scene->toolsettings->normalsize;
-
-       calcDrawDMNormalScale(ob, &data);
-
-       glBegin(GL_LINES);
-       dm->foreachMappedVert(dm, draw_dm_vert_normals__mapFunc, &data, DM_FOREACH_USE_NORMAL);
-       glEnd();
-}
-
-/* Draw verts with color set based on selection */
-static void draw_dm_verts__mapFunc(void *userData, int index, const float co[3],
-                                   const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
-{
-       drawDMVerts_userData *data = userData;
-       BMVert *eve = BM_vert_at_index(data->bm, index);
-
-       if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN) && BM_elem_flag_test(eve, BM_ELEM_SELECT) == data->sel) {
-               /* skin nodes: draw a red circle around the root node(s) */
-               if (data->cd_vskin_offset != -1) {
-                       const MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, data->cd_vskin_offset);
-                       if (vs->flag & MVERT_SKIN_ROOT) {
-                               float radius = (vs->radius[0] + vs->radius[1]) * 0.5f;
-                               glEnd();
-
-                               glColor4ubv(data->th_skin_root);
-                               drawcircball(GL_LINES, co, radius, data->imat);
-
-                               glColor4ubv(data->sel ? data->th_vertex_select : data->th_vertex);
-                               glBegin(GL_POINTS);
-                       }
-               }
-
-               /* draw active in a different color - no need to stop/start point drawing for this :D */
-               if (eve == data->eve_act) {
-                       glColor4ubv(data->th_editmesh_active);
-                       glVertex3fv(co);
-
-                       /* back to regular vertex color */
-                       glColor4ubv(data->sel ? data->th_vertex_select : data->th_vertex);
-               }
-               else {
-                       glVertex3fv(co);
-               }
-       }
-}
-
-static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, const char sel, BMVert *eve_act,
-                          RegionView3D *rv3d)
-{
-       drawDMVerts_userData data;
-       data.sel = sel;
-       data.eve_act = eve_act;
-       data.bm = em->bm;
-
-       /* Cache theme values */
-       UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, data.th_editmesh_active);
-       UI_GetThemeColor4ubv(TH_VERTEX_SELECT, data.th_vertex_select);
-       UI_GetThemeColor4ubv(TH_VERTEX, data.th_vertex);
-       UI_GetThemeColor4ubv(TH_SKIN_ROOT, data.th_skin_root);
-
-       /* For skin root drawing */
-       data.cd_vskin_offset = CustomData_get_offset(&em->bm->vdata, CD_MVERT_SKIN);
-       /* view-aligned matrix */
-       mul_m4_m4m4(data.imat, rv3d->viewmat, em->ob->obmat);
-       invert_m4(data.imat);
-
-       glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
-       glBegin(GL_POINTS);
-       dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data, DM_FOREACH_NOP);
-       glEnd();
-}
-
-/* Draw edges with color set based on selection */
-static DMDrawOption draw_dm_edges_sel__setDrawOptions(void *userData, int index)
-{
-       BMEdge *eed;
-       drawDMEdgesSel_userData *data = userData;
-       unsigned char *col;
-
-       eed = BM_edge_at_index(data->bm, index);
-
-       if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
-               if (eed == data->eed_act) {
-                       glColor4ubv(data->actCol);
-               }
-               else {
-                       if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
-                               col = data->selCol;
-                       }
-                       else {
-                               col = data->baseCol;
-                       }
-                       /* no alpha, this is used so a transparent color can disable drawing unselected edges in editmode */
-                       if (col[3] == 0)
-                               return DM_DRAW_OPTION_SKIP;
-
-                       glColor4ubv(col);
-               }
-               return DM_DRAW_OPTION_NORMAL;
-       }
-       else {
-               return DM_DRAW_OPTION_SKIP;
-       }
-}
-
-static void draw_dm_edges_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol,
-                              unsigned char *selCol, unsigned char *actCol, BMEdge *eed_act)
-{
-       drawDMEdgesSel_userData data;
-
-       data.baseCol = baseCol;
-       data.selCol = selCol;
-       data.actCol = actCol;
-       data.bm = em->bm;
-       data.eed_act = eed_act;
-       dm->drawMappedEdges(dm, draw_dm_edges_sel__setDrawOptions, &data);
-}
-
-/* Draw edges */
-static DMDrawOption draw_dm_edges__setDrawOptions(void *userData, int index)
-{
-       if (BM_elem_flag_test(BM_edge_at_index(userData, index), BM_ELEM_HIDDEN))
-               return DM_DRAW_OPTION_SKIP;
-       else
-               return DM_DRAW_OPTION_NORMAL;
-}
-
-static void draw_dm_edges(BMEditMesh *em, DerivedMesh *dm)
-{
-       dm->drawMappedEdges(dm, draw_dm_edges__setDrawOptions, em->bm);
-}
-
-/* Draw edges with color interpolated based on selection */
-static DMDrawOption draw_dm_edges_sel_interp__setDrawOptions(void *userData, int index)
-{
-       drawDMEdgesSelInterp_userData *data = userData;
-       if (BM_elem_flag_test(BM_edge_at_index(data->bm, index), BM_ELEM_HIDDEN))
-               return DM_DRAW_OPTION_SKIP;
-       else
-               return DM_DRAW_OPTION_NORMAL;
-}
-static void draw_dm_edges_sel_interp__setDrawInterpOptions(void *userData, int index, float t)
-{
-       drawDMEdgesSelInterp_userData *data = userData;
-       BMEdge *eed = BM_edge_at_index(data->bm, index);
-       unsigned char **cols = userData;
-       unsigned int col0_id = (BM_elem_flag_test(eed->v1, BM_ELEM_SELECT)) ? 2 : 1;
-       unsigned int col1_id = (BM_elem_flag_test(eed->v2, BM_ELEM_SELECT)) ? 2 : 1;
-       unsigned char *col0 = cols[col0_id];
-       unsigned char *col1 = cols[col1_id];
-       unsigned char *col_pt;
-
-       if (col0_id == col1_id) {
-               col_pt = col0;
-       }
-       else if (t == 0.0f) {
-               col_pt = col0;
-       }
-       else if (t == 1.0f) {
-               col_pt = col1;
-       }
-       else {
-               unsigned char  col_blend[4];
-               interp_v4_v4v4_uchar(col_blend, col0, col1, t);
-               glColor4ubv(col_blend);
-               data->lastCol = NULL;
-               return;
-       }
-
-       if (data->lastCol != col_pt) {
-               data->lastCol = col_pt;
-               glColor4ubv(col_pt);
-       }
-}
-
-static void draw_dm_edges_sel_interp(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol)
-{
-       drawDMEdgesSelInterp_userData data;
-       data.bm = em->bm;
-       data.baseCol = baseCol;
-       data.selCol = selCol;
-       data.lastCol = NULL;
-
-       dm->drawMappedEdgesInterp(dm, draw_dm_edges_sel_interp__setDrawOptions, draw_dm_edges_sel_interp__setDrawInterpOptions, &data);
-}
-
-static void bm_color_from_weight(float col[3], BMVert *vert, drawDMEdgesWeightInterp_userData *data)
-{
-       MDeformVert *dvert = BM_ELEM_CD_GET_VOID_P(vert, data->cd_dvert_offset);
-       float weight = defvert_find_weight(dvert, data->vgroup_index);
-
-       if ((weight == 0.0f) &&
-           ((data->weight_user == OB_DRAW_GROUPUSER_ACTIVE) ||
-            ((data->weight_user == OB_DRAW_GROUPUSER_ALL) && defvert_is_weight_zero(dvert, data->defgroup_tot))))
-       {
-               copy_v3_v3(col, data->alert_color);
-       }
-       else {
-               weight_to_rgb(col, weight);
-       }
-}
-
-static void draw_dm_edges_nop_interp__setDrawInterpOptions(void *UNUSED(userData), int UNUSED(index), float UNUSED(t))
-{
-       /* pass */
-}
-
-static void draw_dm_edges_weight_interp__setDrawInterpOptions(void *userData, int index, float t)
-{
-       drawDMEdgesWeightInterp_userData *data = userData;
-       BMEdge *eed = BM_edge_at_index(data->bm, index);
-       float col[3];
-
-       if (t == 0.0f) {
-               bm_color_from_weight(col, eed->v1, data);
-       }
-       else if (t == 1.0f) {
-               bm_color_from_weight(col, eed->v2, data);
-       }
-       else {
-               float col_v1[3];
-               float col_v2[3];
-
-               bm_color_from_weight(col_v1, eed->v1, data);
-               bm_color_from_weight(col_v2, eed->v2, data);
-               interp_v3_v3v3(col, col_v1, col_v2, t);
-       }
-
-       glColor3fv(col);
-}
-
-static void draw_dm_edges_weight_interp(BMEditMesh *em, DerivedMesh *dm, const char weight_user)
-{
-       drawDMEdgesWeightInterp_userData data;
-       Object *ob = em->ob;
-
-       data.bm = em->bm;
-       data.cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
-       data.defgroup_tot = BLI_listbase_count(&ob->defbase);
-       data.vgroup_index = ob->actdef - 1;
-       data.weight_user = weight_user;
-       UI_GetThemeColor3fv(TH_VERTEX_UNREFERENCED, data.alert_color);
-
-       if ((data.vgroup_index != -1) && (data.cd_dvert_offset != -1)) {
-               glEnable(GL_BLEND);
-               dm->drawMappedEdgesInterp(
-                       dm,
-                       draw_dm_edges_sel_interp__setDrawOptions,
-                       draw_dm_edges_weight_interp__setDrawInterpOptions,
-                       &data);
-               glDisable(GL_BLEND);
-       }
-       else {
-               float col[3];
-
-               if (data.weight_user == OB_DRAW_GROUPUSER_NONE) {
-                       weight_to_rgb(col, 0.0f);
-               }
-               else {
-                       copy_v3_v3(col, data.alert_color);
-               }
-               glColor3fv(col);
-
-               dm->drawMappedEdgesInterp(
-                       dm,
-                       draw_dm_edges_sel_interp__setDrawOptions,
-                       draw_dm_edges_nop_interp__setDrawInterpOptions,
-                       &data);
-       }
-
-}
-
-static bool draw_dm_edges_weight_check(Mesh *me, View3D *v3d)
-{
-       if (me->drawflag & ME_DRAWEIGHT) {
-               if ((v3d->drawtype == OB_WIRE) ||
-                   (v3d->flag2 & V3D_SOLID_MATCAP) ||
-                   ((v3d->flag2 & V3D_OCCLUDE_WIRE) && (v3d->drawtype > OB_WIRE)))
-               {
-                       return true;
-               }
-       }
-
-       return false;
-}
-
-/* Draw only seam edges */
-static DMDrawOption draw_dm_edges_seams__setDrawOptions(void *userData, int index)
-{
-       BMEdge *eed = BM_edge_at_index(userData, index);
-
-       if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && BM_elem_flag_test(eed, BM_ELEM_SEAM))
-               return DM_DRAW_OPTION_NORMAL;
-       else
-               return DM_DRAW_OPTION_SKIP;
-}
-
-static void draw_dm_edges_seams(BMEditMesh *em, DerivedMesh *dm)
-{
-       dm->drawMappedEdges(dm, draw_dm_edges_seams__setDrawOptions, em->bm);
-}
-
-/* Draw only sharp edges */
-static DMDrawOption draw_dm_edges_sharp__setDrawOptions(void *userData, int index)
-{
-       BMEdge *eed = BM_edge_at_index(userData, index);
-
-       if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && !BM_elem_flag_test(eed, BM_ELEM_SMOOTH))
-               return DM_DRAW_OPTION_NORMAL;
-       else
-               return DM_DRAW_OPTION_SKIP;
-}
-
-static void draw_dm_edges_sharp(BMEditMesh *em, DerivedMesh *dm)
-{
-       dm->drawMappedEdges(dm, draw_dm_edges_sharp__setDrawOptions, em->bm);
-}
-
-#ifdef WITH_FREESTYLE
-
-static bool draw_dm_test_freestyle_edge_mark(BMesh *bm, BMEdge *eed)
-{
-       FreestyleEdge *fed = CustomData_bmesh_get(&bm->edata, eed->head.data, CD_FREESTYLE_EDGE);
-       if (!fed)
-               return false;
-       return (fed->flag & FREESTYLE_EDGE_MARK) != 0;
-}
-
-/* Draw only Freestyle feature edges */
-static DMDrawOption draw_dm_edges_freestyle__setDrawOptions(void *userData, int index)
-{
-       BMEdge *eed = BM_edge_at_index(userData, index);
-
-       if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && draw_dm_test_freestyle_edge_mark(userData, eed))
-               return DM_DRAW_OPTION_NORMAL;
-       else
-               return DM_DRAW_OPTION_SKIP;
-}
-
-static void draw_dm_edges_freestyle(BMEditMesh *em, DerivedMesh *dm)
-{
-       dm->drawMappedEdges(dm, draw_dm_edges_freestyle__setDrawOptions, em->bm);
-}
-
-static bool draw_dm_test_freestyle_face_mark(BMesh *bm, BMFace *efa)
-{
-       FreestyleFace *ffa = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_FREESTYLE_FACE);
-       if (!ffa)
-               return false;
-       return (ffa->flag & FREESTYLE_FACE_MARK) != 0;
-}
-
-#endif
-
-/* Draw loop normals. */
-static void draw_dm_loop_normals__mapFunc(void *userData, int vertex_index, int face_index,
-                                          const float co[3], const float no[3])
-{
-       if (no) {
-               const drawDMNormal_userData *data = userData;
-               const BMVert *eve = BM_vert_at_index(data->bm, vertex_index);
-               const BMFace *efa = BM_face_at_index(data->bm, face_index);
-               float vec[3];
-
-               if (!(BM_elem_flag_test(eve, BM_ELEM_HIDDEN) || BM_elem_flag_test(efa, BM_ELEM_HIDDEN))) {
-                       if (!data->uniform_scale) {
-                               mul_v3_m3v3(vec, (float(*)[3])data->tmat, no);
-                               normalize_v3(vec);
-                               mul_m3_v3((float(*)[3])data->imat, vec);
-                       }
-                       else {
-                               copy_v3_v3(vec, no);
-                       }
-                       mul_v3_fl(vec, data->normalsize);
-                       add_v3_v3(vec, co);
-                       glVertex3fv(co);
-                       glVertex3fv(vec);
-               }
-       }
-}
-
-static void draw_dm_loop_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm)
-{
-       drawDMNormal_userData data;
-
-       data.bm = em->bm;
-       data.normalsize = scene->toolsettings->normalsize;
-
-       calcDrawDMNormalScale(ob, &data);
-
-       glBegin(GL_LINES);
-       dm->foreachMappedLoop(dm, draw_dm_loop_normals__mapFunc, &data, DM_FOREACH_USE_NORMAL);
-       glEnd();
-}
-
-/* Draw faces with color set based on selection
- * return 2 for the active face so it renders with stipple enabled */
-static DMDrawOption draw_dm_faces_sel__setDrawOptions(void *userData, int index)
-{
-       drawDMFacesSel_userData *data = userData;
-       BMFace *efa = BM_face_at_index(data->bm, index);
-       unsigned char *col;
-
-       if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
-               if (efa == data->efa_act) {
-                       glColor4ubv(data->cols[2]);
-                       return DM_DRAW_OPTION_STIPPLE;
-               }
-               else {
-#ifdef WITH_FREESTYLE
-                       col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : draw_dm_test_freestyle_face_mark(data->bm, efa) ? 3 : 0];
-#else
-                       col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : 0];
-#endif
-                       if (col[3] == 0)
-                               return DM_DRAW_OPTION_SKIP;
-                       glColor4ubv(col);
-                       return DM_DRAW_OPTION_NORMAL;
-               }
-       }
-       return DM_DRAW_OPTION_SKIP;
-}
-
-static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int next_index)
-{
-
-       drawDMFacesSel_userData *data = userData;
-       int i;
-       BMFace *efa;
-       BMFace *next_efa;
-
-       unsigned char *col, *next_col;
-
-       i = data->orig_index_mp_to_orig ? data->orig_index_mp_to_orig[index] : index;
-       efa = (i != ORIGINDEX_NONE) ? BM_face_at_index(data->bm, i) : NULL;
-       i = data->orig_index_mp_to_orig ? data->orig_index_mp_to_orig[next_index] : next_index;
-       next_efa = (i != ORIGINDEX_NONE) ? BM_face_at_index(data->bm, i) : NULL;
-
-       if (ELEM(NULL, efa, next_efa))
-               return 0;
-
-       if (efa == next_efa)
-               return 1;
-
-       if (efa == data->efa_act || next_efa == data->efa_act)
-               return 0;
-
-#ifdef WITH_FREESTYLE
-       col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : draw_dm_test_freestyle_face_mark(data->bm, efa) ? 3 : 0];
-       next_col = data->cols[BM_elem_flag_test(next_efa, BM_ELEM_SELECT) ? 1 : draw_dm_test_freestyle_face_mark(data->bm, efa) ? 3 : 0];
-#else
-       col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : 0];
-       next_col = data->cols[BM_elem_flag_test(next_efa, BM_ELEM_SELECT) ? 1 : 0];
-#endif
-
-       if (col[3] == 0 || next_col[3] == 0)
-               return 0;
-
-       return col == next_col;
-}
-
-/* also draws the active face */
-#ifdef WITH_FREESTYLE
-static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol,
-                              unsigned char *selCol, unsigned char *actCol, unsigned char *markCol, BMFace *efa_act)
-#else
-static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol,
-                              unsigned char *selCol, unsigned char *actCol, BMFace *efa_act)
-#endif
-{
-       drawDMFacesSel_userData data;
-       data.dm = dm;
-       data.cols[0] = baseCol;
-       data.bm = em->bm;
-       data.cols[1] = selCol;
-       data.cols[2] = actCol;
-#ifdef WITH_FREESTYLE
-       data.cols[3] = markCol;
-#endif
-       data.efa_act = efa_act;
-       /* double lookup */
-       data.orig_index_mp_to_orig  = DM_get_poly_data_layer(dm, CD_ORIGINDEX);
-
-       dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, NULL, draw_dm_faces_sel__compareDrawOptions, &data, DM_DRAW_SKIP_HIDDEN);
-}
-
-static DMDrawOption draw_dm_creases__setDrawOptions(void *userData, int index)
-{
-       drawDMLayer_userData *data = userData;
-       BMesh *bm = data->bm;
-       BMEdge *eed = BM_edge_at_index(bm, index);
-
-       if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
-               const float crease = BM_ELEM_CD_GET_FLOAT(eed, data->cd_layer_offset);
-               if (crease != 0.0f) {
-                       UI_ThemeColorBlend(TH_WIRE_EDIT, TH_EDGE_CREASE, crease);
-                       return DM_DRAW_OPTION_NORMAL;
-               }
-       }
-       return DM_DRAW_OPTION_SKIP;
-}
-static void draw_dm_creases(BMEditMesh *em, DerivedMesh *dm)
-{
-       drawDMLayer_userData data;
-
-       data.bm = em->bm;
-       data.cd_layer_offset = CustomData_get_offset(&em->bm->edata, CD_CREASE);
-
-       if (data.cd_layer_offset != -1) {
-               glLineWidth(3.0);
-               dm->drawMappedEdges(dm, draw_dm_creases__setDrawOptions, &data);
-       }
-}
-
-static DMDrawOption draw_dm_bweights__setDrawOptions(void *userData, int index)
-{
-       drawDMLayer_userData *data = userData;
-       BMesh *bm = data->bm;
-       BMEdge *eed = BM_edge_at_index(bm, index);
-
-       if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
-               const float bweight = BM_ELEM_CD_GET_FLOAT(eed, data->cd_layer_offset);
-               if (bweight != 0.0f) {
-                       UI_ThemeColorBlend(TH_WIRE_EDIT, TH_EDGE_BEVEL, bweight);
-                       return DM_DRAW_OPTION_NORMAL;
-               }
-       }
-       return DM_DRAW_OPTION_SKIP;
-}
-static void draw_dm_bweights__mapFunc(void *userData, int index, const float co[3],
-                                      const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
-{
-       drawDMLayer_userData *data = userData;
-       BMesh *bm = data->bm;
-       BMVert *eve = BM_vert_at_index(bm, index);
-
-       if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
-               const float bweight = BM_ELEM_CD_GET_FLOAT(eve, data->cd_layer_offset);
-               if (bweight != 0.0f) {
-                       UI_ThemeColorBlend(TH_VERTEX, TH_VERTEX_BEVEL, bweight);
-                       glVertex3fv(co);
-               }
-       }
-}
-static void draw_dm_bweights(BMEditMesh *em, Scene *scene, DerivedMesh *dm)
-{
-       ToolSettings *ts = scene->toolsettings;
-
-       if (ts->selectmode & SCE_SELECT_VERTEX) {
-               drawDMLayer_userData data;
-
-               data.bm = em->bm;
-               data.cd_layer_offset = CustomData_get_offset(&em->bm->vdata, CD_BWEIGHT);
-
-               if (data.cd_layer_offset != -1) {
-                       glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE) + 2);
-                       glBegin(GL_POINTS);
-                       dm->foreachMappedVert(dm, draw_dm_bweights__mapFunc, &data, DM_FOREACH_NOP);
-                       glEnd();
-               }
-       }
-       else {
-               drawDMLayer_userData data;
-
-               data.bm = em->bm;
-               data.cd_layer_offset = CustomData_get_offset(&em->bm->edata, CD_BWEIGHT);
-
-               if (data.cd_layer_offset != -1) {
-                       glLineWidth(3.0);
-                       dm->drawMappedEdges(dm, draw_dm_bweights__setDrawOptions, &data);
-               }
-       }
-}
-
-/* Second section of routines: Combine first sets to form fancy
- * drawing routines (for example rendering twice to get overlays).
- *
- * Also includes routines that are basic drawing but are too
- * specialized to be split out (like drawing creases or measurements).
- */
-
-/* EditMesh drawing routines */
-
-static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit,
-                                BMEditMesh *em, DerivedMesh *cageDM, BMVert *eve_act,
-                                RegionView3D *rv3d)
-{
-       ToolSettings *ts = scene->toolsettings;
-
-       if (v3d->zbuf) glDepthMask(0);  /* disable write in zbuffer, zbuf select */
-
-       for (int sel = 0; sel < 2; sel++) {
-               unsigned char col[4], fcol[4];
-
-               UI_GetThemeColor3ubv(sel ? TH_VERTEX_SELECT : TH_VERTEX, col);
-               UI_GetThemeColor3ubv(sel ? TH_FACE_DOT : TH_WIRE_EDIT, fcol);
-
-               for (int pass = 0; pass < 2; pass++) {
-                       float size = UI_GetThemeValuef(TH_VERTEX_SIZE);
-                       float fsize = UI_GetThemeValuef(TH_FACEDOT_SIZE);
-
-                       if (pass == 0) {
-                               if (v3d->zbuf && !(v3d->flag & V3D_ZBUF_SELECT)) {
-                                       glDisable(GL_DEPTH_TEST);
-                                       glEnable(GL_BLEND);
-                               }
-                               else {
-                                       continue;
-                               }
-
-                               size = (size > 2.1f ? size / 2.0f : size);
-                               fsize = (fsize > 2.1f ? fsize / 2.0f : fsize);
-                               col[3] = fcol[3] = 100;
-                       }
-                       else {
-                               col[3] = fcol[3] = 255;
-                       }
-
-                       if (ts->selectmode & SCE_SELECT_VERTEX) {
-                               glPointSize(size);
-                               glColor4ubv(col);
-                               draw_dm_verts(em, cageDM, sel, eve_act, rv3d);
-                       }
-
-                       if (check_ob_drawface_dot(scene, v3d, obedit->dt)) {
-                               glPointSize(fsize);
-                               glColor4ubv(fcol);
-                               draw_dm_face_centers(em, cageDM, sel);
-                       }
-
-                       if (pass == 0) {
-                               glDisable(GL_BLEND);
-                               glEnable(GL_DEPTH_TEST);
-                       }
-               }
-       }
-
-       if (v3d->zbuf) glDepthMask(1);
-}
-
-static void draw_em_fancy_edges(BMEditMesh *em, Scene *scene, View3D *v3d,
-                                Mesh *me, DerivedMesh *cageDM, short sel_only,
-                                BMEdge *eed_act)
-{
-       ToolSettings *ts = scene->toolsettings;
-       unsigned char wireCol[4], selCol[4], actCol[4];
-
-       /* since this function does transparent... */
-       UI_GetThemeColor4ubv(TH_EDGE_SELECT, selCol);
-       UI_GetThemeColor4ubv(TH_WIRE_EDIT, wireCol);
-       UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, actCol);
-
-       /* when sel only is used, don't render wire, only selected, this is used for
-        * textured draw mode when the 'edges' option is disabled */
-       if (sel_only)
-               wireCol[3] = 0;
-
-       for (int pass = 0; pass < 2; pass++) {
-               /* show wires in transparent when no zbuf clipping for select */
-               if (pass == 0) {
-                       if (v3d->zbuf && (v3d->flag & V3D_ZBUF_SELECT) == 0) {
-                               glEnable(GL_BLEND);
-                               glDisable(GL_DEPTH_TEST);
-                               selCol[3] = 85;
-                               if (!sel_only) wireCol[3] = 85;
-                       }
-                       else {
-                               continue;
-                       }
-               }
-               else {
-                       selCol[3] = 255;
-                       if (!sel_only) wireCol[3] = 255;
-               }
-
-               if ((me->drawflag & ME_DRAWEDGES) || (ts->selectmode & SCE_SELECT_EDGE)) {
-                       if (cageDM->drawMappedEdgesInterp &&
-                           ((ts->selectmode & SCE_SELECT_VERTEX) || (me->drawflag & ME_DRAWEIGHT)))
-                       {
-                               if (draw_dm_edges_weight_check(me, v3d)) {
-                                       // Interpolate vertex weights
-                                       draw_dm_edges_weight_interp(em, cageDM, ts->weightuser);
-                               }
-                               else if (ts->selectmode == SCE_SELECT_FACE) {
-                                       draw_dm_edges_sel(em, cageDM, wireCol, selCol, actCol, eed_act);
-                               }
-                               else {
-                                       // Interpolate vertex selection
-                                       draw_dm_edges_sel_interp(em, cageDM, wireCol, selCol);
-                               }
-                       }
-                       else {
-                               draw_dm_edges_sel(em, cageDM, wireCol, selCol, actCol, eed_act);
-                       }
-               }
-               else {
-                       if (!sel_only) {
-                               glColor4ubv(wireCol);
-                               draw_dm_edges(em, cageDM);
-                       }
-               }
-
-               if (pass == 0) {
-                       glDisable(GL_BLEND);
-                       glEnable(GL_DEPTH_TEST);
-               }
-       }
-}
-
-static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMesh *em, UnitSettings *unit)
-{
-       /* Do not use ascii when using non-default unit system, some unit chars are utf8 (micro, square, etc.).
-        * See bug #36090.
-        */
-       const short txt_flag = V3D_CACHE_TEXT_LOCALCLIP | (unit->system ? 0 : V3D_CACHE_TEXT_ASCII);
-       Mesh *me = ob->data;
-       float v1[3], v2[3], v3[3], vmid[3], fvec[3];
-       char numstr[32]; /* Stores the measurement display text here */
-       size_t numstr_len;
-       const char *conv_float; /* Use a float conversion matching the grid size */
-       unsigned char col[4] = {0, 0, 0, 255}; /* color of the text to draw */
-       float area; /* area of the face */
-       float grid = unit->system ? unit->scale_length : v3d->grid;
-       const bool do_split = (unit->flag & USER_UNIT_OPT_SPLIT) != 0;
-       const bool do_global = (v3d->flag & V3D_GLOBAL_STATS) != 0;
-       const bool do_moving = (G.moving & G_TRANSFORM_EDIT) != 0;
-       /* when 2 edge-info options are enabled, space apart */
-       const bool do_edge_textpair = (me->drawflag & ME_DRAWEXTRA_EDGELEN) && (me->drawflag & ME_DRAWEXTRA_EDGEANG);
-       const float edge_texpair_sep = 0.4f;
-       float clip_planes[4][4];
-       /* allow for displaying shape keys and deform mods */
-       DerivedMesh *dm = EDBM_mesh_deform_dm_get(em);
-       BMIter iter;
-
-       /* make the precision of the display value proportionate to the gridsize */
-
-       if (grid <= 0.01f) conv_float = "%.6g";
-       else if (grid <= 0.1f) conv_float = "%.5g";
-       else if (grid <= 1.0f) conv_float = "%.4g";
-       else if (grid <= 10.0f) conv_float = "%.3g";
-       else conv_float = "%.2g";
-
-       if (me->drawflag & (ME_DRAWEXTRA_EDGELEN | ME_DRAWEXTRA_EDGEANG)) {
-               BoundBox bb;
-               bglMats mats = {{0}};
-               const rcti rect = {0, ar->winx, 0, ar->winy};
-
-               view3d_get_transformation(ar, ar->regiondata, em->ob, &mats);
-               ED_view3d_clipping_calc(&bb, clip_planes, &mats, &rect);
-       }
-
-       if (me->drawflag & ME_DRAWEXTRA_EDGELEN) {
-               BMEdge *eed;
-
-               UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGELEN, col);
-
-               if (dm) {
-                       BM_mesh_elem_index_ensure(em->bm, BM_VERT);
-               }
-
-               BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
-                       /* draw selected edges, or edges next to selected verts while dragging */
-                       if (BM_elem_flag_test(eed, BM_ELEM_SELECT) ||
-                           (do_moving && (BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) ||
-                                          BM_elem_flag_test(eed->v2, BM_ELEM_SELECT))))
-                       {
-                               float v1_clip[3], v2_clip[3];
-
-                               if (dm) {
-                                       dm->getVertCo(dm, BM_elem_index_get(eed->v1), v1);
-                                       dm->getVertCo(dm, BM_elem_index_get(eed->v2), v2);
-                               }
-                               else {
-                                       copy_v3_v3(v1, eed->v1->co);
-                                       copy_v3_v3(v2, eed->v2->co);
-                               }
-
-                               if (clip_segment_v3_plane_n(v1, v2, clip_planes, 4, v1_clip, v2_clip)) {
-
-                                       if (do_edge_textpair) {
-                                               interp_v3_v3v3(vmid, v1, v2, edge_texpair_sep);
-                                       }
-                                       else {
-                                               mid_v3_v3v3(vmid, v1_clip, v2_clip);
-                                       }
-
-                                       if (do_global) {
-                                               mul_mat3_m4_v3(ob->obmat, v1);
-                                               mul_mat3_m4_v3(ob->obmat, v2);
-                                       }
-
-                                       if (unit->system) {
-                                               numstr_len = bUnit_AsString(numstr, sizeof(numstr), len_v3v3(v1, v2) * unit->scale_length, 3,
-                                                                           unit->system, B_UNIT_LENGTH, do_split, false);
-                                       }
-                                       else {
-                                               numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), conv_float, len_v3v3(v1, v2));
-                                       }
-
-                                       view3d_cached_text_draw_add(vmid, numstr, numstr_len, 0, txt_flag, col);
-                               }
-                       }
-               }
-       }
-
-       if (me->drawflag & ME_DRAWEXTRA_EDGEANG) {
-               const bool is_rad = (unit->system_rotation == USER_UNIT_ROT_RADIANS);
-               BMEdge *eed;
-
-               UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGEANG, col);
-
-               if (dm) {
-                       BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE);
-               }
-
-               BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
-                       BMLoop *l_a, *l_b;
-                       if (BM_edge_loop_pair(eed, &l_a, &l_b)) {
-                               /* draw selected edges, or edges next to selected verts while dragging */
-                               if (BM_elem_flag_test(eed, BM_ELEM_SELECT) ||
-                                   (do_moving && (BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) ||
-                                                  BM_elem_flag_test(eed->v2, BM_ELEM_SELECT) ||
-                                                  /* special case, this is useful to show when verts connected to
-                                                   * this edge via a face are being transformed */
-                                                  BM_elem_flag_test(l_a->next->next->v, BM_ELEM_SELECT) ||
-                                                  BM_elem_flag_test(l_a->prev->v, BM_ELEM_SELECT)       ||
-                                                  BM_elem_flag_test(l_b->next->next->v, BM_ELEM_SELECT) ||
-                                                  BM_elem_flag_test(l_b->prev->v, BM_ELEM_SELECT)
-                                                  )))
-                               {
-                                       float v1_clip[3], v2_clip[3];
-
-                                       if (dm) {
-                                               dm->getVertCo(dm, BM_elem_index_get(eed->v1), v1);
-                                               dm->getVertCo(dm, BM_elem_index_get(eed->v2), v2);
-                                       }
-                                       else {
-                                               copy_v3_v3(v1, eed->v1->co);
-                                               copy_v3_v3(v2, eed->v2->co);
-                                       }
-
-                                       if (clip_segment_v3_plane_n(v1, v2, clip_planes, 4, v1_clip, v2_clip)) {
-                                               float no_a[3], no_b[3];
-                                               float angle;
-
-                                               if (do_edge_textpair) {
-                                                       interp_v3_v3v3(vmid, v2_clip, v1_clip, edge_texpair_sep);
-                                               }
-                                               else {
-                                                       mid_v3_v3v3(vmid, v1_clip, v2_clip);
-                                               }
-
-                                               if (dm) {
-                                                       dm->getPolyNo(dm, BM_elem_index_get(l_a->f), no_a);
-                                                       dm->getPolyNo(dm, BM_elem_index_get(l_b->f), no_b);
-                                               }
-                                               else {
-                                                       copy_v3_v3(no_a, l_a->f->no);
-                                                       copy_v3_v3(no_b, l_b->f->no);
-                                               }
-
-                                               if (do_global) {
-                                                       mul_mat3_m4_v3(ob->imat, no_a);
-                                                       mul_mat3_m4_v3(ob->imat, no_b);
-                                                       normalize_v3(no_a);
-                                                       normalize_v3(no_b);
-                                               }
-
-                                               angle = angle_normalized_v3v3(no_a, no_b);
-
-                                               numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle));
-
-                                               view3d_cached_text_draw_add(vmid, numstr, numstr_len, 0, txt_flag, col);
-                                       }
-                               }
-                       }
-               }
-       }
-
-       if (me->drawflag & ME_DRAWEXTRA_FACEAREA) {
-               /* would be nice to use BM_face_calc_area, but that is for 2d faces
-                * so instead add up tessellation triangle areas */
-               BMFace *f = NULL;
-
-#define DRAW_EM_MEASURE_STATS_FACEAREA()                                                 \
-       if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {                                          \
-               mul_v3_fl(vmid, 1.0f / (float)n);                                                \
-               if (unit->system) {                                                              \
-                       numstr_len = bUnit_AsString(                                                 \
-                               numstr, sizeof(numstr),                                              \
-                               (double)(area * unit->scale_length * unit->scale_length),            \
-                               3, unit->system, B_UNIT_AREA, do_split, false);                      \
-               }                                                                                \
-               else {                                                                           \
-                       numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), conv_float, area);    \
-               }                                                                                \
-               view3d_cached_text_draw_add(vmid, numstr, numstr_len, 0, txt_flag, col);         \
-       } (void)0
-
-               UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEAREA, col);
-
-               if (dm) {
-                       BM_mesh_elem_index_ensure(em->bm, BM_VERT);
-               }
-
-               area = 0.0;
-               zero_v3(vmid);
-               int n = 0;
-               for (int i = 0; i < em->tottri; i++) {
-                       BMLoop **l = em->looptris[i];
-                       if (f && l[0]->f != f) {
-                               DRAW_EM_MEASURE_STATS_FACEAREA();
-                               zero_v3(vmid);
-                               area = 0.0;
-                               n = 0;
-                       }
-
-                       f = l[0]->f;
-
-                       if (dm) {
-                               dm->getVertCo(dm, BM_elem_index_get(l[0]->v), v1);
-                               dm->getVertCo(dm, BM_elem_index_get(l[1]->v), v2);
-                               dm->getVertCo(dm, BM_elem_index_get(l[2]->v), v3);
-                       }
-                       else {
-                               copy_v3_v3(v1, l[0]->v->co);
-                               copy_v3_v3(v2, l[1]->v->co);
-                               copy_v3_v3(v3, l[2]->v->co);
-                       }
-
-                       add_v3_v3(vmid, v1);
-                       add_v3_v3(vmid, v2);
-                       add_v3_v3(vmid, v3);
-                       n += 3;
-                       if (do_global) {
-                               mul_mat3_m4_v3(ob->obmat, v1);
-                               mul_mat3_m4_v3(ob->obmat, v2);
-                               mul_mat3_m4_v3(ob->obmat, v3);
-                       }
-                       area += area_tri_v3(v1, v2, v3);
-               }
-
-               if (f) {
-                       DRAW_EM_MEASURE_STATS_FACEAREA();
-               }
-#undef DRAW_EM_MEASURE_STATS_FACEAREA
-       }
-
-       if (me->drawflag & ME_DRAWEXTRA_FACEANG) {
-               BMFace *efa;
-               const bool is_rad = (unit->system_rotation == USER_UNIT_ROT_RADIANS);
-
-               UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEANG, col);
-
-               if (dm) {
-                       BM_mesh_elem_index_ensure(em->bm, BM_VERT);
-               }
-
-               BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-                       const bool is_face_sel = BM_elem_flag_test_bool(efa, BM_ELEM_SELECT);
-
-                       if (is_face_sel || do_moving) {
-                               BMIter liter;
-                               BMLoop *loop;
-                               bool is_first = true;
-
-                               BM_ITER_ELEM (loop, &liter, efa, BM_LOOPS_OF_FACE) {
-                                       if (is_face_sel ||
-                                           (do_moving &&
-                                            (BM_elem_flag_test(loop->v, BM_ELEM_SELECT) ||
-                                             BM_elem_flag_test(loop->prev->v, BM_ELEM_SELECT) ||
-                                             BM_elem_flag_test(loop->next->v, BM_ELEM_SELECT))))
-                                       {
-                                               float v2_local[3];
-
-                                               /* lazy init center calc */
-                                               if (is_first) {
-                                                       if (dm) {
-                                                               BMLoop *l_iter, *l_first;
-                                                               float tvec[3];
-                                                               zero_v3(vmid);
-                                                               l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
-                                                               do {
-                                                                       dm->getVertCo(dm, BM_elem_index_get(l_iter->v), tvec);
-                                                                       add_v3_v3(vmid, tvec);
-                                                               } while ((l_iter = l_iter->next) != l_first);
-                                                               mul_v3_fl(vmid, 1.0f / (float)efa->len);
-                                                       }
-                                                       else {
-                                                               BM_face_calc_center_bounds(efa, vmid);
-                                                       }
-                                                       is_first = false;
-                                               }
-
-                                               if (dm) {
-                                                       dm->getVertCo(dm, BM_elem_index_get(loop->prev->v), v1);
-                                                       dm->getVertCo(dm, BM_elem_index_get(loop->v),       v2);
-                                                       dm->getVertCo(dm, BM_elem_index_get(loop->next->v), v3);
-                                               }
-                                               else {
-                                                       copy_v3_v3(v1, loop->prev->v->co);
-                                                       copy_v3_v3(v2, loop->v->co);
-                                                       copy_v3_v3(v3, loop->next->v->co);
-                                               }
-
-                                               copy_v3_v3(v2_local, v2);
-
-                                               if (do_global) {
-                                                       mul_mat3_m4_v3(ob->obmat, v1);
-                                                       mul_mat3_m4_v3(ob->obmat, v2);
-                                                       mul_mat3_m4_v3(ob->obmat, v3);
-                                               }
-
-                                               float angle = angle_v3v3v3(v1, v2, v3);
-
-                                               numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle));
-                                               interp_v3_v3v3(fvec, vmid, v2_local, 0.8f);
-                                               view3d_cached_text_draw_add(fvec, numstr, numstr_len, 0, txt_flag, col);
-                                       }
-                               }
-                       }
-               }
-       }
-}
-
-static void draw_em_indices(BMEditMesh *em)
-{
-       const short txt_flag = V3D_CACHE_TEXT_ASCII | V3D_CACHE_TEXT_LOCALCLIP;
-       BMEdge *e;
-       BMFace *f;
-       BMVert *v;
-       char numstr[32];
-       size_t numstr_len;
-       float pos[3];
-       unsigned char col[4];
-
-       BMIter iter;
-       BMesh *bm = em->bm;
-
-       /* For now, reuse appropriate theme colors from stats text colors */
-       int i = 0;
-       if (em->selectmode & SCE_SELECT_VERTEX) {
-               UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEANG, col);
-               BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
-                       if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
-                               numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", i);
-                               view3d_cached_text_draw_add(v->co, numstr, numstr_len, 0, txt_flag, col);
-                       }
-                       i++;
-               }
-       }
-
-       if (em->selectmode & SCE_SELECT_EDGE) {
-               i = 0;
-               UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGELEN, col);
-               BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
-                       if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
-                               numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", i);
-                               mid_v3_v3v3(pos, e->v1->co, e->v2->co);
-                               view3d_cached_text_draw_add(pos, numstr, numstr_len, 0, txt_flag, col);
-                       }
-                       i++;
-               }
-       }
-
-       if (em->selectmode & SCE_SELECT_FACE) {
-               i = 0;
-               UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEAREA, col);
-               BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
-                       if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
-                               BM_face_calc_center_mean(f, pos);
-                               numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", i);
-                               view3d_cached_text_draw_add(pos, numstr, numstr_len, 0, txt_flag, col);
-                       }
-                       i++;
-               }
-       }
-}
-
-static DMDrawOption draw_em_fancy__setFaceOpts(void *userData, int index)
-{
-       BMEditMesh *em = userData;
-
-       if (UNLIKELY(index >= em->bm->totface))
-               return DM_DRAW_OPTION_NORMAL;
-
-       BMFace *efa = BM_face_at_index(em->bm, index);
-       if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
-               return DM_DRAW_OPTION_NORMAL;
-       }
-       else {
-               return DM_DRAW_OPTION_SKIP;
-       }
-}
-
-static DMDrawOption draw_em_fancy__setGLSLFaceOpts(void *userData, int index)
-{
-       BMEditMesh *em = userData;
-
-       if (UNLIKELY(index >= em->bm->totface))
-               return DM_DRAW_OPTION_NORMAL;
-
-       BMFace *efa = BM_face_at_index(em->bm, index);
-
-       if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
-               return DM_DRAW_OPTION_NORMAL;
-       }
-       else {
-               return DM_DRAW_OPTION_SKIP;
-       }
-}
-
-static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
-                          Object *ob, BMEditMesh *em, DerivedMesh *cageDM, DerivedMesh *finalDM, const char dt)
-
-{
-       RegionView3D *rv3d = ar->regiondata;
-       Mesh *me = ob->data;
-       const bool use_occlude_wire = (dt > OB_WIRE) && (v3d->flag2 & V3D_OCCLUDE_WIRE);
-       bool use_depth_offset = false;
-
-       glLineWidth(1);
-
-       BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE);
-
-       if (check_object_draw_editweight(me, finalDM)) {
-               if (dt > OB_WIRE) {
-                       draw_mesh_paint_weight_faces(finalDM, true, draw_em_fancy__setFaceOpts, me->edit_btmesh);
-
-                       ED_view3d_polygon_offset(rv3d, 1.0);
-                       glDepthMask(0);
-                       use_depth_offset = true;
-               }
-               else {
-                       glEnable(GL_DEPTH_TEST);
-                       draw_mesh_paint_weight_faces(finalDM, false, draw_em_fancy__setFaceOpts, me->edit_btmesh);
-                       draw_mesh_paint_weight_edges(rv3d, finalDM, true, true, draw_dm_edges__setDrawOptions, me->edit_btmesh->bm);
-                       glDisable(GL_DEPTH_TEST);
-               }
-       }
-       else if (dt > OB_WIRE) {
-               if (use_occlude_wire) {
-                       /* use the cageDM since it always overlaps the editmesh faces */
-                       glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-                       cageDM->drawMappedFaces(cageDM, draw_em_fancy__setFaceOpts,
-                                               GPU_object_material_bind, NULL, me->edit_btmesh, DM_DRAW_SKIP_HIDDEN | DM_DRAW_NEED_NORMALS);
-                       GPU_object_material_unbind();
-                       glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-               }
-               else if (check_object_draw_texture(scene, v3d, dt)) {
-                       if (draw_glsl_material(scene, ob, v3d, dt)) {
-                               glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
-
-                               finalDM->drawMappedFacesGLSL(finalDM, GPU_object_material_bind,
-                                                            draw_em_fancy__setGLSLFaceOpts, em);
-                               GPU_object_material_unbind();
-
-                               glFrontFace(GL_CCW);
-                       }
-                       else {
-                               draw_mesh_textured(scene, v3d, rv3d, ob, finalDM, 0);
-                       }
-               }
-               else {
-                       glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
-                       finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, GPU_object_material_bind, NULL, me->edit_btmesh, DM_DRAW_SKIP_HIDDEN | DM_DRAW_NEED_NORMALS);
-
-                       glFrontFace(GL_CCW);
-
-                       GPU_object_material_unbind();
-               }
-
-               /* Setup for drawing wire over, disable zbuffer
-                * write to show selected edge wires better */
-               UI_ThemeColor(TH_WIRE_EDIT);
-
-               ED_view3d_polygon_offset(rv3d, 1.0);
-               glDepthMask(0);
-               use_depth_offset = true;
-       }
-       else {
-               if (cageDM != finalDM) {
-                       UI_ThemeColorBlend(TH_WIRE_EDIT, TH_BACK, 0.7);
-                       finalDM->drawEdges(finalDM, 1, 0);
-               }
-       }
-
-       if ((dt > OB_WIRE) && (v3d->flag2 & V3D_RENDER_SHADOW)) {
-               /* pass */
-       }
-       else {
-               /* annoying but active faces is stored differently */
-               BMFace *efa_act = BM_mesh_active_face_get(em->bm, false, true);
-               BMEdge *eed_act = NULL;
-               BMVert *eve_act = NULL;
-
-               if (em->bm->selected.last) {
-                       BMEditSelection *ese = em->bm->selected.last;
-                       /* face is handled above */
-#if 0
-                       if (ese->type == BM_FACE) {
-                               efa_act = (BMFace *)ese->data;
-                       }
-                       else
-#endif
-                       if (ese->htype == BM_EDGE) {
-                               eed_act = (BMEdge *)ese->ele;
-                       }
-                       else if (ese->htype == BM_VERT) {
-                               eve_act = (BMVert *)ese->ele;
-                       }
-               }
-
-               if ((me->drawflag & ME_DRAWFACES) && (use_occlude_wire == false)) {  /* transp faces */
-                       unsigned char col1[4], col2[4], col3[4];
-#ifdef WITH_FREESTYLE
-                       unsigned char col4[4];
-#endif
-
-                       UI_GetThemeColor4ubv(TH_FACE, col1);
-                       UI_GetThemeColor4ubv(TH_FACE_SELECT, col2);
-                       UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, col3);
-#ifdef WITH_FREESTYLE
-                       UI_GetThemeColor4ubv(TH_FREESTYLE_FACE_MARK, col4);
-#endif
-
-                       glEnable(GL_BLEND);
-                       glDepthMask(0);  /* disable write in zbuffer, needed for nice transp */
-
-                       /* don't draw unselected faces, only selected, this is MUCH nicer when texturing */
-                       if (check_object_draw_texture(scene, v3d, dt))
-                               col1[3] = 0;
-
-#ifdef WITH_FREESTYLE
-                       if (!(me->drawflag & ME_DRAW_FREESTYLE_FACE) || !CustomData_has_layer(&em->bm->pdata, CD_FREESTYLE_FACE))
-                               col4[3] = 0;
-
-                       draw_dm_faces_sel(em, cageDM, col1, col2, col3, col4, efa_act);
-#else
-                       draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act);
-#endif
-
-                       glDisable(GL_BLEND);
-                       glDepthMask(1);  /* restore write in zbuffer */
-               }
-               else if (efa_act) {
-                       /* even if draw faces is off it would be nice to draw the stipple face
-                        * Make all other faces zero alpha except for the active */
-                       unsigned char col1[4], col2[4], col3[4];
-#ifdef WITH_FREESTYLE
-                       unsigned char col4[4];
-                       col4[3] = 0; /* don't draw */
-#endif
-                       col1[3] = col2[3] = 0; /* don't draw */
-
-                       UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, col3);
-
-                       glEnable(GL_BLEND);
-                       glDepthMask(0);  /* disable write in zbuffer, needed for nice transp */
-
-#ifdef WITH_FREESTYLE
-                       draw_dm_faces_sel(em, cageDM, col1, col2, col3, col4, efa_act);
-#else
-                       draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act);
-#endif
-
-                       glDisable(GL_BLEND);
-                       glDepthMask(1);  /* restore write in zbuffer */
-               }
-
-               /* here starts all fancy draw-extra over */
-               if ((me->drawflag & ME_DRAWEDGES) == 0 && check_object_draw_texture(scene, v3d, dt)) {
-                       /* we are drawing textures and 'ME_DRAWEDGES' is disabled, don't draw any edges */
-
-                       /* only draw selected edges otherwise there is no way of telling if a face is selected */
-                       draw_em_fancy_edges(em, scene, v3d, me, cageDM, 1, eed_act);
-
-               }
-               else {
-                       if (me->drawflag & ME_DRAWSEAMS) {
-                               UI_ThemeColor(TH_EDGE_SEAM);
-                               glLineWidth(2);
-
-                               draw_dm_edges_seams(em, cageDM);
-
-                               glColor3ub(0, 0, 0);
-                       }
-
-                       if (me->drawflag & ME_DRAWSHARP) {
-                               UI_ThemeColor(TH_EDGE_SHARP);
-                               glLineWidth(2);
-
-                               draw_dm_edges_sharp(em, cageDM);
-
-                               glColor3ub(0, 0, 0);
-                       }
-
-#ifdef WITH_FREESTYLE
-                       if (me->drawflag & ME_DRAW_FREESTYLE_EDGE && CustomData_has_layer(&em->bm->edata, CD_FREESTYLE_EDGE)) {
-                               UI_ThemeColor(TH_FREESTYLE_EDGE_MARK);
-                               glLineWidth(2);
-
-                               draw_dm_edges_freestyle(em, cageDM);
-
-                               glColor3ub(0, 0, 0);
-                       }
-#endif
-
-                       if (me->drawflag & ME_DRAWCREASES) {
-                               draw_dm_creases(em, cageDM);
-                       }
-                       if (me->drawflag & ME_DRAWBWEIGHTS) {
-                               draw_dm_bweights(em, scene, cageDM);
-                       }
-
-                       glLineWidth(1);
-                       draw_em_fancy_edges(em, scene, v3d, me, cageDM, 0, eed_act);
-               }
-
-               {
-                       draw_em_fancy_verts(scene, v3d, ob, em, cageDM, eve_act, rv3d);
-
-                       if (me->drawflag & ME_DRAWNORMALS) {
-                               UI_ThemeColor(TH_NORMAL);
-                               draw_dm_face_normals(em, scene, ob, cageDM);
-                       }
-                       if (me->drawflag & ME_DRAW_VNORMALS) {
-                               UI_ThemeColor(TH_VNORMAL);
-                               draw_dm_vert_normals(em, scene, ob, cageDM);
-                       }
-                       if (me->drawflag & ME_DRAW_LNORMALS) {
-                               UI_ThemeColor(TH_LNORMAL);
-                               draw_dm_loop_normals(em, scene, ob, cageDM);
-                       }
-
-                       if ((me->drawflag & (ME_DRAWEXTRA_EDGELEN |
-                                            ME_DRAWEXTRA_FACEAREA |
-                                            ME_DRAWEXTRA_FACEANG |
-                                            ME_DRAWEXTRA_EDGEANG)) &&
-                           !(v3d->flag2 & V3D_RENDER_OVERRIDE))
-                       {
-                               draw_em_measure_stats(ar, v3d, ob, em, &scene->unit);
-                       }
-
-                       if ((G.debug & G_DEBUG) && (me->drawflag & ME_DRAWEXTRA_INDICES) &&
-                           !(v3d->flag2 & V3D_RENDER_OVERRIDE))
-                       {
-                               draw_em_indices(em);
-                       }
-               }
-       }
-
-       if (use_depth_offset) {
-               glDepthMask(1);
-               ED_view3d_polygon_offset(rv3d, 0.0);
-               GPU_object_material_unbind();
-       }
-#if 0  /* currently not needed */
-       else if (use_occlude_wire) {
-               ED_view3d_polygon_offset(rv3d, 0.0);
-       }
-#endif
-}
-
-/* Mesh drawing routines */
-
-static void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm)
-{
-       if ((v3d->transp == false) &&  /* not when we draw the transparent pass */
-           (ob->mode & OB_MODE_ALL_PAINT) == false) /* not when painting (its distracting) - campbell */
-       {
-               glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f);
-               glDepthMask(0);
-
-               /* if transparent, we cannot draw the edges for solid select... edges
-                * have no material info. GPU_object_material_visible will skip the
-                * transparent faces */
-               if (ob->dtx & OB_DRAWTRANSP) {
-                       glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-                       dm->drawFacesSolid(dm, NULL, 0, GPU_object_material_visible);
-                       glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-               }
-               else {
-                       dm->drawEdges(dm, 0, 1);
-               }
-
-               glDepthMask(1);
-       }
-}
-
-static bool object_is_halo(Scene *scene, Object *ob)
-{
-       const Material *ma = give_current_material(ob, 1);
-       return (ma && (ma->material_type == MA_TYPE_HALO) && !BKE_scene_use_new_shading_nodes(scene));
-}
-
-static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
-                            const char dt, const unsigned char ob_wire_col[4], const short dflag)
-{
-#ifdef WITH_GAMEENGINE
-       Object *ob = (rv3d->rflag & RV3D_IS_GAME_ENGINE) ? BKE_object_lod_meshob_get(base->object, scene) : base->object;
-#else
-       Object *ob = base->object;
-#endif
-       Mesh *me = ob->data;
-       eWireDrawMode draw_wire = OBDRAW_WIRE_OFF;
-       bool /* no_verts,*/ no_edges, no_faces;
-       DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
-       const bool is_obact = (ob == OBACT);
-       int draw_flags = (is_obact && BKE_paint_select_face_test(ob)) ? DRAW_FACE_SELECT : 0;
-
-       if (!dm)
-               return;
-
-       DM_update_materials(dm, ob);
-
-       /* Check to draw dynamic paint colors (or weights from WeightVG modifiers).
-        * Note: Last "preview-active" modifier in stack will win! */
-       if (DM_get_loop_data_layer(dm, CD_PREVIEW_MLOOPCOL) && modifiers_isPreview(ob))
-               draw_flags |= DRAW_MODIFIERS_PREVIEW;
-
-       /* Unwanted combination */
-       if (draw_flags & DRAW_FACE_SELECT) {
-               draw_wire = OBDRAW_WIRE_OFF;
-       }
-       else if (ob->dtx & OB_DRAWWIRE) {
-               draw_wire = OBDRAW_WIRE_ON_DEPTH; /* draw wire after solid using zoffset and depth buffer adjusment */
-       }
-
-       /* check polys instead of tessfaces because of dyntopo where tessfaces don't exist */
-       if (dm->type == DM_TYPE_CCGDM) {
-               no_edges = !subsurf_has_edges(dm);
-               no_faces = !subsurf_has_faces(dm);
-       }
-       else {
-               no_edges = (dm->getNumEdges(dm) == 0);
-               no_faces = (dm->getNumPolys(dm) == 0);
-       }
-
-       /* vertexpaint, faceselect wants this, but it doesnt work for shaded? */
-       glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
-
-       if (dt == OB_BOUNDBOX) {
-               if (((v3d->flag2 & V3D_RENDER_OVERRIDE) && v3d->drawtype >= OB_WIRE) == 0)
-                       draw_bounding_volume(ob, ob->boundtype);
-       }
-       else if ((no_faces && no_edges) ||
-                ((!is_obact || (ob->mode == OB_MODE_OBJECT)) && object_is_halo(scene, ob)))
-       {
-               glPointSize(1.5);
-               dm->drawVerts(dm);
-       }
-       else if ((dt == OB_WIRE) || no_faces) {
-               draw_wire = OBDRAW_WIRE_ON; /* draw wire only, no depth buffer stuff */
-       }
-       else if (((is_obact && ob->mode & OB_MODE_TEXTURE_PAINT)) ||
-                check_object_draw_texture(scene, v3d, dt))
-       {
-               bool draw_loose = true;
-
-               if ((v3d->flag & V3D_SELECT_OUTLINE) &&
-                   ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
-                   (base->flag & SELECT) &&
-                   !(G.f & G_PICKSEL || (draw_flags & DRAW_FACE_SELECT)) &&
-                   (draw_wire == OBDRAW_WIRE_OFF))
-               {
-                       draw_mesh_object_outline(v3d, ob, dm);
-               }
-
-               if (draw_glsl_material(scene, ob, v3d, dt) && !(draw_flags & DRAW_MODIFIERS_PREVIEW)) {
-                       Paint *p;
-
-                       glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
-
-                       if ((v3d->flag2 & V3D_SHOW_SOLID_MATCAP) && ob->sculpt && (p = BKE_paint_get_active(scene))) {
-                               GPUVertexAttribs gattribs;
-                               float planes[4][4];
-                               float (*fpl)[4] = NULL;
-                               const bool fast = (p->flags & PAINT_FAST_NAVIGATE) && (rv3d->rflag & RV3D_NAVIGATING);
-
-                               if (ob->sculpt->partial_redraw) {
-                                       if (ar->do_draw & RGN_DRAW_PARTIAL) {
-                                               ED_sculpt_redraw_planes_get(planes, ar, rv3d, ob);
-                                               fpl = planes;
-                                               ob->sculpt->partial_redraw = 0;
-                                       }
-                               }
-
-                               GPU_object_material_bind(1, &gattribs);
-                               dm->drawFacesSolid(dm, fpl, fast, NULL);
-                               draw_loose = false;
-                       }
-                       else
-                               dm->drawFacesGLSL(dm, GPU_object_material_bind);
-
-#if 0 /* XXX */
-                       if (BKE_bproperty_object_get(ob, "Text"))
-                               draw_mesh_text(ob, 1);
-#endif
-                       GPU_object_material_unbind();
-
-                       glFrontFace(GL_CCW);
-
-                       if (draw_flags & DRAW_FACE_SELECT)
-                               draw_mesh_face_select(rv3d, me, dm, false);
-               }
-               else {
-                       draw_mesh_textured(scene, v3d, rv3d, ob, dm, draw_flags);
-               }
-
-               if (draw_loose && !(draw_flags & DRAW_FACE_SELECT)) {
-                       if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
-                               if ((dflag & DRAW_CONSTCOLOR) == 0) {
-                                       glColor3ubv(ob_wire_col);
-                               }
-                               glLineWidth(1.0f);
-                               dm->drawLooseEdges(dm);
-                       }
-               }
-       }
-       else if (dt == OB_SOLID) {
-               if (draw_flags & DRAW_MODIFIERS_PREVIEW) {
-                       /* for object selection draws no shade */
-                       if (dflag & (DRAW_PICKING | DRAW_CONSTCOLOR)) {
-                               dm->drawFacesSolid(dm, NULL, 0, GPU_object_material_bind);
-                               GPU_object_material_unbind();
-                       }
-                       else {
-                               const float specular[3] = {0.47f, 0.47f, 0.47f};
-
-                               /* draw outline */
-                               if ((v3d->flag & V3D_SELECT_OUTLINE) &&
-                                   ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
-                                   (base->flag & SELECT) &&
-                                   (draw_wire == OBDRAW_WIRE_OFF) &&
-                                   (ob->sculpt == NULL))
-                               {
-                                       draw_mesh_object_outline(v3d, ob, dm);
-                               }
-
-                               /* materials arent compatible with vertex colors */
-                               GPU_end_object_materials();
-
-                               /* set default specular */
-                               GPU_basic_shader_colors(NULL, specular, 35, 1.0f);
-                               GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR);
-
-                               dm->drawMappedFaces(dm, NULL, NULL, NULL, NULL, DM_DRAW_USE_COLORS | DM_DRAW_NEED_NORMALS);
-
-                               GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
-                       }
-               }
-               else {
-                       Paint *p;
-
-                       if ((v3d->flag & V3D_SELECT_OUTLINE) &&
-                           ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
-                           (base->flag & SELECT) &&
-                           (draw_wire == OBDRAW_WIRE_OFF) &&
-                           (ob->sculpt == NULL))
-                       {
-                               draw_mesh_object_outline(v3d, ob, dm);
-                       }
-
-                       glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
-
-                       if (ob->sculpt && (p = BKE_paint_get_active(scene))) {
-                               float planes[4][4];
-                               float (*fpl)[4] = NULL;
-                               const bool fast = (p->flags & PAINT_FAST_NAVIGATE) && (rv3d->rflag & RV3D_NAVIGATING);
-
-                               if (ob->sculpt->partial_redraw) {
-                                       if (ar->do_draw & RGN_DRAW_PARTIAL) {
-                                               ED_sculpt_redraw_planes_get(planes, ar, rv3d, ob);
-                                               fpl = planes;
-                                               ob->sculpt->partial_redraw = 0;
-                                       }
-                               }
-
-                               dm->drawFacesSolid(dm, fpl, fast, GPU_object_material_bind);
-                       }
-                       else
-                               dm->drawFacesSolid(dm, NULL, 0, GPU_object_material_bind);
-
-                       glFrontFace(GL_CCW);
-
-                       GPU_object_material_unbind();
-
-                       if (!ob->sculpt && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
-                               if ((dflag & DRAW_CONSTCOLOR) == 0) {
-                                       glColor3ubv(ob_wire_col);
-                               }
-                               glLineWidth(1.0f);
-                               dm->drawLooseEdges(dm);
-                       }
-               }
-       }
-       else if (dt == OB_PAINT) {
-               draw_mesh_paint(v3d, rv3d, ob, dm, draw_flags);
-
-               /* since we already draw wire as wp guide, don't draw over the top */
-               draw_wire = OBDRAW_WIRE_OFF;
-       }
-
-       if ((draw_wire != OBDRAW_WIRE_OFF) &&  /* draw extra wire */
-           /* when overriding with render only, don't bother */
-           (((v3d->flag2 & V3D_RENDER_OVERRIDE) && v3d->drawtype >= OB_SOLID) == 0))
-       {
-               /* When using wireframe object draw in particle edit mode
-                * the mesh gets in the way of seeing the particles, fade the wire color
-                * with the background. */
-
-               if ((dflag & DRAW_CONSTCOLOR) == 0) {
-                       if (is_obact && (ob->mode & OB_MODE_PARTICLE_EDIT)) {
-                               ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.15f);
-                       }
-                       else {
-                               glColor3ubv(ob_wire_col);
-                       }
-               }
-
-               /* If drawing wire and drawtype is not OB_WIRE then we are
-                * overlaying the wires.
-                *
-                * UPDATE bug #10290 - With this wire-only objects can draw
-                * behind other objects depending on their order in the scene. 2x if 0's below. undo'ing zr's commit: r4059
-                *
-                * if draw wire is 1 then just drawing wire, no need for depth buffer stuff,
-                * otherwise this wire is to overlay solid mode faces so do some depth buffer tricks.
-                */
-               if (dt != OB_WIRE && (draw_wire == OBDRAW_WIRE_ON_DEPTH)) {
-                       ED_view3d_polygon_offset(rv3d, 1.0);
-                       glDepthMask(0);  /* disable write in zbuffer, selected edge wires show better */
-               }
-
-               glLineWidth(1.0f);
-               dm->drawEdges(dm, ((dt == OB_WIRE) || no_faces), (ob->dtx & OB_DRAW_ALL_EDGES) != 0);
-
-               if (dt != OB_WIRE && (draw_wire == OBDRAW_WIRE_ON_DEPTH)) {
-                       glDepthMask(1);
-                       ED_view3d_polygon_offset(rv3d, 0.0);
-               }
-       }
-
-       if (is_obact && BKE_paint_select_vert_test(ob)) {
-               const bool use_depth = (v3d->flag & V3D_ZBUF_SELECT) != 0;
-               glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
-
-               if (!use_depth) glDisable(GL_DEPTH_TEST);
-               else            ED_view3d_polygon_offset(rv3d, 1.0);
-               drawSelectedVertices(dm, ob->data);
-               if (!use_depth) glEnable(GL_DEPTH_TEST);
-               else            ED_view3d_polygon_offset(rv3d, 0.0);
-       }
-       dm->release(dm);
-}
-
-/* returns true if nothing was drawn, for detecting to draw an object center */
-static bool draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
-                             const char dt, const unsigned char ob_wire_col[4], const short dflag)
-{
-       Object *ob = base->object;
-       Object *obedit = scene->obedit;
-       Mesh *me = ob->data;
-       BMEditMesh *em = me->edit_btmesh;
-       bool do_alpha_after = false, drawlinked = false, retval = false;
-
-       /* If we are drawing shadows and any of the materials don't cast a shadow,
-        * then don't draw the object */
-       if (v3d->flag2 & V3D_RENDER_SHADOW) {
-               for (int i = 1; i <= ob->totcol; ++i) {
-                       Material *ma = give_current_material(ob, i);
-                       if (ma && !(ma->mode2 & MA_CASTSHADOW)) {
-                               return true;
-                       }
-               }
-       }
-
-       if (obedit && ob != obedit && ob->data == obedit->data) {
-               if (BKE_key_from_object(ob) || BKE_key_from_object(obedit)) {}
-               else if (ob->modifiers.first || obedit->modifiers.first) {}
-               else drawlinked = true;
-       }
-
-       /* backface culling */
-       if (v3d->flag2 & V3D_BACKFACE_CULLING) {
-               glEnable(GL_CULL_FACE);
-               glCullFace(GL_BACK);
-       }
-
-       if (ob == obedit || drawlinked) {
-               DerivedMesh *finalDM, *cageDM;
-
-               if (obedit != ob) {
-                       finalDM = cageDM = editbmesh_get_derived_base(
-                               ob, em, scene->customdata_mask);
-               }
-               else {
-                       cageDM = editbmesh_get_derived_cage_and_final(
-                               scene, ob, em, scene->customdata_mask,
-                               &finalDM);
-               }
-
-               const bool use_material = ((me->drawflag & ME_DRAWEIGHT) == 0);
-
-               DM_update_materials(finalDM, ob);
-               if (cageDM != finalDM) {
-                       DM_update_materials(cageDM, ob);
-               }
-
-               if (use_material) {
-                       if (dt > OB_WIRE) {
-                               const bool glsl = draw_glsl_material(scene, ob, v3d, dt);
-
-                               GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
-                       }
-               }
-
-               draw_em_fancy(scene, ar, v3d, ob, em, cageDM, finalDM, dt);
-
-               if (use_material) {
-                       GPU_end_object_materials();
-               }
-
-               if (obedit != ob)
-                       finalDM->release(finalDM);
-       }
-       else {
-               /* ob->bb was set by derived mesh system, do NULL check just to be sure */
-               if (me->totpoly <= 4 || (!ob->bb || ED_view3d_boundbox_clip(rv3d, ob->bb))) {
-                       if (dt > OB_WIRE) {
-                               const bool glsl = draw_glsl_material(scene, ob, v3d, dt);
-
-                               if (dt == OB_SOLID || glsl) {
-                                       const bool check_alpha = check_alpha_pass(base);
-                                       GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl,
-                                                                  (check_alpha) ? &do_alpha_after : NULL);
-                               }
-                       }
-
-                       draw_mesh_fancy(scene, ar, v3d, rv3d, base, dt, ob_wire_col, dflag);
-
-                       GPU_end_object_materials();
-
-                       if (me->totvert == 0) retval = true;
-               }
-       }
-
-       if ((dflag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0 && (v3d->flag2 & V3D_RENDER_SHADOW) == 0) {
-               /* GPU_begin_object_materials checked if this is needed */
-               if (do_alpha_after) {
-                       if (ob->dtx & OB_DRAWXRAY) {
-                               ED_view3d_after_add(&v3d->afterdraw_xraytransp, base, dflag);
-                       }
-                       else {
-                               ED_view3d_after_add(&v3d->afterdraw_transp, base, dflag);
-                       }
-               }
-               else if (ob->dtx & OB_DRAWXRAY && ob->dtx & OB_DRAWTRANSP) {
-                       /* special case xray+transp when alpha is 1.0, without this the object vanishes */
-                       if (v3d->xray == 0 && v3d->transp == 0) {
-                               ED_view3d_after_add(&v3d->afterdraw_xray, base, dflag);
-                       }
-               }
-       }
-
-       if (v3d->flag2 & V3D_BACKFACE_CULLING)
-               glDisable(GL_CULL_FACE);
-
-       return retval;
-}
-
-/* ************** DRAW DISPLIST ****************** */
-
-
-/**
- * \param dl_type_mask Only draw types matching this mask.
- * \return true when nothing was drawn
- */
-static bool drawDispListwire_ex(ListBase *dlbase, unsigned int dl_type_mask)
-{
-       if (dlbase == NULL) return true;
-
-       glEnableClientState(GL_VERTEX_ARRAY);
-       glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-
-       for (DispList *dl = dlbase->first; dl; dl = dl->next) {
-               if (dl->parts == 0 || dl->nr == 0) {
-                       continue;
-               }
-
-               if ((dl_type_mask & (1 << dl->type)) == 0) {
-                       continue;
-               }
-
-               const float *data = dl->verts;
-               int parts;
-
-               switch (dl->type) {
-                       case DL_SEGM:
-
-                               glVertexPointer(3, GL_FLOAT, 0, data);
-
-                               for (parts = 0; parts < dl->parts; parts++)
-                                       glDrawArrays(GL_LINE_STRIP, parts * dl->nr, dl->nr);
-
-                               break;
-                       case DL_POLY:
-
-                               glVertexPointer(3, GL_FLOAT, 0, data);
-
-                               for (parts = 0; parts < dl->parts; parts++)
-                                       glDrawArrays(GL_LINE_LOOP, parts * dl->nr, dl->nr);
-
-                               break;
-                       case DL_SURF:
-
-                               glVertexPointer(3, GL_FLOAT, 0, data);
-
-                               for (parts = 0; parts < dl->parts; parts++) {
-                                       if (dl->flag & DL_CYCL_U)
-                                               glDrawArrays(GL_LINE_LOOP, parts * dl->nr, dl->nr);
-                                       else
-                                               glDrawArrays(GL_LINE_STRIP, parts * dl->nr, dl->nr);
-                               }
-
-                               for (int nr = 0; nr < dl->nr; nr++) {
-                                       int ofs = 3 * dl->nr;
-
-                                       data = (dl->verts) + 3 * nr;
-                                       parts = dl->parts;
-
-                                       if (dl->flag & DL_CYCL_V) glBegin(GL_LINE_LOOP);
-                                       else glBegin(GL_LINE_STRIP);
-
-                                       while (parts--) {
-                                               glVertex3fv(data);
-                                               data += ofs;
-                                       }
-                                       glEnd();
-
-#if 0
-                               /* (ton) this code crashes for me when resolv is 86 or higher... no clue */
-                               glVertexPointer(3, GL_FLOAT, sizeof(float) * 3 * dl->nr, data + 3 * nr);
-                               if (dl->flag & DL_CYCL_V)
-                                       glDrawArrays(GL_LINE_LOOP, 0, dl->parts);
-                               else
-                                       glDrawArrays(GL_LINE_STRIP, 0, dl->parts);
-#endif
-                               }
-                               break;
-
-                       case DL_INDEX3:
-                               glVertexPointer(3, GL_FLOAT, 0, dl->verts);
-                               glDrawElements(GL_TRIANGLES, 3 * dl->parts, GL_UNSIGNED_INT, dl->index);
-                               break;
-
-                       case DL_INDEX4:
-                               glVertexPointer(3, GL_FLOAT, 0, dl->verts);
-                               glDrawElements(GL_QUADS, 4 * dl->parts, GL_UNSIGNED_INT, dl->index);
-                               break;
-               }
-       }
-
-       glDisableClientState(GL_VERTEX_ARRAY);
-       glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-
-       return false;
-}
-
-static bool drawDispListwire(ListBase *dlbase, const short ob_type)
-{
-       unsigned int dl_mask = 0xffffffff;
-
-       /* skip fill-faces for curves & fonts */
-       if (ELEM(ob_type, OB_FONT, OB_CURVE)) {
-               dl_mask &= ~((1 << DL_INDEX3) | (1 << DL_INDEX4));
-       }
-
-       return drawDispListwire_ex(dlbase, dl_mask);
-}
-
-static bool index3_nors_incr = true;
-
-static void drawDispListsolid(ListBase *lb, Object *ob, const short dflag,
-                              const unsigned char ob_wire_col[4], const bool use_glsl)
-{
-       GPUVertexAttribs gattribs;
-
-       if (lb == NULL) return;
-
-       glEnableClientState(GL_VERTEX_ARRAY);
-
-       /* track current material, -1 for none (needed for lines) */
-       short col = -1;
-
-       DispList *dl = lb->first;
-       while (dl) {
-               const float *data = dl->verts;
-               const float *ndata = dl->nors;
-
-               switch (dl->type) {
-                       case DL_SEGM:
-                               if (ob->type == OB_SURF) {
-                                       if (col != -1) {
-                                               GPU_object_material_unbind();
-                                               col = -1;
-                                       }
-
-                                       if ((dflag & DRAW_CONSTCOLOR) == 0)
-                                               glColor3ubv(ob_wire_col);
-
-                                       // glVertexPointer(3, GL_FLOAT, 0, dl->verts);
-                                       // glDrawArrays(GL_LINE_STRIP, 0, dl->nr);
-                                       glBegin(GL_LINE_STRIP);
-                                       for (int nr = dl->nr; nr; nr--, data += 3)
-                                               glVertex3fv(data);
-                                       glEnd();
-                               }
-                               break;
-                       case DL_POLY:
-                               if (ob->type == OB_SURF) {
-                                       if (col != -1) {
-                                               GPU_object_material_unbind();
-                                               col = -1;
-                                       }
-
-                                       /* for some reason glDrawArrays crashes here in half of the platforms (not osx) */
-                                       //glVertexPointer(3, GL_FLOAT, 0, dl->verts);
-                                       //glDrawArrays(GL_LINE_LOOP, 0, dl->nr);
-
-                                       glBegin(GL_LINE_LOOP);
-                                       for (int nr = dl->nr; nr; nr--, data += 3)
-                                               glVertex3fv(data);
-                                       glEnd();
-                               }
-                               break;
-                       case DL_SURF:
-
-                               if (dl->index) {
-                                       if (col != dl->col) {
-                                               GPU_object_material_bind(dl->col + 1, use_glsl ? &gattribs : NULL);
-                                               col = dl->col;
-                                       }
-                                       /* FLAT/SMOOTH shading for surfaces */
-                                       glShadeModel((dl->rt & CU_SMOOTH) ? GL_SMOOTH : GL_FLAT);
-
-                                       glEnableClientState(GL_NORMAL_ARRAY);
-                                       glVertexPointer(3, GL_FLOAT, 0, dl->verts);
-                                       glNormalPointer(GL_FLOAT, 0, dl->nors);
-                                       glDrawElements(GL_QUADS, 4 * dl->totindex, GL_UNSIGNED_INT, dl->index);
-                                       glDisableClientState(GL_NORMAL_ARRAY);
-                                       glShadeModel(GL_SMOOTH);
-                               }
-                               break;
-
-                       case DL_INDEX3:
-                               if (col != dl->col) {
-                                       GPU_object_material_bind(dl->col + 1, use_glsl ? &gattribs : NULL);
-                                       col = dl->col;
-                               }
-
-                               glVertexPointer(3, GL_FLOAT, 0, dl->verts);
-
-                               /* for polys only one normal needed */
-                               if (index3_nors_incr) {
-                                       glEnableClientState(GL_NORMAL_ARRAY);
-                                       glNormalPointer(GL_FLOAT, 0, dl->nors);
-                               }
-                               else
-                                       glNormal3fv(ndata);
-
-                               glDrawElements(GL_TRIANGLES, 3 * dl->parts, GL_UNSIGNED_INT, dl->index);
-
-                               if (index3_nors_incr)
-                                       glDisableClientState(GL_NORMAL_ARRAY);
-
-                               break;
-
-                       case DL_INDEX4:
-                               if (col != dl->col) {
-                                       GPU_object_material_bind(dl->col + 1, use_glsl ? &gattribs : NULL);
-                                       col = dl->col;
-                               }
-
-                               glEnableClientState(GL_NORMAL_ARRAY);
-                               glVertexPointer(3, GL_FLOAT, 0, dl->verts);
-                               glNormalPointer(GL_FLOAT, 0, dl->nors);
-                               glDrawElements(GL_QUADS, 4 * dl->parts, GL_UNSIGNED_INT, dl->index);
-                               glDisableClientState(GL_NORMAL_ARRAY);
-
-                               break;
-               }
-               dl = dl->next;
-       }
-
-       glDisableClientState(GL_VERTEX_ARRAY);
-       glFrontFace(GL_CCW);
-
-       if (col != -1) {
-               GPU_object_material_unbind();
-       }
-}
-
-static void drawCurveDMWired(Object *ob)
-{
-       DerivedMesh *dm = ob->derivedFinal;
-       dm->drawEdges(dm, 1, 0);
-}
-
-/* return true when nothing was drawn */
-static bool drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, const char dt)
-{
-       Object *ob = base->object;
-       DerivedMesh *dm = ob->derivedFinal;
-
-       if (!dm) {
-               return true;
-       }
-
-       DM_update_materials(dm, ob);
-
-       glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
-
-       if (dt > OB_WIRE && dm->getNumPolys(dm)) {
-               bool glsl = draw_glsl_material(scene, ob, v3d, dt);
-               GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
-
-               if (!glsl)
-                       dm->drawFacesSolid(dm, NULL, 0, GPU_object_material_bind);
-               else
-                       dm->drawFacesGLSL(dm, GPU_object_material_bind);
-
-               GPU_end_object_materials();
-       }
-       else {
-               if (((v3d->flag2 & V3D_RENDER_OVERRIDE) && v3d->drawtype >= OB_SOLID) == 0)
-                       drawCurveDMWired(ob);
-       }
-
-       return false;
-}
-
-/**
- * Only called by #drawDispList
- * \return true when nothing was drawn
- */
-static bool drawDispList_nobackface(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
-                                    const char dt, const short dflag, const unsigned char ob_wire_col[4])
-{
-       Object *ob = base->object;
-       ListBase *lb = NULL;
-       DispList *dl;
-       Curve *cu;
-       const bool render_only = (v3d->flag2 & V3D_RENDER_OVERRIDE) != 0;
-       const bool solid = (dt > OB_WIRE);
-
-       switch (ob->type) {
-               case OB_FONT:
-               case OB_CURVE:
-                       cu = ob->data;
-
-                       lb = &ob->curve_cache->disp;
-
-                       if (solid) {
-                               const bool has_faces = BKE_displist_has_faces(lb);
-                               dl = lb->first;
-                               if (dl == NULL) {
-                                       return true;
-                               }
-
-                               if (dl->nors == NULL) BKE_displist_normals_add(lb);
-                               index3_nors_incr = false;
-
-                               if (!render_only) {
-                                       /* when we have faces, only draw loose-wire */
-                                       if (has_faces) {
-                                               drawDispListwire_ex(lb, (1 << DL_SEGM));
-                                       }
-                                       else {
-                                               drawDispListwire(lb, ob->type);
-                                       }
-                               }
-
-                               if (has_faces == false) {
-                                       /* pass */
-                               }
-                               else {
-                                       if (draw_glsl_material(scene, ob, v3d, dt)) {
-                                               GPU_begin_object_materials(v3d, rv3d, scene, ob, 1, NULL);
-                                               drawDispListsolid(lb, ob, dflag, ob_wire_col, true);
-                                               GPU_end_object_materials();
-                                       }
-                                       else {
-                                               GPU_begin_object_materials(v3d, rv3d, scene, ob, 0, NULL);
-                                               drawDispListsolid(lb, ob, dflag, ob_wire_col, false);
-                                               GPU_end_object_materials();
-                                       }
-                                       if (cu->editnurb && cu->bevobj == NULL && cu->taperobj == NULL && cu->ext1 == 0.0f && cu->ext2 == 0.0f) {
-                                               cpack(0);
-                                               drawDispListwire(lb, ob->type);
-                                       }
-                               }
-                               index3_nors_incr = true;
-                       }
-                       else {
-                               if (!render_only || BKE_displist_has_faces(lb)) {
-                                       return drawDispListwire(lb, ob->type);
-                               }
-                       }
-                       break;
-               case OB_SURF:
-
-                       lb = &ob->curve_cache->disp;
-
-                       if (solid) {
-                               dl = lb->first;
-                               if (dl == NULL) {
-                                       return true;
-                               }
-
-                               if (dl->nors == NULL) BKE_displist_normals_add(lb);
-
-                               if (draw_glsl_material(scene, ob, v3d, dt)) {
-                                       GPU_begin_object_materials(v3d, rv3d, scene, ob, 1, NULL);
-                                       drawDispListsolid(lb, ob, dflag, ob_wire_col, true);
-                                       GPU_end_object_materials();
-                               }
-                               else {
-                                       GPU_begin_object_materials(v3d, rv3d, scene, ob, 0, NULL);
-                                       drawDispListsolid(lb, ob, dflag, ob_wire_col, false);
-                                       GPU_end_object_materials();
-                               }
-                       }
-                       else {
-                               return drawDispListwire(lb, ob->type);
-                       }
-                       break;
-               case OB_MBALL:
-
-                       if (BKE_mball_is_basis(ob)) {
-                               lb = &ob->curve_cache->disp;
-                               if (BLI_listbase_is_empty(lb)) {
-                                       return true;
-                               }
-
-                               if (solid) {
-
-                                       if (draw_glsl_material(scene, ob, v3d, dt)) {
-                                               GPU_begin_object_materials(v3d, rv3d, scene, ob, 1, NULL);
-                                               drawDispListsolid(lb, ob, dflag, ob_wire_col, true);
-                                               GPU_end_object_materials();
-                                       }
-                                       else {
-                                               GPU_begin_object_materials(v3d, rv3d, scene, ob, 0, NULL);
-                                               drawDispListsolid(lb, ob, dflag, ob_wire_col, false);
-                                               GPU_end_object_materials();
-                                       }
-                               }
-                               else {
-                                       return drawDispListwire(lb, ob->type);
-                               }
-                       }
-                       break;
-       }
-
-       return false;
-}
-static bool drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
-                         const char dt, const short dflag, const unsigned char ob_wire_col[4])
-{
-       bool retval;
-
-       /* backface culling */
-       if (v3d->flag2 & V3D_BACKFACE_CULLING) {
-               /* not all displists use same in/out normal direction convention */
-               glEnable(GL_CULL_FACE);
-               glCullFace(GL_BACK);
-       }
-
-#ifdef SEQUENCER_DAG_WORKAROUND
-       ensure_curve_cache(scene, base->object);
-#endif
-
-       if (drawCurveDerivedMesh(scene, v3d, rv3d, base, dt) == false) {
-               retval = false;
-       }
-       else {
-               Object *ob = base->object;
-               GLenum mode;
-
-               if (ob->type == OB_MBALL) {
-                       mode = (ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW;
-               }
-               else {
-                       mode = (ob->transflag & OB_NEG_SCALE) ? GL_CCW : GL_CW;
-               }
-
-               glFrontFace(mode);
-
-               retval = drawDispList_nobackface(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
-
-               if (mode != GL_CCW) {
-                       glFrontFace(GL_CCW);
-               }
-       }
-
-       if (v3d->flag2 & V3D_BACKFACE_CULLING) {
-               glDisable(GL_CULL_FACE);
-       }
-
-       return retval;
-}
-
-/* *********** drawing for particles ************* */
-static void draw_particle_arrays(int draw_as, int totpoint, int ob_dt, int select)
-{
-       /* draw created data arrays */
-       switch (draw_as) {
-               case PART_DRAW_AXIS:
-               case PART_DRAW_CROSS:
-                       glDrawArrays(GL_LINES, 0, 6 * totpoint);
-                       break;
-               case PART_DRAW_LINE:
-                       glDrawArrays(GL_LINES, 0, 2 * totpoint);
-                       break;
-               case PART_DRAW_BB:
-                       if (ob_dt <= OB_WIRE || select)
-                               glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-                       else
-                               glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-
-                       glDrawArrays(GL_QUADS, 0, 4 * totpoint);
-                       break;
-               default:
-                       glDrawArrays(GL_POINTS, 0, totpoint);
-                       break;
-       }
-}
-static void draw_particle(ParticleKey *state, int draw_as, short draw, float pixsize,
-                          float imat[4][4], const float draw_line[2], ParticleBillboardData *bb, ParticleDrawData *pdd)
-{
-       float vec[3], vec2[3];
-       float *vd = NULL;
-       float *cd = NULL;
-       float ma_col[3] = {0.0f, 0.0f, 0.0f};
-
-       /* null only for PART_DRAW_CIRC */
-       if (pdd) {
-               vd = pdd->vd;
-               cd = pdd->cd;
-
-               if (pdd->ma_col) {
-                       copy_v3_v3(ma_col, pdd->ma_col);
-               }
-       }
-
-       switch (draw_as) {
-               case PART_DRAW_DOT:
-               {
-                       if (vd) {
-                               copy_v3_v3(vd, state->co); pdd->vd += 3;
-                       }
-                       if (cd) {
-                               copy_v3_v3(cd, pdd->ma_col);
-                               pdd->cd += 3;
-                       }
-                       break;
-               }
-               case PART_DRAW_CROSS:
-               case PART_DRAW_AXIS:
-               {
-                       vec[0] = 2.0f * pixsize;
-                       vec[1] = vec[2] = 0.0;
-                       mul_qt_v3(state->rot, vec);
-                       if (draw_as == PART_DRAW_AXIS) {
-                               if (cd) {
-                                       cd[1] = cd[2] = cd[4] = cd[5] = 0.0;
-                                       cd[0] = cd[3] = 1.0;
-                                       cd[6] = cd[8] = cd[9] = cd[11] = 0.0;
-                                       cd[7] = cd[10] = 1.0;
-                                       cd[13] = cd[12] = cd[15] = cd[16] = 0.0;
-                                       cd[14] = cd[17] = 1.0;
-                                       pdd->cd += 18;
-                               }
-
-                               copy_v3_v3(vec2, state->co);
-                       }
-                       else {
-                               if (cd) {
-                                       cd[0] = cd[3] = cd[6] = cd[9] = cd[12] = cd[15] = ma_col[0];
-                                       cd[1] = cd[4] = cd[7] = cd[10] = cd[13] = cd[16] = ma_col[1];
-                                       cd[2] = cd[5] = cd[8] = cd[11] = cd[14] = cd[17] = ma_col[2];
-                                       pdd->cd += 18;
-                               }
-                               sub_v3_v3v3(vec2, state->co, vec);
-                       }
-
-                       add_v3_v3(vec, state->co);
-                       copy_v3_v3(pdd->vd, vec); pdd->vd += 3;
-                       copy_v3_v3(pdd->vd, vec2); pdd->vd += 3;
-
-                       vec[1] = 2.0f * pixsize;
-                       vec[0] = vec[2] = 0.0;
-                       mul_qt_v3(state->rot, vec);
-                       if (draw_as == PART_DRAW_AXIS) {
-                               copy_v3_v3(vec2, state->co);
-                       }
-                       else {
-                               sub_v3_v3v3(vec2, state->co, vec);
-                       }
-
-                       add_v3_v3(vec, state->co);
-                       copy_v3_v3(pdd->vd, vec); pdd->vd += 3;
-                       copy_v3_v3(pdd->vd, vec2); pdd->vd += 3;
-
-                       vec[2] = 2.0f * pixsize;
-                       vec[0] = vec[1] = 0.0f;
-                       mul_qt_v3(state->rot, vec);
-                       if (draw_as == PART_DRAW_AXIS) {
-                               copy_v3_v3(vec2, state->co);
-                       }
-                       else {
-                               sub_v3_v3v3(vec2, state->co, vec);
-                       }
-
-                       add_v3_v3(vec, state->co);
-
-                       copy_v3_v3(pdd->vd, vec); pdd->vd += 3;
-                       copy_v3_v3(pdd->vd, vec2); pdd->vd += 3;
-                       break;
-               }
-               case PART_DRAW_LINE:
-               {
-                       copy_v3_v3(vec, state->vel);
-                       normalize_v3(vec);
-                       if (draw & PART_DRAW_VEL_LENGTH)
-                               mul_v3_fl(vec, len_v3(state->vel));
-                       madd_v3_v3v3fl(pdd->vd, state->co, vec, -draw_line[0]); pdd->vd += 3;
-                       madd_v3_v3v3fl(pdd->vd, state->co, vec,  draw_line[1]); pdd->vd += 3;
-                       if (cd) {
-                               cd[0] = cd[3] = ma_col[0];
-                               cd[1] = cd[4] = ma_col[1];
-                               cd[2] = cd[5] = ma_col[2];
-                               pdd->cd += 6;
-                       }
-                       break;
-               }
-               case PART_DRAW_CIRC:
-               {
-                       drawcircball(GL_LINE_LOOP, state->co, pixsize, imat);
-                       break;
-               }
-               case PART_DRAW_BB:
-               {
-                       float xvec[3], yvec[3], zvec[3], bb_center[3];
-                       if (cd) {
-                               cd[0] = cd[3] = cd[6] = cd[9] = ma_col[0];
-                               cd[1] = cd[4] = cd[7] = cd[10] = ma_col[1];
-                               cd[2] = cd[5] = cd[8] = cd[11] = ma_col[2];
-                               pdd->cd += 12;
-                       }
-
-                       copy_v3_v3(bb->vec, state->co);
-                       copy_v3_v3(bb->vel, state->vel);
-
-                       psys_make_billboard(bb, xvec, yvec, zvec, bb_center);
-
-                       add_v3_v3v3(pdd->vd, bb_center, xvec);
-                       add_v3_v3(pdd->vd, yvec); pdd->vd += 3;
-
-                       sub_v3_v3v3(pdd->vd, bb_center, xvec);
-                       add_v3_v3(pdd->vd, yvec); pdd->vd += 3;
-
-                       sub_v3_v3v3(pdd->vd, bb_center, xvec);
-                       sub_v3_v3v3(pdd->vd, pdd->vd, yvec); pdd->vd += 3;
-
-                       add_v3_v3v3(pdd->vd, bb_center, xvec);
-                       sub_v3_v3v3(pdd->vd, pdd->vd, yvec); pdd->vd += 3;
-
-                       copy_v3_v3(pdd->nd, zvec); pdd->nd += 3;
-                       copy_v3_v3(pdd->nd, zvec); pdd->nd += 3;
-                       copy_v3_v3(pdd->nd, zvec); pdd->nd += 3;
-                       copy_v3_v3(pdd->nd, zvec); pdd->nd += 3;
-                       break;
-               }
-       }
-}
-static void draw_particle_data(ParticleSystem *psys, RegionView3D *rv3d,
-                               ParticleKey *state, int draw_as,
-                               float imat[4][4], ParticleBillboardData *bb, ParticleDrawData *pdd,
-                               const float ct, const float pa_size, const float r_tilt, const float pixsize_scale)
-{
-       ParticleSettings *part = psys->part;
-       float pixsize;
-
-       if (psys->parent)
-               mul_m4_v3(psys->parent->obmat, state->co);
-
-       /* create actual particle data */
-       if (draw_as == PART_DRAW_BB) {
-               bb->offset[0] = part->bb_offset[0];
-               bb->offset[1] = part->bb_offset[1];
-               bb->size[0] = part->bb_size[0] * pa_size;
-               if (part->bb_align == PART_BB_VEL) {
-                       float pa_vel = len_v3(state->vel);
-                       float head = part->bb_vel_head * pa_vel;
-                       float tail = part->bb_vel_tail * pa_vel;
-                       bb->size[1] = part->bb_size[1] * pa_size + head + tail;
-                       /* use offset to adjust the particle center. this is relative to size, so need to divide! */
-                       if (bb->size[1] > 0.0f)
-                               bb->offset[1] += (head - tail) / bb->size[1];
-               }
-               else {
-                       bb->size[1] = part->bb_size[1] * pa_size;
-               }
-               bb->tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt);
-               bb->time = ct;
-       }
-
-       pixsize = ED_view3d_pixel_size(rv3d, state->co) * pixsize_scale;
-
-       draw_particle(state, draw_as, part->draw, pixsize, imat, part->draw_line, bb, pdd);
-}
-/* unified drawing of all new particle systems draw types except dupli ob & group
- * mostly tries to use vertex arrays for speed
- *
- * 1. check that everything is ok & updated
- * 2. start initializing things
- * 3. initialize according to draw type
- * 4. allocate drawing data arrays
- * 5. start filling the arrays
- * 6. draw the arrays
- * 7. clean up
- */
-static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv3d,
-                                     Base *base, ParticleSystem *psys,
-                                     const char ob_dt, const short dflag)
-{
-       Object *ob = base->object;
-       ParticleEditSettings *pset = PE_settings(scene);
-       ParticleSettings *part = psys->part;
-       ParticleData *pars = psys->particles;
-       ParticleData *pa;
-       ParticleKey state, *states = NULL;
-       ParticleBillboardData bb;
-       ParticleSimulationData sim = {NULL};
-       ParticleDrawData *pdd = psys->pdd;
-       Material *ma;
-       float vel[3], imat[4][4];
-       float timestep, pixsize_scale = 1.0f, pa_size, r_tilt, r_length;
-       float pa_time, pa_birthtime, pa_dietime, pa_health, intensity;
-       float cfra;
-       float ma_col[3] = {0.0f, 0.0f, 0.0f};
-       int a, totpart, totpoint = 0, totve = 0, drawn, draw_as, totchild = 0;
-       bool select = (ob->flag & SELECT) != 0, create_cdata = false, need_v = false;
-       GLint polygonmode[2];
-       char numstr[32];
-       unsigned char tcol[4] = {0, 0, 0, 255};
-
-/* 1. */
-       if (part == NULL || !psys_check_enabled(ob, psys, G.is_rendering))
-               return;
-
-       if (pars == NULL) return;
-
-       /* don't draw normal paths in edit mode */
-       if (psys_in_edit_mode(scene, psys) && (pset->flag & PE_DRAW_PART) == 0)
-               return;
-
-       if (part->draw_as == PART_DRAW_REND)
-               draw_as = part->ren_as;
-       else
-               draw_as = part->draw_as;
-
-       if (draw_as == PART_DRAW_NOT)
-               return;
-
-       /* prepare curvemapping tables */
-       if ((psys->part->child_flag & PART_CHILD_USE_CLUMP_CURVE) && psys->part->clumpcurve)
-               curvemapping_changed_all(psys->part->clumpcurve);
-       if ((psys->part->child_flag & PART_CHILD_USE_ROUGH_CURVE) && psys->part->roughcurve)
-               curvemapping_changed_all(psys->part->roughcurve);
-       if ((psys->part->child_flag & PART_CHILD_USE_TWIST_CURVE) && psys->part->twistcurve)
-               curvemapping_changed_all(psys->part->twistcurve);
-
-/* 2. */
-       sim.scene = scene;
-       sim.ob = ob;
-       sim.psys = psys;
-       sim.psmd = psys_get_modifier(ob, psys);
-
-       if (part->phystype == PART_PHYS_KEYED) {
-               if (psys->flag & PSYS_KEYED) {
-                       psys_count_keyed_targets(&sim);
-                       if (psys->totkeyed == 0)
-                               return;
-               }
-       }
-
-       if (select) {
-               select = false;
-               if (psys_get_current(ob) == psys)
-                       select = true;
-       }
-
-       psys->flag |= PSYS_DRAWING;
-
-       if (part->type == PART_HAIR && !psys->childcache)
-               totchild = 0;
-       else
-               totchild = psys->totchild * part->disp / 100;
-
-       ma = give_current_material(ob, part->omat);
-
-       if (v3d->zbuf) glDepthMask(1);
-
-       if ((ma) && (part->draw_col == PART_DRAW_COL_MAT)) {
-               rgb_float_to_uchar(tcol, &(ma->r));
-               copy_v3_v3(ma_col, &ma->r);
-       }
-
-       if ((dflag & DRAW_CONSTCOLOR) == 0) {
-               glColor3ubv(tcol);
-       }
-
-       timestep = psys_get_timestep(&sim);
-
-       if ((base->flag & OB_FROMDUPLI) && (ob->flag & OB_FROMGROUP)) {
-               float mat[4][4];
-               mul_m4_m4m4(mat, ob->obmat, psys->imat);
-               glMultMatrixf(mat);
-       }
-
-       /* needed for text display */
-       invert_m4_m4(ob->imat, ob->obmat);
-
-       totpart = psys->totpart;
-
-       cfra = BKE_scene_frame_get(scene);
-
-       if (draw_as == PART_DRAW_PATH && psys->pathcache == NULL && psys->childcache == NULL)
-               draw_as = PART_DRAW_DOT;
-
-/* 3. */
-       glLineWidth(1.0f);
-
-       switch (draw_as) {
-               case PART_DRAW_DOT:
-                       if (part->draw_size)
-                               glPointSize(part->draw_size);
-                       else
-                               glPointSize(2.0);  /* default dot size */
-                       break;
-               case PART_DRAW_CIRC:
-                       /* calculate view aligned matrix: */
-                       copy_m4_m4(imat, rv3d->viewinv);
-                       normalize_v3(imat[0]);
-                       normalize_v3(imat[1]);
-                       ATTR_FALLTHROUGH;
-               case PART_DRAW_CROSS:
-               case PART_DRAW_AXIS:
-                       /* lets calculate the scale: */
-
-                       if (part->draw_size == 0.0)
-                               pixsize_scale = 2.0f;
-                       else
-                               pixsize_scale = part->draw_size;
-
-                       if (draw_as == PART_DRAW_AXIS)
-                               create_cdata = 1;
-                       break;
-               case PART_DRAW_OB:
-                       if (part->dup_ob == NULL)
-                               draw_as = PART_DRAW_DOT;
-                       else
-                               draw_as = 0;
-                       break;
-               case PART_DRAW_GR:
-                       if (part->dup_group == NULL)
-                               draw_as = PART_DRAW_DOT;
-                       else
-                               draw_as = 0;
-                       break;
-               case PART_DRAW_BB:
-                       if (v3d->camera == NULL && part->bb_ob == NULL) {
-                               printf("Billboards need an active camera or a target object!\n");
-
-                               draw_as = part->draw_as = PART_DRAW_DOT;
-
-                               if (part->draw_size)
-                                       glPointSize(part->draw_size);
-                               else
-                                       glPointSize(2.0);  /* default dot size */
-                       }
-                       else if (part->bb_ob)
-                               bb.ob = part->bb_ob;
-                       else
-                               bb.ob = v3d->camera;
-
-                       bb.align = part->bb_align;
-                       bb.anim = part->bb_anim;
-                       bb.lock = part->draw & PART_DRAW_BB_LOCK;
-                       break;
-               case PART_DRAW_PATH:
-                       break;
-               case PART_DRAW_LINE:
-                       need_v = 1;
-                       break;
-       }
-       if (part->draw & PART_DRAW_SIZE && part->draw_as != PART_DRAW_CIRC) {
-               copy_m4_m4(imat, rv3d->viewinv);
-               normalize_v3(imat[0]);
-               normalize_v3(imat[1]);
-       }
-
-       if (ELEM(draw_as, PART_DRAW_DOT, PART_DRAW_CROSS, PART_DRAW_LINE) &&
-           (part->draw_col > PART_DRAW_COL_MAT))
-       {
-               create_cdata = 1;
-       }
-
-       if (!create_cdata && pdd && pdd->cdata) {
-               MEM_freeN(pdd->cdata);
-               pdd->cdata = pdd->cd = NULL;
-       }
-
-/* 4. */
-       if (draw_as && ELEM(draw_as, PART_DRAW_PATH, PART_DRAW_CIRC) == 0) {
-               int partsize = 3 * sizeof(float);
-               int create_ndata = 0;
-
-               if (!pdd)
-                       pdd = psys->pdd = MEM_callocN(sizeof(ParticleDrawData), "ParticleDrawData");
-
-               if (part->draw_as == PART_DRAW_REND && part->trail_count > 1) {
-                       partsize *= part->trail_count;
-                       psys_make_temp_pointcache(ob, psys);
-               }
-
-               switch (draw_as) {
-                       case PART_DRAW_AXIS:
-                       case PART_DRAW_CROSS:
-                               partsize *= 6;
-                               if (draw_as != PART_DRAW_CROSS)
-                                       create_cdata = 1;
-                               break;
-                       case PART_DRAW_LINE:
-                               partsize *= 2;
-                               break;
-                       case PART_DRAW_BB:
-                               partsize *= 4;
-                               create_ndata = 1;
-                               break;
-               }
-
-               if (pdd->totpart != totpart + totchild || pdd->partsize != partsize)
-                       psys_free_pdd(psys);
-
-               if (!pdd->vdata)
-                       pdd->vdata = MEM_calloc_arrayN(totpart + totchild, partsize, "particle_vdata");
-               if (create_cdata && !pdd->cdata)
-                       pdd->cdata = MEM_calloc_arrayN(totpart + totchild, partsize, "particle_cdata");
-               if (create_ndata && !pdd->ndata)
-                       pdd->ndata = MEM_calloc_arrayN(totpart + totchild, partsize, "particle_ndata");
-
-               if (part->draw & PART_DRAW_VEL && draw_as != PART_DRAW_LINE) {
-                       if (!pdd->vedata)
-                               pdd->vedata = MEM_calloc_arrayN(totpart + totchild, 2 * 3 * sizeof(float), "particle_vedata");
-
-                       need_v = 1;
-               }
-               else if (pdd->vedata) {
-                       /* velocity data not needed, so free it */
-                       MEM_freeN(pdd->vedata);
-                       pdd->vedata = NULL;
-               }
-
-               pdd->vd = pdd->vdata;
-               pdd->ved = pdd->vedata;
-               pdd->cd = pdd->cdata;
-               pdd->nd = pdd->ndata;
-               pdd->totpart = totpart + totchild;
-               pdd->partsize = partsize;
-       }
-       else if (psys->pdd) {
-               psys_free_pdd(psys);
-               MEM_freeN(psys->pdd);
-               pdd = psys->pdd = NULL;
-       }
-
-       if (pdd) {
-               pdd->ma_col = ma_col;
-       }
-
-       psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);
-
-       /* circles don't use drawdata, so have to add a special case here */
-       if ((pdd || draw_as == PART_DRAW_CIRC) && draw_as != PART_DRAW_PATH) {
-               /* 5. */
-               if (pdd && (pdd->flag & PARTICLE_DRAW_DATA_UPDATED) &&
-                   (pdd->vedata || part->draw & (PART_DRAW_SIZE | PART_DRAW_NUM | PART_DRAW_HEALTH)) == 0)
-               {
-                       totpoint = pdd->totpoint; /* draw data is up to date */
-               }
-               else {
-                       for (a = 0, pa = pars; a < totpart + totchild; a++, pa++) {
-                               /* setup per particle individual stuff */
-                               if (a < totpart) {
-                                       if (totchild && (part->draw & PART_DRAW_PARENT) == 0) continue;
-                                       if (pa->flag & PARS_NO_DISP || pa->flag & PARS_UNEXIST) continue;
-
-                                       pa_time = (cfra - pa->time) / pa->lifetime;
-                                       pa_birthtime = pa->time;
-                                       pa_dietime = pa->dietime;
-                                       pa_size = pa->size;
-                                       if (part->phystype == PART_PHYS_BOIDS)
-                                               pa_health = pa->boid->data.health;
-                                       else
-                                               pa_health = -1.0;
-
-                                       r_tilt = 2.0f * (psys_frand(psys, a + 21) - 0.5f);
-                                       r_length = psys_frand(psys, a + 22);
-
-                                       if (part->draw_col > PART_DRAW_COL_MAT) {
-                                               switch (part->draw_col) {
-                                                       case PART_DRAW_COL_VEL:
-                                                               intensity = len_v3(pa->state.vel) / part->color_vec_max;
-                                                               break;
-                                                       case PART_DRAW_COL_ACC:
-                                                               intensity = len_v3v3(pa->state.vel, pa->prev_state.vel) / ((pa->state.time - pa->prev_state.time) * part->color_vec_max);
-                                                               break;
-                                                       default:
-                                                               intensity = 1.0f; /* should never happen */
-                                                               BLI_assert(0);
-                                                               break;
-                                               }
-                                               CLAMP(intensity, 0.0f, 1.0f);
-                                               weight_to_rgb(ma_col, intensity);
-                                       }
-                               }
-                               else {
-                                       ChildParticle *cpa = &psys->child[a - totpart];
-
-                                       pa_time = psys_get_child_time(psys, cpa, cfra, &pa_birthtime, &pa_dietime);
-                                       pa_size = psys_get_child_size(psys, cpa, cfra, NULL);
-
-                                       pa_health = -1.0;
-
-                                       r_tilt = 2.0f * (psys_frand(psys, a + 21) - 0.5f);
-                                       r_length = psys_frand(psys, a + 22);
-                               }
-
-                               drawn = 0;
-                               if (part->draw_as == PART_DRAW_REND && part->trail_count > 1) {
-                                       float length = part->path_end * (1.0f - part->randlength * r_length);
-                                       int trail_count = part->trail_count * (1.0f - part->randlength * r_length);
-                                       float ct = ((part->draw & PART_ABS_PATH_TIME) ? cfra : pa_time) - length;
-                                       float dt = length / (trail_count ? (float)trail_count : 1.0f);
-                                       int i = 0;
-
-                                       ct += dt;
-                                       for (i = 0; i < trail_count; i++, ct += dt) {
-
-                                               if (part->draw & PART_ABS_PATH_TIME) {
-                                                       if (ct < pa_birthtime || ct > pa_dietime)
-                                                               continue;
-                                               }
-                                               else if (ct < 0.0f || ct > 1.0f)
-                                                       continue;
-
-                                               state.time = (part->draw & PART_ABS_PATH_TIME) ? -ct : -(pa_birthtime + ct * (pa_dietime - pa_birthtime));
-                                               psys_get_particle_on_path(&sim, a, &state, need_v);
-
-                                               draw_particle_data(psys, rv3d,
-                                                                  &state, draw_as, imat, &bb, psys->pdd,
-                                                                  ct, pa_size, r_tilt, pixsize_scale);
-
-                                               totpoint++;
-                                               drawn = 1;
-                                       }
-                               }
-                               else {
-                                       state.time = cfra;
-                                       if (psys_get_particle_state(&sim, a, &state, 0)) {
-
-                                               draw_particle_data(psys, rv3d,
-                                                                  &state, draw_as, imat, &bb, psys->pdd,
-                                                                  pa_time, pa_size, r_tilt, pixsize_scale);
-
-                                               totpoint++;
-                                               drawn = 1;
-                                       }
-                               }
-
-                               if (drawn) {
-                                       /* additional things to draw for each particle
-                                        * (velocity, size and number) */
-                                       if ((part->draw & PART_DRAW_VEL) && pdd && pdd->vedata) {
-                                               copy_v3_v3(pdd->ved, state.co);
-                                               pdd->ved += 3;
-                                               mul_v3_v3fl(vel, state.vel, timestep);
-                                               add_v3_v3v3(pdd->ved, state.co, vel);
-                                               pdd->ved += 3;
-
-                                               totve++;
-                                       }
-
-                                       if (part->draw & PART_DRAW_SIZE) {
-                                               setlinestyle(3);
-                                               drawcircball(GL_LINE_LOOP, state.co, pa_size, imat);
-                                               setlinestyle(0);
-                                       }
-
-
-                                       if ((part->draw & PART_DRAW_NUM || part->draw & PART_DRAW_HEALTH) &&
-                                           (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0)
-                                       {
-                                               size_t numstr_len;
-                                               float vec_txt[3];
-                                               char *val_pos = numstr;
-                                               numstr[0] = '\0';
-
-                                               if (part->draw & PART_DRAW_NUM) {
-                                                       if (a < totpart && (part->draw & PART_DRAW_HEALTH) && (part->phystype == PART_PHYS_BOIDS)) {
-                                                               numstr_len = BLI_snprintf_rlen(val_pos, sizeof(numstr), "%d:%.2f", a, pa_health);
-                                                       }
-                                                       else {
-                                                               numstr_len = BLI_snprintf_rlen(val_pos, sizeof(numstr), "%d", a);
-                                                       }
-                                               }
-                                               else {
-                                                       if (a < totpart && (part->draw & PART_DRAW_HEALTH) && (part->phystype == PART_PHYS_BOIDS)) {
-                                                               numstr_len = BLI_snprintf_rlen(val_pos, sizeof(numstr), "%.2f", pa_health);
-                                                       }
-                                               }
-
-                                               if (numstr[0]) {
-                                                       /* in path drawing state.co is the end point
-                                                        * use worldspace because object matrix is already applied */
-                                                       mul_v3_m4v3(vec_txt, ob->imat, state.co);
-                                                       view3d_cached_text_draw_add(vec_txt, numstr, numstr_len,
-                                                                                   10, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, tcol);
-                                               }
-                                       }
-                               }
-                       }
-               }
-       }
-/* 6. */
-
-       glGetIntegerv(GL_POLYGON_MODE, polygonmode);
-       glEnableClientState(GL_VERTEX_ARRAY);
-
-       if (draw_as == PART_DRAW_PATH) {
-               ParticleCacheKey **cache, *path;
-               float *cdata2 = NULL;
-
-               /* setup gl flags */
-               if (1) { //ob_dt > OB_WIRE) {
-                       glEnableClientState(GL_NORMAL_ARRAY);
-
-                       if ((dflag & DRAW_CONSTCOLOR) == 0) {
-                               if (part->draw_col == PART_DRAW_COL_MAT)
-                                       glEnableClientState(GL_COLOR_ARRAY);
-                       }
-
-                       // XXX test
-                       GPU_basic_shader_colors(NULL, NULL, 0.0f, 1.0f);
-                       GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR);
-               }
-
-               if (totchild && (part->draw & PART_DRAW_PARENT) == 0)
-                       totpart = 0;
-               else if (psys->pathcache == NULL)
-                       totpart = 0;
-
-               /* draw actual/parent particles */
-               cache = psys->pathcache;
-               for (a = 0, pa = psys->particles; a < totpart; a++, pa++) {
-                       path = cache[a];
-                       if (path->segments > 0) {
-                               glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co);
-
-                               if (1) { //ob_dt > OB_WIRE) {
-                                       glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel);
-                                       if ((dflag & DRAW_CONSTCOLOR) == 0) {
-                                               if (part->draw_col == PART_DRAW_COL_MAT) {
-                                                       glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col);
-                                               }
-                                       }
-                               }
-
-                               glDrawArrays(GL_LINE_STRIP, 0, path->segments + 1);
-                       }
-               }
-
-               if (part->type ==  PART_HAIR) {
-                       if (part->draw & PART_DRAW_GUIDE_HAIRS) {
-                               DerivedMesh *hair_dm = psys->hair_out_dm;
-
-                               glDisableClientState(GL_NORMAL_ARRAY);
-                               glDisableClientState(GL_COLOR_ARRAY);
-
-                               for (a = 0, pa = psys->particles; a < totpart; a++, pa++) {
-                                       if (pa->totkey > 1) {
-                                               HairKey *hkey = pa->hair;
-
-                                               glVertexPointer(3, GL_FLOAT, sizeof(HairKey), hkey->world_co);
-
-#if 0 /* XXX use proper theme color here */
-                                               UI_ThemeColor(TH_NORMAL);
-#else
-                                               glColor3f(0.58f, 0.67f, 1.0f);
-#endif
-
-                                               glDrawArrays(GL_LINE_STRIP, 0, pa->totkey);
-                                       }
-                               }
-
-                               if (hair_dm) {
-                                       MVert *mvert = hair_dm->getVertArray(hair_dm);
-                                       int i;
-
-                                       glColor3f(0.9f, 0.4f, 0.4f);
-
-                                       glBegin(GL_LINES);
-                                       for (a = 0, pa = psys->particles; a < totpart; a++, pa++) {
-                                               for (i = 1; i < pa->totkey; ++i) {
-                                                       float v1[3], v2[3];
-
-                                                       copy_v3_v3(v1, mvert[pa->hair_index + i - 1].co);
-                                                       copy_v3_v3(v2, mvert[pa->hair_index + i].co);
-
-                                                       mul_m4_v3(ob->obmat, v1);
-                                                       mul_m4_v3(ob->obmat, v2);
-
-                                                       glVertex3fv(v1);
-                                                       glVertex3fv(v2);
-                                               }
-                                       }
-                                       glEnd();
-                               }
-
-                               glEnableClientState(GL_NORMAL_ARRAY);
-                               if ((dflag & DRAW_CONSTCOLOR) == 0)
-                                       if (part->draw_col == PART_DRAW_COL_MAT)
-                                               glEnableClientState(GL_COLOR_ARRAY);
-                       }
-
-                       if (part->draw & PART_DRAW_HAIR_GRID) {
-                               ClothModifierData *clmd = psys->clmd;
-                               if (clmd) {
-                                       float *gmin = clmd->hair_grid_min;
-                                       float *gmax = clmd->hair_grid_max;
-                                       int *res = clmd->hair_grid_res;
-                                       int i;
-
-                                       glDisableClientState(GL_NORMAL_ARRAY);
-                                       glDisableClientState(GL_COLOR_ARRAY);
-
-                                       if (select)
-                                               UI_ThemeColor(TH_ACTIVE);
-                                       else
-                                               UI_ThemeColor(TH_WIRE);
-                                       glBegin(GL_LINES);
-                                       glVertex3f(gmin[0], gmin[1], gmin[2]); glVertex3f(gmax[0], gmin[1], gmin[2]);
-                                       glVertex3f(gmax[0], gmin[1], gmin[2]); glVertex3f(gmax[0], gmax[1], gmin[2]);
-                                       glVertex3f(gmax[0], gmax[1], gmin[2]); glVertex3f(gmin[0], gmax[1], gmin[2]);
-                                       glVertex3f(gmin[0], gmax[1], gmin[2]); glVertex3f(gmin[0], gmin[1], gmin[2]);
-
-                                       glVertex3f(gmin[0], gmin[1], gmax[2]); glVertex3f(gmax[0], gmin[1], gmax[2]);
-                                       glVertex3f(gmax[0], gmin[1], gmax[2]); glVertex3f(gmax[0], gmax[1], gmax[2]);
-                                       glVertex3f(gmax[0], gmax[1], gmax[2]); glVertex3f(gmin[0], gmax[1], gmax[2]);
-                                       glVertex3f(gmin[0], gmax[1], gmax[2]); glVertex3f(gmin[0], gmin[1], gmax[2]);
-
-                                       glVertex3f(gmin[0], gmin[1], gmin[2]); glVertex3f(gmin[0], gmin[1], gmax[2]);
-                                       glVertex3f(gmax[0], gmin[1], gmin[2]); glVertex3f(gmax[0], gmin[1], gmax[2]);
-                                       glVertex3f(gmin[0], gmax[1], gmin[2]); glVertex3f(gmin[0], gmax[1], gmax[2]);
-                                       glVertex3f(gmax[0], gmax[1], gmin[2]); glVertex3f(gmax[0], gmax[1], gmax[2]);
-                                       glEnd();
-
-                                       if (select)
-                                               UI_ThemeColorShadeAlpha(TH_ACTIVE, 0, -100);
-                                       else
-                                               UI_ThemeColorShadeAlpha(TH_WIRE, 0, -100);
-                                       glEnable(GL_BLEND);
-                                       glBegin(GL_LINES);
-                                       for (i = 1; i < res[0] - 1; ++i) {
-                                               float f = interpf(gmax[0], gmin[0], (float)i / (float)(res[0] - 1));
-                                               glVertex3f(f, gmin[1], gmin[2]); glVertex3f(f, gmax[1], gmin[2]);
-                                               glVertex3f(f, gmax[1], gmin[2]); glVertex3f(f, gmax[1], gmax[2]);
-                                               glVertex3f(f, gmax[1], gmax[2]); glVertex3f(f, gmin[1], gmax[2]);
-                                               glVertex3f(f, gmin[1], gmax[2]); glVertex3f(f, gmin[1], gmin[2]);
-                                       }
-                                       for (i = 1; i < res[1] - 1; ++i) {
-                                               float f = interpf(gmax[1], gmin[1], (float)i / (float)(res[1] - 1));
-                                               glVertex3f(gmin[0], f, gmin[2]); glVertex3f(gmax[0], f, gmin[2]);
-                                               glVertex3f(gmax[0], f, gmin[2]); glVertex3f(gmax[0], f, gmax[2]);
-                                               glVertex3f(gmax[0], f, gmax[2]); glVertex3f(gmin[0], f, gmax[2]);
-                                               glVertex3f(gmin[0], f, gmax[2]); glVertex3f(gmin[0], f, gmin[2]);
-                                       }
-                                       for (i = 1; i < res[2] - 1; ++i) {
-                                               float f = interpf(gmax[2], gmin[2], (float)i / (float)(res[2] - 1));
-                                               glVertex3f(gmin[0], gmin[1], f); glVertex3f(gmax[0], gmin[1], f);
-                                               glVertex3f(gmax[0], gmin[1], f); glVertex3f(gmax[0], gmax[1], f);
-                                               glVertex3f(gmax[0], gmax[1], f); glVertex3f(gmin[0], gmax[1], f);
-                                               glVertex3f(gmin[0], gmax[1], f); glVertex3f(gmin[0], gmin[1], f);
-                                       }
-                                       glEnd();
-                                       glDisable(GL_BLEND);
-
-                                       glEnableClientState(GL_NORMAL_ARRAY);
-                                       if ((dflag & DRAW_CONSTCOLOR) == 0)
-                                               if (part->draw_col == PART_DRAW_COL_MAT)
-                                                       glEnableClientState(GL_COLOR_ARRAY);
-                               }
-                       }
-               }
-
-               /* draw child particles */
-               cache = psys->childcache;
-               for (a = 0; a < totchild; a++) {
-                       path = cache[a];
-                       glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co);
-
-                       if (1) { //ob_dt > OB_WIRE) {
-                               glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel);
-                               if ((dflag & DRAW_CONSTCOLOR) == 0) {
-                                       if (part->draw_col == PART_DRAW_COL_MAT) {
-                                               glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col);
-                                       }
-                               }
-                       }
-
-                       glDrawArrays(GL_LINE_STRIP, 0, path->segments + 1);
-               }
-
-               /* restore & clean up */
-               if (1) { //ob_dt > OB_WIRE) {
-                       if (part->draw_col == PART_DRAW_COL_MAT)
-                               glDisableClientState(GL_COLOR_ARRAY);
-                       GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
-               }
-
-               if (cdata2) {
-                       MEM_freeN(cdata2);
-                       cdata2 = NULL;
-               }
-
-               if ((part->draw & PART_DRAW_NUM) && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
-                       cache = psys->pathcache;
-
-                       for (a = 0, pa = psys->particles; a < totpart; a++, pa++) {
-                               float vec_txt[3];
-                               size_t numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%i", a);
-                               /* use worldspace because object matrix is already applied */
-                               mul_v3_m4v3(vec_txt, ob->imat, cache[a]->co);
-                               view3d_cached_text_draw_add(vec_txt, numstr, numstr_len,
-                                                           10, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, tcol);
-                       }
-               }
-       }
-       else if (pdd && ELEM(draw_as, 0, PART_DRAW_CIRC) == 0) {
-               glDisableClientState(GL_COLOR_ARRAY);
-
-               /* enable point data array */
-               if (pdd->vdata) {
-                       glEnableClientState(GL_VERTEX_ARRAY);
-                       glVertexPointer(3, GL_FLOAT, 0, pdd->vdata);
-               }
-               else
-                       glDisableClientState(GL_VERTEX_ARRAY);
-
-               if ((dflag & DRAW_CONSTCOLOR) == 0) {
-                       if (select) {
-                               UI_ThemeColor(TH_ACTIVE);
-
-                               if (part->draw_size)
-                                       glPointSize(part->draw_size + 2);
-                               else
-                                       glPointSize(4.0);
-
-                               glLineWidth(3.0);
-
-                               draw_particle_arrays(draw_as, totpoint, ob_dt, 1);
-                       }
-
-                       /* restore from select */
-                       glColor3fv(ma_col);
-               }
-
-               glPointSize(part->draw_size ? part->draw_size : 2.0);
-               glLineWidth(1.0);
-
-               /* enable other data arrays */
-
-               /* billboards are drawn this way */
-               if (pdd->ndata && ob_dt > OB_WIRE) {
-                       glEnableClientState(GL_NORMAL_ARRAY);
-                       glNormalPointer(GL_FLOAT, 0, pdd->ndata);
-                       GPU_basic_shader_colors(NULL, NULL, 0.0f, 1.0f);
-                       GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR);
-               }
-
-               if ((dflag & DRAW_CONSTCOLOR) == 0) {
-                       if (pdd->cdata) {
-                               glEnableClientState(GL_COLOR_ARRAY);
-                               glColorPointer(3, GL_FLOAT, 0, pdd->cdata);
-                       }
-               }
-
-               draw_particle_arrays(draw_as, totpoint, ob_dt, 0);
-
-               pdd->flag |= PARTICLE_DRAW_DATA_UPDATED;
-               pdd->totpoint = totpoint;
-       }
-
-       if (pdd && pdd->vedata) {
-               if ((dflag & DRAW_CONSTCOLOR) == 0) {
-                       glDisableClientState(GL_COLOR_ARRAY);
-                       cpack(0xC0C0C0);
-               }
-
-               glVertexPointer(3, GL_FLOAT, 0, pdd->vedata);
-
-               glDrawArrays(GL_LINES, 0, 2 * totve);
-       }
-
-       glPolygonMode(GL_FRONT, polygonmode[0]);
-       glPolygonMode(GL_BACK, polygonmode[1]);
-
-/* 7. */
-
-       GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
-       glDisableClientState(GL_COLOR_ARRAY);
-       glDisableClientState(GL_VERTEX_ARRAY);
-       glDisableClientState(GL_NORMAL_ARRAY);
-
-       if (states)
-               MEM_freeN(states);
-
-       psys->flag &= ~PSYS_DRAWING;
-
-       /* draw data can't be saved for billboards as they must update to target changes */
-       if (draw_as == PART_DRAW_BB) {
-               psys_free_pdd(psys);
-               pdd->flag &= ~PARTICLE_DRAW_DATA_UPDATED;
-       }
-
-       if (psys->lattice_deform_data) {
-               end_latt_deform(psys->lattice_deform_data);
-               psys->lattice_deform_data = NULL;
-       }
-
-       if (pdd) {
-               /* drop references to stack memory */
-               pdd->ma_col = NULL;
-       }
-
-       if ((base->flag & OB_FROMDUPLI) && (ob->flag & OB_FROMGROUP)) {
-               glLoadMatrixf(rv3d->viewmat);
-       }
-}
-
-static void draw_update_ptcache_edit(Scene *scene, Object *ob, PTCacheEdit *edit)
-{
-       if (edit->psys && edit->psys->flag & PSYS_HAIR_UPDATED)
-               PE_update_object(scene, ob, 0);
-
-       /* create path and child path cache if it doesn't exist already */
-       if (edit->pathcache == NULL)
-               psys_cache_edit_paths(scene, ob, edit, CFRA, G.is_rendering);
-}
-
-static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit)
-{
-       ParticleCacheKey **cache, *path, *pkey;
-       PTCacheEditPoint *point;
-       PTCacheEditKey *key;
-       ParticleEditSettings *pset = PE_settings(scene);
-       int i, k, totpoint = edit->totpoint, timed = (pset->flag & PE_FADE_TIME) ? pset->fade_frames : 0;
-       int totkeys = 1;
-       float sel_col[3];
-       float nosel_col[3];
-       float *pathcol = NULL, *pcol;
-
-       if (edit->pathcache == NULL)
-               return;
-
-       PE_hide_keys_time(scene, edit, CFRA);
-
-       /* opengl setup */
-       if ((v3d->flag & V3D_ZBUF_SELECT) == 0)
-               glDisable(GL_DEPTH_TEST);
-
-       /* get selection theme colors */
-       UI_GetThemeColor3fv(TH_VERTEX_SELECT, sel_col);
-       UI_GetThemeColor3fv(TH_VERTEX, nosel_col);
-
-       /* draw paths */
-       totkeys = (*edit->pathcache)->segments + 1;
-
-       glEnable(GL_BLEND);
-       pathcol = MEM_calloc_arrayN(totkeys, 4 * sizeof(float), "particle path color data");
-
-       glEnableClientState(GL_VERTEX_ARRAY);
-       glEnableClientState(GL_COLOR_ARRAY);
-
-       if (pset->brushtype == PE_BRUSH_WEIGHT)
-               glLineWidth(2.0f);
-
-       cache = edit->pathcache;
-       for (i = 0, point = edit->points; i < totpoint; i++, point++) {
-               path = cache[i];
-               glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co);
-
-               if (point->flag & PEP_HIDE) {
-                       for (k = 0, pcol = pathcol; k < totkeys; k++, pcol += 4) {
-                               copy_v3_v3(pcol, path->col);
-                               pcol[3] = 0.25f;
-                       }
-
-                       glColorPointer(4, GL_FLOAT, 4 * sizeof(float), pathcol);
-               }
-               else if (timed) {
-                       for (k = 0, pcol = pathcol, pkey = path; k < totkeys; k++, pkey++, pcol += 4) {
-                               copy_v3_v3(pcol, pkey->col);
-                               pcol[3] = 1.0f - fabsf((float)(CFRA) -pkey->time) / (float)pset->fade_frames;
-                       }
-
-                       glColorPointer(4, GL_FLOAT, 4 * sizeof(float), pathcol);
-               }
-               else
-                       glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col);
-
-               glDrawArrays(GL_LINE_STRIP, 0, path->segments + 1);
-       }
-
-       if (pathcol) { MEM_freeN(pathcol); pathcol = pcol = NULL; }
-
-
-       /* draw edit vertices */
-       if (pset->selectmode != SCE_SELECT_PATH) {
-               glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
-
-               if (pset->selectmode == SCE_SELECT_POINT) {
-                       float *pd = NULL, *pdata = NULL;
-                       float *cd = NULL, *cdata = NULL;
-                       int totkeys_visible = 0;
-
-                       for (i = 0, point = edit->points; i < totpoint; i++, point++)
-                               if (!(point->flag & PEP_HIDE))
-                                       totkeys_visible += point->totkey;
-
-                       if (totkeys_visible) {
-                               if (edit->points && !(edit->points->keys->flag & PEK_USE_WCO))
-                                       pd = pdata = MEM_calloc_arrayN(totkeys_visible, 3 * sizeof(float), "particle edit point data");
-                               cd = cdata = MEM_calloc_arrayN(totkeys_visible, (timed ? 4 : 3) * sizeof(float), "particle edit color data");
-                       }
-
-                       for (i = 0, point = edit->points; i < totpoint; i++, point++) {
-                               if (point->flag & PEP_HIDE)
-                                       continue;
-
-                               for (k = 0, key = point->keys; k < point->totkey; k++, key++) {
-                                       if (pd) {
-                                               copy_v3_v3(pd, key->co);
-                                               pd += 3;
-                                       }
-
-                                       if (key->flag & PEK_SELECT) {
-                                               copy_v3_v3(cd, sel_col);
-                                       }
-                                       else {
-                                               copy_v3_v3(cd, nosel_col);
-                                       }
-
-                                       if (timed)
-                                               *(cd + 3) = 1.0f - fabsf((float)CFRA - *key->time) / (float)pset->fade_frames;
-
-                                       cd += (timed ? 4 : 3);
-                               }
-                       }
-                       cd = cdata;
-                       pd = pdata;
-                       for (i = 0, point = edit->points; i < totpoint; i++, point++) {
-                               if (point->flag & PEP_HIDE || point->totkey == 0)
-                                       continue;
-
-                               if (point->keys->flag & PEK_USE_WCO)
-                                       glVertexPointer(3, GL_FLOAT, sizeof(PTCacheEditKey), point->keys->world_co);
-                               else
-                                       glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), pd);
-
-                               glColorPointer((timed ? 4 : 3), GL_FLOAT, (timed ? 4 : 3) * sizeof(float), cd);
-
-                               glDrawArrays(GL_POINTS, 0, point->totkey);
-
-                               pd += pd ? 3 * point->totkey : 0;
-                               cd += (timed ? 4 : 3) * point->totkey;
-                       }
-                       if (pdata) { MEM_freeN(pdata); pd = pdata = NULL; }
-                       if (cdata) { MEM_freeN(cdata); cd = cdata = NULL; }
-               }
-               else if (pset->selectmode == SCE_SELECT_END) {
-                       glBegin(GL_POINTS);
-                       for (i = 0, point = edit->points; i < totpoint; i++, point++) {
-                               if ((point->flag & PEP_HIDE) == 0 && point->totkey) {
-                                       key = point->keys + point->totkey - 1;
-                                       glColor3fv((key->flag & PEK_SELECT) ? sel_col : nosel_col);
-                                       /* has to be like this.. otherwise selection won't work, have try glArrayElement later..*/
-                                       glVertex3fv((key->flag & PEK_USE_WCO) ? key->world_co : key->co);
-                               }
-                       }
-                       glEnd();
-               }
-       }
-
-       glDisable(GL_BLEND);
-       glDisableClientState(GL_COLOR_ARRAY);
-       glDisableClientState(GL_NORMAL_ARRAY);
-       glDisableClientState(GL_VERTEX_ARRAY);
-       if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
-}
-
-static void ob_draw_RE_motion(float com[3], float rotscale[3][3], float itw, float ith, float drw_size)
-{
-       float tr[3][3];
-       float root[3], tip[3];
-       /* take a copy for not spoiling original */
-       copy_m3_m3(tr, rotscale);
-       float tw = itw * drw_size;
-       float th = ith * drw_size;
-
-       glBegin(GL_LINES);
-
-       glColor4ub(0x7F, 0x00, 0x00, 155);
-       root[1] = root[2] = 0.0f;
-       root[0] = -drw_size;
-       mul_m3_v3(tr, root);
-       add_v3_v3(root, com);
-       glVertex3fv(root);
-       tip[1] = tip[2] = 0.0f;
-       tip[0] = drw_size;
-       mul_m3_v3(tr, tip);
-       add_v3_v3(tip, com);
-       glVertex3fv(tip);
-
-       root[1] = 0.0f; root[2] = tw;
-       root[0] = th;
-       mul_m3_v3(tr, root);
-       add_v3_v3(root, com);
-       glVertex3fv(root);
-       glVertex3fv(tip);
-
-       root[1] = 0.0f; root[2] = -tw;
-       root[0] = th;
-       mul_m3_v3(tr, root);
-       add_v3_v3(root, com);
-       glVertex3fv(root);
-       glVertex3fv(tip);
-
-       root[1] = tw; root[2] = 0.0f;
-       root[0] = th;
-       mul_m3_v3(tr, root);
-       add_v3_v3(root, com);
-       glVertex3fv(root);
-       glVertex3fv(tip);
-
-       root[1] = -tw; root[2] = 0.0f;
-       root[0] = th;
-       mul_m3_v3(tr, root);
-       add_v3_v3(root, com);
-       glVertex3fv(root);
-       glVertex3fv(tip);
-
-       glColor4ub(0x00, 0x7F, 0x00, 155);
-
-       root[0] = root[2] = 0.0f;
-       root[1] = -drw_size;
-       mul_m3_v3(tr, root);
-       add_v3_v3(root, com);
-       glVertex3fv(root);
-       tip[0] = tip[2] = 0.0f;
-       tip[1] = drw_size;
-       mul_m3_v3(tr, tip);
-       add_v3_v3(tip, com);
-       glVertex3fv(tip);
-
-       root[0] = 0.0f; root[2] = tw;
-       root[1] = th;
-       mul_m3_v3(tr, root);
-       add_v3_v3(root, com);
-       glVertex3fv(root);
-       glVertex3fv(tip);
-
-       root[0] = 0.0f; root[2] = -tw;
-       root[1] = th;
-       mul_m3_v3(tr, root);
-       add_v3_v3(root, com);
-       glVertex3fv(root);
-       glVertex3fv(tip);
-
-       root[0] = tw; root[2] = 0.0f;
-       root[1] = th;
-       mul_m3_v3(tr, root);
-       add_v3_v3(root, com);
-       glVertex3fv(root);
-       glVertex3fv(tip);
-
-       root[0] = -tw; root[2] = 0.0f;
-       root[1] = th;
-       mul_m3_v3(tr, root);
-       add_v3_v3(root, com);
-       glVertex3fv(root);
-       glVertex3fv(tip);
-
-       glColor4ub(0x00, 0x00, 0x7F, 155);
-       root[0] = root[1] = 0.0f;
-       root[2] = -drw_size;
-       mul_m3_v3(tr, root);
-       add_v3_v3(root, com);
-       glVertex3fv(root);
-       tip[0] = tip[1] = 0.0f;
-       tip[2] = drw_size;
-       mul_m3_v3(tr, tip);
-       add_v3_v3(tip, com);
-       glVertex3fv(tip);
-
-       root[0] = 0.0f; root[1] = tw;
-       root[2] = th;
-       mul_m3_v3(tr, root);
-       add_v3_v3(root, com);
-       glVertex3fv(root);
-       glVertex3fv(tip);
-
-       root[0] = 0.0f; root[1] = -tw;
-       root[2] = th;
-       mul_m3_v3(tr, root);
-       add_v3_v3(root, com);
-       glVertex3fv(root);
-       glVertex3fv(tip);
-
-       root[0] = tw; root[1] = 0.0f;
-       root[2] = th;
-       mul_m3_v3(tr, root);
-       add_v3_v3(root, com);
-       glVertex3fv(root);
-       glVertex3fv(tip);
-
-       root[0] = -tw; root[1] = 0.0f;
-       root[2] = th;
-       mul_m3_v3(tr, root);
-       add_v3_v3(root, com);
-       glVertex3fv(root);
-       glVertex3fv(tip);
-
-       glEnd();
-}
-
-/* place to add drawers */
-
-static void drawhandlesN(Nurb *nu, const char sel, const bool hide_handles)
-{
-       if (nu->hide || hide_handles) return;
-
-       if (nu->type == CU_BEZIER) {
-
-               const float *fp;
-
-#define TH_HANDLE_COL_TOT ((TH_HANDLE_SEL_FREE - TH_HANDLE_FREE) + 1)
-               /* use MIN2 when indexing to ensure newer files don't read outside the array */
-               unsigned char handle_cols[TH_HANDLE_COL_TOT][3];
-               const int basecol = sel ? TH_HANDLE_SEL_FREE : TH_HANDLE_FREE;
-
-               for (int a = 0; a < TH_HANDLE_COL_TOT; a++) {
-                       UI_GetThemeColor3ubv(basecol + a, handle_cols[a]);
-               }
-
-               glLineWidth(1.0f);
-
-               glBegin(GL_LINES);
-
-               BezTriple *bezt = nu->bezt;
-               int a = nu->pntsu;
-               while (a--) {
-                       if (bezt->hide == 0) {
-                               if ((bezt->f2 & SELECT) == sel) {
-                                       fp = bezt->vec[0];
-
-                                       glColor3ubv(handle_cols[MIN2(bezt->h1, TH_HANDLE_COL_TOT - 1)]);
-                                       glVertex3fv(fp);
-                                       glVertex3fv(fp + 3);
-
-                                       glColor3ubv(handle_cols[MIN2(bezt->h2, TH_HANDLE_COL_TOT - 1)]);
-                                       glVertex3fv(fp + 3);
-                                       glVertex3fv(fp + 6);
-                               }
-                               else if ((bezt->f1 & SELECT) == sel) {
-                                       fp = bezt->vec[0];
-
-                                       glColor3ubv(handle_cols[MIN2(bezt->h1, TH_HANDLE_COL_TOT - 1)]);
-                                       glVertex3fv(fp);
-                                       glVertex3fv(fp + 3);
-                               }
-                               else if ((bezt->f3 & SELECT) == sel) {
-                                       fp = bezt->vec[1];
-
-                                       glColor3ubv(handle_cols[MIN2(bezt->h2, TH_HANDLE_COL_TOT - 1)]);
-                                       glVertex3fv(fp);
-                                       glVertex3fv(fp + 3);
-                               }
-                       }
-                       bezt++;
-               }
-
-               glEnd();
-
-#undef TH_HANDLE_COL_TOT
-
-       }
-}
-
-static void drawhandlesN_active(Nurb *nu)
-{
-       if (nu->hide) return;
-
-       UI_ThemeColor(TH_ACTIVE_SPLINE);
-       glLineWidth(2);
-
-       glBegin(GL_LINES);
-
-       if (nu->type == CU_BEZIER) {
-               BezTriple *bezt = nu->bezt;
-               int a = nu->pntsu;
-               while (a--) {
-                       if (bezt->hide == 0) {
-                               const float *fp = bezt->vec[0];
-
-                               glVertex3fv(fp);
-                               glVertex3fv(fp + 3);
-
-                               glVertex3fv(fp + 3);
-                               glVertex3fv(fp + 6);
-                       }
-                       bezt++;
-               }
-       }
-       glEnd();
-
-       glColor3ub(0, 0, 0);
-}
-
-static void drawvertsN(Nurb *nu, const char sel, const bool hide_handles, const void *vert)
-{
-       if (nu->hide) return;
-
-       const int color = sel ? TH_VERTEX_SELECT : TH_VERTEX;
-
-       UI_ThemeColor(color);
-
-       glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
-
-       glBegin(GL_POINTS);
-
-       if (nu->type == CU_BEZIER) {
-
-               BezTriple *bezt = nu->bezt;
-               int a = nu->pntsu;
-               while (a--) {
-                       if (bezt->hide == 0) {
-                               if (sel == 1 && bezt == vert) {
-                                       UI_ThemeColor(TH_ACTIVE_VERT);
-
-                                       if (bezt->f2 & SELECT) glVertex3fv(bezt->vec[1]);
-                                       if (!hide_handles) {
-                                               if (bezt->f1 & SELECT) glVertex3fv(bezt->vec[0]);
-                                               if (bezt->f3 & SELECT) glVertex3fv(bezt->vec[2]);
-                                       }
-
-                                       UI_ThemeColor(color);
-                               }
-                               else if (hide_handles) {
-                                       if ((bezt->f2 & SELECT) == sel) glVertex3fv(bezt->vec[1]);
-                               }
-                               else {
-                                       if ((bezt->f1 & SELECT) == sel) glVertex3fv(bezt->vec[0]);
-                                       if ((bezt->f2 & SELECT) == sel) glVertex3fv(bezt->vec[1]);
-                                       if ((bezt->f3 & SELECT) == sel) glVertex3fv(bezt->vec[2]);
-                               }
-                       }
-                       bezt++;
-               }
-       }
-       else {
-               BPoint *bp = nu->bp;
-               int a = nu->pntsu * nu->pntsv;
-               while (a--) {
-                       if (bp->hide == 0) {
-                               if (bp == vert) {
-                                       UI_ThemeColor(TH_ACTIVE_VERT);
-                                       glVertex3fv(bp->vec);
-                                       UI_ThemeColor(color);
-                               }
-                               else {
-                                       if ((bp->f1 & SELECT) == sel) glVertex3fv(bp->vec);
-                               }
-                       }
-                       bp++;
-               }
-       }
-
-       glEnd();
-}
-
-static void editnurb_draw_active_poly(Nurb *nu)
-{
-       UI_ThemeColor(TH_ACTIVE_SPLINE);
-       glLineWidth(2);
-
-       BPoint *bp = nu->bp;
-       for (int b = 0; b < nu->pntsv; b++) {
-               if (nu->flagu & 1) glBegin(GL_LINE_LOOP);
-               else glBegin(GL_LINE_STRIP);
-
-               for (int a = 0; a < nu->pntsu; a++, bp++) {
-                       glVertex3fv(bp->vec);
-               }
-
-               glEnd();
-       }
-
-       glColor3ub(0, 0, 0);
-}
-
-static void editnurb_draw_active_nurbs(Nurb *nu)
-{
-       UI_ThemeColor(TH_ACTIVE_SPLINE);
-       glLineWidth(2);
-
-       glBegin(GL_LINES);
-       BPoint *bp = nu->bp;
-       for (int b = 0; b < nu->pntsv; b++) {
-               BPoint *bp1 = bp;
-               bp++;
-
-               for (int a = nu->pntsu - 1; a > 0; a--, bp++) {
-                       if (bp->hide == 0 && bp1->hide == 0) {
-                               glVertex3fv(bp->vec);
-                               glVertex3fv(bp1->vec);
-                       }
-                       bp1 = bp;
-               }
-       }
-
-       if (nu->pntsv > 1) {    /* surface */
-
-               int ofs = nu->pntsu;
-               for (int b = 0; b < nu->pntsu; b++) {
-                       BPoint *bp1 = nu->bp + b;
-                       bp = bp1 + ofs;
-                       for (int a = nu->pntsv - 1; a > 0; a--, bp += ofs) {
-                               if (bp->hide == 0 && bp1->hide == 0) {
-                                       glVertex3fv(bp->vec);
-                                       glVertex3fv(bp1->vec);
-                               }
-                               bp1 = bp;
-                       }
-               }
-       }
-
-       glEnd();
-
-       glColor3ub(0, 0, 0);
-}
-
-static void draw_editnurb_splines(Object *ob, Nurb *nurb, const bool sel)
-{
-       BPoint *bp, *bp1;
-       int a, b;
-       Curve *cu = ob->data;
-
-       int index = 0;
-       Nurb *nu = nurb;
-       while (nu) {
-               if (nu->hide == 0) {
-                       switch (nu->type) {
-                               case CU_POLY:
-                                       if (!sel && index == cu->actnu) {
-                                               /* we should draw active spline highlight below everything */
-                                               editnurb_draw_active_poly(nu);
-                                       }
-
-                                       glLineWidth(1);
-
-                                       UI_ThemeColor(TH_NURB_ULINE);
-                                       bp = nu->bp;
-                                       for (b = 0; b < nu->pntsv; b++) {
-                                               if (nu->flagu & 1) glBegin(GL_LINE_LOOP);
-                                               else glBegin(GL_LINE_STRIP);
-
-                                               for (a = 0; a < nu->pntsu; a++, bp++) {
-                                                       glVertex3fv(bp->vec);
-                                               }
-
-                                               glEnd();
-                                       }
-                                       break;
-                               case CU_NURBS:
-                                       if (!sel && index == cu->actnu) {
-                                               /* we should draw active spline highlight below everything */
-                                               editnurb_draw_active_nurbs(nu);
-                                       }
-
-                                       glLineWidth(1);
-
-                                       glBegin(GL_LINES);
-
-                                       bp = nu->bp;
-                                       for (b = 0; b < nu->pntsv; b++) {
-                                               bp1 = bp;
-                                               bp++;
-                                               for (a = nu->pntsu - 1; a > 0; a--, bp++) {
-                                                       if (bp->hide == 0 && bp1->hide == 0) {
-                                                               if (sel) {
-                                                                       if ((bp->f1 & SELECT) && (bp1->f1 & SELECT)) {
-                                                                               UI_ThemeColor(TH_NURB_SEL_ULINE);
-
-                                                                               glVertex3fv(bp->vec);
-                                                                               glVertex3fv(bp1->vec);
-                                                                       }
-                                                               }
-                                                               else {
-                                                                       if ((bp->f1 & SELECT) && (bp1->f1 & SELECT)) {
-                                                                               /* pass */
-                                                                       }
-                                                                       else {
-                                                                               UI_ThemeColor(TH_NURB_ULINE);
-
-                                                                               glVertex3fv(bp->vec);
-                                                                               glVertex3fv(bp1->vec);
-                                                                       }
-                                                               }
-                                                       }
-                                                       bp1 = bp;
-                                               }
-                                       }
-
-                                       if (nu->pntsv > 1) {    /* surface */
-                                               int ofs = nu->pntsu;
-                                               for (b = 0; b < nu->pntsu; b++) {
-                                                       bp1 = nu->bp + b;
-                                                       bp = bp1 + ofs;
-                                                       for (a = nu->pntsv - 1; a > 0; a--, bp += ofs) {
-                                                               if (bp->hide == 0 && bp1->hide == 0) {
-                                                                       if (sel) {
-                                                                               if ((bp->f1 & SELECT) && (bp1->f1 & SELECT)) {
-                                                                                       UI_ThemeColor(TH_NURB_SEL_VLINE);
-
-                                                                                       glVertex3fv(bp->vec);
-                                                                                       glVertex3fv(bp1->vec);
-                                                                               }
-                                                                       }
-                                                                       else {
-                                                                               if ((bp->f1 & SELECT) && (bp1->f1 & SELECT)) {
-                                                                                       /* pass */
-                                                                               }
-                                                                               else {
-                                                                                       UI_ThemeColor(TH_NURB_VLINE);
-
-                                                                                       glVertex3fv(bp->vec);
-                                                                                       glVertex3fv(bp1->vec);
-                                                                               }
-                                                                       }
-                                                               }
-                                                               bp1 = bp;
-                                                       }
-                                               }
-                                       }
-
-                                       glEnd();
-                                       break;
-                       }
-               }
-
-               index++;
-               nu = nu->next;
-       }
-}
-
-static void draw_editnurb(
-        Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, Nurb *nurb,
-        const char dt, const short dflag, const unsigned char ob_wire_col[4])
-{
-       ToolSettings *ts = scene->toolsettings;
-       Object *ob = base->object;
-       Curve *cu = ob->data;
-       Nurb *nu;
-       const void *vert = BKE_curve_vert_active_get(cu);
-       const bool hide_handles = (cu->drawflag & CU_HIDE_HANDLES) != 0;
-       unsigned char wire_col[3];
-
-       /* DispList */
-       UI_GetThemeColor3ubv(TH_WIRE_EDIT, wire_col);
-       glColor3ubv(wire_col);
-
-       drawDispList(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
-
-       /* for shadows only show solid faces */
-       if (v3d->flag2 & V3D_RENDER_SHADOW)
-               return;
-
-       if (v3d->zbuf) glDepthFunc(GL_ALWAYS);
-
-       /* first non-selected and active handles */
-       int index = 0;
-       for (nu = nurb; nu; nu = nu->next) {
-               if (nu->type == CU_BEZIER) {
-                       if (index == cu->actnu && !hide_handles)
-                               drawhandlesN_active(nu);
-                       drawhandlesN(nu, 0, hide_handles);
-               }
-               index++;
-       }
-       draw_editnurb_splines(ob, nurb, false);
-       draw_editnurb_splines(ob, nurb, true);
-       /* selected handles */
-       for (nu = nurb; nu; nu = nu->next) {
-               if (nu->type == CU_BEZIER && (cu->drawflag & CU_HIDE_HANDLES) == 0)
-                       drawhandlesN(nu, 1, hide_handles);
-               drawvertsN(nu, 0, hide_handles, NULL);
-       }
-
-       if (v3d->zbuf) glDepthFunc(GL_LEQUAL);
-
-       glColor3ubv(wire_col);
-
-       /* direction vectors for 3d curve paths
-        * when at its lowest, don't render normals */
-       if ((cu->flag & CU_3D) && (ts->normalsize > 0.0015f) && (cu->drawflag & CU_HIDE_NORMALS) == 0) {
-               BevList *bl;
-               glLineWidth(1.0f);
-               for (bl = ob->curve_cache->bev.first, nu = nurb; nu && bl; bl = bl->next, nu = nu->next) {
-                       BevPoint *bevp = bl->bevpoints;
-                       int nr = bl->nr;
-                       int skip = nu->resolu / 16;
-
-                       while (nr-- > 0) { /* accounts for empty bevel lists */
-                               const float fac = bevp->radius * ts->normalsize;
-                               float vec_a[3]; /* Offset perpendicular to the curve */
-                               float vec_b[3]; /* Delta along the curve */
-
-                               vec_a[0] = fac;
-                               vec_a[1] = 0.0f;
-                               vec_a[2] = 0.0f;
-
-                               mul_qt_v3(bevp->quat, vec_a);
-                               madd_v3_v3fl(vec_a, bevp->dir, -fac);
-
-                               reflect_v3_v3v3(vec_b, vec_a, bevp->dir);
-                               negate_v3(vec_b);
-
-                               add_v3_v3(vec_a, bevp->vec);
-                               add_v3_v3(vec_b, bevp->vec);
-
-                               glBegin(GL_LINE_STRIP);
-                               glVertex3fv(vec_a);
-                               glVertex3fv(bevp->vec);
-                               glVertex3fv(vec_b);
-                               glEnd();
-
-                               bevp += skip + 1;
-                               nr -= skip;
-                       }
-               }
-       }
-
-       if (v3d->zbuf) glDepthFunc(GL_ALWAYS);
-
-       for (nu = nurb; nu; nu = nu->next) {
-               drawvertsN(nu, 1, hide_handles, vert);
-       }
-
-       if (v3d->zbuf) glDepthFunc(GL_LEQUAL);
-}
-
-static void draw_editfont_textcurs(RegionView3D *rv3d, float textcurs[4][2])
-{
-       cpack(0);
-       ED_view3d_polygon_offset(rv3d, -1.0);
-       set_inverted_drawing(1);
-       glBegin(GL_QUADS);
-       glVertex2fv(textcurs[0]);
-       glVertex2fv(textcurs[1]);
-       glVertex2fv(textcurs[2]);
-       glVertex2fv(textcurs[3]);
-       glEnd();
-       set_inverted_drawing(0);
-       ED_view3d_polygon_offset(rv3d, 0.0);
-}
-
-static void draw_editfont(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
-                          const char dt, const short dflag, const unsigned char ob_wire_col[4])
-{
-       Object *ob = base->object;
-       Curve *cu = ob->data;
-       EditFont *ef = cu->editfont;
-       float vec1[3], vec2[3];
-
-       draw_editfont_textcurs(rv3d, ef->textcurs);
-
-       if (cu->flag & CU_FAST) {
-               cpack(0xFFFFFF);
-               set_inverted_drawing(1);
-               drawDispList(scene, v3d, rv3d, base, OB_WIRE, dflag, ob_wire_col);
-               set_inverted_drawing(0);
-       }
-       else {
-               drawDispList(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
-       }
-
-       if (cu->linewidth != 0.0f) {
-               UI_ThemeColor(TH_WIRE_EDIT);
-               copy_v3_v3(vec1, ob->orig);
-               copy_v3_v3(vec2, ob->orig);
-               vec1[0] += cu->linewidth;
-               vec2[0] += cu->linewidth;
-               vec1[1] += cu->linedist * cu->fsize;
-               vec2[1] -= cu->lines * cu->linedist * cu->fsize;
-               setlinestyle(3);
-               glBegin(GL_LINES);
-               glVertex2fv(vec1);
-               glVertex2fv(vec2);
-               glEnd();
-               setlinestyle(0);
-       }
-
-       setlinestyle(3);
-       for (int i = 0; i < cu->totbox; i++) {
-               if (cu->tb[i].w != 0.0f) {
-                       UI_ThemeColor(i == (cu->actbox - 1) ? TH_ACTIVE : TH_WIRE);
-                       vec1[0] = cu->xof + cu->tb[i].x;
-                       vec1[1] = cu->yof + cu->tb[i].y + cu->fsize;
-                       vec1[2] = 0.001;
-                       glBegin(GL_LINE_STRIP);
-                       glVertex3fv(vec1);
-                       vec1[0] += cu->tb[i].w;
-                       glVertex3fv(vec1);
-                       vec1[1] -= cu->tb[i].h;
-                       glVertex3fv(vec1);
-                       vec1[0] -= cu->tb[i].w;
-                       glVertex3fv(vec1);
-                       vec1[1] += cu->tb[i].h;
-                       glVertex3fv(vec1);
-                       glEnd();
-               }
-       }
-       setlinestyle(0);
-
-
-       if (ef->selboxes && ef->selboxes_len) {
-               float selboxw;
-
-               cpack(0xffffff);
-               set_inverted_drawing(1);
-               for (int i = 0; i < ef->selboxes_len; i++) {
-                       EditFontSelBox *sb = &ef->selboxes[i];
-                       float tvec[3];
-
-                       if (i + 1 != ef->selboxes_len) {
-                               if (ef->selboxes[i + 1].y == sb->y)
-                                       selboxw = ef->selboxes[i + 1].x - sb->x;
-                               else
-                                       selboxw = sb->w;
-                       }
-                       else {
-                               selboxw = sb->w;
-                       }
-
-                       /* fill in xy below */
-                       tvec[2] = 0.001;
-
-                       glBegin(GL_QUADS);
-
-                       if (sb->rot == 0.0f) {
-                               copy_v2_fl2(tvec, sb->x, sb->y);
-                               glVertex3fv(tvec);
-
-                               copy_v2_fl2(tvec, sb->x + selboxw, sb->y);
-                               glVertex3fv(tvec);
-
-                               copy_v2_fl2(tvec, sb->x + selboxw, sb->y + sb->h);
-                               glVertex3fv(tvec);
-
-                               copy_v2_fl2(tvec, sb->x, sb->y + sb->h);
-                               glVertex3fv(tvec);
-                       }
-                       else {
-                               float mat[2][2];
-
-                               angle_to_mat2(mat, sb->rot);
-
-                               copy_v2_fl2(tvec, sb->x, sb->y);
-                               glVertex3fv(tvec);
-
-                               copy_v2_fl2(tvec, selboxw, 0.0f);
-                               mul_m2v2(mat, tvec);
-                               add_v2_v2(tvec, &sb->x);
-                               glVertex3fv(tvec);
-
-                               copy_v2_fl2(tvec, selboxw, sb->h);
-                               mul_m2v2(mat, tvec);
-                               add_v2_v2(tvec, &sb->x);
-                               glVertex3fv(tvec);
-
-                               copy_v2_fl2(tvec, 0.0f, sb->h);
-                               mul_m2v2(mat, tvec);
-                               add_v2_v2(tvec, &sb->x);
-                               glVertex3fv(tvec);
-                       }
-
-                       glEnd();
-               }
-               set_inverted_drawing(0);
-       }
-}
-
-/* draw a sphere for use as an empty drawtype */
-static void draw_empty_sphere(float size)
-{
-       static GLuint displist = 0;
-
-       if (displist == 0) {
-               GLUquadricObj *qobj;
-
-               displist = glGenLists(1);
-               glNewList(displist, GL_COMPILE);
-
-               glPushMatrix();
-
-               qobj = gluNewQuadric();
-               gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
-               gluDisk(qobj, 0.0,  1, 16, 1);
-
-               glRotatef(90, 0, 1, 0);
-               gluDisk(qobj, 0.0,  1, 16, 1);
-
-               glRotatef(90, 1, 0, 0);
-               gluDisk(qobj, 0.0,  1, 16, 1);
-
-               gluDeleteQuadric(qobj);
-
-               glPopMatrix();
-               glEndList();
-       }
-
-       glScalef(size, size, size);
-       glCallList(displist);
-       glScalef(1.0f / size, 1.0f / size, 1.0f / size);
-}
-
-/* draw a cone for use as an empty drawtype */
-static void draw_empty_cone(float size)
-{
-       const float radius = size;
-
-       GLUquadricObj *qobj = gluNewQuadric();
-       gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
-
-       glPushMatrix();
-
-       glScalef(radius, size * 2.0f, radius);
-       glRotatef(-90.0, 1.0, 0.0, 0.0);
-       gluCylinder(qobj, 1.0, 0.0, 1.0, 8, 1);
-
-       glPopMatrix();
-
-       gluDeleteQuadric(qobj);
-}
-
-static void drawspiral(const float cent[3], float rad, float tmat[4][4], int start)
-{
-       float vec[3], vx[3], vy[3];
-       const float tot_inv = 1.0f / (float)CIRCLE_RESOL;
-       int a;
-       bool inverse = false;
-       float x, y, fac;
-
-       if (start < 0) {
-               inverse = true;
-               start = -start;
-       }
-
-       mul_v3_v3fl(vx, tmat[0], rad);
-       mul_v3_v3fl(vy, tmat[1], rad);
-
-       glBegin(GL_LINE_STRIP);
-
-       if (inverse == 0) {
-               copy_v3_v3(vec, cent);
-               glVertex3fv(vec);
-
-               for (a = 0; a < CIRCLE_RESOL; a++) {
-                       if (a + start >= CIRCLE_RESOL)
-                               start = -a + 1;
-
-                       fac = (float)a * tot_inv;
-                       x = sinval[a + start] * fac;
-                       y = cosval[a + start] * fac;
-
-                       vec[0] = cent[0] + (x * vx[0] + y * vy[0]);
-                       vec[1] = cent[1] + (x * vx[1] + y * vy[1]);
-                       vec[2] = cent[2] + (x * vx[2] + y * vy[2]);
-
-                       glVertex3fv(vec);
-               }
-       }
-       else {
-               fac = (float)(CIRCLE_RESOL - 1) * tot_inv;
-               x = sinval[start] * fac;
-               y = cosval[start] * fac;
-
-               vec[0] = cent[0] + (x * vx[0] + y * vy[0]);
-               vec[1] = cent[1] + (x * vx[1] + y * vy[1]);
-               vec[2] = cent[2] + (x * vx[2] + y * vy[2]);
-
-               glVertex3fv(vec);
-
-               for (a = 0; a < CIRCLE_RESOL; a++) {
-                       if (a + start >= CIRCLE_RESOL)
-                               start = -a + 1;
-
-                       fac = (float)(-a + (CIRCLE_RESOL - 1)) * tot_inv;
-                       x = sinval[a + start] * fac;
-                       y = cosval[a + start] * fac;
-
-                       vec[0] = cent[0] + (x * vx[0] + y * vy[0]);
-                       vec[1] = cent[1] + (x * vx[1] + y * vy[1]);
-                       vec[2] = cent[2] + (x * vx[2] + y * vy[2]);
-                       glVertex3fv(vec);
-               }
-       }
-
-       glEnd();
-}
-
-/* draws a circle on x-z plane given the scaling of the circle, assuming that
- * all required matrices have been set (used for drawing empties) */
-static void drawcircle_size(float size)
-{
-       glBegin(GL_LINE_LOOP);
-
-       /* coordinates are: cos(degrees * 11.25) = x, sin(degrees * 11.25) = y, 0.0f = z */
-       for (short degrees = 0; degrees < CIRCLE_RESOL; degrees++) {
-               float x = cosval[degrees];
-               float y = sinval[degrees];
-
-               glVertex3f(x * size, 0.0f, y * size);
-       }
-
-       glEnd();
-
-}
-
-/* needs fixing if non-identity matrix used */
-static void drawtube(const float vec[3], float radius, float height, float tmat[4][4])
-{
-       float cur[3];
-       drawcircball(GL_LINE_LOOP, vec, radius, tmat);
-
-       copy_v3_v3(cur, vec);
-       cur[2] += height;
-
-       drawcircball(GL_LINE_LOOP, cur, radius, tmat);
-
-       glBegin(GL_LINES);
-       glVertex3f(vec[0] + radius, vec[1], vec[2]);
-       glVertex3f(cur[0] + radius, cur[1], cur[2]);
-       glVertex3f(vec[0] - radius, vec[1], vec[2]);
-       glVertex3f(cur[0] - radius, cur[1], cur[2]);
-       glVertex3f(vec[0], vec[1] + radius, vec[2]);
-       glVertex3f(cur[0], cur[1] + radius, cur[2]);
-       glVertex3f(vec[0], vec[1] - radius, vec[2]);
-       glVertex3f(cur[0], cur[1] - radius, cur[2]);
-       glEnd();
-}
-
-/* needs fixing if non-identity matrix used */
-static void drawcone(const float vec[3], float radius, float height, float tmat[4][4])
-{
-       float cur[3];
-
-       copy_v3_v3(cur, vec);
-       cur[2] += height;
-
-       drawcircball(GL_LINE_LOOP, cur, radius, tmat);
-
-       glBegin(GL_LINES);
-       glVertex3f(vec[0], vec[1], vec[2]);
-       glVertex3f(cur[0] + radius, cur[1], cur[2]);
-       glVertex3f(vec[0], vec[1], vec[2]);
-       glVertex3f(cur[0] - radius, cur[1], cur[2]);
-       glVertex3f(vec[0], vec[1], vec[2]);
-       glVertex3f(cur[0], cur[1] + radius, cur[2]);
-       glVertex3f(vec[0], vec[1], vec[2]);
-       glVertex3f(cur[0], cur[1] - radius, cur[2]);
-       glEnd();
-}
-
-/* return true if nothing was drawn */
-static bool drawmball(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
-                      const char dt, const short dflag, const unsigned char ob_wire_col[4])
-{
-       Object *ob = base->object;
-       MetaElem *ml;
-       float imat[4][4];
-       int code = 1;
-
-       MetaBall *mb = ob->data;
-
-       if (mb->editelems) {
-               if ((G.f & G_PICKSEL) == 0) {
-                       unsigned char wire_col[4];
-                       UI_GetThemeColor4ubv(TH_WIRE_EDIT, wire_col);
-                       glColor3ubv(wire_col);
-
-                       drawDispList(scene, v3d, rv3d, base, dt, dflag, wire_col);
-               }
-               ml = mb->editelems->first;
-       }
-       else {
-               if ((base->flag & OB_FROMDUPLI) == 0) {
-                       drawDispList(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
-               }
-               ml = mb->elems.first;
-       }
-
-       if (ml == NULL) {
-               return true;
-       }
-
-       if (v3d->flag2 & V3D_RENDER_OVERRIDE) {
-               return false;
-       }
-
-       invert_m4_m4(imat, rv3d->viewmatob);
-       normalize_v3(imat[0]);
-       normalize_v3(imat[1]);
-
-       if (mb->editelems == NULL) {
-               if ((dflag & DRAW_CONSTCOLOR) == 0) {
-                       glColor3ubv(ob_wire_col);
-               }
-       }
-
-       glLineWidth(1.0f);
-
-       while (ml) {
-               /* draw radius */
-               if (mb->editelems) {
-                       if ((dflag & DRAW_CONSTCOLOR) == 0) {
-                               if ((ml->flag & SELECT) && (ml->flag & MB_SCALE_RAD)) cpack(0xA0A0F0);
-                               else cpack(0x3030A0);
-                       }
-
-                       if (G.f & G_PICKSEL) {
-                               ml->selcol1 = code;
-                               GPU_select_load_id(code++);
-                       }
-               }
-               drawcircball(GL_LINE_LOOP, &(ml->x), ml->rad, imat);
-
-               /* draw stiffness */
-               if (mb->editelems) {
-                       if ((dflag & DRAW_CONSTCOLOR) == 0) {
-                               if ((ml->flag & SELECT) && !(ml->flag & MB_SCALE_RAD)) cpack(0xA0F0A0);
-                               else cpack(0x30A030);
-                       }
-
-                       if (G.f & G_PICKSEL) {
-                               ml->selcol2 = code;
-                               GPU_select_load_id(code++);
-                       }
-                       drawcircball(GL_LINE_LOOP, &(ml->x), ml->rad * atanf(ml->s) /&n