Merged changes in the trunk up to revision 42116.
[blender.git] / source / blender / editors / space_view3d / drawobject.c
index 81848b2f0d9cfec845489809acfae675592cebd6..be3a599330b15fe65d56c25f5d763c4cacb6b90b 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id$
- *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
@@ -38,6 +36,7 @@
 #include "DNA_camera_types.h"
 #include "DNA_curve_types.h"
 #include "DNA_constraint_types.h" // for drawing constraint
+#include "DNA_dynamicpaint_types.h"
 #include "DNA_lamp_types.h"
 #include "DNA_lattice_types.h"
 #include "DNA_material_types.h"
@@ -57,7 +56,9 @@
 #include "BLI_utildefines.h"
 
 #include "BKE_anim.h"                  //for the where_on_path function
+#include "BKE_camera.h"
 #include "BKE_constraint.h" // for the get_constraint_target function
+#include "BKE_curve.h"
 #include "BKE_DerivedMesh.h"
 #include "BKE_deform.h"
 #include "BKE_displist.h"
 #include "BKE_paint.h"
 #include "BKE_particle.h"
 #include "BKE_pointcache.h"
+#include "BKE_scene.h"
 #include "BKE_unit.h"
+#include "BKE_movieclip.h"
+#include "BKE_tracking.h"
 
 #include "smoke_API.h"
 
@@ -92,7 +96,7 @@
 #include "ED_screen.h"
 #include "ED_sculpt.h"
 #include "ED_types.h"
-#include "ED_curve.h" /* for ED_curve_editnurbs */
+#include "ED_curve.h" /* for curve_editnurbs */
 
 #include "UI_resources.h"
 
 
 
 /* this condition has been made more complex since editmode can draw textures */
-#define CHECK_OB_DRAWTEXTURE(vd, dt) \
-((vd->drawtype==OB_TEXTURE && dt>OB_SOLID) || \
+#define CHECK_OB_DRAWTEXTURE(vd, dt)                                          \
+       ((ELEM(vd->drawtype, OB_TEXTURE, OB_MATERIAL) && dt>OB_SOLID) ||          \
        (vd->drawtype==OB_SOLID && vd->flag2 & V3D_SOLID_TEX))
 
-static void draw_bounding_volume(Scene *scene, Object *ob);
+typedef enum eWireDrawMode {
+       OBDRAW_WIRE_OFF= 0,
+       OBDRAW_WIRE_ON= 1,
+       OBDRAW_WIRE_ON_DEPTH= 2
+} eWireDrawMode;
+
+static void draw_bounding_volume(Scene *scene, Object *ob, char type);
 
 static void drawcube_size(float size);
 static void drawcircle_size(float size);
@@ -201,6 +211,40 @@ static void view3d_project_short_noclip(ARegion *ar, const float vec[3], short *
        }
 }
 
+/* same as view3d_project_short_clip but use persmat instead of persmatob for projection */
+static void view3d_project_short_clip_persmat(ARegion *ar, float *vec, short *adr, int local)
+{
+       RegionView3D *rv3d= ar->regiondata;
+       float fx, fy, vec4[4];
+
+       adr[0]= IS_CLIPPED;
+
+       /* clipplanes in eye space */
+       if(rv3d->rflag & RV3D_CLIPPING) {
+               if(ED_view3d_test_clipping(rv3d, vec, local))
+                       return;
+       }
+
+       copy_v3_v3(vec4, vec);
+       vec4[3]= 1.0;
+
+       mul_m4_v4(rv3d->persmat, vec4);
+
+       /* clipplanes in window space */
+       if( vec4[3] > (float)BL_NEAR_CLIP ) {   /* is the NEAR clipping cutoff for picking */
+               fx= (ar->winx/2)*(1 + vec4[0]/vec4[3]);
+
+               if( fx>0 && fx<ar->winx) {
+
+                       fy= (ar->winy/2)*(1 + vec4[1]/vec4[3]);
+
+                       if(fy > 0.0f && fy < (float)ar->winy) {
+                               adr[0]= (short)floorf(fx);
+                               adr[1]= (short)floorf(fy);
+                       }
+               }
+       }
+}
 /* ************************ */
 
 /* check for glsl drawing */
@@ -215,20 +259,19 @@ int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, int dt)
                return 0;
        if(ob==OBACT && (ob && ob->mode & OB_MODE_WEIGHT_PAINT))
                return 0;
+       if(scene_use_new_shading_nodes(scene))
+               return 0;
        
        return (scene->gm.matmode == GAME_MAT_GLSL) && (dt > OB_SOLID);
 }
 
-static int check_material_alpha(Base *base, Mesh *me, int glsl)
+static int check_material_alpha(Base *base, int glsl)
 {
        if(base->flag & OB_FROMDUPLI)
                return 0;
 
        if(G.f & G_PICKSEL)
                return 0;
-                       
-       if(me->edit_mesh)
-               return 0;
        
        return (glsl || (base->object->dtx & OB_DRAWTRANSP));
 }
@@ -256,7 +299,9 @@ static float cube[8][3] = {
 
 /* ----------------- OpenGL Circle Drawing - Tables for Optimised Drawing Speed ------------------ */
 /* 32 values of sin function (still same result!) */
-static float sinval[32] = {
+#define CIRCLE_RESOL 32
+
+static const float sinval[CIRCLE_RESOL] = {
        0.00000000,
        0.20129852,
        0.39435585,
@@ -292,7 +337,7 @@ static float sinval[32] = {
 };
 
 /* 32 values of cos function (still same result!) */
-static float cosval[32] ={
+static const float cosval[CIRCLE_RESOL] = {
        1.00000000,
        0.97952994,
        0.91895781,
@@ -610,28 +655,39 @@ static void draw_empty_image(Object *ob)
        glPopMatrix();
 }
 
-void drawcircball(int mode, 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])
 {
-       float vec[3], vx[3], vy[3];
-       int a, tot=32;
+       float vx[3], vy[3];
+       float *viter= (float *)verts;
+       unsigned int a;
 
        mul_v3_v3fl(vx, tmat[0], rad);
        mul_v3_v3fl(vy, tmat[1], rad);
 
-       glBegin(mode);
-       for(a=0; a<tot; a++) {
-               vec[0]= cent[0] + *(sinval+a) * vx[0] + *(cosval+a) * vy[0];
-               vec[1]= cent[1] + *(sinval+a) * vx[1] + *(cosval+a) * vy[1];
-               vec[2]= cent[2] + *(sinval+a) * vx[2] + *(cosval+a) * vy[2];
-               glVertex3fv(vec);
+       for (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];
        }
-       glEnd();
+}
+
+void drawcircball(int mode, const float cent[3], float rad, float tmat[][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, int 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 independt order of drawing */
        if(v3d->zbuf)  glDepthFunc(GL_ALWAYS);
@@ -647,12 +703,25 @@ static void drawcentercircle(View3D *v3d, RegionView3D *rv3d, const float co[3],
                else if (selstate == SELECT) UI_ThemeColorShadeAlpha(TH_SELECT, 0, -80);
                else if (selstate == DESELECT) UI_ThemeColorShadeAlpha(TH_TRANSFORM, 0, -80);
        }
-       drawcircball(GL_POLYGON, co, size, rv3d->viewinv);
-       
+
+       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 */
        UI_ThemeColorShadeAlpha(TH_WIRE, 0, -30);
-       drawcircball(GL_LINE_LOOP, co, size, rv3d->viewinv);
-       
+       glDrawArrays(GL_LINE_LOOP, 0, CIRCLE_RESOL);
+
+       /* finishe up */
+       glDisableClientState(GL_VERTEX_ARRAY);
+
        glDisable(GL_BLEND);
+
        if(v3d->zbuf)  glDepthFunc(GL_LEQUAL);
 }
 
@@ -709,7 +778,12 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa
        for(vos= strings->first; vos; vos= vos->next) {
                if(mat && !(vos->flag & V3D_CACHE_TEXT_WORLDSPACE))
                        mul_m4_v3(mat, vos->vec);
-               view3d_project_short_clip(ar, vos->vec, vos->sco, 0);
+
+               if(vos->flag&V3D_CACHE_TEXT_GLOBALSPACE)
+                       view3d_project_short_clip_persmat(ar, vos->vec, vos->sco, 0);
+               else
+                       view3d_project_short_clip(ar, vos->vec, vos->sco, 0);
+
                if(vos->sco[0]!=IS_CLIPPED)
                        tot++;
        }
@@ -741,7 +815,7 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa
                else glDepthMask(0);
                
                for(vos= strings->first; vos; vos= vos->next) {
-#if 0       // too slow, reading opengl info while drawing is very bad, better to see if we cn use the zbuffer while in pixel space - campbell
+#if 0       // too slow, reading opengl info while drawing is very bad, better to see if we can use the zbuffer while in pixel space - campbell
                        if(v3d->zbuf && (vos->flag & V3D_CACHE_TEXT_ZBUF)) {
                                gluProject(vos->vec[0], vos->vec[1], vos->vec[2], mats.modelview, mats.projection, (GLint *)mats.viewport, &ux, &uy, &uz);
                                glReadPixels(ar->winrct.xmin+vos->mval[0]+vos->xoffs, ar->winrct.ymin+vos->mval[1], 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
@@ -1025,7 +1099,12 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
        /* cone can't be drawn for duplicated lamps, because duplilist would be freed to */
        /* the moment of view3d_draw_transp() call */
        const short is_view= (rv3d->persp==RV3D_CAMOB && v3d->camera == base->object);
-       const short drawcone= (dt>OB_WIRE && !(G.f & G_PICKSEL) && (la->type == LA_SPOT) && (la->mode & LA_SHOW_CONE) && !(base->flag & OB_FROMDUPLI) && !is_view);
+       const short drawcone= ((dt > OB_WIRE) &&
+                              !(G.f & G_PICKSEL) &&
+                              (la->type == LA_SPOT) &&
+                              (la->mode & LA_SHOW_CONE) &&
+                              !(base->flag & OB_FROMDUPLI) &&
+                              !is_view);
 
        if(drawcone && !v3d->transp) {
                /* in this case we need to draw delayed */
@@ -1341,19 +1420,203 @@ float view3d_camera_border_hack_col[4];
 short 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);
+               glShadeModel(GL_SMOOTH);
+               gluSphere(qobj, 0.05, 8, 8);
+               glShadeModel(GL_FLAT);
+               gluDeleteQuadric(qobj);
+
+               glEndList();
+       }
+
+       glCallList(displist);
+}
+
+static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d, MovieClip *clip, int flag)
+{
+       MovieTracking *tracking= &clip->tracking;
+       MovieTrackingTrack *track;
+       float mat[4][4], imat[4][4], curcol[4];
+       unsigned char col[4], scol[4];
+       int bundlenr= 1;
+
+       if((v3d->flag2&V3D_SHOW_RECONSTRUCTION)==0)
+               return;
+
+       if(v3d->flag2&V3D_RENDER_OVERRIDE)
+               return;
+
+       glGetFloatv(GL_CURRENT_COLOR, curcol);
+
+       UI_GetThemeColor4ubv(TH_TEXT, col);
+       UI_GetThemeColor4ubv(TH_SELECT, scol);
+
+       BKE_get_tracking_mat(scene, base->object, mat);
+
+       glEnable(GL_LIGHTING);
+       glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
+       glEnable(GL_COLOR_MATERIAL);
+       glShadeModel(GL_SMOOTH);
+
+       /* 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);
+
+       glPushMatrix();
+       glMultMatrixf(imat);
+       glMultMatrixf(mat);
+
+       for ( track= tracking->tracks.first; track; track= track->next) {
+               int selected= track->flag&SELECT || track->pat_flag&SELECT || track->search_flag&SELECT;
+               if((track->flag&TRACK_HAS_BUNDLE)==0)
+                       continue;
+
+               if(flag&DRAW_PICKING)
+                       glLoadName(base->selcol + (bundlenr<<16));
+
+               glPushMatrix();
+                       glTranslatef(track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]);
+                       glScalef(v3d->bundle_size/0.05f, v3d->bundle_size/0.05f, v3d->bundle_size/0.05f);
+
+                       if(v3d->drawtype==OB_WIRE) {
+                               glDisable(GL_LIGHTING);
+                               glDepthMask(0);
+
+                               if(selected) {
+                                       if(base==BASACT) UI_ThemeColor(TH_ACTIVE);
+                                       else UI_ThemeColor(TH_SELECT);
+                               } else {
+                                       if(track->flag&TRACK_CUSTOMCOLOR) glColor3fv(track->color);
+                                       else UI_ThemeColor(TH_WIRE);
+                               }
+
+                               drawaxes(0.05f, v3d->bundle_drawtype);
+
+                               glDepthMask(1);
+                               glEnable(GL_LIGHTING);
+                       } else if(v3d->drawtype>OB_WIRE) {
+                               if(v3d->bundle_drawtype==OB_EMPTY_SPHERE) {
+                                       /* selection outline */
+                                       if(selected) {
+                                               if(base==BASACT) UI_ThemeColor(TH_ACTIVE);
+                                               else UI_ThemeColor(TH_SELECT);
+
+                                               glDepthMask(0);
+                                               glLineWidth(2.f);
+                                               glDisable(GL_LIGHTING);
+                                               glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+
+                                               draw_bundle_sphere();
+
+                                               glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+                                               glEnable(GL_LIGHTING);
+                                               glLineWidth(1.f);
+                                               glDepthMask(1);
+                                       }
+
+                                       if(track->flag&TRACK_CUSTOMCOLOR) glColor3fv(track->color);
+                                       else UI_ThemeColor(TH_BUNDLE_SOLID);
+
+                                       draw_bundle_sphere();
+                               } else {
+                                       glDisable(GL_LIGHTING);
+                                       glDepthMask(0);
+
+                                       if(selected) {
+                                               if(base==BASACT) UI_ThemeColor(TH_ACTIVE);
+                                               else UI_ThemeColor(TH_SELECT);
+                                       } else {
+                                               if(track->flag&TRACK_CUSTOMCOLOR) glColor3fv(track->color);
+                                               else UI_ThemeColor(TH_WIRE);
+                                       }
+
+                                       drawaxes(0.05f, v3d->bundle_drawtype);
+
+                                       glDepthMask(1);
+                                       glEnable(GL_LIGHTING);
+                               }
+                       }
+
+               glPopMatrix();
+
+               if((flag & DRAW_PICKING)==0 && (v3d->flag2&V3D_SHOW_BUNDLENAME)) {
+                       float pos[3];
+                       unsigned char tcol[4];
+
+                       if(selected) memcpy(tcol, scol, sizeof(tcol));
+                       else memcpy(tcol, col, sizeof(tcol));
+
+                       mul_v3_m4v3(pos, mat, track->bundle_pos);
+                       view3d_cached_text_draw_add(pos, track->name, 10, V3D_CACHE_TEXT_GLOBALSPACE, tcol);
+               }
+
+               bundlenr++;
+       }
+
+       if((flag & DRAW_PICKING)==0) {
+               if(v3d->flag2&V3D_SHOW_CAMERAPATH && clip->tracking.reconstruction.camnr) {
+                       int a= 0;
+                       MovieTrackingReconstruction *reconstruction= &tracking->reconstruction;
+                       MovieReconstructedCamera *camera= tracking->reconstruction.cameras;
+
+                       glDisable(GL_LIGHTING);
+                       UI_ThemeColor(TH_CAMERA_PATH);
+                       glLineWidth(2.0f);
+
+                       glBegin(GL_LINE_STRIP);
+                               for(a= 0; a<reconstruction->camnr; a++, camera++) {
+                                       glVertex3fv(camera->mat[3]);
+                               }
+                       glEnd();
+
+                       glLineWidth(1.0f);
+                       glEnable(GL_LIGHTING);
+               }
+       }
+
+       glPopMatrix();
+
+       /* restore */
+       glShadeModel(GL_FLAT);
+       glDisable(GL_COLOR_MATERIAL);
+       glDisable(GL_LIGHTING);
+
+       glColor4fv(curcol);
+
+       if(flag&DRAW_PICKING)
+               glLoadName(base->selcol);
+}
+
 /* flag similar to draw_object() */
-static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, int flag)
+static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int flag)
 {
        /* a standing up pyramid with (0,0,0) as top */
        Camera *cam;
-       float vec[8][4], facx, facy, depth, aspx, aspy, caspx, caspy, shx, shy;
+       Object *ob= base->object;
+       float tvec[3];
+       float vec[4][3], asp[2], shift[2], scale[3];
        int i;
        float drawsize;
        const short is_view= (rv3d->persp==RV3D_CAMOB && ob==v3d->camera);
+       MovieClip *clip= object_get_movieclip(scene, base->object, 0);
 
-       const float scax= 1.0f / len_v3(ob->obmat[0]);
-       const float scay= 1.0f / len_v3(ob->obmat[1]);
-       const float scaz= 1.0f / len_v3(ob->obmat[2]);
+       /* draw data for movie clip set as active for scene */
+       if(clip)
+               draw_viewport_reconstruction(scene, base, v3d, clip, flag);
 
 #ifdef VIEW3D_CAMERA_BORDER_HACK
        if(is_view && !(G.f & G_PICKSEL)) {
@@ -1364,82 +1627,43 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob
 #endif
 
        cam= ob->data;
-       aspx= (float) scene->r.xsch*scene->r.xasp;
-       aspy= (float) scene->r.ysch*scene->r.yasp;
 
-       if(aspx < aspy) {
-               caspx= aspx / aspy;
-               caspy= 1.0;
-       }
-       else {
-               caspx= 1.0;
-               caspy= aspy / aspx;
-       }
-       
-       glDisable(GL_LIGHTING);
-       glDisable(GL_CULL_FACE);
-       
-       if(cam->type==CAM_ORTHO) {
-               facx= 0.5f * cam->ortho_scale * caspx * scax;
-               facy= 0.5f * cam->ortho_scale * caspy * scay;
-               shx= cam->shiftx * cam->ortho_scale * scax;
-               shy= cam->shifty * cam->ortho_scale * scay;
-               depth= is_view ? -((cam->clipsta * scaz) + 0.1f) : - cam->drawsize * cam->ortho_scale * scaz;
-               
-               drawsize= 0.5f * cam->ortho_scale;
-       }
-       else {
-               /* that way it's always visible - clipsta+0.1 */
-               float fac;
-               drawsize= cam->drawsize / ((scax + scay + scaz) / 3.0f);
+       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]);
 
-               if(is_view) {
-                       /* fixed depth, variable size (avoids exceeding clipping range) */
-                       depth = -(cam->clipsta + 0.1f);
-                       fac = depth / (cam->lens/-16.0f * scaz);
-               }
-               else {
-                       /* fixed size, variable depth (stays a reasonable size in the 3D view) */
-                       depth= drawsize * cam->lens/-16.0f * scaz;
-                       fac= drawsize;
-               }
+       camera_view_frame_ex(scene, cam, cam->drawsize, is_view, scale,
+                            asp, shift, &drawsize, vec);
 
-               facx= fac * caspx * scax;
-               facy= fac * caspy * scay;
-               shx= cam->shiftx*fac*2 * scax;
-               shy= cam->shifty*fac*2 * scay;
-       }
-       
-       vec[0][0]= 0.0; vec[0][1]= 0.0; vec[0][2]= 0.0;
-       vec[1][0]= shx + facx; vec[1][1]= shy + facy; vec[1][2]= depth;
-       vec[2][0]= shx + facx; vec[2][1]= shy - facy; vec[2][2]= depth;
-       vec[3][0]= shx - facx; vec[3][1]= shy - facy; vec[3][2]= depth;
-       vec[4][0]= shx - facx; vec[4][1]= shy + facy; vec[4][2]= depth;
+       glDisable(GL_LIGHTING);
+       glDisable(GL_CULL_FACE);
 
        /* camera frame */
        glBegin(GL_LINE_LOOP);
-               glVertex3fv(vec[1]); 
-               glVertex3fv(vec[2]); 
-               glVertex3fv(vec[3]); 
-               glVertex3fv(vec[4]);
+       glVertex3fv(vec[0]);
+       glVertex3fv(vec[1]);
+       glVertex3fv(vec[2]);
+       glVertex3fv(vec[3]);
        glEnd();
 
        if(is_view)
                return;
 
+       zero_v3(tvec);
+
        /* center point to camera frame */
        glBegin(GL_LINE_STRIP);
-               glVertex3fv(vec[2]); 
-               glVertex3fv(vec[0]);
-               glVertex3fv(vec[1]);
-               glVertex3fv(vec[4]);
-               glVertex3fv(vec[0]);
-               glVertex3fv(vec[3]); 
+       glVertex3fv(vec[1]);
+       glVertex3fv(tvec);
+       glVertex3fv(vec[0]);
+       glVertex3fv(vec[3]);
+       glVertex3fv(tvec);
+       glVertex3fv(vec[2]);
        glEnd();
 
 
        /* arrow on top */
-       vec[0][2]= depth;
+       tvec[2]= vec[1][2]; /* copy the depth */
 
 
        /* draw an outline arrow for inactive cameras and filled
@@ -1450,16 +1674,16 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob
                else if (i==1 && (ob == v3d->camera)) glBegin(GL_TRIANGLES);
                else break;
 
-               vec[0][0]= shx + ((-0.7f * drawsize) * scax);
-               vec[0][1]= shy + ((drawsize * (caspy + 0.1f)) * scay);
-               glVertex3fv(vec[0]); /* left */
+               tvec[0]= shift[0] + ((-0.7f * drawsize) * scale[0]);
+               tvec[1]= shift[1] + ((drawsize * (asp[1] + 0.1f)) * scale[1]);
+               glVertex3fv(tvec); /* left */
                
-               vec[0][0]= shx + ((0.7f * drawsize) * scax);
-               glVertex3fv(vec[0]); /* right */
+               tvec[0]= shift[0] + ((0.7f * drawsize) * scale[0]);
+               glVertex3fv(tvec); /* right */
                
-               vec[0][0]= shx;
-               vec[0][1]= shy + ((1.1f * drawsize * (caspy + 0.7f)) * scay);
-               glVertex3fv(vec[0]); /* top */
+               tvec[0]= shift[0];
+               tvec[1]= shift[1] + ((1.1f * drawsize * (asp[1] + 0.7f)) * scale[1]);
+               glVertex3fv(tvec); /* top */
        
                glEnd();
        }
@@ -1480,7 +1704,7 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob
                        if(cam->flag & CAM_SHOWLIMITS) {
                                draw_limit_line(cam->clipsta, cam->clipend, 0x77FFFF);
                                /* qdn: was yafray only, now also enabled for Blender to be used with defocus composit node */
-                               draw_focus_cross(dof_camera(ob), cam->drawsize);
+                               draw_focus_cross(object_camera_dof_distance(ob), cam->drawsize);
                        }
 
                        wrld= scene->world;
@@ -1507,8 +1731,8 @@ static void drawspeaker(Scene *UNUSED(scene), View3D *UNUSED(v3d), RegionView3D
 
                glBegin(GL_LINE_LOOP);
                for(i = 0; i < 16; i++) {
-                       vec[0] = cosf(M_PI * i / 8.0f) * (j == 0 ? 0.5f : 0.25f);
-                       vec[1] = sinf(M_PI * i / 8.0f) * (j == 0 ? 0.5f : 0.25f);
+                       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();
@@ -1593,7 +1817,7 @@ static void drawlattice__point(Lattice *lt, DispList *dl, int u, int v, int w, i
                float col[3];
                MDeformWeight *mdw= defvert_find_index (lt->dvert+index, use_wcol-1);
                
-               weight_to_rgb(mdw?mdw->weight:0.0f, col, col+1, col+2);
+               weight_to_rgb(col, mdw?mdw->weight:0.0f);
                glColor3fv(col);
 
        }
@@ -1712,44 +1936,32 @@ void mesh_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, EditVe
 
        dm->release(dm);
 }
-/*Jason */
-static void mesh_obmode_foreachScreenVert__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
+
+/*  draw callback */
+static void drawSelectedVertices__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
 {
-       struct { void (*func)(void *userData, MVert *mv, int x, int y, int index); void *userData; ViewContext vc; int clipVerts; } *data = userData;
-       Mesh *me = data->vc.obact->data;
-       MVert *mv = me->mvert+index;
-       //MVert *dmv = CDDM_get_verts(data->vc.obact->derivedFinal)+index;
-       //MVert *mv = CDDM_get_verts(data->vc.obact->derivedFinal)+index;
-       if ((mv->flag & ME_HIDE)==0) {
-               short s[2]= {IS_CLIPPED, 0};
+       MVert *mv = &((MVert *)userData)[index];
 
-               if (data->clipVerts) {
-                       view3d_project_short_clip(data->vc.ar, co, s, 1);
-               } else {
-                       view3d_project_short_noclip(data->vc.ar, co, s);
+       if(!(mv->flag & ME_HIDE)) {
+               const char sel= mv->flag & SELECT;
+
+               // TODO define selected color
+               if(sel) {
+                       glColor3f(1.0f, 1.0f, 0.0f);
+               }
+               else {
+                       glColor3f(0.0f, 0.0f, 0.0f);
                }
 
-               if (s[0]!=IS_CLIPPED)
-                       data->func(data->userData, mv, s[0], s[1], index);
+               glVertex3fv(co);
        }
 }
-/*Jason*/
-void mesh_obmode_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, MVert *mv, int x, int y, int index), void *userData, int clipVerts)
-{
-       struct { void (*func)(void *userData, MVert *mv, int x, int y, int index); void *userData; ViewContext vc; int clipVerts; } data;
-       DerivedMesh *dm = mesh_get_derived_final(vc->scene, vc->obact, CD_MASK_BAREMESH);
-
-       data.vc= *vc;
-       data.func = func;
-       data.userData = userData;
-       data.clipVerts = clipVerts;
-       
-       if(clipVerts)
-               ED_view3d_local_clipping(vc->rv3d, vc->obact->obmat); /* for local clipping lookups */
 
-       dm->foreachMappedVert(dm, mesh_obmode_foreachScreenVert__mapFunc, &data);
-
-       dm->release(dm);
+static void drawSelectedVertices(DerivedMesh *dm, Mesh *me)
+{
+       glBegin(GL_POINTS);
+       dm->foreachMappedVert(dm, drawSelectedVertices__mapFunc, me->mvert);
+       glEnd();
 }
 static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, float *v0co, float *v1co)
 {
@@ -1805,7 +2017,9 @@ static void mesh_foreachScreenFace__mapFunc(void *userData, int index, float *ce
        if (efa && efa->h==0 && efa->fgonf!=EM_FGON) {
                view3d_project_short_clip(data->vc.ar, cent, s, 1);
 
-               data->func(data->userData, efa, s[0], s[1], index);
+               if (s[0] != IS_CLIPPED) {
+                       data->func(data->userData, efa, s[0], s[1], index);
+               }
        }
 }
 
@@ -1834,7 +2048,7 @@ void nurbs_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, Nurb
        short s[2] = {IS_CLIPPED, 0};
        Nurb *nu;
        int i;
-       ListBase *nurbs= ED_curve_editnurbs(cu);
+       ListBase *nurbs= curve_editnurbs(cu);
 
        ED_view3d_local_clipping(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
 
@@ -2087,21 +2301,32 @@ static void draw_dm_edges_sharp(DerivedMesh *dm)
        dm->drawMappedEdges(dm, draw_dm_edges_sharp__setDrawOptions, NULL);
 }
 
+       /* Draw only Freestyle feature edges */
+static int draw_dm_edges_freestyle__setDrawOptions(void *UNUSED(userData), int index)
+{
+       EditEdge *eed = EM_get_edge_for_index(index);
+
+       return (eed->h==0 && eed->freestyle);
+}
+static void draw_dm_edges_freestyle(DerivedMesh *dm)
+{
+       dm->drawMappedEdges(dm, draw_dm_edges_freestyle__setDrawOptions, NULL);
+}
 
        /* Draw faces with color set based on selection
         * return 2 for the active face so it renders with stipple enabled */
 static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *UNUSED(drawSmooth_r))
 {
-       struct { unsigned char *cols[3]; EditFace *efa_act; } * data = userData;
+       struct { unsigned char *cols[4]; EditFace *efa_act; } * data = userData;
        EditFace *efa = EM_get_face_for_index(index);
        unsigned char *col;
        
        if (efa->h==0) {
                if (efa == data->efa_act) {
-                       glColor4ubv(data->cols[2]);
+                       glColor4ubv(data->cols[3]);
                        return 2; /* stipple */
                } else {
-                       col = data->cols[(efa->f&SELECT)?1:0];
+                       col = data->cols[(efa->f & SELECT) ? 1 : (efa->flag & ME_FREESTYLE_FACE) ? 2 : 0];
                        if (col[3]==0) return 0;
                        glColor4ubv(col);
                        return 1;
@@ -2112,7 +2337,7 @@ static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *UNU
 
 static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int next_index)
 {
-       struct { unsigned char *cols[3]; EditFace *efa_act; } * data = userData;
+       struct { unsigned char *cols[4]; EditFace *efa_act; } * data = userData;
        EditFace *efa = EM_get_face_for_index(index);
        EditFace *next_efa = EM_get_face_for_index(next_index);
        unsigned char *col, *next_col;
@@ -2123,8 +2348,8 @@ static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int
        if(efa == data->efa_act || next_efa == data->efa_act)
                return 0;
 
-       col = data->cols[(efa->f&SELECT)?1:0];
-       next_col = data->cols[(next_efa->f&SELECT)?1:0];
+       col = data->cols[(efa->f & SELECT) ? 1 : (efa->flag & ME_FREESTYLE_FACE) ? 2 : 0];
+       next_col = data->cols[(next_efa->f & SELECT) ? 1 : (next_efa->flag & ME_FREESTYLE_FACE) ? 2 : 0];
 
        if(col[3]==0 || next_col[3]==0)
                return 0;
@@ -2133,12 +2358,13 @@ static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int
 }
 
 /* also draws the active face */
-static void draw_dm_faces_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *actCol, EditFace *efa_act) 
+static void draw_dm_faces_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *markCol, unsigned char *actCol, EditFace *efa_act) 
 {
-       struct { unsigned char *cols[3]; EditFace *efa_act; } data;
+       struct { unsigned char *cols[4]; EditFace *efa_act; } data;
        data.cols[0] = baseCol;
        data.cols[1] = selCol;
-       data.cols[2] = actCol;
+       data.cols[2] = markCol;
+       data.cols[3] = actCol;
        data.efa_act = efa_act;
 
        dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, &data, 0, GPU_enable_material, draw_dm_faces_sel__compareDrawOptions);
@@ -2361,7 +2587,7 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E
                                copy_v3_v3(v1, eed->v1->co);
                                copy_v3_v3(v2, eed->v2->co);
 
-                               interp_v3_v3v3(vmid, v1, v2, 0.5f);
+                               mid_v3_v3v3(vmid, v1, v2);
 
                                if(do_global) {
                                        mul_mat3_m4_v3(ob->obmat, v1);
@@ -2533,11 +2759,11 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object
                if(CHECK_OB_DRAWTEXTURE(v3d, dt)) {
                        if(draw_glsl_material(scene, ob, v3d, dt)) {
                                glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
-
+                               
                                finalDM->drawMappedFacesGLSL(finalDM, GPU_enable_material,
-                                       draw_em_fancy__setGLSLFaceOpts, NULL);
+                                                            draw_em_fancy__setGLSLFaceOpts, NULL);
                                GPU_disable_material();
-
+                               
                                glFrontFace(GL_CCW);
                        }
                        else {
@@ -2547,12 +2773,12 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object
                else {
                        /* 3 floats for position, 3 for normal and times two because the faces may actually be quads instead of triangles */
                        glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, me->flag & ME_TWOSIDED);
-
+                       
                        glEnable(GL_LIGHTING);
                        glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
-
+                       
                        finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, NULL, 0, GPU_enable_material, NULL);
-
+                       
                        glFrontFace(GL_CCW);
                        glDisable(GL_LIGHTING);
                }
@@ -2572,11 +2798,12 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object
        }
        
        if(me->drawflag & ME_DRAWFACES) {       /* transp faces */
-               unsigned char col1[4], col2[4], col3[4];
+               unsigned char col1[4], col2[4], col3[4], col4[4];
                        
                UI_GetThemeColor4ubv(TH_FACE, col1);
                UI_GetThemeColor4ubv(TH_FACE_SELECT, col2);
-               UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, col3);
+               UI_GetThemeColor4ubv(TH_FREESTYLE_FACE_MARK, col3);
+               UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, col4);
                
                glEnable(GL_BLEND);
                glDepthMask(0);         // disable write in zbuffer, needed for nice transp
@@ -2585,7 +2812,10 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object
                if CHECK_OB_DRAWTEXTURE(v3d, dt)
                        col1[3] = 0;
                
-               draw_dm_faces_sel(cageDM, col1, col2, col3, efa_act);
+               if (!(me->drawflag & ME_DRAW_FREESTYLE_FACE))
+                       col3[3] = 0;
+
+               draw_dm_faces_sel(cageDM, col1, col2, col3, col4, efa_act);
 
                glDisable(GL_BLEND);
                glDepthMask(1);         // restore write in zbuffer
@@ -2593,14 +2823,14 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object
                /* 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; /* dont draw */
-               UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, col3);
+               unsigned char col1[4], col2[4], col3[4], col4[4];
+               col1[3] = col2[3] = col3[3] = 0; /* dont draw */
+               UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, col4);
                
                glEnable(GL_BLEND);
                glDepthMask(0);         // disable write in zbuffer, needed for nice transp
                
-               draw_dm_faces_sel(cageDM, col1, col2, col3, efa_act);
+               draw_dm_faces_sel(cageDM, col1, col2, col3, col4, efa_act);
 
                glDisable(GL_BLEND);
                glDepthMask(1);         // restore write in zbuffer
@@ -2635,6 +2865,16 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object
                        glLineWidth(1);
                }
        
+               if(me->drawflag & ME_DRAW_FREESTYLE_EDGE) {
+                       UI_ThemeColor(TH_FREESTYLE_EDGE_MARK);
+                       glLineWidth(2);
+       
+                       draw_dm_edges_freestyle(cageDM);
+       
+                       glColor3ub(0,0,0);
+                       glLineWidth(1);
+               }
+       
                if(me->drawflag & ME_DRAWCREASES) {
                        draw_dm_creases(cageDM);
                }
@@ -2709,16 +2949,36 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
        Mesh *me = ob->data;
        Material *ma= give_current_material(ob, 1);
        const short hasHaloMat = (ma && (ma->material_type == MA_TYPE_HALO));
-       const short is_paint_sel= (ob==OBACT && paint_facesel_test(ob));
-       int draw_wire = 0;
+       eWireDrawMode draw_wire= OBDRAW_WIRE_OFF;
        int /* totvert,*/ totedge, totface;
        DerivedMesh *dm= mesh_get_derived_final(scene, ob, scene->customdata_mask);
+       ModifierData *md = NULL;
+       int draw_flags = (ob==OBACT && paint_facesel_test(ob)) ? DRAW_FACE_SELECT : 0;
 
        if(!dm)
                return;
-       
-       if (ob->dtx&OB_DRAWWIRE) {
-               draw_wire = 2; /* draw wire after solid using zoffset and depth buffer adjusment */
+
+       /* check to draw dynamic paint colors */
+       if ((md = modifiers_findByType(ob, eModifierType_DynamicPaint)))
+       {
+               /* check if target has an active dpaint modifier        */
+               if(md && (md->mode & eModifierMode_Realtime))                                   
+               {
+                       DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md;
+                       /* if canvas is ready to preview vertex colors */
+                       if (pmd->canvas && pmd->canvas->flags & MOD_DPAINT_PREVIEW_READY &&
+                               DM_get_face_data_layer(dm, CD_WEIGHT_MCOL)) {
+                               draw_flags |= DRAW_DYNAMIC_PAINT_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 */
        }
        
        /* totvert = dm->getNumVerts(dm); */ /*UNUSED*/
@@ -2726,15 +2986,11 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
        totface = dm->getNumFaces(dm);
        
        /* vertexpaint, faceselect wants this, but it doesnt work for shaded? */
-       if(dt!=OB_SHADED)
-               glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
-
-               // Unwanted combination.
-       if (is_paint_sel) draw_wire = 0;
+       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(scene, ob);
+                       draw_bounding_volume(scene, ob, ob->boundtype);
        }
        else if(hasHaloMat || (totface==0 && totedge==0)) {
                glPointSize(1.5);
@@ -2742,16 +2998,21 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
                glPointSize(1.0);
        }
        else if(dt==OB_WIRE || totface==0) {
-               draw_wire = 1; /* draw wire only, no depth buffer stuff  */
+               draw_wire= OBDRAW_WIRE_ON; /* draw wire only, no depth buffer stuff  */
        }
-       else if(        (is_paint_sel || (ob==OBACT && ob->mode & OB_MODE_TEXTURE_PAINT)) ||
-                               CHECK_OB_DRAWTEXTURE(v3d, dt))
+       else if ( (draw_flags & DRAW_FACE_SELECT || (ob==OBACT && ob->mode & OB_MODE_TEXTURE_PAINT)) ||
+                 CHECK_OB_DRAWTEXTURE(v3d, dt))
        {
-               if ((v3d->flag&V3D_SELECT_OUTLINE) && ((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) && (base->flag&SELECT) && !(G.f&G_PICKSEL || is_paint_sel) && !draw_wire) {
+               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)) {
+               if(draw_glsl_material(scene, ob, v3d, dt) && !(draw_flags & DRAW_DYNAMIC_PAINT_PREVIEW)) {
                        glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
 
                        dm->drawFacesGLSL(dm, GPU_enable_material);
@@ -2762,10 +3023,10 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
                        glFrontFace(GL_CCW);
                }
                else {
-                       draw_mesh_textured(scene, v3d, rv3d, ob, dm, is_paint_sel);
+                       draw_mesh_textured(scene, v3d, rv3d, ob, dm, draw_flags);
                }
 
-               if(!is_paint_sel) {
+               if(!(draw_flags & DRAW_FACE_SELECT)) {
                        if(base->flag & SELECT)
                                UI_ThemeColor((ob==OBACT)?TH_ACTIVE:TH_SELECT);
                        else
@@ -2799,13 +3060,57 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
                        GPU_disable_material();
                        
                        /* since we already draw wire as wp guide, dont draw over the top */
-                       draw_wire= 0;
+                       draw_wire= OBDRAW_WIRE_OFF;
+               }
+               else if (draw_flags & DRAW_DYNAMIC_PAINT_PREVIEW) {
+                       /* for object selection draws no shade */
+                       if (flag & (DRAW_PICKING|DRAW_CONSTCOLOR)) {
+                               dm->drawFacesSolid(dm, NULL, 0, GPU_enable_material);
+                       }
+                       else {
+                               /* 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();
+
+                               GPU_enable_material(0, NULL);
+                               
+                               /* set default spec */
+                               glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
+                               glEnable(GL_COLOR_MATERIAL);    /* according manpages needed */
+                               glColor3ub(120, 120, 120);
+                               glDisable(GL_COLOR_MATERIAL);
+                               /* diffuse */
+                               glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
+                               glEnable(GL_LIGHTING);
+                               glEnable(GL_COLOR_MATERIAL);
+
+                               dm->drawMappedFaces(dm, NULL, NULL, 1, GPU_enable_material, NULL);
+                               glDisable(GL_COLOR_MATERIAL);
+                               glDisable(GL_LIGHTING);
+
+                               GPU_disable_material();
+                       }
                }
                else {
                        Paint *p;
 
-                       if((v3d->flag&V3D_SELECT_OUTLINE) && ((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) && (base->flag&SELECT) && !draw_wire && !ob->sculpt)
+                       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);
+                       }
 
                        glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, me->flag & ME_TWOSIDED );
 
@@ -2844,7 +3149,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
                                dm->drawLooseEdges(dm);
                }
        }
-       else if(dt==OB_SHADED) {
+       else if(dt==OB_PAINT) {
                if(ob==OBACT) {
                        if(ob && ob->mode & OB_MODE_WEIGHT_PAINT) {
                                /* enforce default material settings */
@@ -2899,7 +3204,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
                        }
                }
        }
-       if (draw_wire) {
+       if (draw_wire != OBDRAW_WIRE_OFF) {
 
                /* When using wireframe object traw in particle edit mode
                 * the mesh gets in the way of seeing the particles, fade the wire color
@@ -2922,7 +3227,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
                 * 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==2) {
+               if (dt!=OB_WIRE && (draw_wire == OBDRAW_WIRE_ON_DEPTH)) {
                        bglPolygonOffset(rv3d->dist, 1.0);
                        glDepthMask(0); // disable write in zbuffer, selected edge wires show better
                }
@@ -2930,16 +3235,19 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
                if((v3d->flag2 & V3D_RENDER_OVERRIDE && v3d->drawtype >= OB_SOLID)==0)
                        dm->drawEdges(dm, (dt==OB_WIRE || totface==0), me->drawflag & ME_ALLEDGES);
 
-               if (dt!=OB_WIRE && draw_wire==2) {
+               if (dt!=OB_WIRE && (draw_wire == OBDRAW_WIRE_ON_DEPTH)) {
                        glDepthMask(1);
                        bglPolygonOffset(rv3d->dist, 0.0);
                }
        }
-       // Jason
-       if(paint_vertsel_test(ob) && dm->drawSelectedVerts) {
+       
+       if(paint_vertsel_test(ob)) {
+               
                glColor3f(0.0f, 0.0f, 0.0f);
                glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
-               dm->drawSelectedVerts(dm);
+               
+               drawSelectedVertices(dm, ob->data);
+               
                glPointSize(1.0f);
        }
        dm->release(dm);
@@ -2981,8 +3289,8 @@ static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
                                                                                        scene->customdata_mask);
 
                if(dt>OB_WIRE) {
-                       // no transp in editmode, the fancy draw over goes bad then
                        glsl = draw_glsl_material(scene, ob, v3d, dt);
+
                        GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
                }
 
@@ -2997,7 +3305,7 @@ static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
                /* don't create boundbox here with mesh_get_bb(), the derived system will make it, puts deformed bb's OK */
                if(me->totface<=4 || ED_view3d_boundbox_clip(rv3d, ob->obmat, (ob->bb)? ob->bb: me->bb)) {
                        glsl = draw_glsl_material(scene, ob, v3d, dt);
-                       check_alpha = check_material_alpha(base, me, glsl);
+                       check_alpha = check_material_alpha(base, glsl);
 
                        if(dt==OB_SOLID || glsl) {
                                GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl,
@@ -3439,19 +3747,15 @@ static void draw_particle(ParticleKey *state, int draw_as, short draw, float pix
        float vec[3], vec2[3];
        float *vd = NULL;
        float *cd = NULL;
-       float ma_r=0.0f;
-       float ma_g=0.0f;
-       float ma_b=0.0f;
+       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_r) {
-                       ma_r = *pdd->ma_r;
-                       ma_g = *pdd->ma_g;
-                       ma_b = *pdd->ma_b;
+               if(pdd->ma_col) {
+                       copy_v3_v3(ma_col, pdd->ma_col);
                }
        }
 
@@ -3462,9 +3766,7 @@ static void draw_particle(ParticleKey *state, int draw_as, short draw, float pix
                                copy_v3_v3(vd,state->co); pdd->vd+=3;
                        }
                        if(cd) {
-                               cd[0]=ma_r;
-                               cd[1]=ma_g;
-                               cd[2]=ma_b;
+                               copy_v3_v3(cd, pdd->ma_col);
                                pdd->cd+=3;
                        }
                        break;
@@ -3490,9 +3792,9 @@ static void draw_particle(ParticleKey *state, int draw_as, short draw, float pix
                        }
                        else {
                                if(cd) {
-                                       cd[0]=cd[3]=cd[6]=cd[9]=cd[12]=cd[15]=ma_r;
-                                       cd[1]=cd[4]=cd[7]=cd[10]=cd[13]=cd[16]=ma_g;
-                                       cd[2]=cd[5]=cd[8]=cd[11]=cd[14]=cd[17]=ma_b;
+                                       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);
@@ -3537,9 +3839,9 @@ static void draw_particle(ParticleKey *state, int draw_as, short draw, float pix
                        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_r;
-                               cd[1]=cd[4]=ma_g;
-                               cd[2]=cd[5]=ma_b;
+                               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;
@@ -3553,9 +3855,9 @@ static void draw_particle(ParticleKey *state, int draw_as, short draw, float pix
                {
                        float xvec[3], yvec[3], zvec[3], bb_center[3];
                        if(cd) {
-                               cd[0]=cd[3]=cd[6]=cd[9]=ma_r;
-                               cd[1]=cd[4]=cd[7]=cd[10]=ma_g;
-                               cd[2]=cd[5]=cd[8]=cd[11]=ma_b;
+                               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;
                        }
 
@@ -3610,7 +3912,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
        float timestep, pixsize=1.0, pa_size, r_tilt, r_length;
        float pa_time, pa_birthtime, pa_dietime, pa_health, intensity;
        float cfra;
-       float ma_r=0.0f, ma_g=0.0f, ma_b=0.0f;
+       float ma_col[3]= {0.0f, 0.0f, 0.0f};
        int a, totpart, totpoint=0, totve=0, drawn, draw_as, totchild=0;
        int select=ob->flag&SELECT, create_cdata=0, need_v=0;
        GLint polygonmode[2];
@@ -3674,10 +3976,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
 
        if((ma) && (part->draw_col == PART_DRAW_COL_MAT)) {
                rgb_float_to_byte(&(ma->r), tcol);
-
-               ma_r = ma->r;
-               ma_g = ma->g;
-               ma_b = ma->b;
+               copy_v3_v3(ma_col, &ma->r);
        }
 
        glColor3ubv(tcol);
@@ -3695,7 +3994,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
 
        totpart=psys->totpart;
 
-       cfra= bsystem_time(scene, NULL, (float)CFRA, 0.0f);
+       cfra= BKE_curframe(scene);
 
        if(draw_as==PART_DRAW_PATH && psys->pathcache==NULL && psys->childcache==NULL)
                draw_as=PART_DRAW_DOT;
@@ -3843,9 +4142,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
        }
 
        if(pdd) {
-               pdd->ma_r = &ma_r;
-               pdd->ma_g = &ma_g;
-               pdd->ma_b = &ma_b;
+               pdd->ma_col= ma_col;
        }
 
        psys->lattice= psys_get_lattice(&sim);
@@ -3887,7 +4184,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
                                                        intensity= 1.0f; /* should never happen */
                                        }
                                        CLAMP(intensity, 0.f, 1.f);
-                                       weight_to_rgb(intensity, &ma_r, &ma_g, &ma_b);
+                                       weight_to_rgb(ma_col, intensity);
                                }
                        }
                        else{
@@ -4039,7 +4336,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
 
        if(draw_as==PART_DRAW_PATH){
                ParticleCacheKey **cache, *path;
-               float *cd2=NULL,*cdata2=NULL;
+               float /* *cd2=NULL, */ /* UNUSED */ *cdata2=NULL;
 
                /* setup gl flags */
                if (1) { //ob_dt > OB_WIRE) {
@@ -4107,7 +4404,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
 
                if(cdata2)
                        MEM_freeN(cdata2);
-               cd2=cdata2=NULL;
+               /* cd2= */ /* UNUSED */ cdata2=NULL;
 
                glLineWidth(1.0f);
 
@@ -4148,7 +4445,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
                }
 
                /* restore from select */
-               glColor3f(ma_r,ma_g,ma_b);
+               glColor3fv(ma_col);
                glPointSize(part->draw_size ? part->draw_size : 2.0);
                glLineWidth(1.0);
 
@@ -4213,7 +4510,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
 
        if(pdd) {
                /* drop references to stack memory */
-               pdd->ma_r= pdd->ma_g= pdd->ma_b= NULL;
+               pdd->ma_col= NULL;
        }
 
        if( (base->flag & OB_FROMDUPLI) && (ob->flag & OB_FROMGROUP) ) {
@@ -4555,16 +4852,22 @@ static void tekenhandlesN(Nurb *nu, short sel, short hide_handles)
 {
        BezTriple *bezt;
        float *fp;
-       int basecol;
        int a;
-       
+
        if(nu->hide || hide_handles) return;
 
        glBegin(GL_LINES); 
-       
+
        if(nu->type == CU_BEZIER) {
-               if(sel) basecol= TH_HANDLE_SEL_FREE;
-               else basecol= TH_HANDLE_FREE;
+
+#define TH_HANDLE_COL_TOT ((TH_HANDLE_SEL_FREE - TH_HANDLE_FREE) + 1)
+               /* use MIN2 when indexing to ensure newer files dont 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 (a=0; a < TH_HANDLE_COL_TOT; a++) {
+                       UI_GetThemeColor3ubv(basecol + a, handle_cols[a]);
+               }
 
                bezt= nu->bezt;
                a= nu->pntsu;
@@ -4573,31 +4876,34 @@ static void tekenhandlesN(Nurb *nu, short sel, short hide_handles)
                                if( (bezt->f2 & SELECT)==sel) {
                                        fp= bezt->vec[0];
 
-                                       UI_ThemeColor(basecol + bezt->h1);
+                                       glColor3ubv(handle_cols[MIN2(bezt->h1, TH_HANDLE_COL_TOT-1)]);
                                        glVertex3fv(fp);
                                        glVertex3fv(fp+3); 
 
-                                       UI_ThemeColor(basecol + bezt->h2);
+                                       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];
 
-                                       UI_ThemeColor(basecol + bezt->h1);
+                                       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];
 
-                                       UI_ThemeColor(basecol + bezt->h2);
+                                       glColor3ubv(handle_cols[MIN2(bezt->h2, TH_HANDLE_COL_TOT-1)]);
                                        glVertex3fv(fp); 
                                        glVertex3fv(fp+3); 
                                }
                        }
                        bezt++;
                }
+
+#undef TH_HANDLE_COL_TOT
+
        }
        glEnd();
 }
@@ -4935,7 +5241,7 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
                        int skip= nu->resolu/16;
                        
                        while (nr-->0) { /* accounts for empty bevel lists */
-                               float fac= bevp->radius * ts->normalsize;
+                               const float fac= bevp->radius * ts->normalsize;
                                float vec_a[3]; // Offset perpendicular to the curve
                                float vec_b[3]; // Delta along the curve
 
@@ -4951,9 +5257,9 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
                                mul_qt_v3(bevp->quat, vec_b);
                                add_v3_v3(vec_a, bevp->vec);
                                add_v3_v3(vec_b, bevp->vec);
-                               
-                               VECSUBFAC(vec_a, vec_a, bevp->dir, fac);
-                               VECSUBFAC(vec_b, vec_b, bevp->dir, fac);
+
+                               madd_v3_v3fl(vec_a, bevp->dir, -fac);
+                               madd_v3_v3fl(vec_b, bevp->dir, -fac);
 
                                glBegin(GL_LINE_STRIP);
                                glVertex3fv(vec_a);
@@ -5065,7 +5371,7 @@ static void curve_draw_speed(Scene *scene, Object *ob)
 #endif // XXX old animation system stuff
 
 
-static void draw_textcurs(float textcurs[][2])
+static void draw_textcurs(float textcurs[4][2])
 {
        cpack(0);
        
@@ -5082,49 +5388,67 @@ static void draw_textcurs(float textcurs[][2])
 static void drawspiral(const float cent[3], float rad, float tmat[][4], int start)
 {
        float vec[3], vx[3], vy[3];
-       int a, tot=32;
-       char inverse=0;
-               
+       const float tot_inv= (1.0f / (float)CIRCLE_RESOL);
+       int a;
+       char inverse= FALSE;
+       float x, y, fac;
+
        if (start < 0) {
-               inverse = 1;
-               start *= -1;
+               inverse = TRUE;
+               start= -start;
        }
 
        mul_v3_v3fl(vx, tmat[0], rad);
        mul_v3_v3fl(vy, tmat[1], rad);
 
-       copy_v3_v3(vec, cent);
+       glBegin(GL_LINE_STRIP);
 
        if (inverse==0) {
-               for(a=0; a<tot; a++) {
-                       if (a+start>31)
+               copy_v3_v3(vec, cent);
+               glVertex3fv(vec);
+
+               for(a=0; a<CIRCLE_RESOL; a++) {
+                       if (a+start>=CIRCLE_RESOL)
                                start=-a + 1;
-                       glBegin(GL_LINES);                                                      
-                       glVertex3fv(vec);
-                       vec[0]= cent[0] + *(sinval+a+start) * (vx[0] * (float)a/(float)tot) + *(cosval+a+start) * (vy[0] * (float)a/(float)tot);
-                       vec[1]= cent[1] + *(sinval+a+start) * (vx[1] * (float)a/(float)tot) + *(cosval+a+start) * (vy[1] * (float)a/(float)tot);
-                       vec[2]= cent[2] + *(sinval+a+start) * (vx[2] * (float)a/(float)tot) + *(cosval+a+start) * (vy[2] * (float)a/(float)tot);
+
+                       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);
-                       glEnd();
                }
        }
        else {
-               a=0;
-               vec[0]= cent[0] + *(sinval+a+start) * (vx[0] * (float)(-a+31)/(float)tot) + *(cosval+a+start) * (vy[0] * (float)(-a+31)/(float)tot);
-               vec[1]= cent[1] + *(sinval+a+start) * (vx[1] * (float)(-a+31)/(float)tot) + *(cosval+a+start) * (vy[1] * (float)(-a+31)/(float)tot);
-               vec[2]= cent[2] + *(sinval+a+start) * (vx[2] * (float)(-a+31)/(float)tot) + *(cosval+a+start) * (vy[2] * (float)(-a+31)/(float)tot);
-               for(a=0; a<tot; a++) {
-                       if (a+start>31)
+               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;
-                       glBegin(GL_LINES);                                                      
-                       glVertex3fv(vec);
-                       vec[0]= cent[0] + *(sinval+a+start) * (vx[0] * (float)(-a+31)/(float)tot) + *(cosval+a+start) * (vy[0] * (float)(-a+31)/(float)tot);
-                       vec[1]= cent[1] + *(sinval+a+start) * (vx[1] * (float)(-a+31)/(float)tot) + *(cosval+a+start) * (vy[1] * (float)(-a+31)/(float)tot);
-                       vec[2]= cent[2] + *(sinval+a+start) * (vx[2] * (float)(-a+31)/(float)tot) + *(cosval+a+start) * (vy[2] * (float)(-a+31)/(float)tot);
+
+                       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();
                }
        }
+
+       glEnd();
 }
 
 /* draws a circle on x-z plane given the scaling of the circle, assuming that 
@@ -5138,9 +5462,9 @@ 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 (degrees=0; degrees<32; degrees++) {
-               x= *(cosval + degrees);
-               y= *(sinval + degrees);
+       for (degrees=0; degrees<CIRCLE_RESOL; degrees++) {
+               x= cosval[degrees];
+               y= sinval[degrees];
                
                glVertex3f(x*size, 0.0f, y*size);
        }
@@ -5408,8 +5732,7 @@ static void draw_forcefield(Scene *scene, Object *ob, RegionView3D *rv3d)
 
                unit_m4(tmat);
 
-               radius=(pd->flag&PFIELD_USEMAXR)?pd->maxrad:1.0f;
-               radius*=(float)M_PI/180.0f;
+               radius= DEG2RADF((pd->flag&PFIELD_USEMAXR) ? pd->maxrad : 1.0f);
                distance=(pd->flag&PFIELD_USEMAX)?pd->maxdist:0.0f;
 
                if(pd->flag & (PFIELD_USEMAX|PFIELD_USEMAXR)){
@@ -5418,8 +5741,7 @@ static void draw_forcefield(Scene *scene, Object *ob, RegionView3D *rv3d)
                                drawcone(vec, distance * sinf(radius),-distance * cosf(radius),tmat);
                }
 
-               radius=(pd->flag&PFIELD_USEMINR)?pd->minrad:1.0f;
-               radius*=(float)M_PI/180.0f;
+               radius= DEG2RADF((pd->flag&PFIELD_USEMINR) ? pd->minrad : 1.0f);
                distance=(pd->flag&PFIELD_USEMIN)?pd->mindist:0.0f;
 
                if(pd->flag & (PFIELD_USEMIN|PFIELD_USEMINR)){
@@ -5468,7 +5790,7 @@ static void get_local_bounds(Object *ob, float center[3], float size[3])
 }
 #endif
 
-static void draw_bb_quadric(BoundBox *bb, short type)
+static void draw_bb_quadric(BoundBox *bb, char type)
 {
        float size[3], cent[3];
        GLUquadricObj *qobj = gluNewQuadric(); 
@@ -5507,7 +5829,7 @@ static void draw_bb_quadric(BoundBox *bb, short type)
        gluDeleteQuadric(qobj); 
 }
 
-static void draw_bounding_volume(Scene *scene, Object *ob)
+static void draw_bounding_volume(Scene *scene, Object *ob, char type)
 {
        BoundBox *bb= NULL;
        
@@ -5533,8 +5855,8 @@ static void draw_bounding_volume(Scene *scene, Object *ob)
        
        if(bb==NULL) return;
        
-       if(ob->boundtype==OB_BOUND_BOX) draw_box(bb->vec);
-       else draw_bb_quadric(bb, ob->boundtype);
+       if(type==OB_BOUND_BOX) draw_box(bb->vec);
+       else draw_bb_quadric(bb, type);
        
 }
 
@@ -5746,7 +6068,6 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
        Object *ob;
        Curve *cu;
        RegionView3D *rv3d= ar->regiondata;
-       //float cfraont;
        float vec1[3], vec2[3];
        unsigned int col=0;
        int /*sel, drawtype,*/ colindex= 0;
@@ -5785,83 +6106,6 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
        /* no return after this point, otherwise leaks */
        view3d_cached_text_draw_begin();
        
-
-       /* draw keys? */
-#if 0 // XXX old animation system
-       if(base==(scene->basact) || (base->flag & (SELECT+BA_WAS_SEL))) {
-               if(flag==0 && warning_recursive==0 && ob!=scene->obedit) {
-                       if(ob->ipo && ob->ipo->showkey && (ob->ipoflag & OB_DRAWKEY)) {
-                               ListBase elems;
-                               CfraElem *ce;
-                               float temp[7][3];
-
-                               warning_recursive= 1;
-
-                               elems.first= elems.last= 0;
-                               // warning: no longer checks for certain ob-keys only... (so does this need to use the proper ipokeys then?)
-                               make_cfra_list(ob->ipo, &elems); 
-
-                               cfraont= (scene->r.cfra);
-                               drawtype= v3d->drawtype;
-                               if(drawtype>OB_WIRE) v3d->drawtype= OB_WIRE;
-                               sel= base->flag;
-                               memcpy(temp, &ob->loc, 7*3*sizeof(float));
-
-                               ipoflag= ob->ipoflag;
-                               ob->ipoflag &= ~OB_OFFS_OB;
-
-                               set_no_parent_ipo(1);
-                               disable_speed_curve(1);
-
-                               if ((ob->ipoflag & OB_DRAWKEYSEL)==0) {
-                                       ce= elems.first;
-                                       while(ce) {
-                                               if(!ce->sel) {
-                                                       (scene->r.cfra)= ce->cfra/scene->r.framelen;
-
-                                                       base->flag= 0;
-
-                                                       where_is_object_time(scene, ob, (scene->r.cfra));
-                                                       draw_object(scene, ar, v3d, base, 0);
-                                               }
-                                               ce= ce->next;
-                                       }
-                               }
-
-                               ce= elems.first;
-                               while(ce) {
-                                       if(ce->sel) {
-                                               (scene->r.cfra)= ce->cfra/scene->r.framelen;
-
-                                               base->flag= SELECT;
-
-                                               where_is_object_time(scene, ob, (scene->r.cfra));
-                                               draw_object(scene, ar, v3d, base, 0);
-                                       }
-                                       ce= ce->next;
-                               }
-
-                               set_no_parent_ipo(0);
-                               disable_speed_curve(0);
-
-                               base->flag= sel;
-                               ob->ipoflag= ipoflag;
-
-                               /* restore icu->curval */
-                               (scene->r.cfra)= cfraont;
-
-                               memcpy(&ob->loc, temp, 7*3*sizeof(float));
-                               where_is_object(scene, ob);
-                               v3d->drawtype= drawtype;
-
-                               BLI_freelistN(&elems);
-
-                               warning_recursive= 0;
-                       }
-               }
-       }
-#endif // XXX old animation system
-
        /* patch? children objects with a timeoffs change the parents. How to solve! */
        /* if( ((int)ob->ctime) != F_(scene->r.cfra)) where_is_object(scene, ob); */
        
@@ -5919,7 +6163,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                                        if(base->flag & (SELECT+BA_WAS_SEL)) {
                                                /* uses darker active color for non-active + selected*/
                                                theme_id= TH_GROUP_ACTIVE;
-
+                                               
                                                if(scene->basact != base) {
                                                        theme_shade= -16;
                                                }
@@ -5953,7 +6197,9 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
        }
 
        /* maximum drawtype */
-       dt= MIN2(v3d->drawtype, ob->dt);
+       dt= v3d->drawtype;
+       if(dt==OB_RENDER) dt= OB_SOLID;
+       dt= MIN2(dt, ob->dt);
        if(v3d->zbuf==0 && dt>OB_WIRE) dt= OB_WIRE;
        dtx= 0;
 
@@ -5968,7 +6214,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                                        dt= OB_SOLID;
                                }
                                else {
-                                       dt= OB_SHADED;
+                                       dt= OB_PAINT;
                                }
 
                                glEnable(GL_DEPTH_TEST);
@@ -6098,7 +6344,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                        }
                        else if(dt==OB_BOUNDBOX) {
                                if((v3d->flag2 & V3D_RENDER_OVERRIDE && v3d->drawtype >= OB_WIRE)==0)
-                                       draw_bounding_volume(scene, ob);
+                                       draw_bounding_volume(scene, ob, ob->boundtype);
                        }
                        else if(ED_view3d_boundbox_clip(rv3d, ob->obmat, ob->bb ? ob->bb : cu->bb))
                                empty_object= drawDispList(scene, v3d, rv3d, base, dt);
@@ -6109,12 +6355,12 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                        cu= ob->data;
 
                        if(cu->editnurb) {
-                               ListBase *nurbs= ED_curve_editnurbs(cu);
+                               ListBase *nurbs= curve_editnurbs(cu);
                                drawnurb(scene, v3d, rv3d, base, nurbs->first, dt);
                        }
                        else if(dt==OB_BOUNDBOX) {
                                if((v3d->flag2 & V3D_RENDER_OVERRIDE && v3d->drawtype >= OB_WIRE)==0)
-                                       draw_bounding_volume(scene, ob);
+                                       draw_bounding_volume(scene, ob, ob->boundtype);
                        }
                        else if(ED_view3d_boundbox_clip(rv3d, ob->obmat, ob->bb ? ob->bb : cu->bb)) {
                                empty_object= drawDispList(scene, v3d, rv3d, base, dt);
@@ -6131,7 +6377,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                                drawmball(scene, v3d, rv3d, base, dt);
                        else if(dt==OB_BOUNDBOX) {
                                if((v3d->flag2 & V3D_RENDER_OVERRIDE && v3d->drawtype >= OB_WIRE)==0)
-                                       draw_bounding_volume(scene, ob);
+                                       draw_bounding_volume(scene, ob, ob->boundtype);
                        }
                        else 
                                empty_object= drawmball(scene, v3d, rv3d, base, dt);
@@ -6155,7 +6401,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                        break;
                case OB_CAMERA:
                        if((v3d->flag2 & V3D_RENDER_OVERRIDE)==0 || (rv3d->persp==RV3D_CAMOB && v3d->camera==ob)) /* special exception for active camera */
-                               drawcamera(scene, v3d, rv3d, ob, flag);
+                               drawcamera(scene, v3d, rv3d, base, flag);
                        break;
                case OB_SPEAKER:
                        if((v3d->flag2 & V3D_RENDER_OVERRIDE)==0)
@@ -6373,6 +6619,14 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                        }
                }
 
+               if(ob->gameflag & OB_BOUNDS) {
+                       if(ob->boundtype!=ob->collision_boundtype || (dtx & OB_BOUNDBOX)==0) {
+                               setlinestyle(2);
+                               draw_bounding_volume(scene, ob, ob->collision_boundtype);
+                               setlinestyle(0);
+                       }
+               }
+
                /* draw extra: after normal draw because of makeDispList */
                if(dtx && (G.f & G_RENDER_OGL)==0) {
 
@@ -6380,8 +6634,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                                drawaxes(1.0f, OB_ARROWS);
                        }
                        if(dtx & OB_BOUNDBOX) {
-                               if((v3d->flag2 & V3D_RENDER_OVERRIDE)==0)
-                                       draw_bounding_volume(scene, ob);
+                               draw_bounding_volume(scene, ob, ob->boundtype);
                        }
                        if(dtx & OB_TEXSPACE) drawtexspace(ob);
                        if(dtx & OB_DRAWNAME) {
@@ -6499,7 +6752,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                                        for (ct= targets.first; ct; ct= ct->next) {
                                                /* calculate target's matrix */
                                                if (cti->get_target_matrix) 
-                                                       cti->get_target_matrix(curcon, cob, ct, bsystem_time(scene, ob, (float)(scene->r.cfra), give_timeoffset(ob)));
+                                                       cti->get_target_matrix(curcon, cob, ct, BKE_curframe(scene));
                                                else
                                                        unit_m4(ct->matrix);
                                                
@@ -6524,26 +6777,29 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
 }
 
 /* ***************** BACKBUF SEL (BBS) ********* */
-/* Jason */
+
 static void bbs_obmode_mesh_verts__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
 {
-       // TODO: support hidden vertices
-       int offset = (intptr_t) userData;
-       //EditVert *eve = EM_get_vert_for_index(index);
+       struct {void* offset; MVert *mvert;} *data = userData;
+       MVert *mv = &data->mvert[index];
+       int offset = (intptr_t) data->offset;
 
-       //if (eve->h==0) {
-       WM_set_framebuffer_index_color(offset+index);
-       bglVertex3fv(co);
-       //}
+       if (!(mv->flag & ME_HIDE)) {
+               WM_set_framebuffer_index_color(offset+index);
+               bglVertex3fv(co);
+       }
 }
-/* Jason */
-static void bbs_obmode_mesh_verts(Scene* scene, Object *ob, DerivedMesh *dm, int offset)
-{
-       Mesh *me = (Mesh*)ob->data;
 
+static void bbs_obmode_mesh_verts(Object *ob, DerivedMesh *dm, int offset)
+{
+       struct {void* offset; struct MVert *mvert;} data;
+       Mesh *me = ob->data;
+       MVert *mvert = me->mvert;
+       data.mvert = mvert;
+       data.offset = (void*)(intptr_t) offset;
        glPointSize( UI_GetThemeValuef(TH_VERTEX_SIZE) );
        bglBegin(GL_POINTS);
-       dm->foreachMappedVert(dm, bbs_obmode_mesh_verts__mapFunc, (void*)(intptr_t) offset);
+       dm->foreachMappedVert(dm, bbs_obmode_mesh_verts__mapFunc, &data);
        bglEnd();
        glPointSize(1.0);
 }
@@ -6645,13 +6901,13 @@ static int bbs_mesh_solid_hide__setDrawOpts(void *userData, int index, int *UNUS
                return 0;
        }
 }
-/* Jason */
+
 // must have called WM_set_framebuffer_index_color beforehand
 static int bbs_mesh_solid_hide2__setDrawOpts(void *userData, int index, int *UNUSED(drawSmooth_r))
 {
        Mesh *me = userData;
 
-       if (!(me->mface[index].flag&ME_HIDE)) {
+       if (!(me->mface[index].flag & ME_HIDE)) {
                return 1;
        } else {
                return 0;
@@ -6716,15 +6972,17 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
                }
                else {
                        Mesh *me= ob->data;
-                       if(me->editflag & ME_EDIT_VERT_SEL) {
+                       if(     (me->editflag & ME_EDIT_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);
-                               WM_set_framebuffer_index_color(me->totvert+2);
                                glColor3ub(0, 0, 0);
 
                                dm->drawMappedFaces(dm, bbs_mesh_solid_hide2__setDrawOpts, me, 0, GPU_enable_material, NULL);
 
                                
-                               bbs_obmode_mesh_verts(scene, ob, dm, 1);
+                               bbs_obmode_mesh_verts(ob, dm, 1);
                                em_vertoffs = me->totvert+1;
                                dm->release(dm);
                        }