Merging revisions 14946-15020 of https://svn.blender.org/svnroot/bf-blender/trunk...
authorDaniel Genrich <daniel.genrich@gmx.net>
Tue, 27 May 2008 23:15:08 +0000 (23:15 +0000)
committerDaniel Genrich <daniel.genrich@gmx.net>
Tue, 27 May 2008 23:15:08 +0000 (23:15 +0000)
1  2 
source/blender/blenkernel/intern/modifier.c
source/blender/src/buttons_editing.c
source/blender/src/drawobject.c

index fa54b0458d5b42dbb357035f84f6d08b6d53cfbe,f9f17e7762da2b9409b8dd3e4857be8577478909..067108ac8cb06adebdc93b75677876067f8c4f4e
@@@ -58,7 -58,6 +58,7 @@@
  #include "DNA_material_types.h"
  #include "DNA_mesh_types.h"
  #include "DNA_meshdata_types.h"
 +#include "DNA_sph_types.h"
  #include "DNA_modifier_types.h"
  #include "DNA_object_types.h"
  #include "DNA_object_force.h"
@@@ -91,7 -90,6 +91,7 @@@
  #include "BKE_object.h"
  #include "BKE_mesh.h"
  #include "BKE_softbody.h"
 +#include "BKE_sph.h"
  #include "BKE_cloth.h"
  #include "BKE_material.h"
  #include "BKE_particle.h"
@@@ -5182,89 -5180,6 +5182,89 @@@ static void clothModifier_freeData(Modi
        }
  }
  
 +/* Smooth Particly Hydrodynamics */
 +
 +static void sphModifier_initData(ModifierData *md) 
 +{
 +      SphModifierData *sphmd = (SphModifierData*) md;
 +      
 +      sphmd->sim_parms = MEM_callocN(sizeof(SphSimSettings), "SPH sim parms");
 +      sphmd->coll_parms = MEM_callocN(sizeof(SphCollSettings), "SPH coll parms");
 +      
 +      /* check for alloc failing */
 +      if(!sphmd->sim_parms || !sphmd->coll_parms)
 +              return;
 +      
 +      sph_init(sphmd);
 +}
 +
 +static DerivedMesh *sphModifier_applyModifier(ModifierData *md, Object *ob,
 +                                            DerivedMesh *derivedData, int useRenderParams, int isFinalCalc)
 +{
 +      SphModifierData *sphmd = (SphModifierData*) md;
 +      DerivedMesh *result=NULL;
 +      
 +      /* check for alloc failing */
 +      if(!sphmd->sim_parms || !sphmd->coll_parms)
 +              return derivedData;
 +
 +      result = sphModifier_do(sphmd, ob, derivedData, useRenderParams, isFinalCalc);
 +
 +      if(result)
 +      {
 +              CDDM_calc_normals(result);
 +              return result;
 +      }
 +      
 +      return derivedData;
 +}
 +
 +static void sphModifier_updateDepgraph(
 +                                     ModifierData *md, DagForest *forest, Object *ob,
 +         DagNode *obNode)
 +{
 +      SphModifierData *sphmd = (SphModifierData*) md;
 +      
 +      Base *base;
 +      
 +}
 +
 +CustomDataMask sphModifier_requiredDataMask(ModifierData *md)
 +{
 +      CustomDataMask dataMask = 0;
 +
 +      /* ask for vertexgroups if we need them */
 +      dataMask |= (1 << CD_MDEFORMVERT);
 +
 +      return dataMask;
 +}
 +
 +static void sphModifier_copyData(ModifierData *md, ModifierData *target)
 +{
 +      
 +}
 +
 +
 +static int sphModifier_dependsOnTime(ModifierData *md)
 +{
 +      return 1;
 +}
 +
 +static void sphModifier_freeData(ModifierData *md)
 +{
 +      SphModifierData *sphmd = (SphModifierData*) md;
 +      
 +      if (sphmd) 
 +      {       
 +              sph_free_modifier(sphmd);
 +              
 +              if(sphmd->sim_parms)
 +                      MEM_freeN(sphmd->sim_parms);
 +              if(sphmd->coll_parms)
 +                      MEM_freeN(sphmd->coll_parms);
 +      }
 +}
 +
  /* Collision */
  
  static void collisionModifier_initData(ModifierData *md) 
        collmd->current_v = NULL;
        collmd->time = -1;
        collmd->numverts = 0;
 -      collmd->bvh = NULL;
 +      collmd->bvhtree = NULL;
  }
  
  static void collisionModifier_freeData(ModifierData *md)
        
        if (collmd) 
        {
 -              if(collmd->bvh)
 -                      bvh_free(collmd->bvh);
 +              if(collmd->bvhtree)
 +                      BLI_bvhtree_free(collmd->bvhtree);
                if(collmd->x)
                        MEM_freeN(collmd->x);
                if(collmd->xnew)
                        MEM_freeN(collmd->current_xnew);
                if(collmd->current_v)
                        MEM_freeN(collmd->current_v);
 -              
                if(collmd->mfaces)
                        MEM_freeN(collmd->mfaces);
                
                collmd->current_v = NULL;
                collmd->time = -1;
                collmd->numverts = 0;
 -              collmd->bvh = NULL;
 +              collmd->bvhtree = NULL;
                collmd->mfaces = NULL;
        }
  }
@@@ -5377,8 -5293,9 +5377,8 @@@ static void collisionModifier_deformVer
                                collmd->mfaces = dm->dupFaceArray(dm);
                                collmd->numfaces = dm->getNumFaces(dm);
                                
 -                              // TODO: epsilon
                                // create bounding box hierarchy
 -                              collmd->bvh = bvh_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->x, numverts, ob->pd->pdef_sboft);
 +                              collmd->bvhtree = bvhtree_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->x, numverts, ob->pd->pdef_sboft);
                                
                                collmd->time = current_time;
                        }
                                memcpy(collmd->current_x, collmd->x, numverts*sizeof(MVert));
                                
                                /* check if GUI setting has changed for bvh */
 -                              if(collmd->bvh)
 +                              if(collmd->bvhtree) 
                                {
 -                                      if(ob->pd->pdef_sboft != collmd->bvh->epsilon)
 +                                      if(ob->pd->pdef_sboft != BLI_bvhtree_getepsilon(collmd->bvhtree))
                                        {
 -                                              bvh_free(collmd->bvh);
 -                                              collmd->bvh = bvh_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->current_x, numverts, ob->pd->pdef_sboft);
 +                                              BLI_bvhtree_free(collmd->bvhtree);
 +                                              collmd->bvhtree = bvhtree_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->current_x, numverts, ob->pd->pdef_sboft);
                                        }
                        
                                }
                                
 -                              /* happens on file load (ONLY when i decomment changes in readfile.c */
 -                              if(!collmd->bvh)
 +                              /* happens on file load (ONLY when i decomment changes in readfile.c) */
 +                              if(!collmd->bvhtree)
                                {
 -                                      collmd->bvh = bvh_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->current_x, numverts, ob->pd->pdef_sboft);
 +                                      collmd->bvhtree = bvhtree_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->current_x, numverts, ob->pd->pdef_sboft);
                                }
                                else
                                {
                                        // recalc static bounding boxes
 -                                      bvh_update_from_mvert(collmd->bvh, collmd->current_x, numverts, NULL, 0);
 +                                      bvhtree_update_from_mvert ( collmd->bvhtree, collmd->mfaces, collmd->numfaces, collmd->current_x, collmd->current_xnew, collmd->numverts, 1 );
                                }
                                
                                collmd->time = current_time;
@@@ -6568,12 -6485,14 +6568,14 @@@ static DerivedMesh * explodeModifier_ex
        MFace *mf=0;
        MVert *dupvert=0;
        ParticleSettings *part=psmd->psys->part;
-       ParticleData *pa, *pars=psmd->psys->particles;
+       ParticleData *pa=NULL, *pars=psmd->psys->particles;
        ParticleKey state;
+       EdgeHash *vertpahash;
+       EdgeHashIterator *ehi;
        float *vertco=0, imat[4][4];
        float loc0[3], nor[3];
        float timestep, cfra;
-       int *facepa=emd->facepa, *vertpa=0;
+       int *facepa=emd->facepa;
        int totdup=0,totvert=0,totface=0,totpart=0;
        int i, j, v, mindex=0;
  
        else
                cfra=bsystem_time(ob,(float)G.scene->r.cfra,0.0);
  
-       /* table for vertice <-> particle relations (row totpart+1 is for yet unexploded verts) */
-       vertpa = MEM_callocN(sizeof(int)*(totpart+1)*totvert, "explode_vertpatab");
-       for(i=0; i<(totpart+1)*totvert; i++)
-               vertpa[i] = -1;
+       /* hash table for vertice <-> particle relations */
+       vertpahash= BLI_edgehash_new();
  
        for (i=0; i<totface; i++) {
+               /* do mindex + totvert to ensure the vertex index to be the first
+                * with BLI_edgehashIterator_getKey */
                if(facepa[i]==totpart || cfra <= (pars+facepa[i])->time)
-                       mindex = totpart*totvert;
+                       mindex = totvert+totpart;
                else 
-                       mindex = facepa[i]*totvert;
+                       mindex = totvert+facepa[i];
  
                mf=CDDM_get_face(dm,i);
  
-               /*set face vertices to exist in particle group*/
-               vertpa[mindex+mf->v1] = 1;
-               vertpa[mindex+mf->v2] = 1;
-               vertpa[mindex+mf->v3] = 1;
+               /* set face vertices to exist in particle group */
+               BLI_edgehash_insert(vertpahash, mf->v1, mindex, NULL);
+               BLI_edgehash_insert(vertpahash, mf->v2, mindex, NULL);
+               BLI_edgehash_insert(vertpahash, mf->v3, mindex, NULL);
                if(mf->v4)
-                       vertpa[mindex+mf->v4] = 1;
+                       BLI_edgehash_insert(vertpahash, mf->v4, mindex, NULL);
        }
  
-       /*make new vertice indexes & count total vertices after duplication*/
-       for(i=0; i<(totpart+1)*totvert; i++){
-               if(vertpa[i] != -1)
-                       vertpa[i] = totdup++;
+       /* make new vertice indexes & count total vertices after duplication */
+       ehi= BLI_edgehashIterator_new(vertpahash);
+       for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
+               BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(totdup));
+               totdup++;
        }
+       BLI_edgehashIterator_free(ehi);
  
-       /*the final duplicated vertices*/
+       /* the final duplicated vertices */
        explode= CDDM_from_template(dm, totdup, 0,totface);
        dupvert= CDDM_get_verts(explode);
  
  
        psmd->psys->lattice = psys_get_lattice(ob, psmd->psys);
  
-       /*duplicate & displace vertices*/
-       for(i=0, pa=pars; i<=totpart; i++, pa++){
-               if(i!=totpart){
+       /* duplicate & displace vertices */
+       ehi= BLI_edgehashIterator_new(vertpahash);
+       for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
+               MVert source;
+               MVert *dest;
+               /* get particle + vertex from hash */
+               BLI_edgehashIterator_getKey(ehi, &j, &i);
+               i -= totvert;
+               v= GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
+               dm->getVert(dm, j, &source);
+               dest = CDDM_get_vert(explode,v);
+               DM_copy_vert_data(dm,explode,j,v,1);
+               *dest = source;
+               if(i!=totpart) {
+                       /* get particle */
+                       pa= pars+i;
+                       /* get particle state */
                        psys_particle_on_emitter(ob, psmd,part->from,pa->num,-1,pa->fuv,pa->foffset,loc0,nor,0,0,0,0);
                        Mat4MulVecfl(ob->obmat,loc0);
  
                        state.time=cfra;
                        psys_get_particle_state(ob,psmd->psys,i,&state,1);
-               }
-               for(j=0; j<totvert; j++){
-                       v=vertpa[i*totvert+j];
-                       if(v != -1) {
-                               MVert source;
-                               MVert *dest;
-                               dm->getVert(dm, j, &source);
-                               dest = CDDM_get_vert(explode,v);
-                               DM_copy_vert_data(dm,explode,j,v,1);
-                               *dest = source;
  
-                               if(i!=totpart){
-                                       vertco=CDDM_get_vert(explode,v)->co;
-                                       
-                                       Mat4MulVecfl(ob->obmat,vertco);
+                       vertco=CDDM_get_vert(explode,v)->co;
+                       
+                       Mat4MulVecfl(ob->obmat,vertco);
  
-                                       VECSUB(vertco,vertco,loc0);
+                       VECSUB(vertco,vertco,loc0);
  
-                                       /* apply rotation, size & location */
-                                       QuatMulVecf(state.rot,vertco);
-                                       VecMulf(vertco,pa->size);
-                                       VECADD(vertco,vertco,state.co);
+                       /* apply rotation, size & location */
+                       QuatMulVecf(state.rot,vertco);
+                       VecMulf(vertco,pa->size);
+                       VECADD(vertco,vertco,state.co);
  
-                                       Mat4MulVecfl(imat,vertco);
-                               }
-                       }
+                       Mat4MulVecfl(imat,vertco);
                }
        }
+       BLI_edgehashIterator_free(ehi);
  
        /*map new vertices to faces*/
        for (i=0; i<totface; i++) {
                orig_v4 = source.v4;
  
                if(facepa[i]!=totpart && cfra <= pa->time)
-                       mindex = totpart*totvert;
+                       mindex = totvert+totpart;
                else 
-                       mindex = facepa[i]*totvert;
+                       mindex = totvert+facepa[i];
  
-               source.v1 = vertpa[mindex+source.v1];
-               source.v2 = vertpa[mindex+source.v2];
-               source.v3 = vertpa[mindex+source.v3];
+               source.v1 = edgesplit_get(vertpahash, source.v1, mindex);
+               source.v2 = edgesplit_get(vertpahash, source.v2, mindex);
+               source.v3 = edgesplit_get(vertpahash, source.v3, mindex);
                if(source.v4)
-                       source.v4 = vertpa[mindex+source.v4];
+                       source.v4 = edgesplit_get(vertpahash, source.v4, mindex);
  
                DM_copy_face_data(dm,explode,i,i,1);
  
                test_index_face(mf, &explode->faceData, i, (mf->v4 ? 4 : 3));
        }
  
+       MEM_printmemlist_stats();
  
        /* cleanup */
-       if(vertpa) MEM_freeN(vertpa);
+       BLI_edgehash_free(vertpahash, NULL);
  
        /* finalization */
        CDDM_calc_edges(explode);
@@@ -7211,18 -7137,6 +7220,18 @@@ ModifierTypeInfo *modifierType_getInfo(
                mti->requiredDataMask = bevelModifier_requiredDataMask;
                mti->applyModifier = bevelModifier_applyModifier;
                mti->applyModifierEM = bevelModifier_applyModifierEM;
 +              
 +              mti = INIT_TYPE(Sph);
 +              mti->type = eModifierTypeType_Nonconstructive;
 +              mti->flags = eModifierTypeFlag_AcceptsMesh
 +                              | eModifierTypeFlag_UsesPointCache;
 +              mti->initData = sphModifier_initData;
 +              mti->copyData = sphModifier_copyData;
 +              mti->requiredDataMask = sphModifier_requiredDataMask;
 +              mti->applyModifier = sphModifier_applyModifier;
 +              mti->dependsOnTime = sphModifier_dependsOnTime;
 +              mti->freeData = sphModifier_freeData; 
 +              mti->updateDepgraph = sphModifier_updateDepgraph;
  
                mti = INIT_TYPE(Displace);
                mti->type = eModifierTypeType_OnlyDeform;
index bcd373ddbc3dac75563766ed1d76e252e696019f,1365baf075a18a2bb18c3a9371d8c5c00be85aa7..d2f798d0b6e0fec0f2f8b667208ab4a16289df53
@@@ -985,7 -985,7 +985,7 @@@ static uiBlock *modifiers_add_menu(voi
                /* Only allow adding through appropriate other interfaces */
                if(ELEM3(i, eModifierType_Softbody, eModifierType_Hook, eModifierType_ParticleSystem)) continue;
                
 -              if(ELEM(i, eModifierType_Cloth, eModifierType_Collision)) continue;
 +              if(ELEM3(i, eModifierType_Cloth, eModifierType_Collision, eModifierType_Sph)) continue;
  
                if((mti->flags&eModifierTypeFlag_AcceptsCVs) ||
                   (ob->type==OB_MESH && (mti->flags&eModifierTypeFlag_AcceptsMesh))) {
@@@ -1813,8 -1813,6 +1813,8 @@@ static void draw_modifier(uiBlock *bloc
                        height = 31;
                } else if (md->type==eModifierType_Collision) {
                        height = 31;
 +              } else if (md->type==eModifierType_Sph) {
 +                      height = 31;
                } else if (md->type==eModifierType_Boolean) {
                        height = 48;
                } else if (md->type==eModifierType_Array) {
                                uiButSetFunc(but, modifiers_applyModifier, ob, md);
                        }
                        
 -                      if (md->type!=eModifierType_Softbody && md->type!=eModifierType_ParticleSystem && (md->type!=eModifierType_Cloth)) {
 +                      if (md->type!=eModifierType_Softbody && md->type!=eModifierType_ParticleSystem && (md->type!=eModifierType_Cloth) && (md->type!=eModifierType_Sph)) {
                                but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Copy",   lx,(cy-=19),60,19, 0, 0, 0, 0, 0, "Duplicate the current modifier at the same position in the stack");
                                uiButSetFunc(but, modifiers_copyModifier, ob, md);
                        }
                        uiDefBut(block, LABEL, 1, "See Soft Body panel.",       lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
                } else if (md->type==eModifierType_Cloth) {
                        uiDefBut(block, LABEL, 1, "See Cloth panel.",   lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
 +              } else if (md->type==eModifierType_Sph) {
 +                      uiDefBut(block, LABEL, 1, "See Sph panel.",     lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
                } else if (md->type==eModifierType_Collision) {
                        uiDefBut(block, LABEL, 1, "See Collision panel.",       lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
                } else if (md->type==eModifierType_Boolean) {
@@@ -3075,7 -3071,6 +3075,6 @@@ static void editing_panel_font_type(Obj
  
  void do_curvebuts(unsigned short event)
  {
-       extern Nurb *lastnu;
        extern ListBase editNurb;  /* from editcurve */
        Object *ob;
        Curve *cu;
                                if(isNurbsel(nu)) {
                                        if((nu->type & 7)==CU_NURBS) {
                                                if(event<B_UNIFV) {
-                                                       nu->flagu &= 1;
-                                                       nu->flagu += ((event-B_UNIFU)<<1);
+                                                       nu->flagu &= CU_CYCLIC; /* disable all flags except for CU_CYCLIC */
+                                                       nu->flagu |= ((event-B_UNIFU)<<1);
+                                                       clamp_nurb_order_u(nu);
                                                        makeknots(nu, 1, nu->flagu>>1);
                                                }
                                                else if(nu->pntsv>1) {
-                                                       nu->flagv &= 1;
-                                                       nu->flagv += ((event-B_UNIFV)<<1);
+                                                       nu->flagv &= CU_CYCLIC; /* disable all flags except for CU_CYCLIC */
+                                                       nu->flagv |= ((event-B_UNIFV)<<1);
+                                                       clamp_nurb_order_v(nu);
                                                        makeknots(nu, 2, nu->flagv>>1);
                                                }
                                        }
                break;
        case B_SETORDER:
                if(G.obedit) {
-                       nu= lastnu;
+                       nu= get_actNurb();
                        if(nu && (nu->type & 7)==CU_NURBS ) {
-                               if(nu->orderu>nu->pntsu) {
-                                       nu->orderu= nu->pntsu;
+                               if(clamp_nurb_order_u(nu)) {
                                        scrarea_queue_winredraw(curarea);
                                }
                                makeknots(nu, 1, nu->flagu>>1);
-                               if(nu->orderv>nu->pntsv) {
-                                       nu->orderv= nu->pntsv;
+                               if(clamp_nurb_order_v(nu)) {
                                        scrarea_queue_winredraw(curarea);
                                }
                                makeknots(nu, 2, nu->flagv>>1);
@@@ -3277,7 -3272,6 +3276,6 @@@ static void editing_panel_curve_tools(O
  {
        Nurb *nu;
        extern ListBase editNurb;  /* from editcurve */
-       extern Nurb *lastnu;
        uiBlock *block;
        short *sp;
  
        uiBlockEndAlign(block);
  
        if(ob==G.obedit) {
-               nu= lastnu;
-               if(nu==NULL) nu= lastnu= editNurb.first;
+               nu= get_actNurb();
+               if(nu==NULL && editNurb.first) {
+                       nu= editNurb.first;
+                       set_actNurb(nu);
+               }
                if(nu) {
                        if (ob->type==OB_CURVE) {
                                uiDefBut(block, LABEL, 0, "Tilt",
index d5b1f023d7039b42ef97f062a58a31e1c265a93a,3ef14574bc8de58cb59e457e058a5a43fcb5fd54..0b042fc542f853f730a9b860bf97f74022b1d597
@@@ -1883,13 -1883,11 +1883,13 @@@ static void draw_em_measure_stats(Objec
  {
        EditEdge *eed;
        EditFace *efa;
 +      EditVert *eve;
        float v1[3], v2[3], v3[3], v4[3];
        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 */
 +      int i = 0;
        
        /* make the precission of the pronted value proportionate to the gridsize */
        if ((G.vd->grid) < 0.01)
                if(col[1]> 0.5) {col[0]*=0.7; col[2]*= 0.7;}
                else col[1]= col[1]*0.7 + 0.3;
                glColor3fv(col);
 -              
 +              /*
                for(efa= em->faces.first; efa; efa= efa->next) {
                        if((efa->f & SELECT) || (G.moving && faceselectedOR(efa, SELECT)) ) {
                                VECCOPY(v1, efa->v1->co);
                                glRasterPos3fv(efa->cent);
                                BMF_DrawString( G.fonts, val);
                        }
 +              }*/
 +              
 +              /* draw IDs of mesh vertexes */
 +              for(eve = em->verts.first; eve; eve = eve->next) {
 +                      char val[32];
 +                      float fvec[3];
 +                      VecLerpf(fvec, ob->loc, eve->co, 1.1);
 +                      glRasterPos3f(fvec[0], fvec[1], fvec[2]);
 +
 +                      sprintf(val, "%d", eve->keyindex);
 +                      BMF_DrawString(G.fonts, val);
 +              }
 +              for(efa= em->faces.first; efa; efa= efa->next) {
 +                      char val[32];
 +                      sprintf(val, "%d", i);
 +                      glRasterPos3fv(efa->cent);
 +                      BMF_DrawString( G.fonts, val);
 +                      i++;
                }
        }
  
@@@ -2905,7 -2885,7 +2905,7 @@@ static int drawDispList(Base *base, in
  /* 5. start filling the arrays                                */
  /* 6. draw the arrays                                         */
  /* 7. clean up                                                                */
- static void draw_new_particle_system(Base *base, ParticleSystem *psys)
+ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt)
  {
        View3D *v3d= G.vd;
        Object *ob=base->object;
                                float *cd2=0,*cdata2=0;
  
                                glEnableClientState(GL_VERTEX_ARRAY);
-                               glEnableClientState(GL_NORMAL_ARRAY);
-                               glEnable(GL_LIGHTING);
  
-                               glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
-                               glEnable(GL_COLOR_MATERIAL);
+                               if(dt > OB_WIRE) {
+                                       glEnableClientState(GL_NORMAL_ARRAY);
+                                       if(part->draw&PART_DRAW_MAT_COL)
+                                               glEnableClientState(GL_COLOR_ARRAY);
+                                       glEnable(GL_LIGHTING);
+                                       glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
+                                       glEnable(GL_COLOR_MATERIAL);
+                               }
+                               else {
+                                       glDisableClientState(GL_NORMAL_ARRAY);
  
-                               if(part->draw&PART_DRAW_MAT_COL)
-                                       glEnableClientState(GL_COLOR_ARRAY);
+                                       glDisable(GL_COLOR_MATERIAL);
+                                       glDisable(GL_LIGHTING);
+                                       BIF_ThemeColor(TH_WIRE);
+                               }
  
                                if(totchild && (part->draw&PART_DRAW_PARENT)==0)
                                        totpart=0;
                                for(a=0, pa=psys->particles; a<totpart; a++, pa++){
                                        path=cache[a];
                                        glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co);
-                                       glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel);
-                                       if(part->draw&PART_DRAW_MAT_COL)
-                                               glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col);
+                                       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);
+                                       }
                                        glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1);
                                }
                                
                                for(a=0; a<totchild; a++){
                                        path=cache[a];
                                        glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co);
-                                       glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel);
-                                       if(part->draw&PART_DRAW_MAT_COL)
-                                               glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col);
+                                       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);
+                                       }
                                        glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1);
                                }
  
-                               if(part->draw&PART_DRAW_MAT_COL)
-                                       glDisable(GL_COLOR_ARRAY);
-                               glDisable(GL_COLOR_MATERIAL);
+                               if(dt > OB_WIRE) {
+                                       if(part->draw&PART_DRAW_MAT_COL)
+                                               glDisable(GL_COLOR_ARRAY);
+                                       glDisable(GL_COLOR_MATERIAL);
+                               }
  
                                if(cdata2)
                                        MEM_freeN(cdata2);
                                else
                                        glDisableClientState(GL_VERTEX_ARRAY);
  
-                               if(ndata && MIN2(G.vd->drawtype, ob->dt)>OB_WIRE){
+                               if(ndata && dt>OB_WIRE){
                                        glEnableClientState(GL_NORMAL_ARRAY);
                                        glNormalPointer(GL_FLOAT, 0, ndata);
                                        glEnable(GL_LIGHTING);
                                                glDrawArrays(GL_LINES, 0, 2*totpoint);
                                                break;
                                        case PART_DRAW_BB:
-                                               if(MIN2(G.vd->drawtype, ob->dt)<=OB_WIRE)
+                                               if(dt<=OB_WIRE)
                                                        glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
  
                                                glDrawArrays(GL_QUADS, 0, 4*totpoint);
        mymultmatrix(ob->obmat);        // bring back local matrix for dtx
  }
  
- static void draw_particle_edit(Object *ob, ParticleSystem *psys)
+ static void draw_particle_edit(Object *ob, ParticleSystem *psys, int dt)
  {
        ParticleEdit *edit = psys->edit;
        ParticleData *pa;
        float nosel_col[3];
        char val[32];
  
+       /* create path and child path cache if it doesn't exist already */
        if(psys->pathcache==0){
                PE_hide_keys_time(psys,CFRA);
                psys_cache_paths(ob,psys,CFRA,0);
        else if(!(pset->flag & PE_SHOW_CHILD) && psys->childcache)
                free_child_path_cache(psys);
  
+       /* opengl setup */
        if((G.vd->flag & V3D_ZBUF_SELECT)==0)
                glDisable(GL_DEPTH_TEST);
  
        myloadmatrix(G.vd->viewmat);
  
+       /* get selection theme colors */
        BIF_GetThemeColor3ubv(TH_VERTEX_SELECT, sel);
        BIF_GetThemeColor3ubv(TH_VERTEX, nosel);
        sel_col[0]=(float)sel[0]/255.0f;
                totchild = psys->totchildcache;
  
        /* draw paths */
-       glEnableClientState(GL_VERTEX_ARRAY);
-       glEnableClientState(GL_NORMAL_ARRAY);
-       glEnableClientState(GL_COLOR_ARRAY);
        if(timed)
                glEnable(GL_BLEND);
  
-       if(pset->brushtype == PE_BRUSH_WEIGHT){
-               glLineWidth(2.0f);
+       glEnableClientState(GL_VERTEX_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);
+       }
+       else {
+               /* flat wire color */
+               glDisableClientState(GL_NORMAL_ARRAY);
                glDisable(GL_LIGHTING);
+               BIF_ThemeColor(TH_WIRE);
        }
  
-       glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
-       glEnable(GL_COLOR_MATERIAL);
-       for(i=0, pa=psys->particles, path = psys->pathcache; i<totpart; i++, pa++, path++){
-               glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->co);
-               glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), (*path)->vel);
-               glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->col);
-               glDrawArrays(GL_LINE_STRIP, 0, (int)(*path)->steps + 1);
-       }
+       /* only draw child paths with lighting */
+       if(dt > OB_WIRE)
+               glEnable(GL_LIGHTING);
  
-       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);
-                       glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), (*path)->vel);
-                       glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->col);
+                       if(dt > OB_WIRE) {
+                               glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), (*path)->vel);
+                               glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->col);
+                       }
  
                        glDrawArrays(GL_LINE_STRIP, 0, (int)(*path)->steps + 1);
                }
        }
  
-       glDisable(GL_COLOR_MATERIAL);
+       if(dt > OB_WIRE)
+               glDisable(GL_LIGHTING);
+       if(pset->brushtype == PE_BRUSH_WEIGHT) {
+               glLineWidth(2.0f);
+               glEnableClientState(GL_COLOR_ARRAY);
+               glDisable(GL_LIGHTING);
+       }
+       /* 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);
+               glDrawArrays(GL_LINE_STRIP, 0, (int)(*path)->steps + 1);
+       }
  
        /* draw edit vertices */
        if(G.scene->selectmode!=SCE_SELECT_PATH){
  
        glDisable(GL_BLEND);
        glDisable(GL_LIGHTING);
+       glDisable(GL_COLOR_MATERIAL);
        glDisableClientState(GL_COLOR_ARRAY);
        glEnableClientState(GL_NORMAL_ARRAY);
        glEnable(GL_DEPTH_TEST);
@@@ -5031,12 -5055,12 +5075,12 @@@ void draw_object(Base *base, int flag
                glDepthMask(GL_FALSE);
                
                for(psys=ob->particlesystem.first; psys; psys=psys->next)
-                       draw_new_particle_system(base, psys);
+                       draw_new_particle_system(base, psys, dt);
                
                if(G.f & G_PARTICLEEDIT && ob==OBACT) {
                        psys= PE_get_current(ob);
                        if(psys && !G.obedit && psys_in_edit_mode(psys))
-                               draw_particle_edit(ob, psys);
+                               draw_particle_edit(ob, psys, dt);
                }
                glDepthMask(GL_TRUE); 
                if(col) cpack(col);