Merge with -r 22620:23107.
[blender.git] / source / blender / editors / space_view3d / drawobject.c
index 85edf6cf5fb45197dfa220e68f1b82411a9a5f16..7ed029f3eaf0506a684b443268ccdf4f6628a98c 100644 (file)
 
 #include "MEM_guardedalloc.h"
 
-#include "BMF_Api.h"
-
 #include "IMB_imbuf.h"
 
 
-#include "MTC_matrixops.h"
+
 
 #include "DNA_armature_types.h"
+#include "DNA_boid_types.h"
 #include "DNA_camera_types.h"
 #include "DNA_curve_types.h"
 #include "DNA_constraint_types.h" // for drawing constraint
@@ -60,6 +59,7 @@
 #include "DNA_space_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
+#include "DNA_smoke_types.h"
 #include "DNA_userdef_types.h"
 #include "DNA_view3d_types.h"
 #include "DNA_world_types.h"
 #include "BKE_mball.h"
 #include "BKE_modifier.h"
 #include "BKE_object.h"
+#include "BKE_paint.h"
 #include "BKE_particle.h"
+#include "BKE_pointcache.h"
 #include "BKE_property.h"
+#include "BKE_smoke.h"
+#include "BKE_unit.h"
 #include "BKE_utildefines.h"
+#include "smoke_API.h"
 
 #include "BIF_gl.h"
 #include "BIF_glutil.h"
 #include "GPU_material.h"
 #include "GPU_extensions.h"
 
-#include "ED_editparticle.h"
 #include "ED_mesh.h"
+#include "ED_particle.h"
+#include "ED_screen.h"
 #include "ED_types.h"
 #include "ED_util.h"
 
 #include "UI_interface_icons.h"
 
 #include "WM_api.h"
+#include "BLF_api.h"
 
 #include "view3d_intern.h"     // own include
 
        (vd->drawtype==OB_SOLID && vd->flag2 & V3D_SOLID_TEX))
 
 #define CHECK_OB_DRAWFACEDOT(sce, vd, dt) \
-(      (sce->selectmode & SCE_SELECT_FACE) && \
+(      (sce->toolsettings->selectmode & SCE_SELECT_FACE) && \
        (vd->drawtype<=OB_SOLID) && \
        (((vd->drawtype==OB_SOLID) && (dt>=OB_SOLID) && (vd->flag2 & V3D_SOLID_TEX) && (vd->flag & V3D_ZBUF_SELECT)) == 0) \
        )
 
-
-/* pretty stupid */
-/* editmball.c */
-extern ListBase editelems;
-
 static void draw_bounding_volume(Scene *scene, Object *ob);
 
 static void drawcube_size(float size);
@@ -134,6 +136,74 @@ static void drawcircle_size(float size);
 static void draw_empty_sphere(float size);
 static void draw_empty_cone(float size);
 
+
+/* ************* only use while object drawing ************** */
+static void view3d_project_short_clip(ARegion *ar, float *vec, short *adr)
+{
+       RegionView3D *rv3d= ar->regiondata;
+       float fx, fy, vec4[4];
+       
+       adr[0]= IS_CLIPPED;
+       
+       /* clipplanes in eye space */
+       if(rv3d->rflag & RV3D_CLIPPING) {
+               VECCOPY(vec4, vec);
+               Mat4MulVecfl(rv3d->viewmatob, vec4);
+               if(view3d_test_clipping(rv3d, vec4))
+                       return;
+       }
+       
+       VECCOPY(vec4, vec);
+       vec4[3]= 1.0;
+       
+       Mat4MulVec4fl(rv3d->persmatob, vec4);
+       
+       /* clipplanes in window space */
+       if( vec4[3]>BL_NEAR_CLIP ) {    /* is the NEAR clipping cutoff for picking */
+               fx= (ar->winx/2)*(1 + vec4[0]/vec4[3]);
+               
+               if( fx>0 && fx<ar->winx) {
+                       
+                       fy= (ar->winy/2)*(1 + vec4[1]/vec4[3]);
+                       
+                       if(fy>0.0 && fy< (float)ar->winy) {
+                               adr[0]= (short)floor(fx); 
+                               adr[1]= (short)floor(fy);
+                       }
+               }
+       }
+}
+
+/* only use while object drawing */
+static void view3d_project_short_noclip(ARegion *ar, float *vec, short *adr)
+{
+       RegionView3D *rv3d= ar->regiondata;
+       float fx, fy, vec4[4];
+       
+       adr[0]= IS_CLIPPED;
+       
+       VECCOPY(vec4, vec);
+       vec4[3]= 1.0;
+       
+       Mat4MulVec4fl(rv3d->persmatob, vec4);
+       
+       if( vec4[3]>BL_NEAR_CLIP ) {    /* is the NEAR clipping cutoff for picking */
+               fx= (ar->winx/2)*(1 + vec4[0]/vec4[3]);
+               
+               if( fx>-32700 && fx<32700) {
+                       
+                       fy= (ar->winy/2)*(1 + vec4[1]/vec4[3]);
+                       
+                       if(fy>-32700.0 && fy<32700.0) {
+                               adr[0]= (short)floor(fx); 
+                               adr[1]= (short)floor(fy);
+                       }
+               }
+       }
+}
+
+/* ************************ */
+
 /* check for glsl drawing */
 
 int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, int dt)
@@ -144,11 +214,10 @@ int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, int dt)
                return 0;
        if(!CHECK_OB_DRAWTEXTURE(v3d, dt))
                return 0;
-       if(ob==OBACT && (G.f & G_WEIGHTPAINT))
+       if(ob==OBACT && (ob && ob->mode & OB_MODE_WEIGHT_PAINT))
                return 0;
        
-       return ((G.fileflags & G_FILE_GAME_MAT) &&
-          (G.fileflags & G_FILE_GAME_MAT_GLSL) && (dt >= OB_SHADED));
+       return (scene->gm.matmode == GAME_MAT_GLSL) && (dt >= OB_SHADED);
 }
 
 static int check_material_alpha(Base *base, Mesh *me, int glsl)
@@ -361,16 +430,15 @@ void drawaxes(float size, int flag, char drawtype)
                        glEnd();
                                
                        v2[axis]+= size*0.125;
-                       glRasterPos3fv(v2);
                        
                        // patch for 3d cards crashing on glSelect for text drawing (IBM)
                        if((flag & DRAW_PICKING) == 0) {
                                if (axis==0)
-                                       BMF_DrawString(G.font, "x");
+                                       view3d_object_text_draw_add(v2[0], v2[1], v2[2], "x", 0);
                                else if (axis==1)
-                                       BMF_DrawString(G.font, "y");
+                                       view3d_object_text_draw_add(v2[0], v2[1], v2[2], "y", 0);
                                else
-                                       BMF_DrawString(G.font, "z");
+                                       view3d_object_text_draw_add(v2[0], v2[1], v2[2], "z", 0);
                        }
                }
                break;
@@ -428,57 +496,74 @@ static void drawcentercircle(View3D *v3d, RegionView3D *rv3d, float *vec, int se
        if(v3d->zbuf)  glDepthFunc(GL_LEQUAL);
 }
 
+/* *********** text drawing for object ************* */
+static ListBase strings= {NULL, NULL};
 
-void drawsolidcube(float size)
-{
-       float n[3];
-
-       glPushMatrix();
-       glScalef(size, size, size);
-       
-       n[0]=0; n[1]=0; n[2]=0;
-       glBegin(GL_QUADS);
-               n[0]= -1.0;
-               glNormal3fv(n); 
-               glVertex3fv(cube[0]); glVertex3fv(cube[1]); glVertex3fv(cube[2]); glVertex3fv(cube[3]);
-               n[0]=0;
-       glEnd();
-
-       glBegin(GL_QUADS);
-               n[1]= -1.0;
-               glNormal3fv(n); 
-               glVertex3fv(cube[0]); glVertex3fv(cube[4]); glVertex3fv(cube[5]); glVertex3fv(cube[1]);
-               n[1]=0;
-       glEnd();
+typedef struct ViewObjectString {
+       struct ViewObjectString *next, *prev;
+       float vec[3], col[4];
+       char str[128]; 
+       short mval[2];
+       short xoffs;
+} ViewObjectString;
 
-       glBegin(GL_QUADS);
-               n[0]= 1.0;
-               glNormal3fv(n); 
-               glVertex3fv(cube[4]); glVertex3fv(cube[7]); glVertex3fv(cube[6]); glVertex3fv(cube[5]);
-               n[0]=0;
-       glEnd();
 
-       glBegin(GL_QUADS);
-               n[1]= 1.0;
-               glNormal3fv(n); 
-               glVertex3fv(cube[7]); glVertex3fv(cube[3]); glVertex3fv(cube[2]); glVertex3fv(cube[6]);
-               n[1]=0;
-       glEnd();
+void view3d_object_text_draw_add(float x, float y, float z, char *str, short xoffs)
+{
+       ViewObjectString *vos= MEM_callocN(sizeof(ViewObjectString), "ViewObjectString");
+
+       BLI_addtail(&strings, vos);
+       BLI_strncpy(vos->str, str, 128);
+       vos->vec[0]= x;
+       vos->vec[1]= y;
+       vos->vec[2]= z;
+       glGetFloatv(GL_CURRENT_COLOR, vos->col);
+       vos->xoffs= xoffs;
+}
 
-       glBegin(GL_QUADS);
-               n[2]= 1.0;
-               glNormal3fv(n); 
-               glVertex3fv(cube[1]); glVertex3fv(cube[5]); glVertex3fv(cube[6]); glVertex3fv(cube[2]);
-               n[2]=0;
-       glEnd();
+static void view3d_object_text_draw(View3D *v3d, ARegion *ar)
+{
+       ViewObjectString *vos;
+       int tot= 0;
+       
+       /* project first and test */
+       for(vos= strings.first; vos; vos= vos->next) {
+               view3d_project_short_clip(ar, vos->vec, vos->mval);
+               if(vos->mval[0]!=IS_CLIPPED)
+                       tot++;
+       }
+       
+       if(tot) {
+               RegionView3D *rv3d= ar->regiondata;
+               int a;
+               
+               if(rv3d->rflag & RV3D_CLIPPING)
+                       for(a=0; a<6; a++)
+                               glDisable(GL_CLIP_PLANE0+a);
+               
+               wmPushMatrix();
+               ED_region_pixelspace(ar);
+               
+               if(v3d->zbuf) glDisable(GL_DEPTH_TEST);
+               
+               for(vos= strings.first; vos; vos= vos->next) {
+                       if(vos->mval[0]!=IS_CLIPPED) {
+                               glColor3fv(vos->col);
+                               BLF_draw_default((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], 0.0, vos->str);
+                       }
+               }
+               
+               if(v3d->zbuf) glEnable(GL_DEPTH_TEST);
+               
+               wmPopMatrix();
 
-       glBegin(GL_QUADS);
-               n[2]= -1.0;
-               glNormal3fv(n); 
-               glVertex3fv(cube[7]); glVertex3fv(cube[4]); glVertex3fv(cube[0]); glVertex3fv(cube[3]);
-       glEnd();
+               if(rv3d->rflag & RV3D_CLIPPING)
+                       for(a=0; a<6; a++)
+                               glEnable(GL_CLIP_PLANE0+a);
+       }
        
-       glPopMatrix();
+       if(strings.first) 
+               BLI_freelistN(&strings);
 }
 
 static void drawcube(void)
@@ -1039,7 +1124,7 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob
                        Mat4Ortho(vec);
                        wmMultMatrix(vec);
 
-                       MTC_Mat4SwapMat4(rv3d->persmat, tmat);
+                       Mat4SwapMat4(rv3d->persmat, tmat);
                        wmGetSingleMatrix(rv3d->persmat);
 
                        if(cam->flag & CAM_SHOWLIMITS) {
@@ -1052,7 +1137,7 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob
                        if(cam->flag & CAM_SHOWMIST) 
                                if(wrld) draw_limit_line(wrld->miststa, wrld->miststa+wrld->mistdist, 0xFFFFFF);
                                
-                       MTC_Mat4SwapMat4(rv3d->persmat, tmat);
+                       Mat4SwapMat4(rv3d->persmat, tmat);
                }
        }
 }
@@ -1095,16 +1180,14 @@ void lattice_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, BPo
        BPoint *bp = lt->editlatt->def;
        DispList *dl = find_displist(&obedit->disp, DL_VERTS);
        float *co = dl?dl->verts:NULL;
-       float pmat[4][4], vmat[4][4];
        int i, N = lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw;
-       short s[2];
-
-       view3d_get_object_project_mat(vc->rv3d, vc->obedit, pmat, vmat);
+       short s[2] = {IS_CLIPPED, 0};
 
        for (i=0; i<N; i++, bp++, co+=3) {
                if (bp->hide==0) {
-                       view3d_project_short_clip(vc->ar, dl?co:bp->vec, s, pmat, vmat);
-                       func(userData, bp, s[0], s[1]);
+                       view3d_project_short_clip(vc->ar, dl?co:bp->vec, s);
+                       if (s[0] != IS_CLIPPED)
+                               func(userData, bp, s[0], s[1]);
                }
        }
 }
@@ -1115,7 +1198,7 @@ static void drawlattice__point(Lattice *lt, DispList *dl, int u, int v, int w, i
 
        if(use_wcol) {
                float col[3];
-               MDeformWeight *mdw= get_defweight (lt->dvert+index, use_wcol-1);
+               MDeformWeight *mdw= ED_vgroup_weight_get (lt->dvert+index, use_wcol-1);
                
                weight_to_rgb(mdw?mdw->weight:0.0f, col, col+1, col+2);
                glColor3fv(col);
@@ -1196,24 +1279,26 @@ static void drawlattice(Scene *scene, View3D *v3d, Object *ob)
 
 static void mesh_foreachScreenVert__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
 {
-       struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; ViewContext vc; int clipVerts; float pmat[4][4], vmat[4][4]; } *data = userData;
+       struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; ViewContext vc; int clipVerts; } *data = userData;
        EditVert *eve = EM_get_vert_for_index(index);
-       short s[2];
 
        if (eve->h==0) {
+               short s[2]= {IS_CLIPPED, 0};
+
                if (data->clipVerts) {
-                       view3d_project_short_clip(data->vc.ar, co, s, data->pmat, data->vmat);
+                       view3d_project_short_clip(data->vc.ar, co, s);
                } else {
-                       view3d_project_short_noclip(data->vc.ar, co, s, data->pmat);
+                       view3d_project_short_noclip(data->vc.ar, co, s);
                }
 
-               data->func(data->userData, eve, s[0], s[1], index);
+               if (s[0]!=IS_CLIPPED)
+                       data->func(data->userData, eve, s[0], s[1], index);
        }
 }
 
 void mesh_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, EditVert *eve, int x, int y, int index), void *userData, int clipVerts)
 {
-       struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; ViewContext vc; int clipVerts; float pmat[4][4], vmat[4][4]; } data;
+       struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; ViewContext vc; int clipVerts; } data;
        DerivedMesh *dm = editmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
        
        data.vc= *vc;
@@ -1221,8 +1306,6 @@ void mesh_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, EditVe
        data.userData = userData;
        data.clipVerts = clipVerts;
 
-       view3d_get_object_project_mat(vc->rv3d, vc->obedit, data.pmat, data.vmat);
-
        EM_init_index_arrays(vc->em, 1, 0, 0);
        dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data);
        EM_free_index_arrays();
@@ -1232,17 +1315,17 @@ void mesh_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, EditVe
 
 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; int clipVerts; float pmat[4][4], vmat[4][4]; } *data = userData;
+       struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; ViewContext vc; int clipVerts; } *data = userData;
        EditEdge *eed = EM_get_edge_for_index(index);
        short s[2][2];
 
        if (eed->h==0) {
                if (data->clipVerts==1) {
-                       view3d_project_short_clip(data->vc.ar, v0co, s[0], data->pmat, data->vmat);
-                       view3d_project_short_clip(data->vc.ar, v1co, s[1], data->pmat, data->vmat);
+                       view3d_project_short_clip(data->vc.ar, v0co, s[0]);
+                       view3d_project_short_clip(data->vc.ar, v1co, s[1]);
                } else {
-                       view3d_project_short_noclip(data->vc.ar, v0co, s[0], data->pmat);
-                       view3d_project_short_noclip(data->vc.ar, v1co, s[1], data->pmat);
+                       view3d_project_short_noclip(data->vc.ar, v0co, s[0]);
+                       view3d_project_short_noclip(data->vc.ar, v1co, s[1]);
 
                        if (data->clipVerts==2) {
                 if (!(s[0][0]>=0 && s[0][1]>= 0 && s[0][0]<data->vc.ar->winx && s[0][1]<data->vc.ar->winy)) 
@@ -1257,7 +1340,7 @@ static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, float *v0
 
 void mesh_foreachScreenEdge(ViewContext *vc, void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index), void *userData, int clipVerts)
 {
-       struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; ViewContext vc; int clipVerts; float pmat[4][4], vmat[4][4]; } data;
+       struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; ViewContext vc; int clipVerts; } data;
        DerivedMesh *dm = editmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
 
        data.vc= *vc;
@@ -1265,8 +1348,6 @@ void mesh_foreachScreenEdge(ViewContext *vc, void (*func)(void *userData, EditEd
        data.userData = userData;
        data.clipVerts = clipVerts;
 
-       view3d_get_object_project_mat(vc->rv3d, vc->obedit, data.pmat, data.vmat);
-
        EM_init_index_arrays(vc->em, 0, 1, 0);
        dm->foreachMappedEdge(dm, mesh_foreachScreenEdge__mapFunc, &data);
        EM_free_index_arrays();
@@ -1276,12 +1357,12 @@ void mesh_foreachScreenEdge(ViewContext *vc, void (*func)(void *userData, EditEd
 
 static void mesh_foreachScreenFace__mapFunc(void *userData, int index, float *cent, float *no)
 {
-       struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; ViewContext vc; float pmat[4][4], vmat[4][4]; } *data = userData;
+       struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; ViewContext vc; } *data = userData;
        EditFace *efa = EM_get_face_for_index(index);
        short s[2];
 
        if (efa && efa->h==0 && efa->fgonf!=EM_FGON) {
-               view3d_project_short_clip(data->vc.ar, cent, s, data->pmat, data->vmat);
+               view3d_project_short_clip(data->vc.ar, cent, s);
 
                data->func(data->userData, efa, s[0], s[1], index);
        }
@@ -1289,15 +1370,13 @@ static void mesh_foreachScreenFace__mapFunc(void *userData, int index, float *ce
 
 void mesh_foreachScreenFace(ViewContext *vc, 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; float pmat[4][4], vmat[4][4]; } data;
+       struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; ViewContext vc; } data;
        DerivedMesh *dm = editmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
 
        data.vc= *vc;
        data.func = func;
        data.userData = userData;
 
-       view3d_get_object_project_mat(vc->rv3d, vc->obedit, data.pmat, data.vmat);
-
        EM_init_index_arrays(vc->em, 0, 0, 1);
        dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data);
        EM_free_index_arrays();
@@ -1308,31 +1387,29 @@ void mesh_foreachScreenFace(ViewContext *vc, void (*func)(void *userData, EditFa
 void nurbs_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y), void *userData)
 {
        Curve *cu= vc->obedit->data;
-       float pmat[4][4], vmat[4][4];
-       short s[2];
+       short s[2] = {IS_CLIPPED, 0};
        Nurb *nu;
        int i;
 
-       view3d_get_object_project_mat(vc->rv3d, vc->obedit, pmat, vmat);
-
        for (nu= cu->editnurb->first; nu; nu=nu->next) {
-               if((nu->type & 7)==CU_BEZIER) {
+               if(nu->type == CU_BEZIER) {
                        for (i=0; i<nu->pntsu; i++) {
                                BezTriple *bezt = &nu->bezt[i];
 
                                if(bezt->hide==0) {
-                                       if (G.f & G_HIDDENHANDLES) {
-                                               view3d_project_short_clip(vc->ar, bezt->vec[1], s, pmat, vmat);
+                                       
+                                       if(cu->drawflag & CU_HIDE_HANDLES) {
+                                               view3d_project_short_clip(vc->ar, bezt->vec[1], s);
                                                if (s[0] != IS_CLIPPED)
                                                        func(userData, nu, NULL, bezt, 1, s[0], s[1]);
                                        } else {
-                                               view3d_project_short_clip(vc->ar, bezt->vec[0], s, pmat, vmat);
+                                               view3d_project_short_clip(vc->ar, bezt->vec[0], s);
                                                if (s[0] != IS_CLIPPED)
                                                        func(userData, nu, NULL, bezt, 0, s[0], s[1]);
-                                               view3d_project_short_clip(vc->ar, bezt->vec[1], s, pmat, vmat);
+                                               view3d_project_short_clip(vc->ar, bezt->vec[1], s);
                                                if (s[0] != IS_CLIPPED)
                                                        func(userData, nu, NULL, bezt, 1, s[0], s[1]);
-                                               view3d_project_short_clip(vc->ar, bezt->vec[2], s, pmat, vmat);
+                                               view3d_project_short_clip(vc->ar, bezt->vec[2], s);
                                                if (s[0] != IS_CLIPPED)
                                                        func(userData, nu, NULL, bezt, 2, s[0], s[1]);
                                        }
@@ -1344,8 +1421,9 @@ void nurbs_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, Nurb
                                BPoint *bp = &nu->bp[i];
 
                                if(bp->hide==0) {
-                                       view3d_project_short_clip(vc->ar, bp->vec, s, pmat, vmat);
-                                       func(userData, nu, bp, NULL, -1, s[0], s[1]);
+                                       view3d_project_short_clip(vc->ar, bp->vec, s);
+                                       if (s[0] != IS_CLIPPED)
+                                               func(userData, nu, bp, NULL, -1, s[0], s[1]);
                                }
                        }
                }
@@ -1365,14 +1443,14 @@ void nurbs_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, Nurb
 
 static void draw_dm_face_normals__mapFunc(void *userData, int index, float *cent, float *no)
 {
-       Scene *scene= (Scene *)userData;
+       ToolSettings *ts= ((Scene *)userData)->toolsettings;
        EditFace *efa = EM_get_face_for_index(index);
 
        if (efa->h==0 && efa->fgonf!=EM_FGON) {
                glVertex3fv(cent);
-               glVertex3f(     cent[0] + no[0]*scene->editbutsize,
-                                       cent[1] + no[1]*scene->editbutsize,
-                                       cent[2] + no[2]*scene->editbutsize);
+               glVertex3f(     cent[0] + no[0]*ts->normalsize,
+                                       cent[1] + no[1]*ts->normalsize,
+                                       cent[2] + no[2]*ts->normalsize);
        }
 }
 static void draw_dm_face_normals(Scene *scene, DerivedMesh *dm) 
@@ -1401,19 +1479,20 @@ static void draw_dm_face_centers(DerivedMesh *dm, int sel)
 static void draw_dm_vert_normals__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
 {
        Scene *scene= (Scene *)userData;
+       ToolSettings *ts= scene->toolsettings;
        EditVert *eve = EM_get_vert_for_index(index);
 
        if (eve->h==0) {
                glVertex3fv(co);
 
                if (no_f) {
-                       glVertex3f(     co[0] + no_f[0]*scene->editbutsize,
-                                               co[1] + no_f[1]*scene->editbutsize,
-                                               co[2] + no_f[2]*scene->editbutsize);
+                       glVertex3f(     co[0] + no_f[0]*ts->normalsize,
+                                               co[1] + no_f[1]*ts->normalsize,
+                                               co[2] + no_f[2]*ts->normalsize);
                } else {
-                       glVertex3f(     co[0] + no_s[0]*scene->editbutsize/32767.0f,
-                                               co[1] + no_s[1]*scene->editbutsize/32767.0f,
-                                               co[2] + no_s[2]*scene->editbutsize/32767.0f);
+                       glVertex3f(     co[0] + no_s[0]*ts->normalsize/32767.0f,
+                                               co[1] + no_s[1]*ts->normalsize/32767.0f,
+                                               co[2] + no_s[2]*ts->normalsize/32767.0f);
                }
        }
 }
@@ -1634,7 +1713,9 @@ static void draw_dm_bweights__mapFunc(void *userData, int index, float *co, floa
 }
 static void draw_dm_bweights(Scene *scene, DerivedMesh *dm)
 {
-       if (scene->selectmode & SCE_SELECT_VERTEX) {
+       ToolSettings *ts= scene->toolsettings;
+
+       if (ts->selectmode & SCE_SELECT_VERTEX) {
                glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE) + 2);
                bglBegin(GL_POINTS);
                dm->foreachMappedVert(dm, draw_dm_bweights__mapFunc, NULL);
@@ -1658,6 +1739,7 @@ static void draw_dm_bweights(Scene *scene, DerivedMesh *dm)
 
 static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit, EditMesh *em, DerivedMesh *cageDM, EditVert *eve_act)
 {
+       ToolSettings *ts= scene->toolsettings;
        int sel;
 
        if(v3d->zbuf) glDepthMask(0);           // disable write in zbuffer, zbuf select
@@ -1689,7 +1771,7 @@ static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit, EditM
                                col[3] = fcol[3] = 255;
                        }
                                
-                       if(scene->selectmode & SCE_SELECT_VERTEX) {
+                       if(ts->selectmode & SCE_SELECT_VERTEX) {
                                glPointSize(size);
                                glColor4ubv((GLubyte *)col);
                                draw_dm_verts(cageDM, sel, eve_act);
@@ -1714,6 +1796,7 @@ static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit, EditM
 
 static void draw_em_fancy_edges(Scene *scene, View3D *v3d, Mesh *me, DerivedMesh *cageDM, short sel_only, EditEdge *eed_act)
 {
+       ToolSettings *ts= scene->toolsettings;
        int pass;
        unsigned char wireCol[4], selCol[4], actCol[4];
 
@@ -1743,11 +1826,11 @@ static void draw_em_fancy_edges(Scene *scene, View3D *v3d, Mesh *me, DerivedMesh
                        if (!sel_only) wireCol[3] = 255;
                }
 
-               if(scene->selectmode == SCE_SELECT_FACE) {
+               if(ts->selectmode == SCE_SELECT_FACE) {
                        draw_dm_edges_sel(cageDM, wireCol, selCol, actCol, eed_act);
                }       
-               else if( (me->drawflag & ME_DRAWEDGES) || (scene->selectmode & SCE_SELECT_EDGE) ) {     
-                       if(cageDM->drawMappedEdgesInterp && (scene->selectmode & SCE_SELECT_VERTEX)) {
+               else if( (me->drawflag & ME_DRAWEDGES) || (ts->selectmode & SCE_SELECT_EDGE) ) {        
+                       if(cageDM->drawMappedEdgesInterp && (ts->selectmode & SCE_SELECT_VERTEX)) {
                                glShadeModel(GL_SMOOTH);
                                draw_dm_edges_sel_interp(cageDM, wireCol, selCol);
                                glShadeModel(GL_FLAT);
@@ -1769,28 +1852,30 @@ static void draw_em_fancy_edges(Scene *scene, View3D *v3d, Mesh *me, DerivedMesh
        }
 }      
 
-static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, EditMesh *em)
+static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, EditMesh *em, UnitSettings *unit)
 {
        Mesh *me= ob->data;
        EditEdge *eed;
        EditFace *efa;
-       float v1[3], v2[3], v3[3], v4[3];
+       float v1[3], v2[3], v3[3], v4[3], x, y, z;
        float fvec[3];
        char val[32]; /* Stores the measurement display text here */
        char conv_float[5]; /* Use a float conversion matching the grid size */
        float area, col[3]; /* area of the face,  color of the text to draw */
-       
+       float grid= unit->system ? unit->scale_length : v3d->grid;
+       int do_split= unit->flag & USER_UNIT_OPT_SPLIT;
        if(G.f & (G_RENDER_OGL|G_RENDER_SHADOW))
                return;
 
        /* make the precission of the pronted value proportionate to the gridsize */
-       if ((v3d->grid) < 0.01)
+
+       if (grid < 0.01f)
                strcpy(conv_float, "%.6f");
-       else if ((v3d->grid) < 0.1)
+       else if (grid < 0.1f)
                strcpy(conv_float, "%.5f");
-       else if ((v3d->grid) < 1.0)
+       else if (grid < 1.0f)
                strcpy(conv_float, "%.4f");
-       else if ((v3d->grid) < 10.0)
+       else if (grid < 10.0f)
                strcpy(conv_float, "%.3f");
        else
                strcpy(conv_float, "%.2f");
@@ -1799,13 +1884,13 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E
        if(v3d->zbuf && (v3d->flag & V3D_ZBUF_SELECT)==0)
                glDisable(GL_DEPTH_TEST);
 
-       if(v3d->zbuf) bglPolygonOffset(rv3d->dist, 5.0);
+       if(v3d->zbuf) bglPolygonOffset(rv3d->dist, 5.0f);
        
        if(me->drawflag & ME_DRAW_EDGELEN) {
                UI_GetThemeColor3fv(TH_TEXT, col);
                /* make color a bit more red */
-               if(col[0]> 0.5) {col[1]*=0.7; col[2]*= 0.7;}
-               else col[0]= col[0]*0.7 + 0.3;
+               if(col[0]> 0.5f) {col[1]*=0.7f; col[2]*= 0.7f;}
+               else col[0]= col[0]*0.7f + 0.3f;
                glColor3fv(col);
                
                for(eed= em->edges.first; eed; eed= eed->next) {
@@ -1814,15 +1899,20 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E
                                VECCOPY(v1, eed->v1->co);
                                VECCOPY(v2, eed->v2->co);
                                
-                               glRasterPos3f( 0.5*(v1[0]+v2[0]),  0.5*(v1[1]+v2[1]),  0.5*(v1[2]+v2[2]));
+                               x= 0.5f*(v1[0]+v2[0]);
+                               y= 0.5f*(v1[1]+v2[1]);
+                               z= 0.5f*(v1[2]+v2[2]);
                                
                                if(v3d->flag & V3D_GLOBAL_STATS) {
                                        Mat4MulVecfl(ob->obmat, v1);
                                        Mat4MulVecfl(ob->obmat, v2);
                                }
+                               if(unit->system)
+                                       bUnit_AsString(val, sizeof(val), VecLenf(v1, v2)*unit->scale_length, 3, unit->system, B_UNIT_LENGTH, do_split, FALSE);
+                               else
+                                       sprintf(val, conv_float, VecLenf(v1, v2));
                                
-                               sprintf(val, conv_float, VecLenf(v1, v2));
-                               BMF_DrawString( G.fonts, val);
+                               view3d_object_text_draw_add(x, y, z, val, 0);
                        }
                }
        }
@@ -1832,8 +1922,8 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E
                
                UI_GetThemeColor3fv(TH_TEXT, col);
                /* make color a bit more green */
-               if(col[1]> 0.5) {col[0]*=0.7; col[2]*= 0.7;}
-               else col[1]= col[1]*0.7 + 0.3;
+               if(col[1]> 0.5f) {col[0]*=0.7f; col[2]*= 0.7f;}
+               else col[1]= col[1]*0.7f + 0.3f;
                glColor3fv(col);
                
                for(efa= em->faces.first; efa; efa= efa->next) {
@@ -1856,9 +1946,12 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E
                                else
                                        area = AreaT3Dfl(v1, v2, v3);
 
-                               sprintf(val, conv_float, area);
-                               glRasterPos3fv(efa->cent);
-                               BMF_DrawString( G.fonts, val);
+                               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
+                               else
+                                       sprintf(val, conv_float, area);
+
+                               view3d_object_text_draw_add(efa->cent[0], efa->cent[1], efa->cent[2], val, 0);
                        }
                }
        }
@@ -1868,8 +1961,8 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E
                
                UI_GetThemeColor3fv(TH_TEXT, col);
                /* make color a bit more blue */
-               if(col[2]> 0.5) {col[0]*=0.7; col[1]*= 0.7;}
-               else col[2]= col[2]*0.7 + 0.3;
+               if(col[2]> 0.5f) {col[0]*=0.7f; col[1]*= 0.7f;}
+               else col[2]= col[2]*0.7f + 0.3f;
                glColor3fv(col);
                
                for(efa= em->faces.first; efa; efa= efa->next) {
@@ -1899,16 +1992,14 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E
                        if( (e4->f & e1->f & SELECT) || (G.moving && (efa->v1->f & SELECT)) ) {
                                /* Vec 1 */
                                sprintf(val,"%.3f", VecAngle3(v4, v1, v2));
-                               VecLerpf(fvec, efa->cent, efa->v1->co, 0.8);
-                               glRasterPos3fv(fvec);
-                               BMF_DrawString( G.fonts, val);
+                               VecLerpf(fvec, efa->cent, efa->v1->co, 0.8f);
+                               view3d_object_text_draw_add(efa->cent[0], efa->cent[1], efa->cent[2], val, 0);
                        }
                        if( (e1->f & e2->f & SELECT) || (G.moving && (efa->v2->f & SELECT)) ) {
                                /* Vec 2 */
                                sprintf(val,"%.3f", VecAngle3(v1, v2, v3));
-                               VecLerpf(fvec, efa->cent, efa->v2->co, 0.8);
-                               glRasterPos3fv(fvec);
-                               BMF_DrawString( G.fonts, val);
+                               VecLerpf(fvec, efa->cent, efa->v2->co, 0.8f);
+                               view3d_object_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0);
                        }
                        if( (e2->f & e3->f & SELECT) || (G.moving && (efa->v3->f & SELECT)) ) {
                                /* Vec 3 */
@@ -1916,17 +2007,15 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E
                                        sprintf(val,"%.3f", VecAngle3(v2, v3, v4));
                                else
                                        sprintf(val,"%.3f", VecAngle3(v2, v3, v1));
-                               VecLerpf(fvec, efa->cent, efa->v3->co, 0.8);
-                               glRasterPos3fv(fvec);
-                               BMF_DrawString( G.fonts, val);
+                               VecLerpf(fvec, efa->cent, efa->v3->co, 0.8f);
+                               view3d_object_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0);
                        }
                                /* Vec 4 */
                        if(efa->v4) {
                                if( (e3->f & e4->f & SELECT) || (G.moving && (efa->v4->f & SELECT)) ) {
                                        sprintf(val,"%.3f", VecAngle3(v3, v4, v1));
-                                       VecLerpf(fvec, efa->cent, efa->v4->co, 0.8);
-                                       glRasterPos3fv(fvec);
-                                       BMF_DrawString( G.fonts, val);
+                                       VecLerpf(fvec, efa->cent, efa->v4->co, 0.8f);
+                                       view3d_object_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0);
                                }
                        }
                }
@@ -1934,7 +2023,7 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E
        
        if(v3d->zbuf) {
                glEnable(GL_DEPTH_TEST);
-               bglPolygonOffset(rv3d->dist, 0.0);
+               bglPolygonOffset(rv3d->dist, 0.0f);
        }
 }
 
@@ -2019,7 +2108,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object
                }
        }
        
-       if((me->drawflag & (ME_DRAWFACES)) || FACESEL_PAINT_TEST) {     /* transp faces */
+       if((me->drawflag & (ME_DRAWFACES)) || paint_facesel_test(ob)) { /* transp faces */
                unsigned char col1[4], col2[4], col3[4];
                        
                UI_GetThemeColor4ubv(TH_FACE, (char *)col1);
@@ -2107,7 +2196,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object
                }
 
                if(me->drawflag & (ME_DRAW_EDGELEN|ME_DRAW_FACEAREA|ME_DRAW_EDGEANG))
-                       draw_em_measure_stats(v3d, rv3d, ob, em);
+                       draw_em_measure_stats(v3d, rv3d, ob, em, &scene->unit);
        }
 
        if(dt>OB_WIRE) {
@@ -2156,7 +2245,7 @@ static void draw_mesh_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base
        Object *ob= base->object;
        Mesh *me = ob->data;
        Material *ma= give_current_material(ob, 1);
-       int hasHaloMat = (ma && (ma->mode&MA_HALO));
+       int hasHaloMat = (ma && (ma->material_type == MA_TYPE_HALO));
        int draw_wire = 0;
        int totvert, totedge, totface;
        DispList *dl;
@@ -2178,7 +2267,7 @@ static void draw_mesh_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base
                glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
 
                // Unwanted combination.
-       if (ob==OBACT && FACESEL_PAINT_TEST) draw_wire = 0;
+       if (ob==OBACT && paint_facesel_test(ob)) draw_wire = 0;
 
        if(dt==OB_BOUNDBOX) {
                draw_bounding_volume(scene, ob);
@@ -2191,12 +2280,12 @@ static void draw_mesh_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base
        else if(dt==OB_WIRE || totface==0) {
                draw_wire = 1; /* draw wire only, no depth buffer stuff  */
        }
-       else if(        (ob==OBACT && (G.f & G_TEXTUREPAINT || FACESEL_PAINT_TEST)) ||
+       else if(        (ob==OBACT && (ob->mode & OB_MODE_TEXTURE_PAINT || paint_facesel_test(ob))) ||
                                CHECK_OB_DRAWTEXTURE(v3d, dt))
        {
-               int faceselect= (ob==OBACT && FACESEL_PAINT_TEST);
+               int faceselect= (ob==OBACT && paint_facesel_test(ob));
 
-               if ((v3d->flag&V3D_SELECT_OUTLINE) && (base->flag&SELECT) && !(G.f&G_PICKSEL || FACESEL_PAINT_TEST) && !draw_wire) {
+               if ((v3d->flag&V3D_SELECT_OUTLINE) && (base->flag&SELECT) && !(G.f&G_PICKSEL || paint_facesel_test(ob)) && !draw_wire) {
                        draw_mesh_object_outline(v3d, ob, dm);
                }
 
@@ -2250,7 +2339,7 @@ static void draw_mesh_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base
                
                if(ob==OBACT) {
                        do_draw= 0;
-                       if( (G.f & G_WEIGHTPAINT)) {
+                       if(ob && ob->mode & OB_MODE_WEIGHT_PAINT) {
                                /* enforce default material settings */
                                GPU_enable_material(0, NULL);
                                
@@ -2270,12 +2359,13 @@ static void draw_mesh_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base
 
                                GPU_disable_material();
                        }
-                       else if((G.f & (G_VERTEXPAINT+G_TEXTUREPAINT)) && me->mcol) {
-                               dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, NULL, 1);
-                       }
-                       else if(G.f & (G_VERTEXPAINT+G_TEXTUREPAINT)) {
-                               glColor3f(1.0f, 1.0f, 1.0f);
-                               dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, NULL, 0);
+                       else if(ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_TEXTURE_PAINT)) {
+                               if(me->mcol)
+                                       dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, NULL, 1);
+                               else {
+                                       glColor3f(1.0f, 1.0f, 1.0f);
+                                       dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, NULL, 0);
+                               }
                        }
                        else do_draw= 1;
                }
@@ -2385,11 +2475,13 @@ static int draw_mesh_object(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base
                if(dt>OB_WIRE) {
                        // no transp in editmode, the fancy draw over goes bad then
                        glsl = draw_glsl_material(scene, ob, v3d, dt);
-                       GPU_set_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
+                       GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
                }
 
                draw_em_fancy(scene, v3d, rv3d, ob, em, cageDM, finalDM, dt);
 
+               GPU_end_object_materials();
+
                if (obedit!=ob && finalDM)
                        finalDM->release(finalDM);
        }
@@ -2404,17 +2496,19 @@ static int draw_mesh_object(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base
                        check_alpha = check_material_alpha(base, me, glsl);
 
                        if(dt==OB_SOLID || glsl) {
-                               GPU_set_object_materials(v3d, rv3d, scene, ob, glsl,
+                               GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl,
                                        (check_alpha)? &do_alpha_pass: NULL);
                        }
 
                        draw_mesh_fancy(scene, v3d, rv3d, base, dt, flag);
+
+                       GPU_end_object_materials();
                        
                        if(me->totvert==0) retval= 1;
                }
        }
        
-       /* GPU_set_object_materials checked if this is needed */
+       /* GPU_begin_object_materials checked if this is needed */
        if(do_alpha_pass) add_view3d_after(v3d, base, V3D_TRANSP, flag);
        
        return retval;
@@ -2592,7 +2686,6 @@ static void drawDispListsolid(ListBase *lb, Object *ob, int glsl)
                                glVertexPointer(3, GL_FLOAT, 0, dl->verts);
                                glNormalPointer(GL_FLOAT, 0, dl->nors);
                                glDrawElements(GL_QUADS, 4*dl->totindex, GL_UNSIGNED_INT, dl->index);
-                               GPU_disable_material();
                        }                       
                        break;
 
@@ -2610,7 +2703,6 @@ static void drawDispListsolid(ListBase *lb, Object *ob, int glsl)
                                glNormalPointer(GL_FLOAT, 0, dl->nors);
                        
                        glDrawElements(GL_TRIANGLES, 3*dl->parts, GL_UNSIGNED_INT, dl->index);
-                       GPU_disable_material();
                        
                        if(index3_nors_incr==0)
                                glEnableClientState(GL_NORMAL_ARRAY);
@@ -2624,8 +2716,6 @@ static void drawDispListsolid(ListBase *lb, Object *ob, int glsl)
                        glNormalPointer(GL_FLOAT, 0, dl->nors);
                        glDrawElements(GL_QUADS, 4*dl->parts, GL_UNSIGNED_INT, dl->index);
 
-                       GPU_disable_material();
-                       
                        break;
                }
                dl= dl->next;
@@ -2708,7 +2798,7 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
                if(solid) {
                        dl= lb->first;
                        if(dl==NULL) return 1;
-                       
+
                        if(dl->nors==0) addnormalsDispList(ob, lb);
                        index3_nors_incr= 0;
                        
@@ -2719,17 +2809,19 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
                        }
                        else {
                                if(draw_glsl_material(scene, ob, v3d, dt)) {
-                                       GPU_set_object_materials(v3d, rv3d, scene, ob, 1, NULL);
+                                       GPU_begin_object_materials(v3d, rv3d, scene, ob, 1, NULL);
                                        drawDispListsolid(lb, ob, 1);
+                                       GPU_end_object_materials();
                                }
                                else if(dt == OB_SHADED) {
                                        if(ob->disp.first==0) shadeDispList(scene, base);
                                        drawDispListshaded(lb, ob);
                                }
                                else {
-                                       GPU_set_object_materials(v3d, rv3d, scene, ob, 0, NULL);
+                                       GPU_begin_object_materials(v3d, rv3d, scene, ob, 0, NULL);
                                        glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
                                        drawDispListsolid(lb, ob, 0);
+                                       GPU_end_object_materials();
                                }
                                if(cu->editnurb && cu->bevobj==NULL && cu->taperobj==NULL && cu->ext1 == 0.0 && cu->ext2 == 0.0) {
                                        cpack(0);
@@ -2747,7 +2839,7 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
                }
                break;
        case OB_SURF:
-       
+
                lb= &((Curve *)ob->data)->disp;
                
                if(solid) {
@@ -2757,18 +2849,19 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
                        if(dl->nors==NULL) addnormalsDispList(ob, lb);
                        
                        if(draw_glsl_material(scene, ob, v3d, dt)) {
-                               GPU_set_object_materials(v3d, rv3d, scene, ob, 1, NULL);
+                               GPU_begin_object_materials(v3d, rv3d, scene, ob, 1, NULL);
                                drawDispListsolid(lb, ob, 1);
+                               GPU_end_object_materials();
                        }
                        else if(dt==OB_SHADED) {
                                if(ob->disp.first==NULL) shadeDispList(scene, base);
                                drawDispListshaded(lb, ob);
                        }
                        else {
-                               GPU_set_object_materials(v3d, rv3d, scene, ob, 0, NULL);
+                               GPU_begin_object_materials(v3d, rv3d, scene, ob, 0, NULL);
                                glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
-                       
                                drawDispListsolid(lb, ob, 0);
+                               GPU_end_object_materials();
                        }
                }
                else {
@@ -2785,8 +2878,9 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
                        if(solid) {
                                
                                if(draw_glsl_material(scene, ob, v3d, dt)) {
-                                       GPU_set_object_materials(v3d, rv3d, scene, ob, 1, NULL);
+                                       GPU_begin_object_materials(v3d, rv3d, scene, ob, 1, NULL);
                                        drawDispListsolid(lb, ob, 1);
+                                       GPU_end_object_materials();
                                }
                                else if(dt == OB_SHADED) {
                                        dl= lb->first;
@@ -2794,10 +2888,10 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
                                        drawDispListshaded(lb, ob);
                                }
                                else {
-                                       GPU_set_object_materials(v3d, rv3d, scene, ob, 0, NULL);
+                                       GPU_begin_object_materials(v3d, rv3d, scene, ob, 0, NULL);
                                        glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
-                               
                                        drawDispListsolid(lb, ob, 0);
+                                       GPU_end_object_materials();
                                }
                        }
                        else{
@@ -2811,6 +2905,227 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
        return retval;
 }
 
+/* *********** text drawing for particles ************* */
+static ListBase pstrings= {NULL, NULL};
+
+typedef struct ViewParticleString {
+       struct ViewParticleString *next, *prev;
+       float vec[3], col[4];
+       char str[128]; 
+       short mval[2];
+       short xoffs;
+} ViewParticleString;
+
+
+void view3d_particle_text_draw_add(float x, float y, float z, char *str, short xoffs)
+{
+       ViewObjectString *vos= MEM_callocN(sizeof(ViewObjectString), "ViewObjectString");
+
+       BLI_addtail(&pstrings, vos);
+       BLI_strncpy(vos->str, str, 128);
+       vos->vec[0]= x;
+       vos->vec[1]= y;
+       vos->vec[2]= z;
+       glGetFloatv(GL_CURRENT_COLOR, vos->col);
+       vos->xoffs= xoffs;
+}
+
+static void view3d_particle_text_draw(View3D *v3d, ARegion *ar)
+{
+       ViewObjectString *vos;
+       int tot= 0;
+       
+       /* project first and test */
+       for(vos= pstrings.first; vos; vos= vos->next) {
+               project_short(ar, vos->vec, vos->mval);
+               if(vos->mval[0]!=IS_CLIPPED)
+                       tot++;
+       }
+       
+       if(tot) {
+               RegionView3D *rv3d= ar->regiondata;
+               int a;
+               
+               if(rv3d->rflag & RV3D_CLIPPING)
+                       for(a=0; a<6; a++)
+                               glDisable(GL_CLIP_PLANE0+a);
+               
+               wmPushMatrix();
+               ED_region_pixelspace(ar);
+               
+               if(v3d->zbuf) glDepthMask(0);
+
+               for(vos= pstrings.first; vos; vos= vos->next) {
+                       if(vos->mval[0]!=IS_CLIPPED) {
+                               glColor3fv(vos->col);
+                               BLF_draw_default((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], 2.0, vos->str);
+                       }
+               }
+               
+               if(v3d->zbuf) glDepthMask(1);
+               
+               wmPopMatrix();
+
+               if(rv3d->rflag & RV3D_CLIPPING)
+                       for(a=0; a<6; a++)
+                               glEnable(GL_CLIP_PLANE0+a);
+       }
+       
+       if(pstrings.first) 
+               BLI_freelistN(&pstrings);
+}
+typedef struct ParticleDrawData {
+       float *vdata, *vd;
+       float *ndata, *nd;
+       float *cdata, *cd;
+       float *vedata, *ved;
+       float *ma_r, *ma_g, *ma_b;
+} ParticleDrawData;
+static void draw_particle(ParticleKey *state, int draw_as, short draw, float pixsize, float imat[4][4], float *draw_line, ParticleBillboardData *bb, ParticleDrawData *pdd)
+{
+       float vec[3], vec2[3];
+       float *vd = pdd->vd;
+       float *cd = pdd->cd;
+       float ma_r=0.0f;
+       float ma_g=0.0f;
+       float ma_b=0.0f;
+
+       if(pdd->ma_r) {
+               ma_r = *pdd->ma_r;
+               ma_g = *pdd->ma_g;
+               ma_b = *pdd->ma_b;
+       }
+
+       switch(draw_as){
+               case PART_DRAW_DOT:
+               {
+                       if(vd) {
+                               VECCOPY(vd,state->co) pdd->vd+=3;
+                       }
+                       if(cd) {
+                               cd[0]=ma_r;
+                               cd[1]=ma_g;
+                               cd[2]=ma_b;
+                               pdd->cd+=3;
+                       }
+                       break;
+               }
+               case PART_DRAW_CROSS:
+               case PART_DRAW_AXIS:
+               {
+                       vec[0]=2.0f*pixsize;
+                       vec[1]=vec[2]=0.0;
+                       QuatMulVecf(state->rot,vec);
+                       if(draw_as==PART_DRAW_AXIS) {
+                               cd[1]=cd[2]=cd[4]=cd[5]=0.0;
+                               cd[0]=cd[3]=1.0;
+                               cd[6]=cd[8]=cd[9]=cd[11]=0.0;
+                               cd[7]=cd[10]=1.0;
+                               cd[13]=cd[12]=cd[15]=cd[16]=0.0;
+                               cd[14]=cd[17]=1.0;
+                               cd+=18;
+
+                               VECCOPY(vec2,state->co);
+                       }
+                       else {
+                               if(cd) {
+                                       cd[0]=cd[3]=cd[6]=cd[9]=cd[12]=cd[15]=ma_r;
+                                       cd[1]=cd[4]=cd[7]=cd[10]=cd[13]=cd[16]=ma_g;
+                                       cd[2]=cd[5]=cd[8]=cd[11]=cd[14]=cd[17]=ma_b;
+                                       pdd->cd+=18;
+                               }
+                               VECSUB(vec2,state->co,vec);
+                       }
+
+                       VECADD(vec,state->co,vec);
+                       VECCOPY(pdd->vd,vec); pdd->vd+=3;
+                       VECCOPY(pdd->vd,vec2); pdd->vd+=3;
+                               
+                       vec[1]=2.0f*pixsize;
+                       vec[0]=vec[2]=0.0;
+                       QuatMulVecf(state->rot,vec);
+                       if(draw_as==PART_DRAW_AXIS){
+                               VECCOPY(vec2,state->co);
+                       }               
+                       else VECSUB(vec2,state->co,vec);
+
+                       VECADD(vec,state->co,vec);
+                       VECCOPY(pdd->vd,vec); pdd->vd+=3;
+                       VECCOPY(pdd->vd,vec2); pdd->vd+=3;
+
+                       vec[2]=2.0f*pixsize;
+                       vec[0]=vec[1]=0.0;
+                       QuatMulVecf(state->rot,vec);
+                       if(draw_as==PART_DRAW_AXIS){
+                               VECCOPY(vec2,state->co);
+                       }
+                       else VECSUB(vec2,state->co,vec);
+
+                       VECADD(vec,state->co,vec);
+
+                       VECCOPY(pdd->vd,vec); pdd->vd+=3;
+                       VECCOPY(pdd->vd,vec2); pdd->vd+=3;
+                       break;
+               }
+               case PART_DRAW_LINE:
+               {
+                       VECCOPY(vec,state->vel);
+                       Normalize(vec);
+                       if(draw & PART_DRAW_VEL_LENGTH)
+                               VecMulf(vec,VecLength(state->vel));
+                       VECADDFAC(pdd->vd,state->co,vec,-draw_line[0]); pdd->vd+=3;
+                       VECADDFAC(pdd->vd,state->co,vec,draw_line[1]); pdd->vd+=3;
+                       if(cd) {
+                               cd[0]=cd[3]=ma_r;
+                               cd[1]=cd[4]=ma_g;
+                               cd[2]=cd[5]=ma_b;
+                               pdd->cd+=6;
+                       }
+                       break;
+               }
+               case PART_DRAW_CIRC:
+               {
+                       if(pdd->ma_r)
+                               glColor3f(ma_r,ma_g,ma_b);
+                       drawcircball(GL_LINE_LOOP, state->co, pixsize, imat);
+                       break;
+               }
+               case PART_DRAW_BB:
+               {
+                       float xvec[3], yvec[3], zvec[3], bb_center[3];
+                       if(cd) {
+                               cd[0]=cd[3]=cd[6]=cd[9]=ma_r;
+                               cd[1]=cd[4]=cd[7]=cd[10]=ma_g;
+                               cd[2]=cd[5]=cd[8]=cd[11]=ma_b;
+                               pdd->cd+=12;
+                       }
+
+
+                       VECCOPY(bb->vec, state->co);
+                       VECCOPY(bb->vel, state->vel);
+
+                       psys_make_billboard(bb, xvec, yvec, zvec, bb_center);
+                       
+                       VECADD(pdd->vd,bb_center,xvec);
+                       VECADD(pdd->vd,pdd->vd,yvec); pdd->vd+=3;
+
+                       VECSUB(pdd->vd,bb_center,xvec);
+                       VECADD(pdd->vd,pdd->vd,yvec); pdd->vd+=3;
+
+                       VECSUB(pdd->vd,bb_center,xvec);
+                       VECSUB(pdd->vd,pdd->vd,yvec); pdd->vd+=3;
+
+                       VECADD(pdd->vd,bb_center,xvec);
+                       VECSUB(pdd->vd,pdd->vd,yvec); pdd->vd+=3;
+
+                       VECCOPY(pdd->nd, zvec); pdd->nd+=3;
+                       VECCOPY(pdd->nd, zvec); pdd->nd+=3;
+                       VECCOPY(pdd->nd, zvec); pdd->nd+=3;
+                       VECCOPY(pdd->nd, zvec); pdd->nd+=3;
+                       break;
+               }
+       }
+}
 /* unified drawing of all new particle systems draw types except dupli ob & group      */
 /* mostly tries to use vertex arrays for speed                                                                         */
 
@@ -2821,24 +3136,24 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
 /* 5. start filling the arrays                         */
 /* 6. draw the arrays                                          */
 /* 7. clean up                                                         */
-static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, ParticleSystem *psys, int dt)
+static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, ParticleSystem *psys, int ob_dt)
 {
        Object *ob=base->object;
        ParticleSystemModifierData *psmd;
+       ParticleEditSettings *pset = PE_settings(scene);
        ParticleSettings *part;
        ParticleData *pars, *pa;
        ParticleKey state, *states=0;
-       ParticleCacheKey *cache=0;
+       ParticleBillboardData bb;
+       ParticleDrawData pdd;
        Material *ma;
-       Object *bb_ob=0;
-       float vel[3], vec[3], vec2[3], imat[4][4], onevec[3]={0.0f,0.0f,0.0f}, bb_center[3];
-       float timestep, pixsize=1.0, pa_size, pa_time, r_tilt;
+       float vel[3], imat[4][4];
+       float timestep, pixsize=1.0, pa_size, r_tilt, r_length;
+       float pa_time, pa_birthtime, pa_dietime, pa_health;
        float cfra= bsystem_time(scene, ob,(float)CFRA,0.0);
-       float *vdata=0, *vedata=0, *cdata=0, *ndata=0, *vd=0, *ved=0, *cd=0, *nd=0, xvec[3], yvec[3], zvec[3];
        float ma_r=0.0f, ma_g=0.0f, ma_b=0.0f;
-       int a, k, k_max=0, totpart, totpoint=0, draw_as, path_nbr=0;
-       int path_possible=0, keys_possible=0, draw_keys=0, totchild=0;
-       int select=ob->flag&SELECT, create_cdata=0;
+       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];
 
@@ -2854,24 +3169,19 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
 
        if(pars==0) return;
 
-       // XXX what logic is this?
-       if(!scene->obedit && psys_in_edit_mode(scene, psys)
-               && psys->flag & PSYS_HAIR_DONE && part->draw_as==PART_DRAW_PATH)
+       /* don't draw normal paths in edit mode */
+       if(psys_in_edit_mode(scene, psys) && (pset->flag & PE_DRAW_PART)==0)
                return;
                
        if(part->draw_as==PART_DRAW_NOT) return;
 
 /* 2. */
        if(part->phystype==PART_PHYS_KEYED){
-               if(psys->flag & PSYS_FIRST_KEYED){
-                       if(psys->flag&PSYS_KEYED){
-                               select=psys_count_keyed_targets(ob,psys);
-                               if(psys->totkeyed==0)
-                                       return;
-                       }
+               if(psys->flag&PSYS_KEYED){
+                       psys_count_keyed_targets(ob,psys);
+                       if(psys->totkeyed==0)
+                               return;
                }
-               else
-                       return;
        }
 
        if(select){
@@ -2887,13 +3197,9 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
        else
                totchild=psys->totchild*part->disp/100;
        
-       ma= give_current_material(ob,part->omat);
+       memset(&pdd, 0, sizeof(ParticleDrawData));
 
-       if(ma) {
-               ma_r = ma->r;
-               ma_g = ma->g;
-               ma_b = ma->b;
-       }
+       ma= give_current_material(ob,part->omat);
 
        if(v3d->zbuf) glDepthMask(1);
 
@@ -2901,6 +3207,15 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
                cpack(0xFFFFFF);
        else if((ma) && (part->draw&PART_DRAW_MAT_COL)) {
                glColor3f(ma->r,ma->g,ma->b);
+
+               ma_r = ma->r;
+               ma_g = ma->g;
+               ma_b = ma->b;
+
+               pdd.ma_r = &ma_r;
+               pdd.ma_g = &ma_g;
+               pdd.ma_b = &ma_b;
+
                create_cdata = 1;
        }
        else
@@ -2910,8 +3225,6 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
 
        timestep= psys_get_timestep(part);
 
-       wmLoadMatrix(rv3d->viewmat);
-
        if( (base->flag & OB_FROMDUPLI) && (ob->flag & OB_FROMGROUP) ) {
                float mat[4][4];
                Mat4MulMat4(mat, psys->imat, ob->obmat);
@@ -2919,22 +3232,17 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
        }
 
        totpart=psys->totpart;
-       draw_as=part->draw_as;
 
-       if(part->flag&PART_GLOB_TIME)
-               cfra=bsystem_time(scene, 0, (float)CFRA, 0.0f);
+       if(part->draw_as==PART_DRAW_REND)
+               draw_as = part->ren_as;
+       else
+               draw_as = part->draw_as;
 
-       if(psys->pathcache){
-               path_possible=1;
-               keys_possible=1;
-       }
-       if(draw_as==PART_DRAW_PATH && path_possible==0)
-               draw_as=PART_DRAW_DOT;
+       //if(part->flag&PART_GLOB_TIME)
+       cfra=bsystem_time(scene, 0, (float)CFRA, 0.0f);
 
-       if(draw_as!=PART_DRAW_PATH && keys_possible && part->draw&PART_DRAW_KEYS){
-               path_nbr=part->keys_step;
-               draw_keys=1;
-       }
+       if(draw_as==PART_DRAW_PATH && psys->pathcache==NULL)
+               draw_as=PART_DRAW_DOT;
 
 /* 3. */
        switch(draw_as){
@@ -2984,15 +3292,21 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
                                        glPointSize(2.0); /* default dot size */
                        }
                        else if(part->bb_ob)
-                               bb_ob=part->bb_ob;
+                               bb.ob=part->bb_ob;
                        else
-                               bb_ob=v3d->camera;
+                               bb.ob=v3d->camera;
 
-                       if(part->bb_align<PART_BB_VIEW)
-                               onevec[part->bb_align]=1.0f;
+                       bb.align = part->bb_align;
+                       bb.anim = part->bb_anim;
+                       bb.lock = part->draw & PART_DRAW_BB_LOCK;
+                       bb.offset[0] = part->bb_offset[0];
+                       bb.offset[1] = part->bb_offset[1];
                        break;
                case PART_DRAW_PATH:
                        break;
+               case PART_DRAW_LINE:
+                       need_v=1;
+                       break;
        }
        if(part->draw & PART_DRAW_SIZE && part->draw_as!=PART_DRAW_CIRC){
                Mat4CpyMat4(imat, rv3d->viewinv);
@@ -3001,40 +3315,49 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
        }
 
 /* 4. */
-       if(draw_as && draw_as!=PART_DRAW_PATH){
-               if(draw_as!=PART_DRAW_CIRC){
-                       switch(draw_as){
+       if(draw_as && draw_as!=PART_DRAW_PATH) {
+               int tot_vec_size = (totpart + totchild) * 3 * sizeof(float);
+               
+               if(part->draw_as == PART_DRAW_REND && part->trail_count > 1) {
+                       tot_vec_size *= part->trail_count;
+                       psys_make_temp_pointcache(ob, psys);
+               }
+
+               if(draw_as!=PART_DRAW_CIRC) {
+                       switch(draw_as) {
                                case PART_DRAW_AXIS:
                                case PART_DRAW_CROSS:
-                                       if(draw_as!=PART_DRAW_CROSS || create_cdata)
-                                               cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*6*3*sizeof(float), "particle_cdata");
-                                       vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*6*3*sizeof(float), "particle_vdata");
+                                       if(draw_as != PART_DRAW_CROSS || create_cdata)
+                                               pdd.cdata = MEM_callocN(tot_vec_size * 6, "particle_cdata");
+                                       pdd.vdata = MEM_callocN(tot_vec_size * 6, "particle_vdata");
                                        break;
                                case PART_DRAW_LINE:
                                        if(create_cdata)
-                                               cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*2*3*sizeof(float), "particle_cdata");
-                                       vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*2*3*sizeof(float), "particle_vdata");
+                                               pdd.cdata = MEM_callocN(tot_vec_size * 2, "particle_cdata");
+                                       pdd.vdata = MEM_callocN(tot_vec_size * 2, "particle_vdata");
                                        break;
                                case PART_DRAW_BB:
                                        if(create_cdata)
-                                               cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*4*3*sizeof(float), "particle_cdata");
-                                       vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*4*3*sizeof(float), "particle_vdata");
-                                       ndata=MEM_callocN((totpart+totchild)*(path_nbr+1)*4*3*sizeof(float), "particle_vdata");
+                                               pdd.cdata = MEM_callocN(tot_vec_size * 4, "particle_cdata");
+                                       pdd.vdata = MEM_callocN(tot_vec_size * 4, "particle_vdata");
+                                       pdd.ndata = MEM_callocN(tot_vec_size * 4, "particle_vdata");
                                        break;
                                default:
                                        if(create_cdata)
-                                               cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*3*sizeof(float), "particle_cdata");
-                                       vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*3*sizeof(float), "particle_vdata");
+                                               pdd.cdata=MEM_callocN(tot_vec_size, "particle_cdata");
+                                       pdd.vdata=MEM_callocN(tot_vec_size, "particle_vdata");
                        }
                }
 
-               if(part->draw&PART_DRAW_VEL && draw_as!=PART_DRAW_LINE)
-                       vedata=MEM_callocN((totpart+totchild)*2*3*(path_nbr+1)*sizeof(float), "particle_vedata");
+               if(part->draw & PART_DRAW_VEL && draw_as != PART_DRAW_LINE) {
+                       pdd.vedata = MEM_callocN(tot_vec_size * 2, "particle_vedata");
+                       need_v = 1;
+               }
 
-               vd=vdata;
-               ved=vedata;
-               cd=cdata;
-               nd=ndata;
+               pdd.vd= pdd.vdata;
+               pdd.ved= pdd.vedata;
+               pdd.cd= pdd.cdata;
+               pdd.nd= pdd.ndata;
 
                psys->lattice= psys_get_lattice(scene, ob, psys);
        }
@@ -3042,15 +3365,23 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
        if(draw_as){
 /* 5. */
                for(a=0,pa=pars; a<totpart+totchild; a++, pa++){
+                       /* setup per particle individual stuff */
                        if(a<totpart){
                                if(totchild && (part->draw&PART_DRAW_PARENT)==0) continue;
                                if(pa->flag & PARS_NO_DISP || pa->flag & PARS_UNEXIST) continue;
 
                                pa_time=(cfra-pa->time)/pa->lifetime;
+                               pa_birthtime=pa->time;
+                               pa_dietime = pa->dietime;
                                pa_size=pa->size;
+                               if(part->phystype==PART_PHYS_BOIDS) {
+                                       pa_health = pa->boid->data.health;
+                               }
+                               else
+                                       pa_health = -1.0;
 
-                               if((part->flag&PART_ABS_TIME)==0){      
-#if 0 // XXX old animation system                      
+#if 0 // XXX old animation system      
+                               if((part->flag&PART_ABS_TIME)==0){                      
                                        if(ma && ma->ipo){
                                                IpoCurve *icu;
 
@@ -3077,24 +3408,22 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
                                                                pa_size = icu->curval;
                                                }
                                        }
-#endif // XXX old animation system
                                }
+#endif // XXX old animation system
 
-                               r_tilt=1.0f+pa->r_ave[0];
+                               BLI_srandom(psys->seed+a);
 
-                               if(path_nbr){
-                                       cache=psys->pathcache[a];
-                                       k_max=(int)(cache->steps);
-                               }
+                               r_tilt = 2.0f*(BLI_frand() - 0.5f);
+                               r_length = BLI_frand();
                        }
                        else{
                                ChildParticle *cpa= &psys->child[a-totpart];
 
-                               pa_time=psys_get_child_time(psys,cpa,cfra);
+                               pa_time=psys_get_child_time(psys,cpa,cfra,&pa_birthtime,&pa_dietime);
 
+#if 0 // XXX old animation system
                                if((part->flag&PART_ABS_TIME)==0) {
                                        if(ma && ma->ipo){
-#if 0 // XXX old animation system
                                                IpoCurve *icu;
 
                                                /* correction for lifetime */
@@ -3108,215 +3437,88 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
                                                        else if(icu->adrcode == MA_COL_B)
                                                                ma_b = icu->curval;
                                                }
-#endif // XXX old animation system
                                        }
                                }
+#endif // XXX old animation system
 
                                pa_size=psys_get_child_size(psys,cpa,cfra,0);
 
-                               r_tilt=2.0f*cpa->rand[2];
-                               if(path_nbr){
-                                       cache=psys->childcache[a-totpart];
-                                       k_max=(int)(cache->steps);
-                               }
+                               pa_health = -1.0;
+
+                               r_tilt = 2.0f * cpa->rand[2];
+                               r_length = cpa->rand[1];
                        }
 
                        if(draw_as!=PART_DRAW_PATH){
-                               int next_pa=0;
-                               for(k=0; k<=path_nbr; k++){
-                                       if(draw_keys){
-                                               state.time=(float)k/(float)path_nbr;
-                                               psys_get_particle_on_path(scene, ob, psys, a, &state,1);
-                                       }
-                                       else if(path_nbr){
-                                               if(k<=k_max){
-                                                       VECCOPY(state.co,(cache+k)->co);
-                                                       VECCOPY(state.vel,(cache+k)->vel);
-                                                       QUATCOPY(state.rot,(cache+k)->rot);
-                                               }
-                                               else
-                                                       continue;       
-                                       }
-                                       else{
-                                               state.time=cfra;
-                                               if(psys_get_particle_state(scene, ob, psys, a, &state,0)==0){
-                                                       next_pa=1;
-                                                       break;
+                               drawn = 0;
+                               if(part->draw_as == PART_DRAW_REND && part->trail_count > 1) {
+                                       float length = part->path_end * (1.0 - part->randlength * r_length);
+                                       int trail_count = part->trail_count * (1.0 - part->randlength * r_length);
+                                       float ct = ((part->draw & PART_ABS_PATH_TIME) ? cfra : pa_time) - length;
+                                       float dt = length / (trail_count ? (float)trail_count : 1.0f);
+                                       int i=0;
+
+                                       ct+=dt;
+                                       for(i=0; i < trail_count; i++, ct += dt) {
+                                               if(part->draw & PART_ABS_PATH_TIME) {
+                                                       if(ct < pa_birthtime || ct > pa_dietime)
+                                                               continue;
                                                }
-                                       }
-
-                                       switch(draw_as){
-                                               case PART_DRAW_DOT:
-                                                       if(cd) {
-                                                               cd[0]=ma_r;
-                                                               cd[1]=ma_g;
-                                                               cd[2]=ma_b;
-                                                               cd+=3;
-                                                       }
-                                                       if(vd){
-                                                               VECCOPY(vd,state.co) vd+=3;
-                                                       }
-                                                       break;
-                                               case PART_DRAW_CROSS:
-                                               case PART_DRAW_AXIS:
-                                                       vec[0]=2.0f*pixsize;
-                                                       vec[1]=vec[2]=0.0;
-                                                       QuatMulVecf(state.rot,vec);
-                                                       if(draw_as==PART_DRAW_AXIS){
-                                                               cd[1]=cd[2]=cd[4]=cd[5]=0.0;
-                                                               cd[0]=cd[3]=1.0;
-                                                               cd[6]=cd[8]=cd[9]=cd[11]=0.0;
-                                                               cd[7]=cd[10]=1.0;
-                                                               cd[13]=cd[12]=cd[15]=cd[16]=0.0;
-                                                               cd[14]=cd[17]=1.0;
-                                                               cd+=18;
-
-                                                               VECCOPY(vec2,state.co);
-                                                       }
-                                                       else {
-                                                               if(cd) {
-                                                                       cd[0]=cd[3]=cd[6]=cd[9]=cd[12]=cd[15]=ma_r;
-                                                                       cd[1]=cd[4]=cd[7]=cd[10]=cd[13]=cd[16]=ma_g;
-                                                                       cd[2]=cd[5]=cd[8]=cd[11]=cd[14]=cd[17]=ma_b;
-                                                                       cd+=18;
-                                                               }
-                                                               VECSUB(vec2,state.co,vec);
-                                                       }
-
-                                                       VECADD(vec,state.co,vec);
-                                                       VECCOPY(vd,vec); vd+=3;
-                                                       VECCOPY(vd,vec2); vd+=3;
-                                                               
-                                                       vec[1]=2.0f*pixsize;
-                                                       vec[0]=vec[2]=0.0;
-                                                       QuatMulVecf(state.rot,vec);
-                                                       if(draw_as==PART_DRAW_AXIS){
-                                                               VECCOPY(vec2,state.co);
-                                                       }               
-                                                       else VECSUB(vec2,state.co,vec);
-
-                                                       VECADD(vec,state.co,vec);
-                                                       VECCOPY(vd,vec); vd+=3;
-                                                       VECCOPY(vd,vec2); vd+=3;
-
-                                                       vec[2]=2.0f*pixsize;
-                                                       vec[0]=vec[1]=0.0;
-                                                       QuatMulVecf(state.rot,vec);
-                                                       if(draw_as==PART_DRAW_AXIS){
-                                                               VECCOPY(vec2,state.co);
-                                                       }
-                                                       else VECSUB(vec2,state.co,vec);
-
-                                                       VECADD(vec,state.co,vec);
-
-                                                       VECCOPY(vd,vec); vd+=3;
-                                                       VECCOPY(vd,vec2); vd+=3;
-                                                       break;
-                                               case PART_DRAW_LINE:
-                                                       VECCOPY(vec,state.vel);
-                                                       Normalize(vec);
-                                                       if(part->draw & PART_DRAW_VEL_LENGTH)
-                                                               VecMulf(vec,VecLength(state.vel));
-                                                       VECADDFAC(vd,state.co,vec,-part->draw_line[0]); vd+=3;
-                                                       VECADDFAC(vd,state.co,vec,part->draw_line[1]); vd+=3;
-                                                       if(cd) {
-                                                               cd[0]=cd[3]=ma_r;
-                                                               cd[1]=cd[4]=ma_g;
-                                                               cd[2]=cd[5]=ma_b;
-                                                               cd+=3;
-                                                       }
-                                                       break;
-                                               case PART_DRAW_CIRC:
-                                                       if(create_cdata)
-                                                               glColor3f(ma_r,ma_g,ma_b);
-                                                       drawcircball(GL_LINE_LOOP, state.co, pixsize, imat);
-                                                       break;
-                                               case PART_DRAW_BB:
-                                                       if(cd) {
-                                                               cd[0]=cd[3]=cd[6]=cd[9]=ma_r;
-                                                               cd[1]=cd[4]=cd[7]=cd[10]=ma_g;
-                                                               cd[2]=cd[5]=cd[8]=cd[11]=ma_b;
-                                                               cd+=12;
-                                                       }
-                                                       if(part->draw&PART_DRAW_BB_LOCK && part->bb_align==PART_BB_VIEW){
-                                                               VECCOPY(xvec,bb_ob->obmat[0]);
-                                                               Normalize(xvec);
-                                                               VECCOPY(yvec,bb_ob->obmat[1]);
-                                                               Normalize(yvec);
-                                                               VECCOPY(zvec,bb_ob->obmat[2]);
-                                                               Normalize(zvec);
-                                                       }
-                                                       else if(part->bb_align==PART_BB_VEL){
-                                                               float temp[3];
-                                                               VECCOPY(temp,state.vel);
-                                                               Normalize(temp);
-                                                               VECSUB(zvec,bb_ob->obmat[3],state.co);
-                                                               if(part->draw&PART_DRAW_BB_LOCK){
-                                                                       float fac=-Inpf(zvec,temp);
-                                                                       VECADDFAC(zvec,zvec,temp,fac);
-                                                               }
-                                                               Normalize(zvec);
-                                                               Crossf(xvec,temp,zvec);
-                                                               Normalize(xvec);
-                                                               Crossf(yvec,zvec,xvec);
-                                                       }
-                                                       else{
-                                                               VECSUB(zvec,bb_ob->obmat[3],state.co);
-                                                               if(part->draw&PART_DRAW_BB_LOCK)
-                                                                       zvec[part->bb_align]=0.0f;
-                                                               Normalize(zvec);
-
-                                                               if(part->bb_align<PART_BB_VIEW)
-                                                                       Crossf(xvec,onevec,zvec);
-                                                               else
-                                                                       Crossf(xvec,bb_ob->obmat[1],zvec);
-                                                               Normalize(xvec);
-                                                               Crossf(yvec,zvec,xvec);
-                                                       }
-
-                                                       VECCOPY(vec,xvec);
-                                                       VECCOPY(vec2,yvec);
+                                               else if(ct < 0.0f || ct > 1.0f)
+                                                       continue;
 
-                                                       VecMulf(xvec,cos(part->bb_tilt*(1.0f-part->bb_rand_tilt*r_tilt)*(float)M_PI));
-                                                       VecMulf(vec2,sin(part->bb_tilt*(1.0f-part->bb_rand_tilt*r_tilt)*(float)M_PI));
-                                                       VECADD(xvec,xvec,vec2);
-
-                                                       VecMulf(yvec,cos(part->bb_tilt*(1.0f-part->bb_rand_tilt*r_tilt)*(float)M_PI));
-                                                       VecMulf(vec,-sin(part->bb_tilt*(1.0f-part->bb_rand_tilt*r_tilt)*(float)M_PI));
-                                                       VECADD(yvec,yvec,vec);
-
-                                                       VecMulf(xvec,pa_size);
-                                                       VecMulf(yvec,pa_size);
-
-                                                       VECADDFAC(bb_center,state.co,xvec,part->bb_offset[0]);
-                                                       VECADDFAC(bb_center,bb_center,yvec,part->bb_offset[1]);
-
-                                                       VECADD(vd,bb_center,xvec);
-                                                       VECADD(vd,vd,yvec); vd+=3;
+                                               state.time = (part->draw & PART_ABS_PATH_TIME) ? -ct : -(pa_birthtime + ct * (pa_dietime - pa_birthtime));
+                                               psys_get_particle_on_path(scene,ob,psys,a,&state,need_v);
+                                               
+                                               if(psys->parent)
+                                                       Mat4MulVecfl(psys->parent->obmat, state.co);
+
+                                               /* create actiual particle data */
+                                               if(draw_as == PART_DRAW_BB) {
+                                                       bb.size = pa_size;
+                                                       bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt);
+                                                       bb.time = ct;
+                                               }
 
-                                                       VECSUB(vd,bb_center,xvec);
-                                                       VECADD(vd,vd,yvec); vd+=3;
+                                               draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, &pdd);
 
-                                                       VECSUB(vd,bb_center,xvec);
-                                                       VECSUB(vd,vd,yvec); vd+=3;
+                                               totpoint++;
+                                               drawn = 1;
+                                       }
+                               }
+                               else
+                               {
+                                       state.time=cfra;
+                                       if(psys_get_particle_state(scene,ob,psys,a,&state,0)){
+                                               if(psys->parent)
+                                                       Mat4MulVecfl(psys->parent->obmat, state.co);
+
+                                               /* create actiual particle data */
+                                               if(draw_as == PART_DRAW_BB) {
+                                                       bb.size = pa_size;
+                                                       bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt);
+                                                       bb.time = pa_time;
+                                               }
 
-                                                       VECADD(vd,bb_center,xvec);
-                                                       VECSUB(vd,vd,yvec); vd+=3;
+                                               draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, &pdd);
 
-                                                       VECCOPY(nd, zvec); nd+=3;
-                                                       VECCOPY(nd, zvec); nd+=3;
-                                                       VECCOPY(nd, zvec); nd+=3;
-                                                       VECCOPY(nd, zvec); nd+=3;
-                                                       break;
+                                               totpoint++;
+                                               drawn = 1;
                                        }
+                               }
 
-                                       if(vedata){
-                                               VECCOPY(ved,state.co);
-                                               ved+=3;
+                               if(drawn) {
+                                       /* additional things to draw for each particle  */
+                                       /* (velocity, size and number)                                  */
+                                       if(pdd.vedata){
+                                               VECCOPY(pdd.ved,state.co);
+                                               pdd.ved+=3;
                                                VECCOPY(vel,state.vel);
                                                VecMulf(vel,timestep);
-                                               VECADD(ved,state.co,vel);
-                                               ved+=3;
+                                               VECADD(pdd.ved,state.co,vel);
+                                               pdd.ved+=3;
+
+                                               totve++;
                                        }
 
                                        if(part->draw & PART_DRAW_SIZE){
@@ -3325,15 +3527,21 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
                                                setlinestyle(0);
                                        }
 
-                                       totpoint++;
-                               }
-                               if(next_pa)
-                                               continue;
-                               if(part->draw&PART_DRAW_NUM && !(G.f & G_RENDER_SHADOW)){
-                                       /* in path drawing state.co is the end point */
-                                       glRasterPos3f(state.co[0],  state.co[1],  state.co[2]);
-                                       sprintf(val," %i",a);
-                                       BMF_DrawString(G.font, val);
+                                       if((part->draw&PART_DRAW_NUM || part->draw&PART_DRAW_HEALTH) && !(G.f & G_RENDER_SHADOW)){
+                                               val[0]= '\0';
+                                               
+                                               if(part->draw&PART_DRAW_NUM)
+                                                       sprintf(val, " %i", a);
+
+                                               if(part->draw&PART_DRAW_NUM && part->draw&PART_DRAW_HEALTH)
+                                                       sprintf(val, "%s:", val);
+
+                                               if(part->draw&PART_DRAW_HEALTH && a < totpart && part->phystype==PART_PHYS_BOIDS)
+                                                       sprintf(val, "%s %.2f", val, pa_health);
+
+                                               /* in path drawing state.co is the end point */
+                                               view3d_particle_text_draw_add(state.co[0],  state.co[1],  state.co[2], val, 0);
+                                       }
                                }
                        }
                }
@@ -3342,54 +3550,42 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
                glGetIntegerv(GL_POLYGON_MODE, polygonmode);
                glDisableClientState(GL_NORMAL_ARRAY);
 
-               if(draw_as != PART_DRAW_CIRC){
-                       if(draw_as==PART_DRAW_PATH){
-                               ParticleCacheKey **cache, *path;
-                               float *cd2=0,*cdata2=0;
-
-                               glEnableClientState(GL_VERTEX_ARRAY);
+               if(draw_as==PART_DRAW_PATH){
+                       ParticleCacheKey **cache, *path;
+                       float *cd2=0,*cdata2=0;
 
-                               if(dt > OB_WIRE) {
-                                       glEnableClientState(GL_NORMAL_ARRAY);
-
-                                       if(part->draw&PART_DRAW_MAT_COL)
-                                               glEnableClientState(GL_COLOR_ARRAY);
+                       glEnableClientState(GL_VERTEX_ARRAY);
 
-                                       glEnable(GL_LIGHTING);
-                                       glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
-                                       glEnable(GL_COLOR_MATERIAL);
-                               }
-                               else {
-                                       glDisableClientState(GL_NORMAL_ARRAY);
+                       /* setup gl flags */
+                       if(ob_dt > OB_WIRE) {
+                               glEnableClientState(GL_NORMAL_ARRAY);
 
-                                       glDisable(GL_COLOR_MATERIAL);
-                                       glDisable(GL_LIGHTING);
-                                       UI_ThemeColor(TH_WIRE);
-                               }
+                               if(part->draw&PART_DRAW_MAT_COL)
+                                       glEnableClientState(GL_COLOR_ARRAY);
 
-                               if(totchild && (part->draw&PART_DRAW_PARENT)==0)
-                                       totpart=0;
+                               glEnable(GL_LIGHTING);
+                               glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
+                               glEnable(GL_COLOR_MATERIAL);
+                       }
+                       else {
+                               glDisableClientState(GL_NORMAL_ARRAY);
 
-                               cache=psys->pathcache;
-                               for(a=0, pa=psys->particles; a<totpart; a++, pa++){
-                                       path=cache[a];
-                                       glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co);
+                               glDisable(GL_COLOR_MATERIAL);
+                               glDisable(GL_LIGHTING);
+                               UI_ThemeColor(TH_WIRE);
+                       }
 
-                                       if(dt > OB_WIRE) {
-                                               glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel);
-                                               if(part->draw&PART_DRAW_MAT_COL)
-                                                       glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col);
-                                       }
+                       if(totchild && (part->draw&PART_DRAW_PARENT)==0)
+                               totpart=0;
 
-                                       glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1);
-                               }
-                               
-                               cache=psys->childcache;
-                               for(a=0; a<totchild; a++){
-                                       path=cache[a];
+                       /* draw actual/parent particles */
+                       cache=psys->pathcache;
+                       for(a=0, pa=psys->particles; a<totpart; a++, pa++){
+                               path=cache[a];
+                               if(path->steps > 0) {
                                        glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co);
 
-                                       if(dt > OB_WIRE) {
+                                       if(ob_dt > OB_WIRE) {
                                                glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel);
                                                if(part->draw&PART_DRAW_MAT_COL)
                                                        glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col);
@@ -3397,76 +3593,93 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
 
                                        glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1);
                                }
-
-                               if(dt > OB_WIRE) {
+                       }
+                       
+                       /* draw child particles */
+                       cache=psys->childcache;
+                       for(a=0; a<totchild; a++){
+                               path=cache[a];
+                               glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co);
+
+                               if(ob_dt > OB_WIRE) {
+                                       glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel);
                                        if(part->draw&PART_DRAW_MAT_COL)
-                                               glDisable(GL_COLOR_ARRAY);
-                                       glDisable(GL_COLOR_MATERIAL);
+                                               glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col);
                                }
 
-                               if(cdata2)
-                                       MEM_freeN(cdata2);
-                               cd2=cdata2=0;
+                               glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1);
+                       }
 
-                               glLineWidth(1.0f);
 
-                               /* draw particle edit mode key points*/
+                       /* restore & clean up */
+                       if(ob_dt > OB_WIRE) {
+                               if(part->draw&PART_DRAW_MAT_COL)
+                                       glDisable(GL_COLOR_ARRAY);
+                               glDisable(GL_COLOR_MATERIAL);
                        }
 
-                       if(draw_as!=PART_DRAW_PATH){
-                               glDisableClientState(GL_COLOR_ARRAY);
+                       if(cdata2)
+                               MEM_freeN(cdata2);
+                       cd2=cdata2=0;
 
-                               if(vdata){
-                                       glEnableClientState(GL_VERTEX_ARRAY);
-                                       glVertexPointer(3, GL_FLOAT, 0, vdata);
-                               }
-                               else
-                                       glDisableClientState(GL_VERTEX_ARRAY);
+                       glLineWidth(1.0f);
+               }
+               else if(draw_as!=PART_DRAW_CIRC){
+                       glDisableClientState(GL_COLOR_ARRAY);
 
-                               if(ndata && dt>OB_WIRE){
-                                       glEnableClientState(GL_NORMAL_ARRAY);
-                                       glNormalPointer(GL_FLOAT, 0, ndata);
-                                       glEnable(GL_LIGHTING);
-                               }
-                               else{
-                                       glDisableClientState(GL_NORMAL_ARRAY);
-                                       glDisable(GL_LIGHTING);
-                               }
+                       /* setup created data arrays */
+                       if(pdd.vdata){
+                               glEnableClientState(GL_VERTEX_ARRAY);
+                               glVertexPointer(3, GL_FLOAT, 0, pdd.vdata);
+                       }
+                       else
+                               glDisableClientState(GL_VERTEX_ARRAY);
 
-                               if(cdata){
-                                       glEnableClientState(GL_COLOR_ARRAY);
-                                       glColorPointer(3, GL_FLOAT, 0, cdata);
-                               }
+                       /* billboards are drawn this way */
+                       if(pdd.ndata && ob_dt>OB_WIRE){
+                               glEnableClientState(GL_NORMAL_ARRAY);
+                               glNormalPointer(GL_FLOAT, 0, pdd.ndata);
+                               glEnable(GL_LIGHTING);
+                       }
+                       else{
+                               glDisableClientState(GL_NORMAL_ARRAY);
+                               glDisable(GL_LIGHTING);
+                       }
 
-                               switch(draw_as){
-                                       case PART_DRAW_AXIS:
-                                       case PART_DRAW_CROSS:
-                                               glDrawArrays(GL_LINES, 0, 6*totpoint);
-                                               break;
-                                       case PART_DRAW_LINE:
-                                               glDrawArrays(GL_LINES, 0, 2*totpoint);
-                                               break;
-                                       case PART_DRAW_BB:
-                                               if(dt<=OB_WIRE)
-                                                       glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
-
-                                               glDrawArrays(GL_QUADS, 0, 4*totpoint);
-                                               break;
-                                       default:
-                                               glDrawArrays(GL_POINTS, 0, totpoint);
-                                               break;
-                               }
+                       if(pdd.cdata){
+                               glEnableClientState(GL_COLOR_ARRAY);
+                               glColorPointer(3, GL_FLOAT, 0, pdd.cdata);
                        }
 
+                       /* draw created data arrays */
+                       switch(draw_as){
+                               case PART_DRAW_AXIS:
+                               case PART_DRAW_CROSS:
+                                       glDrawArrays(GL_LINES, 0, 6*totpoint);
+                                       break;
+                               case PART_DRAW_LINE:
+                                       glDrawArrays(GL_LINES, 0, 2*totpoint);
+                                       break;
+                               case PART_DRAW_BB:
+                                       if(ob_dt<=OB_WIRE)
+                                               glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
+
+                                       glDrawArrays(GL_QUADS, 0, 4*totpoint);
+                                       break;
+                               default:
+                                       glDrawArrays(GL_POINTS, 0, totpoint);
+                                       break;
+                       }
                }
-               if(vedata){
+
+               if(pdd.vedata){
                        glDisableClientState(GL_COLOR_ARRAY);
                        cpack(0xC0C0C0);
                        
                        glEnableClientState(GL_VERTEX_ARRAY);
-                       glVertexPointer(3, GL_FLOAT, 0, vedata);
+                       glVertexPointer(3, GL_FLOAT, 0, pdd.vedata);
                        
-                       glDrawArrays(GL_LINES, 0, 2*totpoint);
+                       glDrawArrays(GL_LINES, 0, 2*totve);
                }
 
                glPolygonMode(GL_FRONT, polygonmode[0]);
@@ -3481,14 +3694,14 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
 
        if(states)
                MEM_freeN(states);
-       if(vdata)
-               MEM_freeN(vdata);
-       if(vedata)
-               MEM_freeN(vedata);
-       if(cdata)
-               MEM_freeN(cdata);
-       if(ndata)
-               MEM_freeN(ndata);
+       if(pdd.vdata)
+               MEM_freeN(pdd.vdata);
+       if(pdd.vedata)
+               MEM_freeN(pdd.vedata);
+       if(pdd.cdata)
+               MEM_freeN(pdd.cdata);
+       if(pdd.ndata)
+               MEM_freeN(pdd.ndata);
 
        psys->flag &= ~PSYS_DRAWING;
 
@@ -3497,44 +3710,36 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
                psys->lattice= NULL;
        }
 
-       wmLoadMatrix(rv3d->viewmat);
-       wmMultMatrix(ob->obmat);        // bring back local matrix for dtx
+       if( (base->flag & OB_FROMDUPLI) && (ob->flag & OB_FROMGROUP) )
+               wmLoadMatrix(rv3d->viewmat);
 }
 
-static void draw_particle_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, ParticleSystem *psys, int dt)
+static void draw_ptcache_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, PTCacheEdit *edit, int dt)
 {
-       ParticleEdit *edit = psys->edit;
-       ParticleData *pa;
-       ParticleCacheKey **path;
-       ParticleEditKey *key;
+       ParticleCacheKey **cache, *path, *pkey;
+       PTCacheEditPoint *point;
+       PTCacheEditKey *key;
        ParticleEditSettings *pset = PE_settings(scene);
-       int i, k, totpart = psys->totpart, totchild=0, timed = pset->draw_timed;
+       int i, k, totpoint = edit->totpoint, timed = pset->flag & PE_FADE_TIME ? pset->fade_frames : 0;
+       int steps;
        char nosel[4], sel[4];
        float sel_col[3];
        float nosel_col[3];
-       char val[32];
+       float *pathcol = NULL, *pcol;
 
        /* create path and child path cache if it doesn't exist already */
-       if(psys->pathcache==0){
-               PE_hide_keys_time(scene, psys,CFRA);
-               psys_cache_paths(scene, ob, psys, CFRA,0);
-       }
-       if(psys->pathcache==0)
+       if(edit->pathcache==0)
+               psys_cache_edit_paths(scene, ob, edit, CFRA);
+
+       if(edit->pathcache==0)
                return;
 
-       if(pset->flag & PE_SHOW_CHILD && psys->part->draw_as == PART_DRAW_PATH) {
-               if(psys->childcache==0)
-                       psys_cache_child_paths(scene, ob, psys, CFRA, 0);
-       }
-       else if(!(pset->flag & PE_SHOW_CHILD) && psys->childcache)
-               free_child_path_cache(psys);
+       PE_hide_keys_time(scene, edit, CFRA);
 
        /* opengl setup */
        if((v3d->flag & V3D_ZBUF_SELECT)==0)
                glDisable(GL_DEPTH_TEST);
 
-       wmLoadMatrix(rv3d->viewmat);
-
        /* get selection theme colors */
        UI_GetThemeColor3ubv(TH_VERTEX_SELECT, sel);
        UI_GetThemeColor3ubv(TH_VERTEX, nosel);
@@ -3545,131 +3750,115 @@ static void draw_particle_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Ob
        nosel_col[1]=(float)nosel[1]/255.0f;
        nosel_col[2]=(float)nosel[2]/255.0f;
 
-       if(psys->childcache)
-               totchild = psys->totchildcache;
-
        /* draw paths */
-       if(timed)
+       if(timed) {
                glEnable(GL_BLEND);
+               steps = (*edit->pathcache)->steps + 1;
+               pathcol = MEM_callocN(steps*4*sizeof(float), "particle path color data");
+       }
 
        glEnableClientState(GL_VERTEX_ARRAY);
+       glDisableClientState(GL_NORMAL_ARRAY);
+       glEnableClientState(GL_COLOR_ARRAY);
 
-       if(dt > OB_WIRE) {
-               /* solid shaded with lighting */
-               glEnableClientState(GL_NORMAL_ARRAY);
-               glEnableClientState(GL_COLOR_ARRAY);
+       glEnable(GL_COLOR_MATERIAL);
+       glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
 
-               glEnable(GL_COLOR_MATERIAL);
-               glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
-       }
-       else {
-               /* flat wire color */
-               glDisableClientState(GL_NORMAL_ARRAY);
-               glDisable(GL_LIGHTING);
-               UI_ThemeColor(TH_WIRE);
-       }
+       cache=edit->pathcache;
+       for(i=0; i<totpoint; i++){
+               path = cache[i];
+               glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co);
 
-       /* only draw child paths with lighting */
-       if(dt > OB_WIRE)
-               glEnable(GL_LIGHTING);
-
-       if(psys->part->draw_as == PART_DRAW_PATH) {
-               for(i=0, path=psys->childcache; i<totchild; i++,path++){
-                       glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->co);
-                       if(dt > OB_WIRE) {
-                               glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), (*path)->vel);
-                               glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->col);
+               if(timed) {
+                       for(k=0, pcol=pathcol, pkey=path; k<steps; k++, pkey++, pcol+=4){
+                               VECCOPY(pcol, pkey->col);
+                               pcol[3] = 1.0f - fabs((float)CFRA - pkey->time)/(float)pset->fade_frames;
                        }
 
-                       glDrawArrays(GL_LINE_STRIP, 0, (int)(*path)->steps + 1);
+                       glColorPointer(4, GL_FLOAT, 4*sizeof(float), pathcol);
                }
-       }
-
-       if(dt > OB_WIRE)
-               glDisable(GL_LIGHTING);
+               else
+                       glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col);
 
-       if(pset->brushtype == PE_BRUSH_WEIGHT) {
-               glLineWidth(2.0f);
-               glEnableClientState(GL_COLOR_ARRAY);
-               glDisable(GL_LIGHTING);
+               glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1);
        }
 
-       /* draw parents last without lighting */
-       for(i=0, pa=psys->particles, path = psys->pathcache; i<totpart; i++, pa++, path++){
-               glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->co);
-               if(dt > OB_WIRE)
-                       glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), (*path)->vel);
-               if(dt > OB_WIRE || pset->brushtype == PE_BRUSH_WEIGHT)
-                       glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->col);
+       if(pathcol) { MEM_freeN(pathcol); pathcol = pcol = NULL; }
 
-               glDrawArrays(GL_LINE_STRIP, 0, (int)(*path)->steps + 1);
-       }
 
        /* draw edit vertices */
-       if(scene->selectmode!=SCE_SELECT_PATH){
-               glDisableClientState(GL_NORMAL_ARRAY);
-               glEnableClientState(GL_COLOR_ARRAY);
-               glDisable(GL_LIGHTING);
+       if(pset->selectmode!=SCE_SELECT_PATH){
                glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
 
-               if(scene->selectmode==SCE_SELECT_POINT){
+               if(pset->selectmode==SCE_SELECT_POINT){
+                       float *pd=0,*pdata=0;
                        float *cd=0,*cdata=0;
-                       cd=cdata=MEM_callocN(edit->totkeys*(timed?4:3)*sizeof(float), "particle edit color data");
+                       int totkeys = 0;
+
+                       for (i=0, point=edit->points; i<totpoint; i++, point++)
+                               if(!(point->flag & PEP_HIDE))
+                                       totkeys += point->totkey;
+
+                       if(!(edit->points->keys->flag & PEK_USE_WCO))
+                               pd=pdata=MEM_callocN(totkeys*3*sizeof(float), "particle edit point data");
+                       cd=cdata=MEM_callocN(totkeys*(timed?4:3)*sizeof(float), "particle edit color data");
+
+                       for(i=0, point=edit->points; i<totpoint; i++, point++){
+                               if(point->flag & PEP_HIDE)
+                                       continue;
+
+                               for(k=0, key=point->keys; k<point->totkey; k++, key++){
+                                       if(pd) {
+                                               VECCOPY(pd, key->co);
+                                               pd += 3;
+                                       }
 
-                       for(i=0, pa=psys->particles; i<totpart; i++, pa++){
-                               for(k=0, key=edit->keys[i]; k<pa->totkey; k++, key++){
                                        if(key->flag&PEK_SELECT){
                                                VECCOPY(cd,sel_col);
                                        }
                                        else{
                                                VECCOPY(cd,nosel_col);
                                        }
+
                                        if(timed)
-                                               *(cd+3) = (key->flag&PEK_HIDE)?0.0f:1.0f;
+                                               *(cd+3) = 1.0f - fabs((float)CFRA - *key->time)/(float)pset->fade_frames;
+
                                        cd += (timed?4:3);
                                }
                        }
                        cd=cdata;
-                       for(i=0, pa=psys->particles; i<totpart; i++, pa++){
-                               if((pa->flag & PARS_HIDE)==0){
-                                       glVertexPointer(3, GL_FLOAT, sizeof(ParticleEditKey), edit->keys[i]->world_co);
-                                       glColorPointer((timed?4:3), GL_FLOAT, (timed?4:3)*sizeof(float), cd);
-                                       glDrawArrays(GL_POINTS, 0, pa->totkey);
-                               }
-                               cd += (timed?4:3) * pa->totkey;
+                       pd=pdata;
+                       for(i=0, point=edit->points; i<totpoint; i++, point++){
+                               if(point->flag & PEP_HIDE)
+                                       continue;
 
-                               if((pset->flag&PE_SHOW_TIME) && (pa->flag&PARS_HIDE)==0 && !(G.f & G_RENDER_SHADOW)){
-                                       for(k=0, key=edit->keys[i]+k; k<pa->totkey; k++, key++){
-                                               if(key->flag & PEK_HIDE) continue;
+                               if(point->keys->flag & PEK_USE_WCO)
+                                       glVertexPointer(3, GL_FLOAT, sizeof(PTCacheEditKey), point->keys->world_co);
+                               else
+                                       glVertexPointer(3, GL_FLOAT, 3*sizeof(float), pd);
 
-                                               glRasterPos3fv(key->world_co);
-                                               sprintf(val," %.1f",*key->time);
-                                               BMF_DrawString(G.font, val);
-                                       }
-                               }
+                               glColorPointer((timed?4:3), GL_FLOAT, (timed?4:3)*sizeof(float), cd);
+
+                               glDrawArrays(GL_POINTS, 0, point->totkey);
+
+                               pd += pd ? 3 * point->totkey : 0;
+                               cd += (timed?4:3) * point->totkey;
                        }
-                       if(cdata)
-                               MEM_freeN(cdata);
-                       cd=cdata=0;
-               }
-               else if(scene->selectmode == SCE_SELECT_END){
-                       for(i=0, pa=psys->particles; i<totpart; i++, pa++){
-                               if((pa->flag & PARS_HIDE)==0){
-                                       key = edit->keys[i] + pa->totkey - 1;
+                       if(pdata) { MEM_freeN(pdata); pd=pdata=0; }
+                       if(cdata) { MEM_freeN(cdata); cd=cdata=0; }
+               }
+               else if(pset->selectmode == SCE_SELECT_END){
+                       for(i=0, point=edit->points; i<totpoint; i++, point++){
+                               if((point->flag & PEP_HIDE)==0){
+                                       key = point->keys + point->totkey - 1;
                                        if(key->flag & PEK_SELECT)
                                                glColor3fv(sel_col);
                                        else
                                                glColor3fv(nosel_col);
                                        /* has to be like this.. otherwise selection won't work, have try glArrayElement later..*/
                                        glBegin(GL_POINTS);
-                                       glVertex3fv(key->world_co);
+                                       glVertex3fv(key->flag & PEK_USE_WCO ? key->world_co : key->co);
                                        glEnd();
-
-                                       if((pset->flag & PE_SHOW_TIME) && !(G.f & G_RENDER_SHADOW)){
-                                               glRasterPos3fv(key->world_co);
-                                               sprintf(val," %.1f",*key->time);
-                                               BMF_DrawString(G.font, val);
-                                       }
                                }
                        }
                }
@@ -3683,25 +3872,24 @@ static void draw_particle_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Ob
        glEnable(GL_DEPTH_TEST);
        glLineWidth(1.0f);
 
-       wmMultMatrix(ob->obmat);        // bring back local matrix for dtx
        glPointSize(1.0);
 }
 
 unsigned int nurbcol[8]= {
        0, 0x9090, 0x409030, 0x603080, 0, 0x40fff0, 0x40c033, 0xA090F0 };
 
-static void tekenhandlesN(Nurb *nu, short sel)
+static void tekenhandlesN(Nurb *nu, short sel, short hide_handles)
 {
        BezTriple *bezt;
        float *fp;
        unsigned int *col;
        int a;
        
-       if(nu->hide || (G.f & G_HIDDENHANDLES)) return;
+       if(nu->hide || hide_handles) return;
        
        glBegin(GL_LINES); 
        
-       if( (nu->type & 7)==1) {
+       if(nu->type == CU_BEZIER) {
                if(sel) col= nurbcol+4;
                else col= nurbcol;
 
@@ -3741,7 +3929,7 @@ static void tekenhandlesN(Nurb *nu, short sel)
        glEnd();
 }
 
-static void tekenvertsN(Nurb *nu, short sel)
+static void tekenvertsN(Nurb *nu, short sel, short hide_handles)
 {
        BezTriple *bezt;
        BPoint *bp;
@@ -3758,13 +3946,13 @@ static void tekenvertsN(Nurb *nu, short sel)
        
        bglBegin(GL_POINTS);
        
-       if((nu->type & 7)==1) {
+       if(nu->type == CU_BEZIER) {
 
                bezt= nu->bezt;
                a= nu->pntsu;
                while(a--) {
                        if(bezt->hide==0) {
-                               if (G.f & G_HIDDENHANDLES) {
+                               if (hide_handles) {
                                        if((bezt->f2 & SELECT)==sel) bglVertex3fv(bezt->vec[1]);
                                } else {
                                        if((bezt->f1 & SELECT)==sel) bglVertex3fv(bezt->vec[0]);
@@ -3799,7 +3987,7 @@ static void draw_editnurb(Object *ob, Nurb *nurb, int sel)
        nu= nurb;
        while(nu) {
                if(nu->hide==0) {
-                       switch(nu->type & 7) {
+                       switch(nu->type) {
                        case CU_POLY:
                                cpack(nurbcol[3]);
                                bp= nu->bp;
@@ -3891,10 +4079,12 @@ 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)
 {
+       ToolSettings *ts= scene->toolsettings;
        Object *ob= base->object;
        Curve *cu = ob->data;
        Nurb *nu;
        BevList *bl;
+       short hide_handles = (cu->drawflag & CU_HIDE_HANDLES);
 
 // XXX retopo_matrix_update(v3d);
 
@@ -3906,23 +4096,25 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
        
        /* first non-selected handles */
        for(nu=nurb; nu; nu=nu->next) {
-               if((nu->type & 7)==CU_BEZIER) {
-                       tekenhandlesN(nu, 0);
+               if(nu->type == CU_BEZIER) {
+                       tekenhandlesN(nu, 0, hide_handles);
                }
        }
        draw_editnurb(ob, nurb, 0);
        draw_editnurb(ob, nurb, 1);
        /* selected handles */
        for(nu=nurb; nu; nu=nu->next) {
-               if((nu->type & 7)==1) tekenhandlesN(nu, 1);
-               tekenvertsN(nu, 0);
+               if(nu->type == CU_BEZIER && (cu->drawflag & CU_HIDE_HANDLES)==0)
+                       tekenhandlesN(nu, 1, hide_handles);
+               tekenvertsN(nu, 0, hide_handles);
        }
        
        if(v3d->zbuf) glEnable(GL_DEPTH_TEST);
 
        /*      direction vectors for 3d curve paths
                when at its lowest, dont render normals */
-       if(cu->flag & CU_3D && scene->editbutsize > 0.0015) {
+       if(cu->flag & CU_3D && ts->normalsize > 0.0015 && (cu->drawflag & CU_HIDE_NORMALS)==0) {
+
                UI_ThemeColor(TH_WIRE);
                for (bl=cu->bev.first,nu=nurb; nu && bl; bl=bl->next,nu=nu->next) {
                        BevPoint *bevp= (BevPoint *)(bl+1);             
@@ -3930,7 +4122,7 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
                        int skip= nu->resolu/16;
                        
                        while (nr-->0) { /* accounts for empty bevel lists */
-                               float fac= bevp->radius * scene->editbutsize;
+                               float fac= bevp->radius * ts->normalsize;
                                float ox,oy,oz; // Offset perpendicular to the curve
                                float dx,dy,dz; // Delta along the curve
                                
@@ -3957,7 +4149,7 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
        if(v3d->zbuf) glDisable(GL_DEPTH_TEST);
        
        for(nu=nurb; nu; nu=nu->next) {
-               tekenvertsN(nu, 1);
+               tekenvertsN(nu, 1, hide_handles);
        }
        
        if(v3d->zbuf) glEnable(GL_DEPTH_TEST); 
@@ -4206,7 +4398,7 @@ static int drawmball(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
        if(ml==NULL) return 1;
        
        /* in case solid draw, reset wire colors */
-       if(mb->editelems && (ob->flag & SELECT)) {
+       if(ob->flag & SELECT) {
                if(ob==OBACT) UI_ThemeColor(TH_ACTIVE);
                else UI_ThemeColor(TH_SELECT);
        }
@@ -4583,7 +4775,7 @@ static void drawSolidSelect(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base
                        drawDispListwire(&ob->disp);
        }
        else if(ob->type==OB_ARMATURE) {
-               if(!(ob->flag & OB_POSEMODE))
+               if(!(ob->mode & OB_MODE_POSE))
                        draw_armature(scene, v3d, rv3d, base, OB_WIRE, 0);
        }
 
@@ -4681,25 +4873,24 @@ void drawRBpivot(bRigidBodyJointConstraint *data)
        glLineWidth (4.0f);
        setlinestyle(2);
        for (axis=0; axis<3; axis++) {
-                       float dir[3] = {0,0,0};
-                       float v[3]= {data->pivX, data->pivY, data->pivZ};
+               float dir[3] = {0,0,0};
+               float v[3]= {data->pivX, data->pivY, data->pivZ};
 
-                       dir[axis] = 1.f;
-                       glBegin(GL_LINES);
-                       Mat4MulVecfl(mat,dir);
-                       v[0] += dir[0];
-                       v[1] += dir[1];
-                       v[2] += dir[2];
-                       glVertex3fv(v1);
-                       glVertex3fv(v);                 
-                       glEnd();
-                       glRasterPos3fv(v);
-                       if (axis==0)
-                               BMF_DrawString(G.font, "px");
-                       else if (axis==1)
-                               BMF_DrawString(G.font, "py");
-                       else
-                               BMF_DrawString(G.font, "pz");                   
+               dir[axis] = 1.f;
+               glBegin(GL_LINES);
+               Mat4MulVecfl(mat,dir);
+               v[0] += dir[0];
+               v[1] += dir[1];
+               v[2] += dir[2];
+               glVertex3fv(v1);
+               glVertex3fv(v);                 
+               glEnd();
+               if (axis==0)
+                       view3d_object_text_draw_add(v[0], v[1], v[2], "px", 0);
+               else if (axis==1)
+                       view3d_object_text_draw_add(v[0], v[1], v[2], "py", 0);
+               else
+                       view3d_object_text_draw_add(v[0], v[1], v[2], "pz", 0);
        }
        glLineWidth (1.0f);
        setlinestyle(0);
@@ -4709,6 +4900,7 @@ void drawRBpivot(bRigidBodyJointConstraint *data)
 void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
 {
        static int warning_recursive= 0;
+       ModifierData *md = NULL;
        Object *ob;
        Curve *cu;
        RegionView3D *rv3d= ar->regiondata;
@@ -4732,9 +4924,9 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
        /* xray delay? */
        if((flag & DRAW_PICKING)==0 && (base->flag & OB_FROMDUPLI)==0) {
                /* don't do xray in particle mode, need the z-buffer */
-               if(!(G.f & G_PARTICLEEDIT)) {
+               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)) {
+                       if(!v3d->xray && !v3d->transp && (ob->dtx & OB_DRAWXRAY) && !(ob->dtx & OB_DRAWTRANSP)) {
                                add_view3d_after(v3d, base, V3D_XRAY, flag);
                                return;
                        }
@@ -4819,8 +5011,15 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
 
        /* patch? children objects with a timeoffs change the parents. How to solve! */
        /* if( ((int)ob->ctime) != F_(scene->r.cfra)) where_is_object(scene, ob); */
+       
+       /* draw paths... */
+       // TODO...
 
+       /* multiply view with object matrix */
        wmMultMatrix(ob->obmat);
+       /* local viewmat and persmat, to calculate projections */
+       wmGetMatrix(rv3d->viewmatob);
+       wmGetSingleMatrix(rv3d->persmatob);
 
        /* which wire color */
        if((flag & DRAW_CONSTCOLOR) == 0) {
@@ -4874,7 +5073,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
        dtx= 0;
 
        /* faceselect exception: also draw solid when dt==wire, except in editmode */
-       if(ob==OBACT && (G.f & (G_VERTEXPAINT+G_TEXTUREPAINT+G_WEIGHTPAINT))) {
+       if(ob==OBACT && (ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT))) {
                if(ob->type==OB_MESH) {
 
                        if(ob==scene->obedit);
@@ -5080,19 +5279,95 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
          ) {
                ParticleSystem *psys;
                if(col || (ob->flag & SELECT)) cpack(0xFFFFFF); /* for visibility, also while wpaint */
-               glDepthMask(GL_FALSE);
+               //glDepthMask(GL_FALSE);
+
+               wmLoadMatrix(rv3d->viewmat);
                
                for(psys=ob->particlesystem.first; psys; psys=psys->next)
                        draw_new_particle_system(scene, v3d, rv3d, base, psys, dt);
                
-               if(G.f & G_PARTICLEEDIT && ob==OBACT) {
-                       psys= PE_get_current(ob);
-                       if(psys && !scene->obedit && psys_in_edit_mode(scene, psys))
-                               draw_particle_edit(scene, v3d, rv3d, ob, psys, dt);
-               }
-               glDepthMask(GL_TRUE); 
+               view3d_particle_text_draw(v3d, ar);
+
+               wmMultMatrix(ob->obmat);
+               
+               //glDepthMask(GL_TRUE);
                if(col) cpack(col);
        }
+       
+       if(             (warning_recursive==0) &&
+                       (flag & DRAW_PICKING)==0 &&
+                       (!scene->obedit)        
+         ) {
+
+               if(ob->mode & OB_MODE_PARTICLE_EDIT && ob==OBACT) {
+                       PTCacheEdit *edit = PE_get_current(scene, ob);
+                       if(edit) {
+                               wmLoadMatrix(rv3d->viewmat);
+                               draw_ptcache_edit(scene, v3d, rv3d, ob, edit, dt);
+                               wmMultMatrix(ob->obmat);
+                       }
+               }
+       }
+
+       /* draw code for smoke */
+       if((md = modifiers_findByType(ob, eModifierType_Smoke)))
+       {
+               SmokeModifierData *smd = (SmokeModifierData *)md;
+
+               // draw collision objects
+               if((smd->type & MOD_SMOKE_TYPE_COLL) && smd->coll)
+               {
+                       /*SmokeCollSettings *scs = smd->coll;
+                       if(scs->points)
+                       {
+                               size_t i;
+
+                               wmLoadMatrix(rv3d->viewmat);
+
+                               if(col || (ob->flag & SELECT)) cpack(0xFFFFFF); 
+                               glDepthMask(GL_FALSE);
+                               glEnable(GL_BLEND);
+                               
+
+                               // glPointSize(3.0);
+                               bglBegin(GL_POINTS);
+
+                               for(i = 0; i < scs->numpoints; i++)
+                               {
+                                       bglVertex3fv(&scs->points[3*i]);
+                               }
+
+                               bglEnd();
+                               glPointSize(1.0);
+
+                               wmMultMatrix(ob->obmat);
+                               glDisable(GL_BLEND);
+                               glDepthMask(GL_TRUE);
+                               if(col) cpack(col);
+                               
+                       }
+                       */
+               }
+
+               // only draw domains
+               if(smd->domain && smd->domain->fluid)
+               {
+                       if(!smd->domain->wt || !(smd->domain->viewsettings & MOD_SMOKE_VIEW_SHOWBIG))
+                       {
+                               smd->domain->tex = NULL;
+                               GPU_create_smoke(smd, 0);
+                               draw_volume(scene, ar, v3d, base, smd->domain->tex, smd->domain->res, smd->domain->dx, smd->domain->tex_shadow);
+                               GPU_free_smoke(smd);
+                       }
+                       else if(smd->domain->wt || (smd->domain->viewsettings & MOD_SMOKE_VIEW_SHOWBIG))
+                       {
+                               smd->domain->tex = NULL;
+                               GPU_create_smoke(smd, 1);
+                               draw_volume(scene, ar, v3d, base, smd->domain->tex, smd->domain->res_wt, smd->domain->dx_wt, smd->domain->tex_shadow);
+                               GPU_free_smoke(smd);
+                       }
+               }
+       }
 
        {
                bConstraint *con;
@@ -5118,12 +5393,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                        /* patch for several 3d cards (IBM mostly) that crash on glSelect with text drawing */
                        /* but, we also dont draw names for sets or duplicators */
                        if(flag == 0) {
-                               if(v3d->zbuf) glDisable(GL_DEPTH_TEST);
-                               glRasterPos3f(0.0,  0.0,  0.0);
-
-                               BMF_DrawString(G.font, " ");
-                               BMF_DrawString(G.font, ob->id.name+2);
-                               if(v3d->zbuf) glEnable(GL_DEPTH_TEST);
+                               view3d_object_text_draw_add(0.0f, 0.0f, 0.0f, ob->id.name+2, 10);
                        }
                }
                /*if(dtx & OB_DRAWIMAGE) drawDispListwire(&ob->disp);*/
@@ -5144,6 +5414,9 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                        setlinestyle(0);
                }
        }
+       
+       /* return warning, this is cached text draw */
+       view3d_object_text_draw(v3d, ar);
 
        wmLoadMatrix(rv3d->viewmat);
 
@@ -5154,7 +5427,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
        if(G.f & G_RENDER_SHADOW) return;
 
        /* object centers, need to be drawn in viewmat space for speed, but OK for picking select */
-       if(ob!=OBACT || (G.f & (G_VERTEXPAINT|G_TEXTUREPAINT|G_WEIGHTPAINT))==0) {
+       if(ob!=OBACT || !(ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT))) {
                int do_draw_center= -1; /* defines below are zero or positive... */
 
                if((scene->basact)==base) 
@@ -5203,7 +5476,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                        char col[4], col2[4];
                        
                        UI_GetThemeColor3ubv(TH_GRID, col);
-                       make_axis_color(col, col2, 'z');
+                       UI_make_axis_color(col, col2, 'z');
                        glColor3ubv((GLubyte *)col2);
                        
                        cob= constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
@@ -5351,6 +5624,7 @@ static void bbs_mesh_solid(Scene *scene, View3D *v3d, Object *ob)
 
 void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
 {
+       ToolSettings *ts= scene->toolsettings;
 
        wmMultMatrix(ob->obmat);
 
@@ -5360,15 +5634,16 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
        switch( ob->type) {
        case OB_MESH:
        {
-               Mesh *me= ob->data;
-               EditMesh *em= me->edit_mesh;
-               if(em) {
+               if(ob == scene->obedit) {
+                       Mesh *me= ob->data;
+                       EditMesh *em= me->edit_mesh;
+
                        DerivedMesh *dm = editmesh_get_derived_cage(scene, ob, em, CD_MASK_BAREMESH);
 
                        EM_init_index_arrays(em, 1, 1, 1);
 
-                       bbs_mesh_solid_EM(scene, v3d, ob, dm, scene->selectmode & SCE_SELECT_FACE);
-                       if(scene->selectmode & SCE_SELECT_FACE)
+                       bbs_mesh_solid_EM(scene, v3d, ob, dm, ts->selectmode & SCE_SELECT_FACE);
+                       if(ts->selectmode & SCE_SELECT_FACE)
                                em_solidoffs = 1+em->totface;
                        else
                                em_solidoffs= 1;
@@ -5380,7 +5655,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
                        em_wireoffs= em_solidoffs + em->totedge;
                        
                        // we draw verts if vert select mode or if in transform (for snap).
-                       if(scene->selectmode & SCE_SELECT_VERTEX || G.moving & G_TRANSFORM_EDIT) {
+                       if(ts->selectmode & SCE_SELECT_VERTEX || G.moving & G_TRANSFORM_EDIT) {
                                bbs_mesh_verts(dm, em_wireoffs);
                                em_vertoffs= em_wireoffs + em->totvert;
                        }
@@ -5415,7 +5690,7 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r
        DerivedMesh *dm=NULL, *edm=NULL;
        int glsl;
        
-       if(me->edit_mesh)
+       if(ob == scene->obedit)
                edm= editmesh_get_derived_base(ob, me->edit_mesh);
        else 
                dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
@@ -5432,7 +5707,7 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r
 
                if(dm) {
                        glsl = draw_glsl_material(scene, ob, v3d, dt);
-                       GPU_set_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
+                       GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
                }
                else {
                        glEnable(GL_COLOR_MATERIAL);
@@ -5446,7 +5721,7 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r
                
                if(dm) {
                        dm->drawFacesSolid(dm, GPU_enable_material);
-                       GPU_disable_material();
+                       GPU_end_object_materials();
                }
                else if(edm)
                        edm->drawMappedFaces(edm, NULL, NULL, 0);