Internal refactoring of tracking module, should be no functional changes
[blender.git] / source / blender / editors / space_view3d / drawobject.c
index 00622f368f091966ed8488133f240202504734be..b92d3d9d24cd6f79edda65e3071d02e0ca9cc59a 100644 (file)
@@ -143,6 +143,17 @@ typedef struct drawDMVerts_userData {
 
        int sel;
        BMVert *eve_act;
+
+       /* cached theme values */
+       unsigned char th_editmesh_active[4];
+       unsigned char th_vertex_select[4];
+       unsigned char th_vertex[4];
+       unsigned char th_skin_root[4];
+       float th_vertex_size;
+
+       /* for skin node drawing */
+       int has_vskin;
+       float imat[4][4];
 } drawDMVerts_userData;
 
 typedef struct drawDMEdgesSel_userData {
@@ -322,7 +333,7 @@ static void view3d_project_short_clip_persmat(ARegion *ar, const float vec[3], s
 
 /* check for glsl drawing */
 
-int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, int dt)
+int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, const short dt)
 {
        if (!GPU_glsl_support())
                return 0;
@@ -1178,14 +1189,17 @@ static void draw_transp_spot_volume(Lamp *la, float x, float z)
        glCullFace(GL_BACK);
 }
 
-static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt, int flag)
+static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
+                     const short 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]);
        Lamp *la = ob->data;
        float vec[3], lvec[3], vvec[3], circrad, x, y, z;
        float lampsize;
-       float imat[4][4], curcol[4];
+       float imat[4][4];
+
+       unsigned char curcol[4];
        unsigned char col[4];
        /* cone can't be drawn for duplicated lamps, because duplilist would be freed to */
        /* the moment of view3d_draw_transp() call */
@@ -1199,7 +1213,7 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
 
        if (drawcone && !v3d->transp) {
                /* in this case we need to draw delayed */
-               add_view3d_after(&v3d->afterdraw_transp, base, flag);
+               ED_view3d_after_add(&v3d->afterdraw_transp, base, dflag);
                return;
        }
        
@@ -1217,17 +1231,23 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
 
        /* lamp center */
        copy_v3_v3(vec, ob->obmat[3]);
-       
-       /* for AA effects */
-       glGetFloatv(GL_CURRENT_COLOR, curcol);
-       curcol[3] = 0.6;
-       glColor4fv(curcol);
-       
+
+       if ((dflag & DRAW_CONSTCOLOR) == 0) {
+               /* for AA effects */
+               curcol[0] = ob_wire_col[0];
+               curcol[1] = ob_wire_col[1];
+               curcol[2] = ob_wire_col[2];
+               curcol[3] = 154;
+               glColor4ubv(curcol);
+       }
+
        if (lampsize > 0.0f) {
 
-               if (ob->id.us > 1) {
-                       if (ob == OBACT || (ob->flag & SELECT)) glColor4ub(0x88, 0xFF, 0xFF, 155);
-                       else glColor4ub(0x77, 0xCC, 0xCC, 155);
+               if ((dflag & DRAW_CONSTCOLOR) == 0) {
+                       if (ob->id.us > 1) {
+                               if (ob == OBACT || (ob->flag & SELECT)) glColor4ub(0x88, 0xFF, 0xFF, 155);
+                               else glColor4ub(0x77, 0xCC, 0xCC, 155);
+                       }
                }
                
                /* Inner Circle */
@@ -1237,8 +1257,10 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
                drawcircball(GL_POLYGON, vec, lampsize, imat);
                
                /* restore */
-               if (ob->id.us > 1)
-                       glColor4fv(curcol);
+               if ((dflag & DRAW_CONSTCOLOR) == 0) {
+                       if (ob->id.us > 1)
+                               glColor4ubv(curcol);
+               }
 
                /* Outer circle */
                circrad = 3.0f * lampsize;
@@ -1470,9 +1492,10 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
        
        glDisable(GL_BLEND);
        
-       /* restore for drawing extra stuff */
-       glColor3fv(curcol);
-
+       if ((dflag & DRAW_CONSTCOLOR) == 0) {
+               /* restore for drawing extra stuff */
+               glColor3ubv(ob_wire_col);
+       }
 }
 
 static void draw_limit_line(float sta, float end, unsigned int col)
@@ -1505,7 +1528,7 @@ static void draw_focus_cross(float dist, float size)
 }
 
 #ifdef VIEW3D_CAMERA_BORDER_HACK
-float view3d_camera_border_hack_col[4];
+unsigned char view3d_camera_border_hack_col[3];
 short view3d_camera_border_hack_test = FALSE;
 #endif
 
@@ -1535,20 +1558,20 @@ static void draw_bundle_sphere(void)
 }
 
 static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D *v3d,
-                                                MovieClip *clip, MovieTrackingObject *tracking_object, int flag,
-                                                int *global_track_index, int draw_selected)
+                                                MovieClip *clip, MovieTrackingObject *tracking_object,
+                                                const short dflag, int *global_track_index, int draw_selected)
 {
        MovieTracking *tracking = &clip->tracking;
        MovieTrackingTrack *track;
        float mat[4][4], imat[4][4];
        unsigned char col[4], scol[4];
        int tracknr = *global_track_index;
-       ListBase *tracksbase = BKE_tracking_object_tracks(tracking, tracking_object);
+       ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, tracking_object);
 
        UI_GetThemeColor4ubv(TH_TEXT, col);
        UI_GetThemeColor4ubv(TH_SELECT, scol);
 
-       BKE_get_tracking_mat(scene, base->object, mat);
+       BKE_tracking_get_camera_object_matrix(scene, base->object, mat);
 
        glPushMatrix();
 
@@ -1564,7 +1587,7 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D
        else {
                float obmat[4][4];
 
-               BKE_tracking_get_interpolated_camera(tracking, tracking_object, scene->r.cfra, obmat);
+               BKE_tracking_camera_get_reconstructed_interpolate(tracking, tracking_object, scene->r.cfra, obmat);
 
                invert_m4_m4(imat, obmat);
                glMultMatrixf(imat);
@@ -1579,7 +1602,7 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D
                if ((track->flag & TRACK_HAS_BUNDLE) == 0)
                        continue;
 
-               if (flag & DRAW_PICKING)
+               if (dflag & DRAW_PICKING)
                        glLoadName(base->selcol + (tracknr << 16));
 
                glPushMatrix();
@@ -1645,7 +1668,7 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D
 
                glPopMatrix();
 
-               if ((flag & DRAW_PICKING) == 0 && (v3d->flag2 & V3D_SHOW_BUNDLENAME)) {
+               if ((dflag & DRAW_PICKING) == 0 && (v3d->flag2 & V3D_SHOW_BUNDLENAME)) {
                        float pos[3];
                        unsigned char tcol[4];
 
@@ -1659,10 +1682,10 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D
                tracknr++;
        }
 
-       if ((flag & DRAW_PICKING) == 0) {
+       if ((dflag & DRAW_PICKING) == 0) {
                if ((v3d->flag2 & V3D_SHOW_CAMERAPATH) && (tracking_object->flag & TRACKING_OBJECT_CAMERA)) {
                        MovieTrackingReconstruction *reconstruction;
-                       reconstruction = BKE_tracking_object_reconstruction(tracking, tracking_object);
+                       reconstruction = BKE_tracking_object_get_reconstruction(tracking, tracking_object);
 
                        if (reconstruction->camnr) {
                                MovieReconstructedCamera *camera = reconstruction->cameras;
@@ -1690,11 +1713,11 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D
 }
 
 static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d, MovieClip *clip,
-                                         int flag, int draw_selected)
+                                         const short dflag, const unsigned char ob_wire_col[4],
+                                         int draw_selected)
 {
        MovieTracking *tracking = &clip->tracking;
        MovieTrackingObject *tracking_object;
-       float curcol[4];
        int global_track_index = 1;
 
        if ((v3d->flag2 & V3D_SHOW_RECONSTRUCTION) == 0)
@@ -1703,8 +1726,6 @@ static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d,
        if (v3d->flag2 & V3D_RENDER_OVERRIDE)
                return;
 
-       glGetFloatv(GL_CURRENT_COLOR, curcol);
-
        glEnable(GL_LIGHTING);
        glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
        glEnable(GL_COLOR_MATERIAL);
@@ -1713,7 +1734,7 @@ static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d,
        tracking_object = tracking->objects.first;
        while (tracking_object) {
                draw_viewport_object_reconstruction(scene, base, v3d, clip, tracking_object,
-                                                   flag, &global_track_index, draw_selected);
+                                                   dflag, &global_track_index, draw_selected);
 
                tracking_object = tracking_object->next;
        }
@@ -1723,14 +1744,17 @@ static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d,
        glDisable(GL_COLOR_MATERIAL);
        glDisable(GL_LIGHTING);
 
-       glColor4fv(curcol);
+       if ((dflag & DRAW_CONSTCOLOR) == 0) {
+               glColor3ubv(ob_wire_col);
+       }
 
-       if (flag & DRAW_PICKING)
+       if (dflag & DRAW_PICKING)
                glLoadName(base->selcol);
 }
 
 /* flag similar to draw_object() */
-static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int flag)
+static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
+                       const short dflag, const unsigned char ob_wire_col[4])
 {
        /* a standing up pyramid with (0,0,0) as top */
        Camera *cam;
@@ -1744,13 +1768,22 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base
 
        /* draw data for movie clip set as active for scene */
        if (clip) {
-               draw_viewport_reconstruction(scene, base, v3d, clip, flag, FALSE);
-               draw_viewport_reconstruction(scene, base, v3d, clip, flag, TRUE);
+               draw_viewport_reconstruction(scene, base, v3d, clip, dflag, ob_wire_col, FALSE);
+               draw_viewport_reconstruction(scene, base, v3d, clip, dflag, ob_wire_col, TRUE);
        }
 
 #ifdef VIEW3D_CAMERA_BORDER_HACK
        if (is_view && !(G.f & G_PICKSEL)) {
-               glGetFloatv(GL_CURRENT_COLOR, view3d_camera_border_hack_col);
+               if ((dflag & DRAW_CONSTCOLOR) == 0) {
+                       view3d_camera_border_hack_col[0] = ob_wire_col[0];
+                       view3d_camera_border_hack_col[1] = ob_wire_col[1];
+                       view3d_camera_border_hack_col[2] = ob_wire_col[2];
+               }
+               else {
+                       float col[4];
+                       glGetFloatv(GL_CURRENT_COLOR, col);
+                       rgb_float_to_uchar(view3d_camera_border_hack_col, col);
+               }
                view3d_camera_border_hack_test = TRUE;
                return;
        }
@@ -1818,7 +1851,7 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base
                glEnd();
        }
 
-       if (flag == 0) {
+       if (dflag == 0) {
                if (cam->flag & (CAM_SHOWLIMITS + CAM_SHOWMIST)) {
                        float nobmat[4][4];
                        World *wrld;
@@ -1967,7 +2000,7 @@ static void drawlattice(Scene *scene, View3D *v3d, Object *ob)
        Lattice *lt = ob->data;
        DispList *dl;
        int u, v, w;
-       int use_wcol = 0, is_edit = (lt->editlatt != NULL);
+       int use_wcol = FALSE, is_edit = (lt->editlatt != NULL);
 
        /* now we default make displist, this will modifiers work for non animated case */
        if (ob->disp.first == NULL)
@@ -2400,20 +2433,37 @@ static void draw_dm_verts__mapFunc(void *userData, int index, const float co[3],
        BMVert *eve = EDBM_vert_at_index(data->em, index);
 
        if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN) && BM_elem_flag_test(eve, BM_ELEM_SELECT) == data->sel) {
+               /* skin nodes: draw a red circle around the root
+                * node(s) */
+               if (data->has_vskin) {
+                       const MVertSkin *vs = CustomData_bmesh_get(&data->em->bm->vdata,
+                                                                  eve->head.data,
+                                                                  CD_MVERT_SKIN);
+                       if (vs->flag & MVERT_SKIN_ROOT) {
+                               float radius = (vs->radius[0] + vs->radius[1]) * 0.5f;
+                               bglEnd();
+                       
+                               glColor4ubv(data->th_skin_root);
+                               drawcircball(GL_LINES, co, radius, data->imat);
+
+                               glColor4ubv(data->sel ? data->th_vertex_select : data->th_vertex);
+                               bglBegin(GL_POINTS);
+                       }
+               }
+
                /* draw active larger - need to stop/start point drawing for this :/ */
                if (eve == data->eve_act) {
-                       float size = UI_GetThemeValuef(TH_VERTEX_SIZE);
-                       UI_ThemeColor4(TH_EDITMESH_ACTIVE);
+                       glColor4ubv(data->th_editmesh_active);
                        
                        bglEnd();
                        
-                       glPointSize(size);
+                       glPointSize(data->th_vertex_size);
                        bglBegin(GL_POINTS);
                        bglVertex3fv(co);
                        bglEnd();
-                       
-                       UI_ThemeColor4(data->sel ? TH_VERTEX_SELECT : TH_VERTEX);
-                       glPointSize(size);
+
+                       glColor4ubv(data->sel ? data->th_vertex_select : data->th_vertex);
+                       glPointSize(data->th_vertex_size);
                        bglBegin(GL_POINTS);
                }
                else {
@@ -2422,13 +2472,27 @@ static void draw_dm_verts__mapFunc(void *userData, int index, const float co[3],
        }
 }
 
-static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, int sel, BMVert *eve_act)
+static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, int sel, BMVert *eve_act,
+                          RegionView3D *rv3d)
 {
        drawDMVerts_userData data;
        data.sel = sel;
        data.eve_act = eve_act;
        data.em = em;
 
+       /* Cache theme values */
+       UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, data.th_editmesh_active);
+       UI_GetThemeColor4ubv(TH_VERTEX_SELECT, data.th_vertex_select);
+       UI_GetThemeColor4ubv(TH_VERTEX, data.th_vertex);
+       UI_GetThemeColor4ubv(TH_SKIN_ROOT, data.th_skin_root);
+       data.th_vertex_size = UI_GetThemeValuef(TH_VERTEX_SIZE);
+
+       /* For skin root drawing */
+       data.has_vskin = CustomData_has_layer(&em->bm->vdata, CD_MVERT_SKIN);
+       /* view-aligned matrix */
+       mult_m4_m4m4(data.imat, rv3d->viewmat, em->ob->obmat);
+       invert_m4(data.imat);
+
        bglBegin(GL_POINTS);
        dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data);
        bglEnd();
@@ -2711,7 +2775,8 @@ static void draw_dm_bweights(BMEditMesh *em, Scene *scene, DerivedMesh *dm)
 /* EditMesh drawing routines*/
 
 static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit, 
-                                BMEditMesh *em, DerivedMesh *cageDM, BMVert *eve_act)
+                                BMEditMesh *em, DerivedMesh *cageDM, BMVert *eve_act,
+                                                               RegionView3D *rv3d)
 {
        ToolSettings *ts = scene->toolsettings;
        int sel;
@@ -2750,7 +2815,7 @@ static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit,
                        if (ts->selectmode & SCE_SELECT_VERTEX) {
                                glPointSize(size);
                                glColor4ubv(col);
-                               draw_dm_verts(em, cageDM, sel, eve_act);
+                               draw_dm_verts(em, cageDM, sel, eve_act, rv3d);
                        }
                        
                        if (check_ob_drawface_dot(scene, v3d, obedit->dt)) {
@@ -2910,7 +2975,7 @@ static void draw_em_measure_stats(View3D *v3d, Object *ob, BMEditMesh *em, UnitS
                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);
                
@@ -2931,16 +2996,16 @@ static void draw_em_measure_stats(View3D *v3d, Object *ob, BMEditMesh *em, UnitS
                        copy_v3_v3(v1, l[0]->v->co);
                        copy_v3_v3(v2, l[1]->v->co);
                        copy_v3_v3(v3, l[2]->v->co);
+                       add_v3_v3(vmid, v1);
+                       add_v3_v3(vmid, v2);
+                       add_v3_v3(vmid, v3);
+                       n += 3;
                        if (do_global) {
                                mul_mat3_m4_v3(ob->obmat, v1);
                                mul_mat3_m4_v3(ob->obmat, v2);
                                mul_mat3_m4_v3(ob->obmat, v3);
                        }
                        area += area_tri_v3(v1, v2, v3);
-                       add_v3_v3(vmid, v1);
-                       add_v3_v3(vmid, v2);
-                       add_v3_v3(vmid, v3);
-                       n += 3;
                }
 
                if (f) {
@@ -2951,6 +3016,7 @@ static void draw_em_measure_stats(View3D *v3d, Object *ob, BMEditMesh *em, UnitS
 
        if (me->drawflag & ME_DRAWEXTRA_FACEANG) {
                BMFace *efa;
+               int is_rad = unit->system_rotation == USER_UNIT_ROT_RADIANS;
 
                UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEANG, col);
 
@@ -2961,37 +3027,40 @@ static void draw_em_measure_stats(View3D *v3d, Object *ob, BMEditMesh *em, UnitS
                        if (is_face_sel || do_moving) {
                                BMIter liter;
                                BMLoop *loop;
-                               int cent_ok = FALSE;
+                               int is_first = TRUE;
 
-                               BM_ITER_ELEM(loop, &liter, efa, BM_LOOPS_OF_FACE) {
+                               BM_ITER_ELEM (loop, &liter, efa, BM_LOOPS_OF_FACE) {
                                        if (is_face_sel || (do_moving && BM_elem_flag_test(loop->v, BM_ELEM_SELECT))) {
-                                               /* yes, we should avoid triple matrix multiply every vertex for 'global' */
                                                float angle;
 
                                                /* lazy init center calc */
-                                               if (cent_ok == FALSE) {
+                                               if (is_first) {
                                                        BM_face_calc_center_bounds(efa, vmid);
-                                                       cent_ok = TRUE;
+                                                       /* Avoid triple matrix multiply every vertex for 'global' */
+                                                       if (do_global) {
+                                                               copy_v3_v3(v1, loop->prev->v->co);
+                                                               copy_v3_v3(v2, loop->v->co);
+                                                               mul_mat3_m4_v3(ob->obmat, v1);
+                                                               mul_mat3_m4_v3(ob->obmat, v2);
+                                                       }
+                                                       is_first = FALSE;
                                                }
 
                                                if (do_global) {
-                                                       copy_v3_v3(v1, loop->prev->v->co);
-                                                       copy_v3_v3(v2, loop->v->co);
                                                        copy_v3_v3(v3, loop->next->v->co);
 
-                                                       mul_mat3_m4_v3(ob->obmat, v1);
-                                                       mul_mat3_m4_v3(ob->obmat, v2);
                                                        mul_mat3_m4_v3(ob->obmat, v3);
 
                                                        angle = angle_v3v3v3(v1, v2, v3);
-                                                       interp_v3_v3v3(fvec, vmid, v2, 0.8f);
+                                                       copy_v3_v3(v1, v2);
+                                                       copy_v3_v3(v2, v3);
                                                }
                                                else {
                                                        angle = angle_v3v3v3(loop->prev->v->co, loop->v->co, loop->next->v->co);
-                                                       interp_v3_v3v3(fvec, vmid, loop->v->co, 0.8f);
                                                }
 
-                                               BLI_snprintf(numstr, sizeof(numstr), "%.3f", RAD2DEGF(angle));
+                                               BLI_snprintf(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle));
+                                               interp_v3_v3v3(fvec, vmid, loop->v->co, 0.8f);
                                                view3d_cached_text_draw_add(fvec, numstr, 0, txt_flag, col);
                                        }
                                }
@@ -3077,7 +3146,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, int dt)
+                          Object *ob, BMEditMesh *em, DerivedMesh *cageDM, DerivedMesh *finalDM, const short dt)
 
 {
        Mesh *me = ob->data;
@@ -3223,7 +3292,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d,
                draw_em_fancy_edges(em, scene, v3d, me, cageDM, 0, eed_act);
        }
        if (em) {
-               draw_em_fancy_verts(scene, v3d, ob, em, cageDM, eve_act);
+               draw_em_fancy_verts(scene, v3d, ob, em, cageDM, eve_act, rv3d);
 
                if (me->drawflag & ME_DRAWNORMALS) {
                        UI_ThemeColor(TH_NORMAL);
@@ -3241,7 +3310,8 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d,
                }
 
                if ((G.debug & G_DEBUG) && (me->drawflag & ME_DRAWEXTRA_INDICES) &&
-                   !(v3d->flag2 & V3D_RENDER_OVERRIDE)) {
+                   !(v3d->flag2 & V3D_RENDER_OVERRIDE))
+               {
                        draw_em_indices(em);
                }
        }
@@ -3283,7 +3353,8 @@ 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, int dt, int flag)
+static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
+                            const short dt, const short dflag)
 {
        Object *ob = base->object;
        Mesh *me = ob->data;
@@ -3369,10 +3440,12 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
        else if (dt == OB_SOLID) {
                if (draw_flags & DRAW_MODIFIERS_PREVIEW) {
                        /* for object selection draws no shade */
-                       if (flag & (DRAW_PICKING | DRAW_CONSTCOLOR)) {
+                       if (dflag & (DRAW_PICKING | DRAW_CONSTCOLOR)) {
                                dm->drawFacesSolid(dm, NULL, 0, GPU_enable_material);
                        }
                        else {
+                               const float spec[4] = {0.47f, 0.47f, 0.47f, 0.47f};
+
                                /* draw outline */
                                if ( (v3d->flag & V3D_SELECT_OUTLINE) &&
                                     ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
@@ -3390,9 +3463,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
                                
                                /* 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);
+                               glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
                                /* diffuse */
                                glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
                                glEnable(GL_LIGHTING);
@@ -3471,7 +3542,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
                                UI_ThemeColor(TH_GROUP_ACTIVE);
                        else if (ob->flag & OB_FROMGROUP)
                                UI_ThemeColorShade(TH_GROUP_ACTIVE, -16);
-                       else if (flag != DRAW_CONSTCOLOR)
+                       else if (dflag != DRAW_CONSTCOLOR)
                                UI_ThemeColor(is_obact ? TH_ACTIVE : TH_SELECT);
                        else
                                glColor3ub(80, 80, 80);
@@ -3480,7 +3551,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
                        if (ob->flag & OB_FROMGROUP)
                                UI_ThemeColor(TH_GROUP);
                        else {
-                               if (ob->dtx & OB_DRAWWIRE && flag == DRAW_CONSTCOLOR)
+                               if (ob->dtx & OB_DRAWWIRE && dflag == DRAW_CONSTCOLOR)
                                        glColor3ub(80, 80, 80);
                                else
                                        UI_ThemeColor(TH_WIRE);
@@ -3537,13 +3608,14 @@ 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, int dt, int flag)
+static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
+                            const short dt, const short dflag)
 {
        Object *ob = base->object;
        Object *obedit = scene->obedit;
        Mesh *me = ob->data;
        BMEditMesh *em = me->edit_btmesh;
-       int do_alpha_after = 0, drawlinked = 0, retval = 0, glsl, check_alpha, i;
+       int do_alpha_after = FALSE, drawlinked = 0, retval = 0, glsl, check_alpha, i;
 
        /* If we are drawing shadows and any of the materials don't cast a shadow,
         * then don't draw the object */
@@ -3561,7 +3633,13 @@ static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
                else if (ob->modifiers.first || obedit->modifiers.first) {}
                else drawlinked = 1;
        }
-       
+
+       /* backface culling */
+       if (v3d->flag2 & V3D_BACKFACE_CULLING) {
+               glEnable(GL_CULL_FACE);
+               glCullFace(GL_BACK);
+       }
+
        if (ob == obedit || drawlinked) {
                DerivedMesh *finalDM, *cageDM;
                
@@ -3595,7 +3673,7 @@ static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
                                                           (check_alpha) ? &do_alpha_after : NULL);
                        }
 
-                       draw_mesh_fancy(scene, ar, v3d, rv3d, base, dt, flag);
+                       draw_mesh_fancy(scene, ar, v3d, rv3d, base, dt, dflag);
 
                        GPU_end_object_materials();
                        
@@ -3603,23 +3681,26 @@ static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
                }
        }
        
-       if ((flag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0) {
+       if ((dflag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0) {
                /* GPU_begin_object_materials checked if this is needed */
                if (do_alpha_after) {
                        if (ob->dtx & OB_DRAWXRAY) {
-                               add_view3d_after(&v3d->afterdraw_xraytransp, base, flag);
+                               ED_view3d_after_add(&v3d->afterdraw_xraytransp, base, dflag);
                        }
                        else {
-                               add_view3d_after(&v3d->afterdraw_transp, base, flag);
+                               ED_view3d_after_add(&v3d->afterdraw_transp, base, dflag);
                        }
                }
                else if (ob->dtx & OB_DRAWXRAY && ob->dtx & OB_DRAWTRANSP) {
                        /* special case xray+transp when alpha is 1.0, without this the object vanishes */
                        if (v3d->xray == 0 && v3d->transp == 0) {
-                               add_view3d_after(&v3d->afterdraw_xray, base, flag);
+                               ED_view3d_after_add(&v3d->afterdraw_xray, base, dflag);
                        }
                }
        }
+
+       if (v3d->flag2 & V3D_BACKFACE_CULLING)
+               glDisable(GL_CULL_FACE);
        
        return retval;
 }
@@ -3721,17 +3802,15 @@ static int drawDispListwire(ListBase *dlbase)
        return 0;
 }
 
-static void drawDispListsolid(ListBase *lb, Object *ob, int glsl)
+static void drawDispListsolid(ListBase *lb, Object *ob,
+                              const unsigned char ob_wire_col[4], int use_glsl)
 {
        DispList *dl;
        GPUVertexAttribs gattribs;
-       float *data, curcol[4];
+       float *data;
        float *ndata;
        
        if (lb == NULL) return;
-       
-       /* for drawing wire */
-       glGetFloatv(GL_CURRENT_COLOR, curcol);
 
        glEnable(GL_LIGHTING);
        glEnableClientState(GL_VERTEX_ARRAY);
@@ -3754,7 +3833,7 @@ static void drawDispListsolid(ListBase *lb, Object *ob, int glsl)
                                        int nr;
 
                                        glDisable(GL_LIGHTING);
-                                       glColor3fv(curcol);
+                                       glColor3ubv(ob_wire_col);
 
                                        // glVertexPointer(3, GL_FLOAT, 0, dl->verts);
                                        // glDrawArrays(GL_LINE_STRIP, 0, dl->nr);
@@ -3788,7 +3867,7 @@ static void drawDispListsolid(ListBase *lb, Object *ob, int glsl)
                        case DL_SURF:
 
                                if (dl->index) {
-                                       GPU_enable_material(dl->col + 1, (glsl) ? &gattribs : NULL);
+                                       GPU_enable_material(dl->col + 1, (use_glsl) ? &gattribs : NULL);
 
                                        if (dl->rt & CU_SMOOTH) glShadeModel(GL_SMOOTH);
                                        else glShadeModel(GL_FLAT);
@@ -3802,11 +3881,11 @@ static void drawDispListsolid(ListBase *lb, Object *ob, int glsl)
                                break;
 
                        case DL_INDEX3:
-                               GPU_enable_material(dl->col + 1, (glsl) ? &gattribs : NULL);
+                               GPU_enable_material(dl->col + 1, (use_glsl) ? &gattribs : NULL);
 
                                glVertexPointer(3, GL_FLOAT, 0, dl->verts);
 
-                               /* voor polys only one normal needed */
+                               /* for polys only one normal needed */
                                if (index3_nors_incr) {
                                        glEnableClientState(GL_NORMAL_ARRAY);
                                        glNormalPointer(GL_FLOAT, 0, dl->nors);
@@ -3822,7 +3901,7 @@ static void drawDispListsolid(ListBase *lb, Object *ob, int glsl)
                                break;
 
                        case DL_INDEX4:
-                               GPU_enable_material(dl->col + 1, (glsl) ? &gattribs : NULL);
+                               GPU_enable_material(dl->col + 1, (use_glsl) ? &gattribs : NULL);
 
                                glEnableClientState(GL_NORMAL_ARRAY);
                                glVertexPointer(3, GL_FLOAT, 0, dl->verts);
@@ -3848,7 +3927,7 @@ static void drawCurveDMWired(Object *ob)
 }
 
 /* return 1 when nothing was drawn */
-static int drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt)
+static int drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, const short dt)
 {
        Object *ob = base->object;
        DerivedMesh *dm = ob->derivedFinal;
@@ -3880,7 +3959,8 @@ static int drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d, B
 }
 
 /* returns 1 when nothing was drawn */
-static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt)
+static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
+                        const short dt, const unsigned char ob_wire_col[4])
 {
        Object *ob = base->object;
        ListBase *lb = NULL;
@@ -3890,7 +3970,17 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
        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;
        }
 
@@ -3918,12 +4008,12 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
                                else {
                                        if (draw_glsl_material(scene, ob, v3d, dt)) {
                                                GPU_begin_object_materials(v3d, rv3d, scene, ob, 1, NULL);
-                                               drawDispListsolid(lb, ob, 1);
+                                               drawDispListsolid(lb, ob, ob_wire_col, TRUE);
                                                GPU_end_object_materials();
                                        }
                                        else {
                                                GPU_begin_object_materials(v3d, rv3d, scene, ob, 0, NULL);
-                                               drawDispListsolid(lb, ob, 0);
+                                               drawDispListsolid(lb, ob, ob_wire_col, FALSE);
                                                GPU_end_object_materials();
                                        }
                                        if (cu->editnurb && cu->bevobj == NULL && cu->taperobj == NULL && cu->ext1 == 0.0f && cu->ext2 == 0.0f) {
@@ -3955,12 +4045,12 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
 
                                if (draw_glsl_material(scene, ob, v3d, dt)) {
                                        GPU_begin_object_materials(v3d, rv3d, scene, ob, 1, NULL);
-                                       drawDispListsolid(lb, ob, 1);
+                                       drawDispListsolid(lb, ob, ob_wire_col, TRUE);
                                        GPU_end_object_materials();
                                }
                                else {
                                        GPU_begin_object_materials(v3d, rv3d, scene, ob, 0, NULL);
-                                       drawDispListsolid(lb, ob, 0);
+                                       drawDispListsolid(lb, ob, ob_wire_col, FALSE);
                                        GPU_end_object_materials();
                                }
                        }
@@ -3979,12 +4069,12 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
 
                                        if (draw_glsl_material(scene, ob, v3d, dt)) {
                                                GPU_begin_object_materials(v3d, rv3d, scene, ob, 1, NULL);
-                                               drawDispListsolid(lb, ob, 1);
+                                               drawDispListsolid(lb, ob, ob_wire_col, TRUE);
                                                GPU_end_object_materials();
                                        }
                                        else {
                                                GPU_begin_object_materials(v3d, rv3d, scene, ob, 0, NULL);
-                                               drawDispListsolid(lb, ob, 0);
+                                               drawDispListsolid(lb, ob, ob_wire_col, FALSE);
                                                GPU_end_object_materials();
                                        }
                                }
@@ -3996,6 +4086,9 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
                        break;
        }
        
+       if (v3d->flag2 & V3D_BACKFACE_CULLING)
+               glDisable(GL_CULL_FACE);
+
        return retval;
 }
 
@@ -5493,7 +5586,8 @@ static void draw_editnurb(Object *ob, Nurb *nurb, int sel)
        }
 }
 
-static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, Nurb *nurb, int dt)
+static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, Nurb *nurb,
+                     const short dt, const unsigned char ob_wire_col[4])
 {
        ToolSettings *ts = scene->toolsettings;
        Object *ob = base->object;
@@ -5502,10 +5596,13 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
        BevList *bl;
        short hide_handles = (cu->drawflag & CU_HIDE_HANDLES);
        int index;
+       unsigned char wire_col[3];
 
        /* DispList */
-       UI_ThemeColor(TH_WIRE);
-       drawDispList(scene, v3d, rv3d, base, dt);
+       UI_GetThemeColor3ubv(TH_WIRE, wire_col);
+       glColor3ubv(wire_col);
+
+       drawDispList(scene, v3d, rv3d, base, dt, ob_wire_col);
 
        if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
        
@@ -5817,7 +5914,8 @@ static void drawcone(const float vec[3], float radius, float height, float tmat[
        glEnd();
 }
 /* return 1 if nothing was drawn */
-static int drawmball(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt)
+static int drawmball(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
+                     const short dt, const unsigned char ob_wire_col[4])
 {
        Object *ob = base->object;
        MetaBall *mb;
@@ -5828,13 +5926,19 @@ static int drawmball(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
        mb = ob->data;
 
        if (mb->editelems) {
-               UI_ThemeColor(TH_WIRE);
-               if ((G.f & G_PICKSEL) == 0) drawDispList(scene, v3d, rv3d, base, dt);
+               if ((G.f & G_PICKSEL) == 0) {
+                       unsigned char wire_col[3];
+                       UI_GetThemeColor3ubv(TH_WIRE, wire_col);
+                       glColor3ubv(wire_col);
+
+                       drawDispList(scene, v3d, rv3d, base, dt, wire_col);
+               }
                ml = mb->editelems->first;
        }
        else {
-               if ((base->flag & OB_FROMDUPLI) == 0)
-                       drawDispList(scene, v3d, rv3d, base, dt);
+               if ((base->flag & OB_FROMDUPLI) == 0) {
+                       drawDispList(scene, v3d, rv3d, base, dt, ob_wire_col);
+               }
                ml = mb->elems.first;
        }
 
@@ -6206,7 +6310,8 @@ static void drawtexspace(Object *ob)
 }
 
 /* draws wire outline */
-static void drawObjectSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
+static void drawObjectSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
+                             const unsigned char ob_wire_col[4])
 {
        RegionView3D *rv3d = ar->regiondata;
        Object *ob = base->object;
@@ -6245,7 +6350,7 @@ static void drawObjectSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
        }
        else if (ob->type == OB_ARMATURE) {
                if (!(ob->mode & OB_MODE_POSE && base == scene->basact))
-                       draw_armature(scene, v3d, ar, base, OB_WIRE, FALSE, TRUE);
+                       draw_armature(scene, v3d, ar, base, OB_WIRE, FALSE, ob_wire_col, TRUE);
        }
 
        glLineWidth(1.0);
@@ -6337,19 +6442,13 @@ static void draw_hooks(Object *ob)
        }
 }
 
-static void drawRBpivot(bRigidBodyJointConstraint *data)
+static void drawRBpivot(bRigidBodyJointConstraint *data, const unsigned char ob_wire_col[4])
 {
        const char *axis_str[3] = {"px", "py", "pz"};
        int axis;
        float mat[4][4];
 
        /* color */
-       float curcol[4];
-       unsigned char tcol[4];
-
-       glGetFloatv(GL_CURRENT_COLOR, curcol);
-       rgb_float_to_uchar(tcol, curcol);
-       tcol[3] = 255;
 
        eul_to_mat4(mat, &data->axX);
        glLineWidth(4.0f);
@@ -6368,14 +6467,89 @@ static void drawRBpivot(bRigidBodyJointConstraint *data)
                glVertex3fv(v);
                glEnd();
 
-               view3d_cached_text_draw_add(v, axis_str[axis], 0, V3D_CACHE_TEXT_ASCII, tcol);
+               view3d_cached_text_draw_add(v, axis_str[axis], 0, V3D_CACHE_TEXT_ASCII, ob_wire_col);
        }
        glLineWidth(1.0f);
        setlinestyle(0);
 }
 
+static void draw_object_wire_color(Scene *scene, Base *base, unsigned char r_ob_wire_col[4],
+                                   const int warning_recursive)
+{
+       Object *ob = base->object;
+       int colindex = 0;
+
+       /* confusing logic here, there are 2 methods of setting the color
+        * 'colortab[colindex]' and 'theme_id', colindex overrides theme_id.
+        *
+        * note: no theme yet for 'colindex' */
+       int theme_id = TH_WIRE;
+       int theme_shade = 0;
+
+       if ((scene->obedit == NULL) &&
+           (G.moving & G_TRANSFORM_OBJ) &&
+           (base->flag & (SELECT + BA_WAS_SEL)))
+       {
+               theme_id = TH_TRANSFORM;
+       }
+       else {
+               /* Sets the 'colindex' */
+               if (ob->id.lib) {
+                       colindex = (base->flag & (SELECT + BA_WAS_SEL)) ? 4 : 3;
+               }
+               else if (warning_recursive == 1) {
+                       if (base->flag & (SELECT + BA_WAS_SEL)) {
+                               colindex = (scene->basact == base) ? 8 : 7;
+                       }
+                       else {
+                               colindex = 6;
+                       }
+               }
+               /* Sets the 'theme_id' or fallback to wire */
+               else {
+                       if (ob->flag & OB_FROMGROUP) {
+                               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;
+                                       }
+                               }
+                               else {
+                                       theme_id = TH_GROUP;
+                               }
+                       }
+                       else {
+                               if (base->flag & (SELECT + BA_WAS_SEL)) {
+                                       theme_id = scene->basact == base ? TH_ACTIVE : TH_SELECT;
+                               }
+                               else {
+                                       if (ob->type == OB_LAMP) theme_id = TH_LAMP;
+                                       else if (ob->type == OB_SPEAKER) theme_id = TH_SPEAKER;
+                                       else if (ob->type == OB_CAMERA) theme_id = TH_CAMERA;
+                                       else if (ob->type == OB_EMPTY) theme_id = TH_EMPTY;
+                                       /* fallback to TH_WIRE */
+                               }
+                       }
+               }
+       }
+
+       /* finally set the color */
+       if (colindex == 0) {
+               if (theme_shade == 0) UI_GetThemeColor3ubv(theme_id, r_ob_wire_col);
+               else                  UI_GetThemeColorShade3ubv(theme_id, theme_shade, r_ob_wire_col);
+       }
+       else {
+               cpack_cpy_3ub(r_ob_wire_col, colortab[colindex]);
+       }
+
+       /* no reason to use this but some functions take col[4] */
+       r_ob_wire_col[3] = 255;
+}
+
 /* flag can be DRAW_PICKING    and/or DRAW_CONSTCOLOR, DRAW_SCENESET */
-void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
+void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short dflag)
 {
        static int warning_recursive = 0;
        ModifierData *md = NULL;
@@ -6384,7 +6558,8 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
        RegionView3D *rv3d = ar->regiondata;
        float vec1[3], vec2[3];
        unsigned int col = 0;
-       int /*sel, drawtype,*/ colindex = 0;
+       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;
        const short is_obact = (ob == OBACT);
@@ -6408,12 +6583,12 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                return;
 
        /* xray delay? */
-       if ((flag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0) {
+       if ((dflag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0) {
                /* don't do xray in particle mode, need the z-buffer */
                if (!(ob->mode & OB_MODE_PARTICLE_EDIT)) {
                        /* xray and transp are set when it is drawing the 2nd/3rd pass */
                        if (!v3d->xray && !v3d->transp && (ob->dtx & OB_DRAWXRAY) && !(ob->dtx & OB_DRAWTRANSP)) {
-                               add_view3d_after(&v3d->afterdraw_xray, base, flag);
+                               ED_view3d_after_add(&v3d->afterdraw_xray, base, dflag);
                                return;
                        }
                }
@@ -6422,9 +6597,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();
        
-       /* patch? children objects with a timeoffs change the parents. How to solve! */
-       /* if ( ((int)ob->ctime) != F_(scene->r.cfra)) BKE_object_where_is_calc(scene, ob); */
-       
        /* draw motion paths (in view space) */
        if (ob->mpath && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
                bAnimVizSettings *avs = &ob->avs;
@@ -6444,74 +6616,14 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
        ED_view3d_init_mats_rv3d_gl(ob, rv3d);
 
        /* which wire color */
-       if ((flag & DRAW_CONSTCOLOR) == 0) {
-               /* confusing logic here, there are 2 methods of setting the color
-                * 'colortab[colindex]' and 'theme_id', colindex overrides theme_id.
-                *
-                * note: no theme yet for 'colindex' */
-               int theme_id = TH_WIRE;
-               int theme_shade = 0;
+       if ((dflag & DRAW_CONSTCOLOR) == 0) {
 
                project_short(ar, ob->obmat[3], &base->sx);
 
-               if ((scene->obedit == NULL) &&
-                   (G.moving & G_TRANSFORM_OBJ) &&
-                   (base->flag & (SELECT + BA_WAS_SEL)))
-               {
-                       theme_id = TH_TRANSFORM;
-               }
-               else {
-                       /* Sets the 'colindex' */
-                       if (ob->id.lib) {
-                               colindex = (base->flag & (SELECT + BA_WAS_SEL)) ? 4 : 3;
-                       }
-                       else if (warning_recursive == 1) {
-                               if (base->flag & (SELECT + BA_WAS_SEL)) {
-                                       colindex = (scene->basact == base) ? 8 : 7;
-                               }
-                               else {
-                                       colindex = 6;
-                               }
-                       }
-                       /* Sets the 'theme_id' or fallback to wire */
-                       else {
-                               if (ob->flag & OB_FROMGROUP) {
-                                       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;
-                                               }
-                                       }
-                                       else {
-                                               theme_id = TH_GROUP;
-                                       }
-                               }
-                               else {
-                                       if (base->flag & (SELECT + BA_WAS_SEL)) {
-                                               theme_id = scene->basact == base ? TH_ACTIVE : TH_SELECT;
-                                       }
-                                       else {
-                                               if (ob->type == OB_LAMP) theme_id = TH_LAMP;
-                                               else if (ob->type == OB_SPEAKER) theme_id = TH_SPEAKER;
-                                               else if (ob->type == OB_CAMERA) theme_id = TH_CAMERA;
-                                               else if (ob->type == OB_EMPTY) theme_id = TH_EMPTY;
-                                               /* fallback to TH_WIRE */
-                                       }
-                               }
-                       }
-               }
+               draw_object_wire_color(scene, base, _ob_wire_col, warning_recursive);
+               ob_wire_col = _ob_wire_col;
 
-               /* finally set the color */
-               if (colindex == 0) {
-                       if (theme_shade == 0) UI_ThemeColor(theme_id);
-                       else UI_ThemeColorShade(theme_id, theme_shade);
-               }
-               else {
-                       col = colortab[colindex];
-                       cpack(col);
-               }
+               glColor3ubv(ob_wire_col);
        }
 
        /* maximum drawtype */
@@ -6521,7 +6633,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
        if (v3d->zbuf == 0 && dt > OB_WIRE) dt = OB_WIRE;
        dtx = 0;
 
-       /* faceselect exception: also draw solid when dt==wire, except in editmode */
+       /* 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))) {
                if (ob->type == OB_MESH) {
 
@@ -6569,18 +6681,18 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
        
        /* draw outline for selected objects, mesh does itself */
        if ((v3d->flag & V3D_SELECT_OUTLINE) && ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && ob->type != OB_MESH) {
-               if (dt > OB_WIRE && (ob->mode & OB_MODE_EDIT) == 0 && (flag & DRAW_SCENESET) == 0) {
-                       if (!(ob->dtx & OB_DRAWWIRE) && (ob->flag & SELECT) && !(flag & DRAW_PICKING)) {
+               if (dt > OB_WIRE && (ob->mode & OB_MODE_EDIT) == 0 && (dflag & DRAW_SCENESET) == 0) {
+                       if (!(ob->dtx & OB_DRAWWIRE) && (ob->flag & SELECT) && !(dflag & DRAW_PICKING)) {
                                
-                               drawObjectSelect(scene, v3d, ar, base);
+                               drawObjectSelect(scene, v3d, ar, base, ob_wire_col);
                        }
                }
        }
 
        switch (ob->type) {
                case OB_MESH:
-                       empty_object = draw_mesh_object(scene, ar, v3d, rv3d, base, dt, flag);
-                       if (flag != DRAW_CONSTCOLOR) dtx &= ~OB_DRAWWIRE;  // mesh draws wire itself
+                       empty_object = draw_mesh_object(scene, ar, v3d, rv3d, base, dt, dflag);
+                       if (dflag != DRAW_CONSTCOLOR) dtx &= ~OB_DRAWWIRE;  // mesh draws wire itself
 
                        break;
                case OB_FONT:
@@ -6591,11 +6703,11 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                                if (cu->flag & CU_FAST) {
                                        cpack(0xFFFFFF);
                                        set_inverted_drawing(1);
-                                       drawDispList(scene, v3d, rv3d, base, OB_WIRE);
+                                       drawDispList(scene, v3d, rv3d, base, OB_WIRE, ob_wire_col);
                                        set_inverted_drawing(0);
                                }
                                else {
-                                       drawDispList(scene, v3d, rv3d, base, dt);
+                                       drawDispList(scene, v3d, rv3d, base, dt, ob_wire_col);
                                }
 
                                if (cu->linewidth != 0.0f) {
@@ -6670,7 +6782,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                                }
                        }
                        else if (ED_view3d_boundbox_clip(rv3d, ob->obmat, ob->bb ? ob->bb : cu->bb)) {
-                               empty_object = drawDispList(scene, v3d, rv3d, base, dt);
+                               empty_object = drawDispList(scene, v3d, rv3d, base, dt, ob_wire_col);
                        }
 
                        break;
@@ -6680,7 +6792,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
 
                        if (cu->editnurb) {
                                ListBase *nurbs = BKE_curve_editNurbs_get(cu);
-                               drawnurb(scene, v3d, rv3d, base, nurbs->first, dt);
+                               drawnurb(scene, v3d, rv3d, base, nurbs->first, dt, ob_wire_col);
                        }
                        else if (dt == OB_BOUNDBOX) {
                                if (((v3d->flag2 & V3D_RENDER_OVERRIDE) && (v3d->drawtype >= OB_WIRE)) == 0) {
@@ -6688,7 +6800,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                                }
                        }
                        else if (ED_view3d_boundbox_clip(rv3d, ob->obmat, ob->bb ? ob->bb : cu->bb)) {
-                               empty_object = drawDispList(scene, v3d, rv3d, base, dt);
+                               empty_object = drawDispList(scene, v3d, rv3d, base, dt, ob_wire_col);
 
 //XXX old animsys                              if (cu->path)
 //                                  curve_draw_speed(scene, ob);
@@ -6699,14 +6811,14 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                        MetaBall *mb = ob->data;
                        
                        if (mb->editelems)
-                               drawmball(scene, v3d, rv3d, base, dt);
+                               drawmball(scene, v3d, rv3d, base, dt, ob_wire_col);
                        else if (dt == OB_BOUNDBOX) {
                                if (((v3d->flag2 & V3D_RENDER_OVERRIDE) && (v3d->drawtype >= OB_WIRE)) == 0) {
                                        draw_bounding_volume(scene, ob, ob->boundtype);
                                }
                        }
                        else
-                               empty_object = drawmball(scene, v3d, rv3d, base, dt);
+                               empty_object = drawmball(scene, v3d, rv3d, base, dt, ob_wire_col);
                        break;
                }
                case OB_EMPTY:
@@ -6721,7 +6833,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                        break;
                case OB_LAMP:
                        if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
-                               drawlamp(scene, v3d, rv3d, base, dt, flag);
+                               drawlamp(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
                                if (dtx || (base->flag & SELECT)) glMultMatrixf(ob->obmat);
                        }
                        break;
@@ -6729,12 +6841,12 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                        if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0 ||
                            (rv3d->persp == RV3D_CAMOB && v3d->camera == ob)) /* special exception for active camera */
                        {
-                               drawcamera(scene, v3d, rv3d, base, flag);
+                               drawcamera(scene, v3d, rv3d, base, dflag, ob_wire_col);
                                break;
                        }
                case OB_SPEAKER:
                        if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0)
-                               drawspeaker(scene, v3d, rv3d, ob, flag);
+                               drawspeaker(scene, v3d, rv3d, ob, dflag);
                        break;
                case OB_LATTICE:
                        if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
@@ -6752,7 +6864,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                                else {
                                        if (dt > OB_WIRE)
                                                GPU_enable_material(0, NULL);  /* we use default material */
-                                       empty_object = draw_armature(scene, v3d, ar, base, dt, flag, FALSE);
+                                       empty_object = draw_armature(scene, v3d, ar, base, dt, dflag, ob_wire_col, FALSE);
                                        if (dt > OB_WIRE)
                                                GPU_disable_material();
                                }
@@ -6766,7 +6878,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
 
        if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
 
-               if (ob->soft /*&& flag & OB_SBMOTION*/) {
+               if (ob->soft /*&& dflag & OB_SBMOTION*/) {
                        float mrt[3][3], msc[3][3], mtr[3][3];
                        SoftBody *sb = NULL;
                        float tipw = 0.5f, tiph = 0.5f, drawsize = 4.0f;
@@ -6791,7 +6903,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
        /* code for new particle system */
        if ((warning_recursive == 0) &&
            (ob->particlesystem.first) &&
-           (flag & DRAW_PICKING) == 0 &&
+           (dflag & DRAW_PICKING) == 0 &&
            (ob != scene->obedit)
            )
        {
@@ -6825,7 +6937,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
 
        /* draw edit particles last so that they can draw over child particles */
        if ( (warning_recursive == 0) &&
-            (flag & DRAW_PICKING) == 0 &&
+            (dflag & DRAW_PICKING) == 0 &&
             (!scene->obedit))
        {
 
@@ -6956,7 +7068,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                        if (con->type == CONSTRAINT_TYPE_RIGIDBODYJOINT) {
                                bRigidBodyJointConstraint *data = (bRigidBodyJointConstraint *)con->data;
                                if (data->flag & CONSTRAINT_DRAW_PIVOT)
-                                       drawRBpivot(data);
+                                       drawRBpivot(data, ob_wire_col);
                        }
                }
 
@@ -6983,14 +7095,9 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                        if (dtx & OB_DRAWNAME) {
                                /* patch for several 3d cards (IBM mostly) that crash on GL_SELECT with text drawing */
                                /* but, we also don't draw names for sets or duplicators */
-                               if (flag == 0) {
-                                       float zero[3] = {0, 0, 0};
-                                       float curcol[4];
-                                       unsigned char tcol[4];
-                                       glGetFloatv(GL_CURRENT_COLOR, curcol);
-                                       rgb_float_to_uchar(tcol, curcol);
-                                       tcol[3] = 255;
-                                       view3d_cached_text_draw_add(zero, ob->id.name + 2, 10, 0, tcol);
+                               if (dflag == 0) {
+                                       const float zero[3] = {0, 0, 0};
+                                       view3d_cached_text_draw_add(zero, ob->id.name + 2, 10, 0, ob_wire_col);
                                }
                        }
                        /*if (dtx & OB_DRAWIMAGE) drawDispListwire(&ob->disp);*/
@@ -7046,13 +7153,13 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                        do_draw_center = DESELECT;
 
                if (do_draw_center != -1) {
-                       if (flag & DRAW_PICKING) {
+                       if (dflag & DRAW_PICKING) {
                                /* draw a single point for opengl selection */
                                glBegin(GL_POINTS);
                                glVertex3fv(ob->obmat[3]);
                                glEnd();
                        }
-                       else if ((flag & DRAW_CONSTCOLOR) == 0) {
+                       else if ((dflag & DRAW_CONSTCOLOR) == 0) {
                                /* we don't draw centers for duplicators and sets */
                                if (U.obcenter_dia > 0) {
                                        /* check > 0 otherwise grease pencil can draw into the circle select which is annoying. */
@@ -7063,7 +7170,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
        }
 
        /* not for sets, duplicators or picking */
-       if (flag == 0 && (v3d->flag & V3D_HIDE_HELPLINES) == 0 && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
+       if (dflag == 0 && (v3d->flag & V3D_HIDE_HELPLINES) == 0 && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
                ListBase *list;
                
                /* draw hook center and offset line */
@@ -7405,7 +7512,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
 
 /* helper function for drawing object instances - meshes */
 static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, 
-                                      Object *ob, int dt, int outline)
+                                      Object *ob, const short dt, int outline)
 {
        Mesh *me = ob->data;
        DerivedMesh *dm = NULL, *edm = NULL;
@@ -7453,7 +7560,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, int dt, int outline)
+void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, const short dt, int outline)
 {
        if (ob == NULL)
                return;