Merged changes in the trunk up to revision 54110.
[blender.git] / source / blender / editors / space_view3d / drawobject.c
index f100f003ff553e6cba1349eaa10faf5e6ea76eb2..fc8d5d26455ed8d78e51cb986d3650f16256441a 100644 (file)
@@ -88,6 +88,7 @@
 #include "ED_types.h"
 
 #include "UI_resources.h"
+#include "UI_interface_icons.h"
 
 #include "WM_api.h"
 #include "BLF_api.h"
@@ -101,7 +102,7 @@ typedef enum eWireDrawMode {
 } eWireDrawMode;
 
 typedef struct drawDMVerts_userData {
-       BMEditMesh *em; /* BMESH BRANCH ONLY */
+       BMEditMesh *em;
 
        int sel;
        BMVert *eve_act;
@@ -119,17 +120,21 @@ typedef struct drawDMVerts_userData {
 } drawDMVerts_userData;
 
 typedef struct drawDMEdgesSel_userData {
-       BMEditMesh *em; /* BMESH BRANCH ONLY */
+       BMEditMesh *em;
 
        unsigned char *baseCol, *selCol, *actCol;
        BMEdge *eed_act;
 } drawDMEdgesSel_userData;
 
 typedef struct drawDMFacesSel_userData {
+#ifdef WITH_FREESTYLE
+       unsigned char *cols[4];
+#else
        unsigned char *cols[3];
+#endif
 
-       DerivedMesh *dm; /* BMESH BRANCH ONLY */
-       BMEditMesh *em;  /* BMESH BRANCH ONLY */
+       DerivedMesh *dm;
+       BMEditMesh *em;
 
        BMFace *efa_act;
        int *orig_index_mf_to_mpoly;
@@ -168,17 +173,26 @@ static void ob_wire_color_blend_theme_id(const unsigned char ob_wire_col[4], con
 }
 
 /* this condition has been made more complex since editmode can draw textures */
-static int check_object_draw_texture(Scene *scene, View3D *v3d, int drawtype)
+static bool check_object_draw_texture(Scene *scene, View3D *v3d, int drawtype)
 {
        /* texture and material draw modes */
-       if (ELEM(v3d->drawtype, OB_TEXTURE, OB_MATERIAL) && drawtype > OB_SOLID)
-               return TRUE;
+       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))
-               return TRUE;
+       if ((v3d->drawtype == OB_SOLID) &&
+           (v3d->flag2 & V3D_SOLID_TEX) &&
+           (BKE_scene_use_new_shading_nodes(scene) == false))
+       {
+               return true;
+       }
        
-       return FALSE;
+       if (v3d->flag2 & V3D_SHOW_SOLID_MATCAP) {
+               return true;
+       }
+       
+       return false;
 }
 
 static int check_ob_drawface_dot(Scene *sce, View3D *vd, char dt)
@@ -206,7 +220,7 @@ static int check_ob_drawface_dot(Scene *sce, View3D *vd, char dt)
 
 /* check for glsl drawing */
 
-int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, const short dt)
+int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, const char dt)
 {
        if (!GPU_glsl_support())
                return 0;
@@ -216,6 +230,10 @@ int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, const short dt)
                return 0;
        if (ob == OBACT && (ob && ob->mode & OB_MODE_WEIGHT_PAINT))
                return 0;
+       
+       if (v3d->flag2 & V3D_SHOW_SOLID_MATCAP)
+               return 1;
+       
        if (BKE_scene_use_new_shading_nodes(scene))
                return 0;
        
@@ -229,7 +247,10 @@ static int check_alpha_pass(Base *base)
 
        if (G.f & G_PICKSEL)
                return 0;
-       
+
+       if (base->object->mode & OB_MODE_ALL_PAINT)
+               return 0;
+
        return (base->object->dtx & OB_DRAWTRANSP);
 }
 
@@ -530,7 +551,7 @@ void drawaxes(float size, char drawtype)
 static void draw_empty_image(Object *ob, const short dflag, const unsigned char ob_wire_col[4])
 {
        Image *ima = (Image *)ob->data;
-       ImBuf *ibuf = ima ? BKE_image_get_ibuf(ima, NULL) : NULL;
+       ImBuf *ibuf = ima ? BKE_image_acquire_ibuf(ima, NULL, NULL) : NULL;
 
        float scale, ofs_x, ofs_y, sca_x, sca_y;
        int ima_x, ima_y;
@@ -615,9 +636,11 @@ static void draw_empty_image(Object *ob, const short dflag, const unsigned char
        /* Reset GL settings */
        glMatrixMode(GL_MODELVIEW);
        glPopMatrix();
+
+       BKE_image_release_ibuf(ima, ibuf, NULL);
 }
 
-static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3], float rad, float tmat[][4])
+static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3], float rad, float tmat[4][4])
 {
        float vx[3], vy[3];
        float *viter = (float *)verts;
@@ -633,7 +656,7 @@ static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3
        }
 }
 
-void drawcircball(int mode, const float cent[3], float rad, float tmat[][4])
+void drawcircball(int mode, const float cent[3], float rad, float tmat[4][4])
 {
        float verts[CIRCLE_RESOL][3];
 
@@ -734,7 +757,7 @@ void view3d_cached_text_draw_add(const float co[3],
        memcpy(++vos, str, alloc_len);
 }
 
-void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, float mat[][4])
+void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, float mat[4][4])
 {
        RegionView3D *rv3d = ar->regiondata;
        ListBase *strings = &CachedText[CachedTextLevel - 1];
@@ -750,7 +773,7 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa
                                               (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_RET_OK)
+                                              V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
                {
                        tot++;
                }
@@ -924,7 +947,7 @@ static void drawcube_size(const float size[3])
 }
 #endif
 
-static void drawshadbuflimits(Lamp *la, float mat[][4])
+static void drawshadbuflimits(Lamp *la, float mat[4][4])
 {
        float sta[3], end[3], lavec[3];
 
@@ -1072,7 +1095,7 @@ static void draw_transp_spot_volume(Lamp *la, float x, float z)
 }
 
 static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
-                     const short dt, const short dflag, const unsigned char ob_wire_col[4])
+                     const char dt, const short dflag, const unsigned char ob_wire_col[4])
 {
        Object *ob = base->object;
        const float pixsize = ED_view3d_pixel_size(rv3d, ob->obmat[3]);
@@ -1281,6 +1304,13 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
                        glVertex3fv(vvec_clip);
                        glEnd();
                }
+               /* Else, draw spot direction (using distance as end limit, same as for Area lamp). */
+               else {
+                       glBegin(GL_LINE_STRIP);
+                       glVertex3f(0.0, 0.0, -circrad);
+                       glVertex3f(0.0, 0.0, -la->dist);
+                       glEnd();
+               }
        }
        else if (ELEM(la->type, LA_HEMI, LA_SUN)) {
                
@@ -2275,6 +2305,23 @@ static void draw_dm_edges_sharp(BMEditMesh *em, DerivedMesh *dm)
        dm->drawMappedEdges(dm, draw_dm_edges_sharp__setDrawOptions, em);
 }
 
+#ifdef WITH_FREESTYLE
+/* Draw only Freestyle feature edges */
+static DMDrawOption draw_dm_edges_freestyle__setDrawOptions(void *userData, int index)
+{
+       BMEdge *eed = EDBM_edge_at_index(userData, index);
+
+       if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && BM_elem_flag_test(eed, BM_ELEM_FREESTYLE))
+               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);
+}
+#endif
 
 /* Draw faces with color set based on selection
  * return 2 for the active face so it renders with stipple enabled */
@@ -2293,7 +2340,11 @@ static DMDrawOption draw_dm_faces_sel__setDrawOptions(void *userData, int index)
                        return DM_DRAW_OPTION_STIPPLE;
                }
                else {
+#ifdef WITH_FREESTYLE
+                       col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : BM_elem_flag_test(efa, BM_ELEM_FREESTYLE) ? 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);
@@ -2324,8 +2375,13 @@ static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int
        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 : BM_elem_flag_test(efa, BM_ELEM_FREESTYLE) ? 3 : 0];
+       next_col = data->cols[BM_elem_flag_test(next_efa, BM_ELEM_SELECT) ? 1 : BM_elem_flag_test(next_efa, BM_ELEM_FREESTYLE) ? 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;
@@ -2334,8 +2390,13 @@ static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int
 }
 
 /* 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;
@@ -2343,6 +2404,9 @@ static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *ba
        data.em = em;
        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_mf_to_mpoly = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
@@ -2577,12 +2641,12 @@ static void draw_em_measure_stats(View3D *v3d, Object *ob, BMEditMesh *em, UnitS
        BMIter iter;
        int i;
 
-       /* make the precision of the pronted value proportionate to the gridsize */
+       /* 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";
+       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) {
@@ -2627,16 +2691,21 @@ static void draw_em_measure_stats(View3D *v3d, Object *ob, BMEditMesh *em, UnitS
                BMFace *f;
                int n;
 
-#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)                                                     \
-                       bUnit_AsString(numstr, sizeof(numstr),                            \
-                                      (double)(area * unit->scale_length),               \
-                                      3, unit->system, B_UNIT_LENGTH, do_split, FALSE);  \
-               else                                                                  \
-                       BLI_snprintf(numstr, sizeof(numstr), conv_float, area);           \
-               view3d_cached_text_draw_add(vmid, numstr, 0, txt_flag, col);          \
+#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) {                                                              \
+                       bUnit_AsString(numstr, sizeof(numstr),                                       \
+                                      (double)(area * unit->scale_length * unit->scale_length),     \
+                                      3, unit->system, B_UNIT_AREA, do_split, FALSE);               \
+                       view3d_cached_text_draw_add(vmid, numstr, 0,                                 \
+                                                   /* Metric system uses unicode "squared" sign! */ \
+                                                   txt_flag ^ V3D_CACHE_TEXT_ASCII, col);           \
+               }                                                                                \
+               else {                                                                           \
+                       BLI_snprintf(numstr, sizeof(numstr), conv_float, area);                      \
+                       view3d_cached_text_draw_add(vmid, numstr, 0, txt_flag, col);                 \
+               }                                                                                \
        } (void)0
 
                UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEAREA, col);
@@ -2808,7 +2877,7 @@ static DMDrawOption draw_em_fancy__setGLSLFaceOpts(void *userData, int index)
 }
 
 static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d,
-                          Object *ob, BMEditMesh *em, DerivedMesh *cageDM, DerivedMesh *finalDM, const short dt)
+                          Object *ob, BMEditMesh *em, DerivedMesh *cageDM, DerivedMesh *finalDM, const char dt)
 
 {
        Mesh *me = ob->data;
@@ -2833,7 +2902,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d,
                }
        }
        
-       EDBM_index_arrays_init(em, 1, 1, 1);
+       EDBM_index_arrays_ensure(em, BM_VERT | BM_EDGE | BM_FACE);
 
        if (dt > OB_WIRE) {
                if (check_object_draw_texture(scene, v3d, dt)) {
@@ -2880,10 +2949,16 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d,
        
        if (me->drawflag & ME_DRAWFACES) {  /* 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 */
@@ -2892,7 +2967,14 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d,
                if (check_object_draw_texture(scene, v3d, dt))
                        col1[3] = 0;
 
+#ifdef WITH_FREESTYLE
+               if (!(me->drawflag & ME_DRAW_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 */
@@ -2901,14 +2983,19 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d,
                /* 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];
-               col1[3] = col2[3] = 0; /* don't draw */
+               /* col4 is only used by WITH_FREESTYLE, but keeping it here spares some #ifdef's... */
+               unsigned char col1[4], col2[4], col3[4], col4[4];
+               col1[3] = col2[3] = col4[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 */
@@ -2944,6 +3031,18 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d,
                        glLineWidth(1);
                }
 
+#ifdef WITH_FREESTYLE
+               if(me->drawflag & ME_DRAW_FREESTYLE_EDGE) {
+                       UI_ThemeColor(TH_FREESTYLE_EDGE_MARK);
+                       glLineWidth(2);
+       
+                       draw_dm_edges_freestyle(em, cageDM);
+       
+                       glColor3ub(0,0,0);
+                       glLineWidth(1);
+               }
+#endif
+       
                if (me->drawflag & ME_DRAWCREASES && CustomData_has_layer(&em->bm->edata, CD_CREASE)) {
                        draw_dm_creases(em, cageDM);
                }
@@ -2984,8 +3083,6 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d,
                bglPolygonOffset(rv3d->dist, 0.0);
                GPU_disable_material();
        }
-
-       EDBM_index_arrays_free(em);
 }
 
 /* Mesh drawing routines */
@@ -3016,7 +3113,7 @@ static void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm)
 }
 
 static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
-                            const short dt, const unsigned char ob_wire_col[4], const short dflag)
+                            const char dt, const unsigned char ob_wire_col[4], const short dflag)
 {
        Object *ob = base->object;
        Mesh *me = ob->data;
@@ -3225,7 +3322,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
                        glDepthMask(0);  /* disable write in zbuffer, selected edge wires show better */
                }
                
-               dm->drawEdges(dm, (dt == OB_WIRE || totface == 0), me->drawflag & ME_ALLEDGES);
+               dm->drawEdges(dm, (dt == OB_WIRE || totface == 0), (ob->dtx & OB_DRAW_ALL_EDGES));
 
                if (dt != OB_WIRE && (draw_wire == OBDRAW_WIRE_ON_DEPTH)) {
                        glDepthMask(1);
@@ -3234,11 +3331,15 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
        }
        
        if (is_obact && paint_vertsel_test(ob)) {
-               
+               const int use_depth = (v3d->flag & V3D_ZBUF_SELECT);
                glColor3f(0.0f, 0.0f, 0.0f);
                glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
-               
+
+               if (!use_depth) glDisable(GL_DEPTH_TEST);
+               else            bglPolygonOffset(rv3d->dist, 1.0);
                drawSelectedVertices(dm, ob->data);
+               if (!use_depth) glEnable(GL_DEPTH_TEST);
+               else            bglPolygonOffset(rv3d->dist, 0.0);
                
                glPointSize(1.0f);
        }
@@ -3247,7 +3348,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
 
 /* returns 1 if nothing was drawn, for detecting to draw an object center */
 static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
-                            const short dt, const unsigned char ob_wire_col[4], const short dflag)
+                            const char dt, const unsigned char ob_wire_col[4], const short dflag)
 {
        Object *ob = base->object;
        Object *obedit = scene->obedit;
@@ -3411,7 +3512,7 @@ static int drawDispListwire(ListBase *dlbase)
 
 #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);
+                               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
@@ -3569,7 +3670,7 @@ static void drawCurveDMWired(Object *ob)
 }
 
 /* return 1 when nothing was drawn */
-static int drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, const short dt)
+static int drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, const char dt)
 {
        Object *ob = base->object;
        DerivedMesh *dm = ob->derivedFinal;
@@ -3600,9 +3701,12 @@ static int drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d, B
        return 0;
 }
 
-/* returns 1 when nothing was drawn */
-static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
-                        const short dt, const short dflag, const unsigned char ob_wire_col[4])
+/**
+ * Only called by #drawDispList
+ * \return 1 when nothing was drawn
+ */
+static int 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;
@@ -3610,20 +3714,9 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
        Curve *cu;
        const short render_only = (v3d->flag2 & V3D_RENDER_OVERRIDE);
        const short solid = (dt > OB_WIRE);
-       int retval = 0;
-
-       /* backface culling */
-       if (v3d->flag2 & V3D_BACKFACE_CULLING) {
-               /* not all displists use same in/out normal direction convention */
-               glEnable(GL_CULL_FACE);
-               glCullFace((ob->type == OB_MBALL) ? GL_BACK : GL_FRONT);
-       }
 
        if (drawCurveDerivedMesh(scene, v3d, rv3d, base, dt) == 0) {
-               if (v3d->flag2 & V3D_BACKFACE_CULLING)
-                       glDisable(GL_CULL_FACE);
-
-               return 0;
+               return FALSE;
        }
 
        switch (ob->type) {
@@ -3635,7 +3728,9 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
 
                        if (solid) {
                                dl = lb->first;
-                               if (dl == NULL) return 1;
+                               if (dl == NULL) {
+                                       return TRUE;
+                               }
 
                                if (dl->nors == NULL) BKE_displist_normals_add(lb);
                                index3_nors_incr = 0;
@@ -3669,9 +3764,11 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
                        }
                        else {
                                if (!render_only || (render_only && BKE_displist_has_faces(lb))) {
+                                       int retval;
                                        draw_index_wire = 0;
                                        retval = drawDispListwire(lb);
                                        draw_index_wire = 1;
+                                       return retval;
                                }
                        }
                        break;
@@ -3681,7 +3778,9 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
 
                        if (solid) {
                                dl = lb->first;
-                               if (dl == NULL) return 1;
+                               if (dl == NULL) {
+                                       return TRUE;
+                               }
 
                                if (dl->nors == NULL) BKE_displist_normals_add(lb);
 
@@ -3697,7 +3796,7 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
                                }
                        }
                        else {
-                               retval = drawDispListwire(lb);
+                               return drawDispListwire(lb);
                        }
                        break;
                case OB_MBALL:
@@ -3705,7 +3804,9 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
                        if (BKE_mball_is_basis(ob)) {
                                lb = &ob->disp;
                                if (lb->first == NULL) BKE_displist_make_mball(scene, ob);
-                               if (lb->first == NULL) return 1;
+                               if (lb->first == NULL) {
+                                       return TRUE;
+                               }
 
                                if (solid) {
 
@@ -3722,14 +3823,31 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
                                }
                                else {
                                        /* MetaBalls use DL_INDEX4 type of DispList */
-                                       retval = drawDispListwire(lb);
+                                       return drawDispListwire(lb);
                                }
                        }
                        break;
        }
-       
-       if (v3d->flag2 & V3D_BACKFACE_CULLING)
+
+       return FALSE;
+}
+static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
+                        const char dt, const short dflag, const unsigned char ob_wire_col[4])
+{
+       int retval;
+
+       /* backface culling */
+       if (v3d->flag2 & V3D_BACKFACE_CULLING) {
+               /* not all displists use same in/out normal direction convention */
+               glEnable(GL_CULL_FACE);
+               glCullFace((base->object->type == OB_MBALL) ? GL_BACK : GL_FRONT);
+       }
+
+       retval = drawDispList_nobackface(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
+
+       if (v3d->flag2 & V3D_BACKFACE_CULLING) {
                glDisable(GL_CULL_FACE);
+       }
 
        return retval;
 }
@@ -4637,9 +4755,11 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit)
                                if (!(point->flag & PEP_HIDE))
                                        totkeys += point->totkey;
 
-                       if (edit->points && !(edit->points->keys->flag & PEK_USE_WCO))
-                               pd = pdata = MEM_callocN(totkeys * 3 * sizeof(float), "particle edit point data");
-                       cd = cdata = MEM_callocN(totkeys * (timed ? 4 : 3) * sizeof(float), "particle edit color data");
+                       if (totkeys) {
+                               if (edit->points && !(edit->points->keys->flag & PEK_USE_WCO))
+                                       pd = pdata = MEM_callocN(totkeys * 3 * sizeof(float), "particle edit point data");
+                               cd = cdata = MEM_callocN(totkeys * (timed ? 4 : 3) * sizeof(float), "particle edit color data");
+                       }
 
                        for (i = 0, point = edit->points; i < totpoint; i++, point++) {
                                if (point->flag & PEP_HIDE)
@@ -4876,9 +4996,9 @@ static void ob_draw_RE_motion(float com[3], float rotscale[3][3], float itw, flo
        glEnd();
 }
 
-/*place to add drawers */
+/* place to add drawers */
 
-static void tekenhandlesN(Nurb *nu, short sel, short hide_handles)
+static void drawhandlesN(Nurb *nu, short sel, short hide_handles)
 {
        BezTriple *bezt;
        float *fp;
@@ -4938,7 +5058,7 @@ static void tekenhandlesN(Nurb *nu, short sel, short hide_handles)
        glEnd();
 }
 
-static void tekenhandlesN_active(Nurb *nu)
+static void drawhandlesN_active(Nurb *nu)
 {
        BezTriple *bezt;
        float *fp;
@@ -4973,7 +5093,7 @@ static void tekenhandlesN_active(Nurb *nu)
        glLineWidth(1);
 }
 
-static void tekenvertsN(Nurb *nu, short sel, short hide_handles, void *lastsel)
+static void drawvertsN(Nurb *nu, short sel, short hide_handles, void *lastsel)
 {
        BezTriple *bezt;
        BPoint *bp;
@@ -5229,7 +5349,7 @@ static void draw_editnurb(Object *ob, Nurb *nurb, int sel)
 }
 
 static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, Nurb *nurb,
-                     const short dt, const short dflag, const unsigned char ob_wire_col[4])
+                     const char dt, const short dflag, const unsigned char ob_wire_col[4])
 {
        ToolSettings *ts = scene->toolsettings;
        Object *ob = base->object;
@@ -5253,8 +5373,8 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
        for (nu = nurb; nu; nu = nu->next) {
                if (nu->type == CU_BEZIER) {
                        if (index == cu->actnu && !hide_handles)
-                               tekenhandlesN_active(nu);
-                       tekenhandlesN(nu, 0, hide_handles);
+                               drawhandlesN_active(nu);
+                       drawhandlesN(nu, 0, hide_handles);
                }
                index++;
        }
@@ -5263,8 +5383,8 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
        /* selected handles */
        for (nu = nurb; nu; nu = nu->next) {
                if (nu->type == CU_BEZIER && (cu->drawflag & CU_HIDE_HANDLES) == 0)
-                       tekenhandlesN(nu, 1, hide_handles);
-               tekenvertsN(nu, 0, hide_handles, NULL);
+                       drawhandlesN(nu, 1, hide_handles);
+               drawvertsN(nu, 0, hide_handles, NULL);
        }
        
        if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
@@ -5315,7 +5435,7 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
        if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
        
        for (nu = nurb; nu; nu = nu->next) {
-               tekenvertsN(nu, 1, hide_handles, cu->lastsel);
+               drawvertsN(nu, 1, hide_handles, cu->lastsel);
        }
        
        if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
@@ -5377,43 +5497,10 @@ static void draw_empty_cone(float size)
        gluDeleteQuadric(qobj);
 }
 
-/* draw points on curve speed handles */
-#if 0  /* XXX old animation system stuff */
-static void curve_draw_speed(Scene *scene, Object *ob)
-{
-       Curve *cu = ob->data;
-       IpoCurve *icu;
-       BezTriple *bezt;
-       float loc[4], dir[3];
-       int a;
-       
-       if (cu->ipo == NULL)
-               return;
-       
-       icu = cu->ipo->curve.first;
-       if (icu == NULL || icu->totvert < 2)
-               return;
-       
-       glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
-       bglBegin(GL_POINTS);
-
-       for (a = 0, bezt = icu->bezt; a < icu->totvert; a++, bezt++) {
-               if (where_on_path(ob, bezt->vec[1][1], loc, dir)) {
-                       UI_ThemeColor((bezt->f2 & SELECT) && ob == OBACT ? TH_VERTEX_SELECT : TH_VERTEX);
-                       bglVertex3fv(loc);
-               }
-       }
-
-       glPointSize(1.0);
-       bglEnd();
-}
-#endif  /* XXX old animation system stuff */
-
-
-static void draw_textcurs(float textcurs[4][2])
+static void draw_textcurs(RegionView3D *rv3d, float textcurs[4][2])
 {
        cpack(0);
-       
+       bglPolygonOffset(rv3d->dist, -1.0);
        set_inverted_drawing(1);
        glBegin(GL_QUADS);
        glVertex2fv(textcurs[0]);
@@ -5422,9 +5509,10 @@ static void draw_textcurs(float textcurs[4][2])
        glVertex2fv(textcurs[3]);
        glEnd();
        set_inverted_drawing(0);
+       bglPolygonOffset(rv3d->dist, 0.0);
 }
 
-static void drawspiral(const float cent[3], float rad, float tmat[][4], int start)
+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);
@@ -5512,8 +5600,8 @@ static void drawcircle_size(float size)
 
 }
 
-/* needs fixing if non-identity matrice used */
-static void drawtube(const float vec[3], float radius, float height, float tmat[][4])
+/* 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);
@@ -5534,8 +5622,9 @@ static void drawtube(const float vec[3], float radius, float height, float tmat[
        glVertex3f(cur[0], cur[1] - radius, cur[2]);
        glEnd();
 }
-/* needs fixing if non-identity matrice used */
-static void drawcone(const float vec[3], float radius, float height, float tmat[][4])
+
+/* 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];
 
@@ -5555,9 +5644,10 @@ static void drawcone(const float vec[3], float radius, float height, float tmat[
        glVertex3f(cur[0], cur[1] - radius, cur[2]);
        glEnd();
 }
+
 /* return TRUE if nothing was drawn */
 static int drawmball(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
-                     const short dt, const short dflag, const unsigned char ob_wire_col[4])
+                     const char dt, const short dflag, const unsigned char ob_wire_col[4])
 {
        Object *ob = base->object;
        MetaBall *mb;
@@ -5603,7 +5693,6 @@ static int drawmball(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
        }
        
        while (ml) {
-
                /* draw radius */
                if (mb->editelems) {
                        if ((dflag & DRAW_CONSTCOLOR) == 0) {
@@ -6190,6 +6279,34 @@ static void draw_object_wire_color(Scene *scene, Base *base, unsigned char r_ob_
        r_ob_wire_col[3] = 255;
 }
 
+static void draw_object_matcap_check(Scene *scene, View3D *v3d, Object *ob)
+{
+       /* fixed rule, active object draws as matcap */
+       if (ob == OBACT) {
+               if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))
+                       return;
+                       
+               if (v3d->defmaterial == NULL) {
+                       extern Material defmaterial;
+                       
+                       v3d->defmaterial = MEM_mallocN(sizeof(Material), "matcap material");
+                       *(v3d->defmaterial) = defmaterial;
+                       v3d->defmaterial->gpumaterial.first = v3d->defmaterial->gpumaterial.last = NULL;
+                       v3d->defmaterial->preview = NULL;
+               }
+               /* first time users */
+               if (v3d->matcap_icon == 0)
+                       v3d->matcap_icon = ICON_MATCAP_01;
+               
+               if (v3d->defmaterial->preview == NULL)
+                       v3d->defmaterial->preview = UI_icon_to_preview(v3d->matcap_icon);
+               
+               /* signal to all material checks, gets cleared below */
+               v3d->flag2 |= V3D_SHOW_SOLID_MATCAP;
+       }
+
+}
+
 /**
  * main object drawing function, draws in selection
  * \param dflag (draw flag) can be DRAW_PICKING and/or DRAW_CONSTCOLOR, DRAW_SCENESET
@@ -6206,7 +6323,9 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
        unsigned char _ob_wire_col[4];      /* dont initialize this */
        unsigned char *ob_wire_col = NULL;  /* dont initialize this, use NULL crashes as a way to find invalid use */
        int i, selstart, selend, empty_object = 0;
-       short dt, dtx, zbufoff = 0;
+       short dtx;
+       char  dt;
+       short zbufoff = 0;
        const short is_obact = (ob == OBACT);
 
        /* only once set now, will be removed too, should become a global standard */
@@ -6277,6 +6396,10 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
        dt = MIN2(dt, ob->dt);
        if (v3d->zbuf == 0 && dt > OB_WIRE) dt = OB_WIRE;
        dtx = 0;
+       
+       /* matcap check */
+       if (dt == OB_SOLID && (v3d->flag2 & V3D_SOLID_MATCAP))
+               draw_object_matcap_check(scene, v3d, ob);
 
        /* faceselect exception: also draw solid when (dt == wire), except in editmode */
        if (is_obact && (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))) {
@@ -6342,7 +6465,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
                case OB_FONT:
                        cu = ob->data;
                        if (cu->editfont) {
-                               draw_textcurs(cu->editfont->textcurs);
+                               draw_textcurs(rv3d, cu->editfont->textcurs);
 
                                if (cu->flag & CU_FAST) {
                                        cpack(0xFFFFFF);
@@ -6720,7 +6843,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
                }
 
                if (ob->gameflag & OB_BOUNDS) {
-                       if (ob->boundtype != ob->collision_boundtype || (dtx & OB_BOUNDBOX) == 0) {
+                       if (ob->boundtype != ob->collision_boundtype || (dtx & OB_DRAWBOUNDOX) == 0) {
 
                                setlinestyle(2);
                                draw_bounding_volume(scene, ob, ob->collision_boundtype);
@@ -6734,7 +6857,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
                        if (dtx & OB_AXIS) {
                                drawaxes(1.0f, OB_ARROWS);
                        }
-                       if (dtx & OB_BOUNDBOX) {
+                       if (dtx & OB_DRAWBOUNDOX) {
                                draw_bounding_volume(scene, ob, ob->boundtype);
                        }
                        if (dtx & OB_TEXSPACE) {
@@ -6777,7 +6900,9 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
        /* return warning, this is cached text draw */
        invert_m4_m4(ob->imat, ob->obmat);
        view3d_cached_text_draw_end(v3d, ar, 1, NULL);
-
+       /* return warning, clear temp flag */
+       v3d->flag2 &= ~V3D_SHOW_SOLID_MATCAP;
+       
        glLoadMatrixf(rv3d->viewmat);
 
        if (zbufoff) {
@@ -6851,10 +6976,10 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
                        UI_make_axis_color(col1, col2, 'Z');
                        glColor3ubv(col2);
                        
-                       cob = constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
+                       cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
                        
                        for (curcon = list->first; curcon; curcon = curcon->next) {
-                               bConstraintTypeInfo *cti = constraint_get_typeinfo(curcon);
+                               bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(curcon);
                                ListBase targets = {NULL, NULL};
                                bConstraintTarget *ct;
                                
@@ -6908,7 +7033,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
                                }
                        }
                        
-                       constraints_clear_evalob(cob);
+                       BKE_constraints_clear_evalob(cob);
                }
        }
 
@@ -7069,14 +7194,28 @@ static DMDrawOption bbs_mesh_solid_hide2__setDrawOpts(void *userData, int index)
                return DM_DRAW_OPTION_SKIP;
        }
 }
-static void bbs_mesh_solid(Scene *scene, Object *ob)
+
+static void bbs_mesh_solid_verts(Scene *scene, Object *ob)
+{
+       Mesh *me = ob->data;
+       DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
+       glColor3ub(0, 0, 0);
+
+       dm->drawMappedFaces(dm, bbs_mesh_solid_hide2__setDrawOpts, GPU_enable_material, NULL, me, 0);
+
+       bbs_obmode_mesh_verts(ob, dm, 1);
+       bm_vertoffs = me->totvert + 1;
+       dm->release(dm);
+}
+
+static void bbs_mesh_solid_faces(Scene *scene, Object *ob)
 {
        DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
        Mesh *me = (Mesh *)ob->data;
        
        glColor3ub(0, 0, 0);
 
-       if ((me->editflag & ME_EDIT_PAINT_MASK))
+       if ((me->editflag & ME_EDIT_PAINT_FACE_SEL))
                dm->drawMappedFaces(dm, bbs_mesh_solid_hide__setDrawOpts, GPU_enable_material, NULL, me, 0);
        else
                dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, GPU_enable_material, NULL, me, 0);
@@ -7101,7 +7240,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
 
                                DerivedMesh *dm = editbmesh_get_derived_cage(scene, ob, em, CD_MASK_BAREMESH);
 
-                               EDBM_index_arrays_init(em, 1, 1, 1);
+                               EDBM_index_arrays_ensure(em, BM_VERT | BM_EDGE | BM_FACE);
 
                                bbs_mesh_solid_EM(em, scene, v3d, ob, dm, ts->selectmode & SCE_SELECT_FACE);
                                if (ts->selectmode & SCE_SELECT_FACE)
@@ -7127,27 +7266,17 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
                                bglPolygonOffset(rv3d->dist, 0.0);
 
                                dm->release(dm);
-
-                               EDBM_index_arrays_free(em);
                        }
                        else {
                                Mesh *me = ob->data;
-                               if ((me->editflag & ME_EDIT_VERT_SEL) &&
+                               if ((me->editflag & ME_EDIT_PAINT_VERT_SEL) &&
                                    /* currently vertex select only supports weight paint */
                                    (ob->mode & OB_MODE_WEIGHT_PAINT))
                                {
-                                       DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
-                                       glColor3ub(0, 0, 0);
-
-                                       dm->drawMappedFaces(dm, bbs_mesh_solid_hide2__setDrawOpts, GPU_enable_material, NULL, me, 0);
-
-
-                                       bbs_obmode_mesh_verts(ob, dm, 1);
-                                       bm_vertoffs = me->totvert + 1;
-                                       dm->release(dm);
+                                       bbs_mesh_solid_verts(scene, ob);
                                }
                                else {
-                                       bbs_mesh_solid(scene, ob);
+                                       bbs_mesh_solid_faces(scene, ob);
                                }
                        }
                        break;
@@ -7213,7 +7342,7 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r
        if (dm) dm->release(dm);
 }
 
-void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, const short dt, int outline)
+void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, const char dt, int outline)
 {
        if (ob == NULL)
                return;