use BLI_strncpy and BLI_snprintf when the size of the string is known.
[blender.git] / source / blender / editors / space_view3d / drawobject.c
index a36f49a..1f57845 100644 (file)
@@ -118,6 +118,48 @@ typedef enum eWireDrawMode {
        OBDRAW_WIRE_ON_DEPTH= 2
 } eWireDrawMode;
 
+/* user data structures for derived mesh callbacks */
+typedef struct foreachScreenVert_userData {
+       void (*func)(void *userData, EditVert *eve, int x, int y, int index);
+       void *userData;
+       ViewContext vc;
+       eV3DClipTest clipVerts;
+} foreachScreenVert_userData;
+
+typedef struct foreachScreenEdge_userData {
+       void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index);
+       void *userData;
+       ViewContext vc;
+       eV3DClipTest clipVerts;
+} foreachScreenEdge_userData;
+
+typedef struct foreachScreenFace_userData {
+       void (*func)(void *userData, EditFace *efa, int x, int y, int index);
+       void *userData;
+       ViewContext vc;
+} foreachScreenFace_userData;
+
+typedef struct drawDMVerts_userData {
+       int sel;
+       EditVert *eve_act;
+} drawDMVerts_userData;
+
+typedef struct drawDMEdgesSel_userData {
+       unsigned char *baseCol, *selCol, *actCol;
+       EditEdge *eed_act;
+} drawDMEdgesSel_userData;
+
+typedef struct drawDMFacesSel_userData {
+       unsigned char *cols[3];
+       EditFace *efa_act;
+       int *orig_index;
+} drawDMFacesSel_userData;
+
+typedef struct bbsObmodeMeshVerts_userData {
+       void *offset;
+       MVert *mvert;
+} bbsObmodeMeshVerts_userData;
+
 static void draw_bounding_volume(Scene *scene, Object *ob, char type);
 
 static void drawcube_size(float size);
@@ -265,7 +307,7 @@ int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, int dt)
        return (scene->gm.matmode == GAME_MAT_GLSL) && (dt > OB_SOLID);
 }
 
-static int check_material_alpha(Base *base, int glsl)
+static int check_alpha_pass(Base *base)
 {
        if(base->flag & OB_FROMDUPLI)
                return 0;
@@ -273,7 +315,7 @@ static int check_material_alpha(Base *base, int glsl)
        if(G.f & G_PICKSEL)
                return 0;
        
-       return (glsl || (base->object->dtx & OB_DRAWTRANSP));
+       return (base->object->dtx & OB_DRAWTRANSP);
 }
 
        /***/
@@ -1459,13 +1501,13 @@ 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)
+                       MovieClip *clip, MovieTrackingObject *tracking_object, int flag, int *global_track_index)
 {
        MovieTracking *tracking= &clip->tracking;
        MovieTrackingTrack *track;
        float mat[4][4], imat[4][4];
        unsigned char col[4], scol[4];
-       int bundlenr= 1;
+       int tracknr= *global_track_index;
        ListBase *tracksbase= BKE_tracking_object_tracks(tracking, tracking_object);
 
        UI_GetThemeColor4ubv(TH_TEXT, col);
@@ -1500,7 +1542,7 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D
                        continue;
 
                if(flag&DRAW_PICKING)
-                       glLoadName(base->selcol + (bundlenr<<16));
+                       glLoadName(base->selcol + (tracknr<<16));
 
                glPushMatrix();
                        glTranslatef(track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]);
@@ -1508,7 +1550,6 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D
 
                        if(v3d->drawtype==OB_WIRE) {
                                glDisable(GL_LIGHTING);
-                               glDepthMask(0);
 
                                if(selected) {
                                        if(base==BASACT) UI_ThemeColor(TH_ACTIVE);
@@ -1520,7 +1561,6 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D
 
                                drawaxes(0.05f, v3d->bundle_drawtype);
 
-                               glDepthMask(1);
                                glEnable(GL_LIGHTING);
                        } else if(v3d->drawtype>OB_WIRE) {
                                if(v3d->bundle_drawtype==OB_EMPTY_SPHERE) {
@@ -1529,7 +1569,6 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D
                                                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);
@@ -1539,7 +1578,6 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D
                                                glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
                                                glEnable(GL_LIGHTING);
                                                glLineWidth(1.f);
-                                               glDepthMask(1);
                                        }
 
                                        if(track->flag&TRACK_CUSTOMCOLOR) glColor3fv(track->color);
@@ -1548,7 +1586,6 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D
                                        draw_bundle_sphere();
                                } else {
                                        glDisable(GL_LIGHTING);
-                                       glDepthMask(0);
 
                                        if(selected) {
                                                if(base==BASACT) UI_ThemeColor(TH_ACTIVE);
@@ -1560,7 +1597,6 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D
 
                                        drawaxes(0.05f, v3d->bundle_drawtype);
 
-                                       glDepthMask(1);
                                        glEnable(GL_LIGHTING);
                                }
                        }
@@ -1578,7 +1614,7 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D
                        view3d_cached_text_draw_add(pos, track->name, 10, V3D_CACHE_TEXT_GLOBALSPACE, tcol);
                }
 
-               bundlenr++;
+               tracknr++;
        }
 
        if((flag & DRAW_PICKING)==0) {
@@ -1607,6 +1643,8 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D
        }
 
        glPopMatrix();
+
+       *global_track_index= tracknr;
 }
 
 static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d, MovieClip *clip, int flag)
@@ -1614,6 +1652,7 @@ static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d,
        MovieTracking *tracking= &clip->tracking;
        MovieTrackingObject *tracking_object;
        float curcol[4];
+       int global_track_index= 1;
 
        if((v3d->flag2&V3D_SHOW_RECONSTRUCTION)==0)
                return;
@@ -1630,7 +1669,8 @@ 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);
+               draw_viewport_object_reconstruction(scene, base, v3d, clip, tracking_object,
+                                       flag, &global_track_index);
 
                tracking_object= tracking_object->next;
        }
@@ -1946,9 +1986,7 @@ static void drawlattice(Scene *scene, View3D *v3d, Object *ob)
  * use the object matrix in the useual way */
 static void mesh_foreachScreenVert__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
 {
-       struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index);
-                    void *userData; ViewContext vc; eV3DClipTest clipVerts; } *data = userData;
-
+       foreachScreenVert_userData *data = userData;
        EditVert *eve = EM_get_vert_for_index(index);
 
        if (eve->h==0) {
@@ -1970,9 +2008,7 @@ void mesh_foreachScreenVert(
         void (*func)(void *userData, EditVert *eve, int x, int y, int index),
         void *userData, eV3DClipTest clipVerts)
 {
-       struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index);
-                    void *userData; ViewContext vc; eV3DClipTest clipVerts; } data;
-
+       foreachScreenVert_userData data;
        DerivedMesh *dm = editmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
        
        data.vc= *vc;
@@ -2026,8 +2062,7 @@ static int is_co_in_region(ARegion *ar, const short co[2])
 }
 static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, float *v0co, float *v1co)
 {
-       struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index);
-                    void *userData; ViewContext vc; eV3DClipTest clipVerts; } *data = userData;
+       foreachScreenEdge_userData *data = userData;
        EditEdge *eed = EM_get_edge_for_index(index);
        short s[2][2];
 
@@ -2058,8 +2093,7 @@ void mesh_foreachScreenEdge(
         void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index),
         void *userData, eV3DClipTest clipVerts)
 {
-       struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index);
-                    void *userData; ViewContext vc; eV3DClipTest clipVerts; } data;
+       foreachScreenEdge_userData data;
        DerivedMesh *dm = editmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
 
        data.vc= *vc;
@@ -2079,7 +2113,7 @@ void mesh_foreachScreenEdge(
 
 static void mesh_foreachScreenFace__mapFunc(void *userData, int index, float *cent, float *UNUSED(no))
 {
-       struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; ViewContext vc; } *data = userData;
+       foreachScreenFace_userData *data = userData;
        EditFace *efa = EM_get_face_for_index(index);
        short s[2];
 
@@ -2097,7 +2131,7 @@ void mesh_foreachScreenFace(
         void (*func)(void *userData, EditFace *efa, int x, int y, int index),
         void *userData)
 {
-       struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; ViewContext vc; } data;
+       foreachScreenFace_userData data;
        DerivedMesh *dm = editmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
 
        data.vc= *vc;
@@ -2242,7 +2276,7 @@ static void draw_dm_vert_normals(Scene *scene, DerivedMesh *dm)
        /* Draw verts with color set based on selection */
 static void draw_dm_verts__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
 {
-       struct { int sel; EditVert *eve_act; } * data = userData;
+       drawDMVerts_userData * data = userData;
        EditVert *eve = EM_get_vert_for_index(index);
 
        if (eve->h==0 && (eve->f&SELECT)==data->sel) {
@@ -2269,7 +2303,7 @@ static void draw_dm_verts__mapFunc(void *userData, int index, float *co, float *
 
 static void draw_dm_verts(DerivedMesh *dm, int sel, EditVert *eve_act)
 {
-       struct { int sel; EditVert *eve_act; } data;
+       drawDMVerts_userData data;
        data.sel = sel;
        data.eve_act = eve_act;
 
@@ -2283,7 +2317,7 @@ static int draw_dm_edges_sel__setDrawOptions(void *userData, int index)
 {
        EditEdge *eed = EM_get_edge_for_index(index);
        //unsigned char **cols = userData, *col;
-       struct { unsigned char *baseCol, *selCol, *actCol; EditEdge *eed_act; } * data = userData;
+       drawDMEdgesSel_userData * data = userData;
        unsigned char *col;
 
        if (eed->h==0) {
@@ -2307,7 +2341,7 @@ static int draw_dm_edges_sel__setDrawOptions(void *userData, int index)
 }
 static void draw_dm_edges_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *actCol, EditEdge *eed_act) 
 {
-       struct { unsigned char *baseCol, *selCol, *actCol; EditEdge *eed_act; } data;
+       drawDMEdgesSel_userData data;
        
        data.baseCol = baseCol;
        data.selCol = selCol;
@@ -2381,7 +2415,7 @@ static void draw_dm_edges_sharp(DerivedMesh *dm)
         * 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 { DerivedMesh *dm; unsigned char *cols[3]; EditFace *efa_act; } * data = userData;
+       drawDMFacesSel_userData * data = userData;
        EditFace *efa = EM_get_face_for_index(index);
        unsigned char *col;
        
@@ -2401,17 +2435,16 @@ 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 { DerivedMesh *dm; unsigned char *cols[3]; EditFace *efa_act; } *data = userData;
-       int *orig_index= DM_get_face_data_layer(data->dm, CD_ORIGINDEX);
+       drawDMFacesSel_userData *data = userData;
        EditFace *efa;
        EditFace *next_efa;
        unsigned char *col, *next_col;
 
-       if(!orig_index)
+       if(!data->orig_index)
                return 0;
 
-       efa= EM_get_face_for_index(orig_index[index]);
-       next_efa= EM_get_face_for_index(orig_index[next_index]);
+       efa= EM_get_face_for_index(data->orig_index[index]);
+       next_efa= EM_get_face_for_index(data->orig_index[next_index]);
 
        if(efa == next_efa)
                return 1;
@@ -2431,12 +2464,12 @@ 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) 
 {
-       struct { DerivedMesh *dm; unsigned char *cols[3]; EditFace *efa_act; } data;
-       data.dm= dm;
+       drawDMFacesSel_userData data;
        data.cols[0] = baseCol;
        data.cols[1] = selCol;
        data.cols[2] = actCol;
        data.efa_act = efa_act;
+       data.orig_index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
 
        dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, GPU_enable_material, draw_dm_faces_sel__compareDrawOptions, &data, 0);
 }
@@ -2623,15 +2656,14 @@ static void draw_em_fancy_edges(Scene *scene, View3D *v3d,
        }
 }      
 
-static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d,
-                                  Object *ob, EditMesh *em, UnitSettings *unit)
+static void draw_em_measure_stats(View3D *v3d, Object *ob, EditMesh *em, UnitSettings *unit)
 {
        Mesh *me= ob->data;
        EditEdge *eed;
        EditFace *efa;
        float v1[3], v2[3], v3[3], v4[3], vmid[3];
        float fvec[3];
-       char val[32]; /* Stores the measurement display text here */
+       char numstr[32]; /* Stores the measurement display text here */
        const char *conv_float; /* Use a float conversion matching the grid size */
        unsigned char col[4]= {0, 0, 0, 255}; /* color of the text to draw */
        float area; /* area of the face */
@@ -2647,11 +2679,6 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d,
        else if (grid < 1.0f)   conv_float= "%.4g";
        else if (grid < 10.0f)  conv_float= "%.3g";
        else                                    conv_float= "%.2g";
-
-       if(v3d->zbuf && (v3d->flag & V3D_ZBUF_SELECT)==0)
-               glDisable(GL_DEPTH_TEST);
-
-       if(v3d->zbuf) bglPolygonOffset(rv3d->dist, 5.0f);
        
        if(me->drawflag & ME_DRAWEXTRA_EDGELEN) {
                UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGELEN, col);
@@ -2669,11 +2696,11 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d,
                                        mul_mat3_m4_v3(ob->obmat, v2);
                                }
                                if(unit->system)
-                                       bUnit_AsString(val, sizeof(val), len_v3v3(v1, v2)*unit->scale_length, 3, unit->system, B_UNIT_LENGTH, do_split, FALSE);
+                                       bUnit_AsString(numstr, sizeof(numstr), len_v3v3(v1, v2)*unit->scale_length, 3, unit->system, B_UNIT_LENGTH, do_split, FALSE);
                                else
-                                       sprintf(val, conv_float, len_v3v3(v1, v2));
+                                       sprintf(numstr, conv_float, len_v3v3(v1, v2));
 
-                               view3d_cached_text_draw_add(vmid, val, 0, V3D_CACHE_TEXT_ASCII, col);
+                               view3d_cached_text_draw_add(vmid, numstr, 0, V3D_CACHE_TEXT_ASCII, col);
                        }
                }
        }
@@ -2703,11 +2730,11 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d,
                                        area = area_tri_v3(v1, v2, v3);
 
                                if(unit->system)
-                                       bUnit_AsString(val, sizeof(val), area*unit->scale_length, 3, unit->system, B_UNIT_LENGTH, do_split, FALSE); // XXX should be B_UNIT_AREA
+                                       bUnit_AsString(numstr, sizeof(numstr), area*unit->scale_length, 3, unit->system, B_UNIT_LENGTH, do_split, FALSE); // XXX should be B_UNIT_AREA
                                else
-                                       sprintf(val, conv_float, area);
+                                       sprintf(numstr, conv_float, area);
 
-                               view3d_cached_text_draw_add(efa->cent, val, 0, V3D_CACHE_TEXT_ASCII, col);
+                               view3d_cached_text_draw_add(efa->cent, numstr, 0, V3D_CACHE_TEXT_ASCII, col);
                        }
                }
        }
@@ -2741,52 +2768,78 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d,
                                
                        if( (e4->f & e1->f & SELECT) || (do_moving && (efa->v1->f & SELECT)) ) {
                                /* Vec 1 */
-                               sprintf(val,"%.3g", RAD2DEGF(angle_v3v3v3(v4, v1, v2)));
+                               sprintf(numstr,"%.3g", RAD2DEGF(angle_v3v3v3(v4, v1, v2)));
                                interp_v3_v3v3(fvec, efa->cent, efa->v1->co, 0.8f);
-                               view3d_cached_text_draw_add(fvec, val, 0, V3D_CACHE_TEXT_ASCII, col);
+                               view3d_cached_text_draw_add(fvec, numstr, 0, V3D_CACHE_TEXT_ASCII, col);
                        }
                        if( (e1->f & e2->f & SELECT) || (do_moving && (efa->v2->f & SELECT)) ) {
                                /* Vec 2 */
-                               sprintf(val,"%.3g", RAD2DEGF(angle_v3v3v3(v1, v2, v3)));
+                               sprintf(numstr,"%.3g", RAD2DEGF(angle_v3v3v3(v1, v2, v3)));
                                interp_v3_v3v3(fvec, efa->cent, efa->v2->co, 0.8f);
-                               view3d_cached_text_draw_add(fvec, val, 0, V3D_CACHE_TEXT_ASCII, col);
+                               view3d_cached_text_draw_add(fvec, numstr, 0, V3D_CACHE_TEXT_ASCII, col);
                        }
                        if( (e2->f & e3->f & SELECT) || (do_moving && (efa->v3->f & SELECT)) ) {
                                /* Vec 3 */
                                if(efa->v4) 
-                                       sprintf(val,"%.3g", RAD2DEGF(angle_v3v3v3(v2, v3, v4)));
+                                       sprintf(numstr,"%.3g", RAD2DEGF(angle_v3v3v3(v2, v3, v4)));
                                else
-                                       sprintf(val,"%.3g", RAD2DEGF(angle_v3v3v3(v2, v3, v1)));
+                                       sprintf(numstr,"%.3g", RAD2DEGF(angle_v3v3v3(v2, v3, v1)));
                                interp_v3_v3v3(fvec, efa->cent, efa->v3->co, 0.8f);
-                               view3d_cached_text_draw_add(fvec, val, 0, V3D_CACHE_TEXT_ASCII, col);
+                               view3d_cached_text_draw_add(fvec, numstr, 0, V3D_CACHE_TEXT_ASCII, col);
                        }
                                /* Vec 4 */
                        if(efa->v4) {
                                if( (e3->f & e4->f & SELECT) || (do_moving && (efa->v4->f & SELECT)) ) {
-                                       sprintf(val,"%.3g", RAD2DEGF(angle_v3v3v3(v3, v4, v1)));
+                                       sprintf(numstr,"%.3g", RAD2DEGF(angle_v3v3v3(v3, v4, v1)));
                                        interp_v3_v3v3(fvec, efa->cent, efa->v4->co, 0.8f);
-                                       view3d_cached_text_draw_add(fvec, val, 0, V3D_CACHE_TEXT_ASCII, col);
+                                       view3d_cached_text_draw_add(fvec, numstr, 0, V3D_CACHE_TEXT_ASCII, col);
                                }
                        }
                }
        }
+}
 
-       /* useful for debugging index vs shape key index */
-#if 0
-       {
-               EditVert *eve;
-               int j;
+static void draw_em_indices(EditMesh *em)
+{
+       EditEdge *e;
+       EditFace *f;
+       EditVert *v;
+       int i;
+       char numstr[32];
+       float pos[3];
+       unsigned char col[4];
+
+       /* For now, reuse appropriate theme colors from stats text colors */
+
+       if (em->selectmode & SCE_SELECT_VERTEX) {
                UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEANG, col);
-               for(eve= em->verts.first, j= 0; eve; eve= eve->next, j++) {
-                       sprintf(val, "%d:%d", j, eve->keyindex);
-                       view3d_cached_text_draw_add(eve->co, val, 0, V3D_CACHE_TEXT_ASCII, col);
+               for (v = em->verts.first, i = 0; v; v = v->next, i++) {
+                       if (v->f & SELECT) {
+                               sprintf(numstr, "%d", i);
+                               view3d_cached_text_draw_add(v->co, numstr, 0, V3D_CACHE_TEXT_ASCII, col);
+                       }
                }
        }
-#endif
 
-       if(v3d->zbuf) {
-               glEnable(GL_DEPTH_TEST);
-               bglPolygonOffset(rv3d->dist, 0.0f);
+       if (em->selectmode & SCE_SELECT_EDGE) {
+               UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGELEN, col);
+               for (e = em->edges.first, i = 0; e; e = e->next, i++) {
+                       if (e->f & SELECT) {
+                               sprintf(numstr, "%d", i);
+                               mid_v3_v3v3(pos, e->v1->co, e->v2->co);
+                               view3d_cached_text_draw_add(pos, numstr, 0, V3D_CACHE_TEXT_ASCII, col);
+                       }
+               }
+       }
+
+       if (em->selectmode & SCE_SELECT_FACE) {
+               UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEAREA, col);
+               for (f = em->faces.first, i = 0; f; f = f->next, i++) {
+                       if (f->f & SELECT) {
+                               sprintf(numstr, "%d", i);
+                               view3d_cached_text_draw_add(f->cent, numstr, 0, V3D_CACHE_TEXT_ASCII, col);
+                       }
+               }
        }
 }
 
@@ -2963,7 +3016,12 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d,
                if ( (me->drawflag & (ME_DRAWEXTRA_EDGELEN|ME_DRAWEXTRA_FACEAREA|ME_DRAWEXTRA_FACEANG)) &&
                     !(v3d->flag2 & V3D_RENDER_OVERRIDE))
                {
-                       draw_em_measure_stats(v3d, rv3d, ob, em, &scene->unit);
+                       draw_em_measure_stats(v3d, ob, em, &scene->unit);
+               }
+
+               if ((G.f & G_DEBUG) && (me->drawflag & ME_DRAWEXTRA_INDICES) &&
+                   !(v3d->flag2 & V3D_RENDER_OVERRIDE)) {
+                       draw_em_indices(em);
                }
        }
 
@@ -3018,7 +3076,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
        int /* totvert,*/ totedge, totface;
        DerivedMesh *dm= mesh_get_derived_final(scene, ob, scene->customdata_mask);
        ModifierData *md = NULL;
-       const short is_obact= (ob != NULL && ob == OBACT);
+       const short is_obact= (ob == OBACT);
        int draw_flags = (is_obact && paint_facesel_test(ob)) ? DRAW_FACE_SELECT : 0;
 
        if(!dm)
@@ -3326,7 +3384,7 @@ static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
        Object *obedit= scene->obedit;
        Mesh *me= ob->data;
        EditMesh *em= me->edit_mesh;
-       int do_alpha_pass= 0, drawlinked= 0, retval= 0, glsl, check_alpha, i;
+       int do_alpha_after= 0, 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 */
@@ -3371,11 +3429,11 @@ 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, glsl);
+                       check_alpha = check_alpha_pass(base);
 
                        if(dt==OB_SOLID || glsl) {
                                GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl,
-                                       (check_alpha)? &do_alpha_pass: NULL);
+                                       (check_alpha)? &do_alpha_after: NULL);
                        }
 
                        draw_mesh_fancy(scene, ar, v3d, rv3d, base, dt, flag);
@@ -3387,7 +3445,7 @@ static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
        }
        
        /* GPU_begin_object_materials checked if this is needed */
-       if(do_alpha_pass) {
+       if(do_alpha_after) {
                if(ob->dtx & OB_DRAWXRAY) {
                        add_view3d_after(&v3d->afterdraw_xraytransp, base, flag);
                }
@@ -3984,7 +4042,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
        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];
-       char val[32];
+       char numstr[32];
        unsigned char tcol[4]= {0, 0, 0, 255};
 
 /* 1. */
@@ -4053,7 +4111,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
 
        if( (base->flag & OB_FROMDUPLI) && (ob->flag & OB_FROMGROUP) ) {
                float mat[4][4];
-               mul_m4_m4m4(mat, psys->imat, ob->obmat);
+               mult_m4_m4m4(mat, ob->obmat, psys->imat);
                glMultMatrixf(mat);
        }
 
@@ -4372,8 +4430,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
 
                                if((part->draw & PART_DRAW_NUM || part->draw & PART_DRAW_HEALTH) && (v3d->flag2 & V3D_RENDER_OVERRIDE)==0){
                                        float vec_txt[3];
-                                       char *val_pos= val;
-                                       val[0]= '\0';
+                                       char *val_pos= numstr;
+                                       numstr[0]= '\0';
 
                                        if(part->draw&PART_DRAW_NUM) {
                                                if(a < totpart && (part->draw & PART_DRAW_HEALTH) && (part->phystype==PART_PHYS_BOIDS)) {
@@ -4392,7 +4450,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
                                        /* in path drawing state.co is the end point */
                                        /* use worldspace beause object matrix is already applied */
                                        mul_v3_m4v3(vec_txt, ob->imat, state.co);
-                                       view3d_cached_text_draw_add(vec_txt, val, 10, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII, tcol);
+                                       view3d_cached_text_draw_add(vec_txt, numstr, 10, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII, tcol);
                                }
                        }
                }
@@ -4481,10 +4539,10 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
 
                        for(a=0, pa=psys->particles; a<totpart; a++, pa++){
                                float vec_txt[3];
-                               sprintf(val, "%i", a);
+                               BLI_snprintf(numstr, sizeof(numstr), "%i", a);
                                /* use worldspace beause object matrix is already applied */
                                mul_v3_m4v3(vec_txt, ob->imat, cache[a]->co);
-                               view3d_cached_text_draw_add(vec_txt, val, 10, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII, tcol);
+                               view3d_cached_text_draw_add(vec_txt, numstr, 10, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII, tcol);
                        }
                }
        }
@@ -6140,7 +6198,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
        int /*sel, drawtype,*/ colindex= 0;
        int i, selstart, selend, empty_object=0;
        short dt, dtx, zbufoff= 0;
-       const short is_obact= (ob != NULL && ob == OBACT);
+       const short is_obact= (ob == OBACT);
 
        /* only once set now, will be removed too, should become a global standard */
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -6821,7 +6879,34 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                                ListBase targets = {NULL, NULL};
                                bConstraintTarget *ct;
                                
-                               if ((curcon->flag & CONSTRAINT_EXPAND) && (cti) && (cti->get_constraint_targets)) {
+                               if(ELEM(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_OBJECTSOLVER)) {
+                                       /* special case for object solver and follow track constraints because they don't fill
+                                          constraint targets properly (design limitation -- scene is needed for their target
+                                          but it can't be accessed from get_targets callvack) */
+
+                                       Object *camob= NULL;
+
+                                       if(cti->type==CONSTRAINT_TYPE_FOLLOWTRACK) {
+                                               bFollowTrackConstraint *data= (bFollowTrackConstraint *)curcon->data;
+
+                                               camob= data->camera ? data->camera : scene->camera;
+                                       }
+                                       else if(cti->type==CONSTRAINT_TYPE_OBJECTSOLVER) {
+                                               bObjectSolverConstraint *data= (bObjectSolverConstraint *)curcon->data;
+
+                                               camob= data->camera ? data->camera : scene->camera;
+                                       }
+
+                                       if(camob) {
+                                               setlinestyle(3);
+                                               glBegin(GL_LINES);
+                                               glVertex3fv(camob->obmat[3]);
+                                               glVertex3fv(ob->obmat[3]);
+                                               glEnd();
+                                               setlinestyle(0);
+                                       }
+                               }
+                               else if ((curcon->flag & CONSTRAINT_EXPAND) && (cti) && (cti->get_constraint_targets)) {
                                        cti->get_constraint_targets(curcon, &targets);
                                        
                                        for (ct= targets.first; ct; ct= ct->next) {
@@ -6855,7 +6940,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
 
 static void bbs_obmode_mesh_verts__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
 {
-       struct {void* offset; MVert *mvert;} *data = userData;
+       bbsObmodeMeshVerts_userData *data = userData;
        MVert *mv = &data->mvert[index];
        int offset = (intptr_t) data->offset;
 
@@ -6867,7 +6952,7 @@ static void bbs_obmode_mesh_verts__mapFunc(void *userData, int index, float *co,
 
 static void bbs_obmode_mesh_verts(Object *ob, DerivedMesh *dm, int offset)
 {
-       struct {void* offset; struct MVert *mvert;} data;
+       bbsObmodeMeshVerts_userData data;
        Mesh *me = ob->data;
        MVert *mvert = me->mvert;
        data.mvert = mvert;