Merge branch 'master' into blender2.8
[blender.git] / source / blender / render / intern / source / convertblender.c
index 907974e20dcf1164edcfc8af60f6bad6e2db8459..3dcde1f4bb1d3959b092a6e7a69f0494f0008db5 100644 (file)
@@ -57,7 +57,6 @@
 #include "DNA_node_types.h"
 #include "DNA_object_types.h"
 #include "DNA_object_fluidsim.h"
-#include "DNA_particle_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_texture_types.h"
 
@@ -79,7 +78,6 @@
 #include "BKE_modifier.h"
 #include "BKE_node.h"
 #include "BKE_object.h"
-#include "BKE_particle.h"
 #include "BKE_scene.h"
 
 #include "PIL_time.h"
@@ -748,1148 +746,6 @@ static Material *give_render_material(Render *re, Object *ob, short nr)
        return ma;
 }
 
-/* ------------------------------------------------------------------------- */
-/* Particles                                                                 */
-/* ------------------------------------------------------------------------- */
-typedef struct ParticleStrandData {
-       struct MCol *mcol;
-       float *orco, *uvco, *surfnor;
-       float time, adapt_angle, adapt_pix, size;
-       int totuv, totcol;
-       int first, line, adapt, override_uv;
-}
-ParticleStrandData;
-/* future thread problem... */
-static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, ParticleStrandData *sd, const float vec[3], const float vec1[3])
-{
-       static VertRen *v1= NULL, *v2= NULL;
-       VlakRen *vlr= NULL;
-       float nor[3], cross[3], crosslen, w, dx, dy, width;
-       static float anor[3], avec[3];
-       int flag, i;
-       static int second=0;
-       
-       sub_v3_v3v3(nor, vec, vec1);
-       normalize_v3(nor);  /* nor needed as tangent */
-       cross_v3_v3v3(cross, vec, nor);
-
-       /* turn cross in pixelsize */
-       w= vec[2]*re->winmat[2][3] + re->winmat[3][3];
-       dx= re->winx*cross[0]*re->winmat[0][0];
-       dy= re->winy*cross[1]*re->winmat[1][1];
-       w = sqrtf(dx * dx + dy * dy) / w;
-       
-       if (w!=0.0f) {
-               float fac;
-               if (ma->strand_ease!=0.0f) {
-                       if (ma->strand_ease<0.0f)
-                               fac= pow(sd->time, 1.0f+ma->strand_ease);
-                       else
-                               fac= pow(sd->time, 1.0f/(1.0f-ma->strand_ease));
-               }
-               else fac= sd->time;
-
-               width= ((1.0f-fac)*ma->strand_sta + (fac)*ma->strand_end);
-
-               /* use actual Blender units for strand width and fall back to minimum width */
-               if (ma->mode & MA_STR_B_UNITS) {
-                       crosslen= len_v3(cross);
-                       w= 2.0f*crosslen*ma->strand_min/w;
-
-                       if (width < w)
-                               width= w;
-
-                       /*cross is the radius of the strand so we want it to be half of full width */
-                       mul_v3_fl(cross, 0.5f/crosslen);
-               }
-               else
-                       width/=w;
-
-               mul_v3_fl(cross, width);
-       }
-       
-       if (ma->mode & MA_TANGENT_STR)
-               flag= R_SMOOTH|R_TANGENT;
-       else
-               flag= R_SMOOTH;
-       
-       /* only 1 pixel wide strands filled in as quads now, otherwise zbuf errors */
-       if (ma->strand_sta==1.0f)
-               flag |= R_STRAND;
-       
-       /* single face line */
-       if (sd->line) {
-               vlr= RE_findOrAddVlak(obr, obr->totvlak++);
-               vlr->flag= flag;
-               vlr->v1= RE_findOrAddVert(obr, obr->totvert++);
-               vlr->v2= RE_findOrAddVert(obr, obr->totvert++);
-               vlr->v3= RE_findOrAddVert(obr, obr->totvert++);
-               vlr->v4= RE_findOrAddVert(obr, obr->totvert++);
-               
-               copy_v3_v3(vlr->v1->co, vec);
-               add_v3_v3(vlr->v1->co, cross);
-               copy_v3_v3(vlr->v1->n, nor);
-               vlr->v1->orco= sd->orco;
-               vlr->v1->accum = -1.0f;  /* accum abuse for strand texco */
-               
-               copy_v3_v3(vlr->v2->co, vec);
-               sub_v3_v3v3(vlr->v2->co, vlr->v2->co, cross);
-               copy_v3_v3(vlr->v2->n, nor);
-               vlr->v2->orco= sd->orco;
-               vlr->v2->accum= vlr->v1->accum;
-
-               copy_v3_v3(vlr->v4->co, vec1);
-               add_v3_v3(vlr->v4->co, cross);
-               copy_v3_v3(vlr->v4->n, nor);
-               vlr->v4->orco= sd->orco;
-               vlr->v4->accum = 1.0f;  /* accum abuse for strand texco */
-
-               copy_v3_v3(vlr->v3->co, vec1);
-               sub_v3_v3v3(vlr->v3->co, vlr->v3->co, cross);
-               copy_v3_v3(vlr->v3->n, nor);
-               vlr->v3->orco= sd->orco;
-               vlr->v3->accum= vlr->v4->accum;
-
-               normal_quad_v3(vlr->n, vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co);
-               
-               vlr->mat= ma;
-               vlr->ec= ME_V2V3;
-
-               if (sd->surfnor) {
-                       float *snor= RE_vlakren_get_surfnor(obr, vlr, 1);
-                       copy_v3_v3(snor, sd->surfnor);
-               }
-
-               if (sd->uvco) {
-                       for (i=0; i<sd->totuv; i++) {
-                               MTFace *mtf;
-                               mtf=RE_vlakren_get_tface(obr, vlr, i, NULL, 1);
-                               mtf->uv[0][0]=mtf->uv[1][0]=
-                               mtf->uv[2][0]=mtf->uv[3][0]=(sd->uvco+2*i)[0];
-                               mtf->uv[0][1]=mtf->uv[1][1]=
-                               mtf->uv[2][1]=mtf->uv[3][1]=(sd->uvco+2*i)[1];
-                       }
-                       if (sd->override_uv>=0) {
-                               MTFace *mtf;
-                               mtf=RE_vlakren_get_tface(obr, vlr, sd->override_uv, NULL, 0);
-                               
-                               mtf->uv[0][0]=mtf->uv[3][0]=0.0f;
-                               mtf->uv[1][0]=mtf->uv[2][0]=1.0f;
-
-                               mtf->uv[0][1]=mtf->uv[1][1]=0.0f;
-                               mtf->uv[2][1]=mtf->uv[3][1]=1.0f;
-                       }
-               }
-               if (sd->mcol) {
-                       for (i=0; i<sd->totcol; i++) {
-                               MCol *mc;
-                               mc=RE_vlakren_get_mcol(obr, vlr, i, NULL, 1);
-                               mc[0]=mc[1]=mc[2]=mc[3]=sd->mcol[i];
-                               mc[0]=mc[1]=mc[2]=mc[3]=sd->mcol[i];
-                       }
-               }
-       }
-       /* first two vertices of a strand */
-       else if (sd->first) {
-               if (sd->adapt) {
-                       copy_v3_v3(anor, nor);
-                       copy_v3_v3(avec, vec);
-                       second=1;
-               }
-
-               v1= RE_findOrAddVert(obr, obr->totvert++);
-               v2= RE_findOrAddVert(obr, obr->totvert++);
-               
-               copy_v3_v3(v1->co, vec);
-               add_v3_v3(v1->co, cross);
-               copy_v3_v3(v1->n, nor);
-               v1->orco= sd->orco;
-               v1->accum = -1.0f;  /* accum abuse for strand texco */
-               
-               copy_v3_v3(v2->co, vec);
-               sub_v3_v3v3(v2->co, v2->co, cross);
-               copy_v3_v3(v2->n, nor);
-               v2->orco= sd->orco;
-               v2->accum= v1->accum;
-       }
-       /* more vertices & faces to strand */
-       else {
-               if (sd->adapt==0 || second) {
-                       vlr= RE_findOrAddVlak(obr, obr->totvlak++);
-                       vlr->flag= flag;
-                       vlr->v1= v1;
-                       vlr->v2= v2;
-                       vlr->v3= RE_findOrAddVert(obr, obr->totvert++);
-                       vlr->v4= RE_findOrAddVert(obr, obr->totvert++);
-
-                       v1= vlr->v4; /* cycle */
-                       v2= vlr->v3; /* cycle */
-
-
-                       if (sd->adapt) {
-                               second=0;
-                               copy_v3_v3(anor, nor);
-                               copy_v3_v3(avec, vec);
-                       }
-
-               }
-               else if (sd->adapt) {
-                       float dvec[3], pvec[3];
-                       sub_v3_v3v3(dvec, avec, vec);
-                       project_v3_v3v3(pvec, dvec, vec);
-                       sub_v3_v3v3(dvec, dvec, pvec);
-
-                       w= vec[2]*re->winmat[2][3] + re->winmat[3][3];
-                       dx= re->winx*dvec[0]*re->winmat[0][0]/w;
-                       dy= re->winy*dvec[1]*re->winmat[1][1]/w;
-                       w = sqrtf(dx * dx + dy * dy);
-                       if (dot_v3v3(anor, nor)<sd->adapt_angle && w>sd->adapt_pix) {
-                               vlr= RE_findOrAddVlak(obr, obr->totvlak++);
-                               vlr->flag= flag;
-                               vlr->v1= v1;
-                               vlr->v2= v2;
-                               vlr->v3= RE_findOrAddVert(obr, obr->totvert++);
-                               vlr->v4= RE_findOrAddVert(obr, obr->totvert++);
-
-                               v1= vlr->v4; /* cycle */
-                               v2= vlr->v3; /* cycle */
-
-                               copy_v3_v3(anor, nor);
-                               copy_v3_v3(avec, vec);
-                       }
-                       else {
-                               vlr= RE_findOrAddVlak(obr, obr->totvlak-1);
-                       }
-               }
-       
-               copy_v3_v3(vlr->v4->co, vec);
-               add_v3_v3(vlr->v4->co, cross);
-               copy_v3_v3(vlr->v4->n, nor);
-               vlr->v4->orco= sd->orco;
-               vlr->v4->accum= -1.0f + 2.0f * sd->time;  /* accum abuse for strand texco */
-
-               copy_v3_v3(vlr->v3->co, vec);
-               sub_v3_v3v3(vlr->v3->co, vlr->v3->co, cross);
-               copy_v3_v3(vlr->v3->n, nor);
-               vlr->v3->orco= sd->orco;
-               vlr->v3->accum= vlr->v4->accum;
-               
-               normal_quad_v3(vlr->n, vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co);
-               
-               vlr->mat= ma;
-               vlr->ec= ME_V2V3;
-
-               if (sd->surfnor) {
-                       float *snor= RE_vlakren_get_surfnor(obr, vlr, 1);
-                       copy_v3_v3(snor, sd->surfnor);
-               }
-
-               if (sd->uvco) {
-                       for (i=0; i<sd->totuv; i++) {
-                               MTFace *mtf;
-                               mtf=RE_vlakren_get_tface(obr, vlr, i, NULL, 1);
-                               mtf->uv[0][0]=mtf->uv[1][0]=
-                               mtf->uv[2][0]=mtf->uv[3][0]=(sd->uvco+2*i)[0];
-                               mtf->uv[0][1]=mtf->uv[1][1]=
-                               mtf->uv[2][1]=mtf->uv[3][1]=(sd->uvco+2*i)[1];
-                       }
-                       if (sd->override_uv>=0) {
-                               MTFace *mtf;
-                               mtf=RE_vlakren_get_tface(obr, vlr, sd->override_uv, NULL, 0);
-                               
-                               mtf->uv[0][0]=mtf->uv[3][0]=0.0f;
-                               mtf->uv[1][0]=mtf->uv[2][0]=1.0f;
-
-                               mtf->uv[0][1]=mtf->uv[1][1]=(vlr->v1->accum+1.0f)/2.0f;
-                               mtf->uv[2][1]=mtf->uv[3][1]=(vlr->v3->accum+1.0f)/2.0f;
-                       }
-               }
-               if (sd->mcol) {
-                       for (i=0; i<sd->totcol; i++) {
-                               MCol *mc;
-                               mc=RE_vlakren_get_mcol(obr, vlr, i, NULL, 1);
-                               mc[0]=mc[1]=mc[2]=mc[3]=sd->mcol[i];
-                               mc[0]=mc[1]=mc[2]=mc[3]=sd->mcol[i];
-                       }
-               }
-       }
-}
-
-static void static_particle_wire(ObjectRen *obr, Material *ma, const float vec[3], const float vec1[3], int first, int line)
-{
-       VlakRen *vlr;
-       static VertRen *v1;
-
-       if (line) {
-               vlr= RE_findOrAddVlak(obr, obr->totvlak++);
-               vlr->v1= RE_findOrAddVert(obr, obr->totvert++);
-               vlr->v2= RE_findOrAddVert(obr, obr->totvert++);
-               vlr->v3= vlr->v2;
-               vlr->v4= NULL;
-               
-               copy_v3_v3(vlr->v1->co, vec);
-               copy_v3_v3(vlr->v2->co, vec1);
-               
-               sub_v3_v3v3(vlr->n, vec, vec1);
-               normalize_v3(vlr->n);
-               copy_v3_v3(vlr->v1->n, vlr->n);
-               copy_v3_v3(vlr->v2->n, vlr->n);
-               
-               vlr->mat= ma;
-               vlr->ec= ME_V1V2;
-
-       }
-       else if (first) {
-               v1= RE_findOrAddVert(obr, obr->totvert++);
-               copy_v3_v3(v1->co, vec);
-       }
-       else {
-               vlr= RE_findOrAddVlak(obr, obr->totvlak++);
-               vlr->v1= v1;
-               vlr->v2= RE_findOrAddVert(obr, obr->totvert++);
-               vlr->v3= vlr->v2;
-               vlr->v4= NULL;
-               
-               v1= vlr->v2; /* cycle */
-               copy_v3_v3(v1->co, vec);
-               
-               sub_v3_v3v3(vlr->n, vec, vec1);
-               normalize_v3(vlr->n);
-               copy_v3_v3(v1->n, vlr->n);
-               
-               vlr->mat= ma;
-               vlr->ec= ME_V1V2;
-       }
-
-}
-
-static void particle_curve(Render *re, ObjectRen *obr, DerivedMesh *dm, Material *ma, ParticleStrandData *sd,
-                           const float loc[3], const float loc1[3], int seed, float *pa_co)
-{
-       HaloRen *har = NULL;
-
-       if (ma->material_type == MA_TYPE_WIRE)
-               static_particle_wire(obr, ma, loc, loc1, sd->first, sd->line);
-       else if (ma->material_type == MA_TYPE_HALO) {
-               har= RE_inithalo_particle(re, obr, dm, ma, loc, loc1, sd->orco, sd->uvco, sd->size, 1.0, seed, pa_co);
-               if (har) har->lay= obr->ob->lay;
-       }
-       else
-               static_particle_strand(re, obr, ma, sd, loc, loc1);
-}
-static void particle_billboard(Render *re, ObjectRen *obr, Material *ma, ParticleBillboardData *bb)
-{
-       VlakRen *vlr;
-       MTFace *mtf;
-       float xvec[3], yvec[3], zvec[3], bb_center[3];
-       /* Number of tiles */
-       int totsplit = bb->uv_split * bb->uv_split;
-       int tile, x, y;
-       /* Tile offsets */
-       float uvx = 0.0f, uvy = 0.0f, uvdx = 1.0f, uvdy = 1.0f, time = 0.0f;
-
-       vlr= RE_findOrAddVlak(obr, obr->totvlak++);
-       vlr->v1= RE_findOrAddVert(obr, obr->totvert++);
-       vlr->v2= RE_findOrAddVert(obr, obr->totvert++);
-       vlr->v3= RE_findOrAddVert(obr, obr->totvert++);
-       vlr->v4= RE_findOrAddVert(obr, obr->totvert++);
-
-       psys_make_billboard(bb, xvec, yvec, zvec, bb_center);
-
-       add_v3_v3v3(vlr->v1->co, bb_center, xvec);
-       add_v3_v3(vlr->v1->co, yvec);
-       mul_m4_v3(re->viewmat, vlr->v1->co);
-
-       sub_v3_v3v3(vlr->v2->co, bb_center, xvec);
-       add_v3_v3(vlr->v2->co, yvec);
-       mul_m4_v3(re->viewmat, vlr->v2->co);
-
-       sub_v3_v3v3(vlr->v3->co, bb_center, xvec);
-       sub_v3_v3v3(vlr->v3->co, vlr->v3->co, yvec);
-       mul_m4_v3(re->viewmat, vlr->v3->co);
-
-       add_v3_v3v3(vlr->v4->co, bb_center, xvec);
-       sub_v3_v3(vlr->v4->co, yvec);
-       mul_m4_v3(re->viewmat, vlr->v4->co);
-
-       normal_quad_v3(vlr->n, vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co);
-       copy_v3_v3(vlr->v1->n, vlr->n);
-       copy_v3_v3(vlr->v2->n, vlr->n);
-       copy_v3_v3(vlr->v3->n, vlr->n);
-       copy_v3_v3(vlr->v4->n, vlr->n);
-       
-       vlr->mat= ma;
-       vlr->ec= ME_V2V3;
-
-       if (bb->uv_split > 1) {
-               uvdx = uvdy = 1.0f / (float)bb->uv_split;
-
-               if (ELEM(bb->anim, PART_BB_ANIM_AGE, PART_BB_ANIM_FRAME)) {
-                       if (bb->anim == PART_BB_ANIM_FRAME)
-                               time = ((int)(bb->time * bb->lifetime) % totsplit)/(float)totsplit;
-                       else
-                               time = bb->time;
-               }
-               else if (bb->anim == PART_BB_ANIM_ANGLE) {
-                       if (bb->align == PART_BB_VIEW) {
-                               time = (float)fmod((bb->tilt + 1.0f) / 2.0f, 1.0);
-                       }
-                       else {
-                               float axis1[3] = {0.0f, 0.0f, 0.0f};
-                               float axis2[3] = {0.0f, 0.0f, 0.0f};
-
-                               axis1[(bb->align + 1) % 3] = 1.0f;
-                               axis2[(bb->align + 2) % 3] = 1.0f;
-
-                               if (bb->lock == 0) {
-                                       zvec[bb->align] = 0.0f;
-                                       normalize_v3(zvec);
-                               }
-                               
-                               time = saacos(dot_v3v3(zvec, axis1)) / (float)M_PI;
-                               
-                               if (dot_v3v3(zvec, axis2) < 0.0f)
-                                       time = 1.0f - time / 2.0f;
-                               else
-                                       time /= 2.0f;
-                       }
-               }
-
-               if (bb->split_offset == PART_BB_OFF_LINEAR)
-                       time = (float)fmod(time + (float)bb->num / (float)totsplit, 1.0f);
-               else if (bb->split_offset==PART_BB_OFF_RANDOM)
-                       time = (float)fmod(time + bb->random, 1.0f);
-
-               /* Find the coordinates in tile space (integer), then convert to UV
-                * space (float). Note that Y is flipped. */
-               tile = (int)((time + FLT_EPSILON10) * totsplit);
-               x = tile % bb->uv_split;
-               y = tile / bb->uv_split;
-               y = (bb->uv_split - 1) - y;
-               uvx = uvdx * x;
-               uvy = uvdy * y;
-       }
-
-       /* normal UVs */
-       if (bb->uv[0] >= 0) {
-               mtf = RE_vlakren_get_tface(obr, vlr, bb->uv[0], NULL, 1);
-               mtf->uv[0][0] = 1.0f;
-               mtf->uv[0][1] = 1.0f;
-               mtf->uv[1][0] = 0.0f;
-               mtf->uv[1][1] = 1.0f;
-               mtf->uv[2][0] = 0.0f;
-               mtf->uv[2][1] = 0.0f;
-               mtf->uv[3][0] = 1.0f;
-               mtf->uv[3][1] = 0.0f;
-       }
-
-       /* time-index UVs */
-       if (bb->uv[1] >= 0) {
-               mtf = RE_vlakren_get_tface(obr, vlr, bb->uv[1], NULL, 1);
-               mtf->uv[0][0] = mtf->uv[1][0] = mtf->uv[2][0] = mtf->uv[3][0] = bb->time;
-               mtf->uv[0][1] = mtf->uv[1][1] = mtf->uv[2][1] = mtf->uv[3][1] = (float)bb->num/(float)bb->totnum;
-       }
-
-       /* split UVs */
-       if (bb->uv_split > 1 && bb->uv[2] >= 0) {
-               mtf = RE_vlakren_get_tface(obr, vlr, bb->uv[2], NULL, 1);
-               mtf->uv[0][0] = uvx + uvdx;
-               mtf->uv[0][1] = uvy + uvdy;
-               mtf->uv[1][0] = uvx;
-               mtf->uv[1][1] = uvy + uvdy;
-               mtf->uv[2][0] = uvx;
-               mtf->uv[2][1] = uvy;
-               mtf->uv[3][0] = uvx + uvdx;
-               mtf->uv[3][1] = uvy;
-       }
-}
-static void particle_normal_ren(short ren_as, ParticleSettings *part, Render *re, ObjectRen *obr, DerivedMesh *dm, Material *ma, ParticleStrandData *sd, ParticleBillboardData *bb, ParticleKey *state, int seed, float hasize, float *pa_co)
-{
-       float loc[3], loc0[3], loc1[3], vel[3];
-       
-       copy_v3_v3(loc, state->co);
-
-       if (ren_as != PART_DRAW_BB)
-               mul_m4_v3(re->viewmat, loc);
-
-       switch (ren_as) {
-               case PART_DRAW_LINE:
-                       sd->line = 1;
-                       sd->time = 0.0f;
-                       sd->size = hasize;
-
-                       mul_v3_mat3_m4v3(vel, re->viewmat, state->vel);
-                       normalize_v3(vel);
-
-                       if (part->draw & PART_DRAW_VEL_LENGTH)
-                               mul_v3_fl(vel, len_v3(state->vel));
-
-                       madd_v3_v3v3fl(loc0, loc, vel, -part->draw_line[0]);
-                       madd_v3_v3v3fl(loc1, loc, vel, part->draw_line[1]);
-
-                       particle_curve(re, obr, dm, ma, sd, loc0, loc1, seed, pa_co);
-
-                       break;
-
-               case PART_DRAW_BB:
-
-                       copy_v3_v3(bb->vec, loc);
-                       copy_v3_v3(bb->vel, state->vel);
-
-                       particle_billboard(re, obr, ma, bb);
-
-                       break;
-
-               default:
-               {
-                       HaloRen *har = NULL;
-
-                       har = RE_inithalo_particle(re, obr, dm, ma, loc, NULL, sd->orco, sd->uvco, hasize, 0.0, seed, pa_co);
-                       
-                       if (har) har->lay= obr->ob->lay;
-
-                       break;
-               }
-       }
-}
-static void get_particle_uvco_mcol(short from, DerivedMesh *dm, float *fuv, int num, ParticleStrandData *sd)
-{
-       int i;
-
-       /* get uvco */
-       if (sd->uvco && ELEM(from, PART_FROM_FACE, PART_FROM_VOLUME)) {
-               for (i=0; i<sd->totuv; i++) {
-                       if (!ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) {
-                               MFace *mface = dm->getTessFaceData(dm, num, CD_MFACE);
-                               MTFace *mtface = (MTFace*)CustomData_get_layer_n(&dm->faceData, CD_MTFACE, i);
-                               mtface += num;
-                               
-                               psys_interpolate_uvs(mtface, mface->v4, fuv, sd->uvco + 2 * i);
-                       }
-                       else {
-                               sd->uvco[2*i] = 0.0f;
-                               sd->uvco[2*i + 1] = 0.0f;
-                       }
-               }
-       }
-
-       /* get mcol */
-       if (sd->mcol && ELEM(from, PART_FROM_FACE, PART_FROM_VOLUME)) {
-               for (i=0; i<sd->totcol; i++) {
-                       if (!ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) {
-                               MFace *mface = dm->getTessFaceData(dm, num, CD_MFACE);
-                               MCol *mc = (MCol*)CustomData_get_layer_n(&dm->faceData, CD_MCOL, i);
-                               mc += num * 4;
-
-                               psys_interpolate_mcol(mc, mface->v4, fuv, sd->mcol + i);
-                       }
-                       else
-                               memset(&sd->mcol[i], 0, sizeof(MCol));
-               }
-       }
-}
-static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem *psys, int timeoffset)
-{
-       Object *ob= obr->ob;
-//     Object *tob=0;
-       Material *ma = NULL;
-       ParticleSystemModifierData *psmd;
-       ParticleSystem *tpsys = NULL;
-       ParticleSettings *part, *tpart = NULL;
-       ParticleData *pars, *pa = NULL, *tpa = NULL;
-       ParticleKey *states = NULL;
-       ParticleKey state;
-       ParticleCacheKey *cache = NULL;
-       ParticleBillboardData bb;
-       ParticleSimulationData sim = {NULL};
-       ParticleStrandData sd;
-       StrandBuffer *strandbuf = NULL;
-       StrandVert *svert = NULL;
-       StrandBound *sbound = NULL;
-       StrandRen *strand = NULL;
-       RNG *rng = NULL;
-       float loc[3], loc1[3], loc0[3], mat[4][4], nmat[3][3], co[3], nor[3], duplimat[4][4];
-       float strandlen=0.0f, curlen=0.0f;
-       float hasize, pa_size, r_tilt, r_length;
-       float pa_time, pa_birthtime, pa_dietime;
-       float random, simplify[2], pa_co[3];
-       const float cfra= BKE_scene_frame_get(re->scene);
-       int i, a, k, max_k=0, totpart;
-       bool do_simplify = false, do_surfacecache = false, use_duplimat = false;
-       int totchild=0, step_nbr;
-       int seed, path_nbr=0, orco1=0, num;
-       int totface;
-
-       const int *index_mf_to_mpoly = NULL;
-       const int *index_mp_to_orig = NULL;
-
-/* 1. check that everything is ok & updated */
-       if (psys==NULL)
-               return 0;
-
-       part=psys->part;
-       pars=psys->particles;
-
-       if (part==NULL || pars==NULL || !psys_check_enabled(ob, psys, G.is_rendering))
-               return 0;
-       
-       if (part->ren_as==PART_DRAW_OB || part->ren_as==PART_DRAW_GR || part->ren_as==PART_DRAW_NOT)
-               return 1;
-
-       if ((re->r.scemode & R_VIEWPORT_PREVIEW) && (ob->mode & OB_MODE_PARTICLE_EDIT))
-               return 0;
-
-       if (part->ren_as == PART_DRAW_BB && part->bb_ob == NULL && RE_GetCamera(re) == NULL)
-               return 0;
-
-/* 2. start initializing things */
-
-       /* last possibility to bail out! */
-       psmd = psys_get_modifier(ob, psys);
-       if (!(psmd->modifier.mode & eModifierMode_Render))
-               return 0;
-
-       sim.scene= re->scene;
-       sim.ob= ob;
-       sim.psys= psys;
-       sim.psmd= psmd;
-
-       if (part->phystype==PART_PHYS_KEYED)
-               psys_count_keyed_targets(&sim);
-
-       totchild=psys->totchild;
-
-       /* can happen for disconnected/global hair */
-       if (part->type==PART_HAIR && !psys->childcache)
-               totchild= 0;
-
-       if (re->r.scemode & R_VIEWPORT_PREVIEW) { /* preview render */
-               totchild = (int)((float)totchild * (float)part->disp / 100.0f);
-               step_nbr = 1 << part->draw_step;
-       }
-       else {
-               step_nbr = 1 << part->ren_step;
-       }
-       if (ELEM(part->kink, PART_KINK_SPIRAL))
-               step_nbr += part->kink_extra_steps;
-
-       psys->flag |= PSYS_DRAWING;
-
-       rng= BLI_rng_new(psys->seed);
-
-       totpart=psys->totpart;
-
-       memset(&sd, 0, sizeof(ParticleStrandData));
-       sd.override_uv = -1;
-
-/* 2.1 setup material stff */
-       ma= give_render_material(re, ob, part->omat);
-       
-#if 0  /* XXX old animation system */
-       if (ma->ipo) {
-               calc_ipo(ma->ipo, cfra);
-               execute_ipo((ID *)ma, ma->ipo);
-       }
-#endif  /* XXX old animation system */
-
-       hasize = ma->hasize;
-       seed = ma->seed1;
-
-       re->flag |= R_HALO;
-
-       RE_set_customdata_names(obr, &psmd->dm_final->faceData);
-       sd.totuv = CustomData_number_of_layers(&psmd->dm_final->faceData, CD_MTFACE);
-       sd.totcol = CustomData_number_of_layers(&psmd->dm_final->faceData, CD_MCOL);
-
-       if (ma->texco & TEXCO_UV && sd.totuv) {
-               sd.uvco = MEM_callocN(sd.totuv * 2 * sizeof(float), "particle_uvs");
-
-               if (ma->strand_uvname[0]) {
-                       sd.override_uv = CustomData_get_named_layer_index(&psmd->dm_final->faceData, CD_MTFACE, ma->strand_uvname);
-                       sd.override_uv -= CustomData_get_layer_index(&psmd->dm_final->faceData, CD_MTFACE);
-               }
-       }
-       else
-               sd.uvco = NULL;
-
-       if (sd.totcol)
-               sd.mcol = MEM_callocN(sd.totcol * sizeof(MCol), "particle_mcols");
-
-/* 2.2 setup billboards */
-       if (part->ren_as == PART_DRAW_BB) {
-               int first_uv = CustomData_get_layer_index(&psmd->dm_final->faceData, CD_MTFACE);
-
-               bb.uv[0] = CustomData_get_named_layer_index(&psmd->dm_final->faceData, CD_MTFACE, psys->bb_uvname[0]);
-               if (bb.uv[0] < 0)
-                       bb.uv[0] = CustomData_get_active_layer_index(&psmd->dm_final->faceData, CD_MTFACE);
-
-               bb.uv[1] = CustomData_get_named_layer_index(&psmd->dm_final->faceData, CD_MTFACE, psys->bb_uvname[1]);
-
-               bb.uv[2] = CustomData_get_named_layer_index(&psmd->dm_final->faceData, CD_MTFACE, psys->bb_uvname[2]);
-
-               if (first_uv >= 0) {
-                       bb.uv[0] -= first_uv;
-                       bb.uv[1] -= first_uv;
-                       bb.uv[2] -= first_uv;
-               }
-
-               bb.align = part->bb_align;
-               bb.anim = part->bb_anim;
-               bb.lock = part->draw & PART_DRAW_BB_LOCK;
-               bb.ob = (part->bb_ob ? part->bb_ob : RE_GetCamera(re));
-               bb.split_offset = part->bb_split_offset;
-               bb.totnum = totpart+totchild;
-               bb.uv_split = part->bb_uv_split;
-       }
-       
-/* 2.5 setup matrices */
-       mul_m4_m4m4(mat, re->viewmat, ob->obmat);
-       invert_m4_m4(ob->imat, mat);    /* need to be that way, for imat texture */
-       transpose_m3_m4(nmat, ob->imat);
-
-       if (psys->flag & PSYS_USE_IMAT) {
-               /* psys->imat is the original emitter's inverse matrix, ob->obmat is the duplicated object's matrix */
-               mul_m4_m4m4(duplimat, ob->obmat, psys->imat);
-               use_duplimat = true;
-       }
-
-/* 2.6 setup strand rendering */
-       if (part->ren_as == PART_DRAW_PATH && psys->pathcache) {
-               path_nbr = step_nbr;
-
-               if (path_nbr) {
-                       if (!ELEM(ma->material_type, MA_TYPE_HALO, MA_TYPE_WIRE)) {
-                               sd.orco = get_object_orco(re, psys);
-                               if (!sd.orco) {
-                                       sd.orco = MEM_mallocN(3*sizeof(float)*(totpart+totchild), "particle orcos");
-                                       set_object_orco(re, psys, sd.orco);
-                               }
-                       }
-               }
-
-               if (part->draw & PART_DRAW_REN_ADAPT) {
-                       sd.adapt = 1;
-                       sd.adapt_pix = (float)part->adapt_pix;
-                       sd.adapt_angle = cosf(DEG2RADF((float)part->adapt_angle));
-               }
-
-               if (part->draw & PART_DRAW_REN_STRAND) {
-                       strandbuf= RE_addStrandBuffer(obr, (totpart+totchild)*(path_nbr+1));
-                       strandbuf->ma= ma;
-                       strandbuf->lay= ob->lay;
-                       copy_m4_m4(strandbuf->winmat, re->winmat);
-                       strandbuf->winx= re->winx;
-                       strandbuf->winy= re->winy;
-                       strandbuf->maxdepth= 2;
-                       strandbuf->adaptcos= cosf(DEG2RADF((float)part->adapt_angle));
-                       strandbuf->overrideuv= sd.override_uv;
-                       strandbuf->minwidth= ma->strand_min;
-
-                       if (ma->strand_widthfade == 0.0f)
-                               strandbuf->widthfade= -1.0f;
-                       else if (ma->strand_widthfade >= 1.0f)
-                               strandbuf->widthfade= 2.0f - ma->strand_widthfade;
-                       else
-                               strandbuf->widthfade= 1.0f/MAX2(ma->strand_widthfade, 1e-5f);
-
-                       if (part->flag & PART_HAIR_BSPLINE)
-                               strandbuf->flag |= R_STRAND_BSPLINE;
-                       if (ma->mode & MA_STR_B_UNITS)
-                               strandbuf->flag |= R_STRAND_B_UNITS;
-
-                       svert= strandbuf->vert;
-
-                       if (re->r.mode & R_SPEED)
-                               do_surfacecache = true;
-                       else if ((re->wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT)) && (re->wrld.ao_gather_method == WO_AOGATHER_APPROX))
-                               if (ma->amb != 0.0f)
-                                       do_surfacecache = true;
-
-                       totface= psmd->dm_final->getNumTessFaces(psmd->dm_final);
-                       index_mf_to_mpoly = psmd->dm_final->getTessFaceDataArray(psmd->dm_final, CD_ORIGINDEX);
-                       index_mp_to_orig = psmd->dm_final->getPolyDataArray(psmd->dm_final, CD_ORIGINDEX);
-                       if (index_mf_to_mpoly == NULL) {
-                               index_mp_to_orig = NULL;
-                       }
-                       for (a=0; a<totface; a++)
-                               strandbuf->totbound = max_ii(strandbuf->totbound, (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a): a);
-
-                       strandbuf->totbound++;
-                       strandbuf->bound= MEM_callocN(sizeof(StrandBound)*strandbuf->totbound, "StrandBound");
-                       sbound= strandbuf->bound;
-                       sbound->start= sbound->end= 0;
-               }
-       }
-
-       if (sd.orco == NULL) {
-               sd.orco = MEM_mallocN(3 * sizeof(float), "particle orco");
-               orco1 = 1;
-       }
-
-       if (path_nbr == 0)
-               psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);
-
-/* 3. start creating renderable things */
-       for (a=0, pa=pars; a<totpart+totchild; a++, pa++, seed++) {
-               random = BLI_rng_get_float(rng);
-               /* setup per particle individual stuff */
-               if (a<totpart) {
-                       if (pa->flag & PARS_UNEXIST) continue;
-
-                       pa_time=(cfra-pa->time)/pa->lifetime;
-                       pa_birthtime = pa->time;
-                       pa_dietime = pa->dietime;
-
-                       hasize = ma->hasize;
-
-                       /* XXX 'tpsys' is alwyas NULL, this code won't run! */
-                       /* get orco */
-                       if (tpsys && part->phystype == PART_PHYS_NO) {
-                               tpa = tpsys->particles + pa->num;
-                               psys_particle_on_emitter(
-                                       psmd,
-                                       tpart->from, tpa->num, pa->num_dmcache, tpa->fuv,
-                                       tpa->foffset, co, nor, NULL, NULL, sd.orco, NULL);
-                       }
-                       else {
-                               psys_particle_on_emitter(
-                                       psmd,
-                                       part->from, pa->num, pa->num_dmcache,
-                                       pa->fuv, pa->foffset, co, nor, NULL, NULL, sd.orco, NULL);
-                       }
-
-                       /* get uvco & mcol */
-                       num= pa->num_dmcache;
-
-                       if (num == DMCACHE_NOTFOUND)
-                               if (pa->num < psmd->dm_final->getNumTessFaces(psmd->dm_final))
-                                       num= pa->num;
-
-                       get_particle_uvco_mcol(part->from, psmd->dm_final, pa->fuv, num, &sd);
-
-                       pa_size = pa->size;
-
-                       r_tilt = 2.0f*(psys_frand(psys, a) - 0.5f);
-                       r_length = psys_frand(psys, a+1);
-
-                       if (path_nbr) {
-                               cache = psys->pathcache[a];
-                               max_k = (int)cache->segments;
-                       }
-
-                       if (totchild && (part->draw&PART_DRAW_PARENT)==0) continue;
-               }
-               else {
-                       ChildParticle *cpa= psys->child+a-totpart;
-
-                       if (path_nbr) {
-                               cache = psys->childcache[a-totpart];
-
-                               if (cache->segments < 0)
-                                       continue;
-
-                               max_k = (int)cache->segments;
-                       }
-                       
-                       pa_time = psys_get_child_time(psys, cpa, cfra, &pa_birthtime, &pa_dietime);
-                       pa_size = psys_get_child_size(psys, cpa, cfra, &pa_time);
-
-                       r_tilt = 2.0f*(psys_frand(psys, a + 21) - 0.5f);
-                       r_length = psys_frand(psys, a + 22);
-
-                       num = cpa->num;
-
-                       /* get orco */
-                       if (part->childtype == PART_CHILD_FACES) {
-                               psys_particle_on_emitter(
-                                       psmd,
-                                       PART_FROM_FACE, cpa->num, DMCACHE_ISCHILD,
-                                       cpa->fuv, cpa->foffset, co, nor, NULL, NULL, sd.orco, NULL);
-                       }
-                       else {
-                               ParticleData *par = psys->particles + cpa->parent;
-                               psys_particle_on_emitter(
-                                       psmd,
-                                       part->from, par->num, DMCACHE_ISCHILD, par->fuv,
-                                       par->foffset, co, nor, NULL, NULL, sd.orco, NULL);
-                       }
-
-                       /* get uvco & mcol */
-                       if (part->childtype==PART_CHILD_FACES) {
-                               get_particle_uvco_mcol(PART_FROM_FACE, psmd->dm_final, cpa->fuv, cpa->num, &sd);
-                       }
-                       else {
-                               ParticleData *parent = psys->particles + cpa->parent;
-                               num = parent->num_dmcache;
-
-                               if (num == DMCACHE_NOTFOUND)
-                                       if (parent->num < psmd->dm_final->getNumTessFaces(psmd->dm_final))
-                                               num = parent->num;
-
-                               get_particle_uvco_mcol(part->from, psmd->dm_final, parent->fuv, num, &sd);
-                       }
-
-                       do_simplify = psys_render_simplify_params(psys, cpa, simplify);
-
-                       if (strandbuf) {
-                               int orignum = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, cpa->num) : cpa->num;
-
-                               if ((orignum > sbound - strandbuf->bound) &&
-                                   (orignum < strandbuf->totbound))
-                               {
-                                       sbound = &strandbuf->bound[orignum];
-                                       sbound->start = sbound->end = obr->totstrand;
-                               }
-                       }
-               }
-
-               /* TEXCO_PARTICLE */
-               pa_co[0] = pa_time;
-               pa_co[1] = 0.f;
-               pa_co[2] = 0.f;
-
-               /* surface normal shading setup */
-               if (ma->mode_l & MA_STR_SURFDIFF) {
-                       mul_m3_v3(nmat, nor);
-                       sd.surfnor= nor;
-               }
-               else
-                       sd.surfnor= NULL;
-
-               /* strand render setup */
-               if (strandbuf) {
-                       strand= RE_findOrAddStrand(obr, obr->totstrand++);
-                       strand->buffer= strandbuf;
-                       strand->vert= svert;
-                       copy_v3_v3(strand->orco, sd.orco);
-
-                       if (do_simplify) {
-                               float *ssimplify= RE_strandren_get_simplify(obr, strand, 1);
-                               ssimplify[0]= simplify[0];
-                               ssimplify[1]= simplify[1];
-                       }
-
-                       if (sd.surfnor) {
-                               float *snor= RE_strandren_get_surfnor(obr, strand, 1);
-                               copy_v3_v3(snor, sd.surfnor);
-                       }
-
-                       if (do_surfacecache && num >= 0) {
-                               int *facenum= RE_strandren_get_face(obr, strand, 1);
-                               *facenum= num;
-                       }
-
-                       if (sd.uvco) {
-                               for (i=0; i<sd.totuv; i++) {
-                                       if (i != sd.override_uv) {
-                                               float *uv= RE_strandren_get_uv(obr, strand, i, NULL, 1);
-
-                                               uv[0]= sd.uvco[2*i];
-                                               uv[1]= sd.uvco[2*i+1];
-                                       }
-                               }
-                       }
-                       if (sd.mcol) {
-                               for (i=0; i<sd.totcol; i++) {
-                                       MCol *mc= RE_strandren_get_mcol(obr, strand, i, NULL, 1);
-                                       *mc = sd.mcol[i];
-                               }
-                       }
-
-                       sbound->end++;
-               }
-
-               /* strandco computation setup */
-               if (path_nbr) {
-                       strandlen= 0.0f;
-                       curlen= 0.0f;
-                       for (k=1; k<=path_nbr; k++)
-                               if (k<=max_k)
-                                       strandlen += len_v3v3((cache+k-1)->co, (cache+k)->co);
-               }
-
-               if (path_nbr) {
-                       /* render strands */
-                       for (k=0; k<=path_nbr; k++) {
-                               float time;
-
-                               if (k<=max_k) {
-                                       copy_v3_v3(state.co, (cache+k)->co);
-                                       copy_v3_v3(state.vel, (cache+k)->vel);
-                               }
-                               else
-                                       continue;
-
-                               if (k > 0)
-                                       curlen += len_v3v3((cache+k-1)->co, (cache+k)->co);
-                               time= curlen/strandlen;
-
-                               copy_v3_v3(loc, state.co);
-                               mul_m4_v3(re->viewmat, loc);
-
-                               if (strandbuf) {
-                                       copy_v3_v3(svert->co, loc);
-                                       svert->strandco= -1.0f + 2.0f*time;
-                                       svert++;
-                                       strand->totvert++;
-                               }
-                               else {
-                                       sd.size = hasize;
-
-                                       if (k==1) {
-                                               sd.first = 1;
-                                               sd.time = 0.0f;
-                                               sub_v3_v3v3(loc0, loc1, loc);
-                                               add_v3_v3v3(loc0, loc1, loc0);
-
-                                               particle_curve(re, obr, psmd->dm_final, ma, &sd, loc1, loc0, seed, pa_co);
-                                       }
-
-                                       sd.first = 0;
-                                       sd.time = time;
-
-                                       if (k)
-                                               particle_curve(re, obr, psmd->dm_final, ma, &sd, loc, loc1, seed, pa_co);
-
-                                       copy_v3_v3(loc1, loc);
-                               }
-                       }
-
-               }
-               else {
-                       /* render normal particles */
-                       if (part->trail_count > 1) {
-                               float length = part->path_end * (1.0f - part->randlength * r_length);
-                               int trail_count = part->trail_count * (1.0f - part->randlength * r_length);
-                               float ct = (part->draw & PART_ABS_PATH_TIME) ? cfra : pa_time;
-                               float dt = length / (trail_count ? (float)trail_count : 1.0f);
-
-                               /* make sure we have pointcache in memory before getting particle on path */
-                               psys_make_temp_pointcache(ob, psys);
-
-                               for (i=0; i < trail_count; i++, ct -= dt) {
-                                       if (part->draw & PART_ABS_PATH_TIME) {
-                                               if (ct < pa_birthtime || ct > pa_dietime)
-                                                       continue;
-                                       }
-                                       else if (ct < 0.0f || ct > 1.0f)
-                                               continue;
-
-                                       state.time = (part->draw & PART_ABS_PATH_TIME) ? -ct : ct;
-                                       psys_get_particle_on_path(&sim, a, &state, 1);
-
-                                       if (psys->parent)
-                                               mul_m4_v3(psys->parent->obmat, state.co);
-
-                                       if (use_duplimat)
-                                               mul_m4_v4(duplimat, state.co);
-
-                                       if (part->ren_as == PART_DRAW_BB) {
-                                               bb.random = random;
-                                               bb.offset[0] = part->bb_offset[0];
-                                               bb.offset[1] = part->bb_offset[1];
-                                               bb.size[0] = part->bb_size[0] * pa_size;
-                                               if (part->bb_align==PART_BB_VEL) {
-                                                       float pa_vel = len_v3(state.vel);
-                                                       float head = part->bb_vel_head*pa_vel;
-                                                       float tail = part->bb_vel_tail*pa_vel;
-                                                       bb.size[1] = part->bb_size[1]*pa_size + head + tail;
-                                                       /* use offset to adjust the particle center. this is relative to size, so need to divide! */
-                                                       if (bb.size[1] > 0.0f)
-                                                               bb.offset[1] += (head-tail) / bb.size[1];
-                                               }
-                                               else
-                                                       bb.size[1] = part->bb_size[1] * pa_size;
-                                               bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt);
-                                               bb.time = ct;
-                                               bb.num = a;
-                                       }
-
-                                       pa_co[0] = (part->draw & PART_ABS_PATH_TIME) ? (ct-pa_birthtime)/(pa_dietime-pa_birthtime) : ct;
-                                       pa_co[1] = (float)i/(float)(trail_count-1);
-
-                                       particle_normal_ren(part->ren_as, part, re, obr, psmd->dm_final, ma, &sd, &bb, &state, seed, hasize, pa_co);
-                               }
-                       }
-                       else {
-                               state.time=cfra;
-                               if (psys_get_particle_state(&sim, a, &state, 0)==0)
-                                       continue;
-
-                               if (psys->parent)
-                                       mul_m4_v3(psys->parent->obmat, state.co);
-
-                               if (use_duplimat)
-                                       mul_m4_v3(duplimat, state.co);
-
-                               if (part->ren_as == PART_DRAW_BB) {
-                                       bb.random = random;
-                                       bb.offset[0] = part->bb_offset[0];
-                                       bb.offset[1] = part->bb_offset[1];
-                                       bb.size[0] = part->bb_size[0] * pa_size;
-                                       if (part->bb_align==PART_BB_VEL) {
-                                               float pa_vel = len_v3(state.vel);
-                                               float head = part->bb_vel_head*pa_vel;
-                                               float tail = part->bb_vel_tail*pa_vel;
-                                               bb.size[1] = part->bb_size[1]*pa_size + head + tail;
-                                               /* use offset to adjust the particle center. this is relative to size, so need to divide! */
-                                               if (bb.size[1] > 0.0f)
-                                                       bb.offset[1] += (head-tail) / bb.size[1];
-                                       }
-                                       else
-                                               bb.size[1] = part->bb_size[1] * pa_size;
-                                       bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt);
-                                       bb.time = pa_time;
-                                       bb.num = a;
-                                       bb.lifetime = pa_dietime-pa_birthtime;
-                               }
-
-                               particle_normal_ren(part->ren_as, part, re, obr, psmd->dm_final, ma, &sd, &bb, &state, seed, hasize, pa_co);
-                       }
-               }
-
-               if (orco1==0)
-                       sd.orco+=3;
-
-               if (re->test_break(re->tbh))
-                       break;
-       }
-
-       if (do_surfacecache)
-               strandbuf->surface= cache_strand_surface(re, obr, psmd->dm_final, mat, timeoffset);
-
-/* 4. clean up */
-#if 0  /* XXX old animation system */
-       if (ma) do_mat_ipo(re->scene, ma);
-#endif  /* XXX old animation system */
-
-       if (orco1)
-               MEM_freeN(sd.orco);
-
-       if (sd.uvco)
-               MEM_freeN(sd.uvco);
-       
-       if (sd.mcol)
-               MEM_freeN(sd.mcol);
-
-       if (states)
-               MEM_freeN(states);
-       
-       BLI_rng_free(rng);
-
-       psys->flag &= ~PSYS_DRAWING;
-
-       if (psys->lattice_deform_data) {
-               end_latt_deform(psys->lattice_deform_data);
-               psys->lattice_deform_data = NULL;
-       }
-
-       if (path_nbr && (ma->mode_l & MA_TANGENT_STR)==0)
-               calc_vertexnormals(re, obr, 1, 0, 0);
-
-       return 1;
-}
-
 /* ------------------------------------------------------------------------- */
 /* Halo's                                                                                                                               */
 /* ------------------------------------------------------------------------- */
@@ -4608,38 +3464,15 @@ static void set_dupli_tex_mat(Render *re, ObjectInstanceRen *obi, DupliObject *d
 static void init_render_object_data(Render *re, ObjectRen *obr, int timeoffset)
 {
        Object *ob= obr->ob;
-       ParticleSystem *psys;
-       int i;
-
-       if (obr->psysindex) {
-               if ((!obr->prev || obr->prev->ob != ob || (obr->prev->flag & R_INSTANCEABLE)==0) && ob->type==OB_MESH) {
-                       /* the emitter mesh wasn't rendered so the modifier stack wasn't
-                        * evaluated with render settings */
-                       DerivedMesh *dm;
-                       const CustomDataMask mask = CD_MASK_RENDER_INTERNAL;
 
-                       if (re->r.scemode & R_VIEWPORT_PREVIEW)
-                               dm = mesh_create_derived_view(re->scene, ob, mask);
-                       else
-                               dm = mesh_create_derived_render(re->scene, ob, mask);
-                       dm->release(dm);
-               }
-
-               for (psys=ob->particlesystem.first, i=0; i<obr->psysindex-1; i++)
-                       psys= psys->next;
-
-               render_new_particle_system(re, obr, psys, timeoffset);
-       }
-       else {
-               if (ELEM(ob->type, OB_FONT, OB_CURVE))
-                       init_render_curve(re, obr, timeoffset);
-               else if (ob->type==OB_SURF)
-                       init_render_surf(re, obr, timeoffset);
-               else if (ob->type==OB_MESH)
-                       init_render_mesh(re, obr, timeoffset);
-               else if (ob->type==OB_MBALL)
-                       init_render_mball(re, obr);
-       }
+       if (ELEM(ob->type, OB_FONT, OB_CURVE))
+               init_render_curve(re, obr, timeoffset);
+       else if (ob->type==OB_SURF)
+               init_render_surf(re, obr, timeoffset);
+       else if (ob->type==OB_MESH)
+               init_render_mesh(re, obr, timeoffset);
+       else if (ob->type==OB_MBALL)
+               init_render_mball(re, obr);
 
        finalize_render_object(re, obr, timeoffset);
 
@@ -4653,26 +3486,10 @@ static void add_render_object(Render *re, Object *ob, Object *par, DupliObject *
 {
        ObjectRen *obr;
        ObjectInstanceRen *obi;
-       ParticleSystem *psys;
-       int show_emitter, allow_render= 1, index, psysindex, i;
+       int allow_render= 1, index, i;
 
        index= (dob)? dob->persistent_id[0]: 0;
 
-       /* the emitter has to be processed first (render levels of modifiers) */
-       /* so here we only check if the emitter should be rendered */
-       if (ob->particlesystem.first) {
-               show_emitter= 0;
-               for (psys=ob->particlesystem.first; psys; psys=psys->next) {
-                       show_emitter += psys->part->draw & PART_DRAW_EMITTER;
-                       if (!(re->r.scemode & R_VIEWPORT_PREVIEW))
-                               psys_render_set(ob, psys, re->viewmat, re->winmat, re->winx, re->winy, timeoffset);
-               }
-
-               /* if no psys has "show emitter" selected don't render emitter */
-               if (show_emitter == 0)
-                       allow_render= 0;
-       }
-
        /* one render object for the data itself */
        if (allow_render) {
                obr= RE_addRenderObject(re, ob, par, index, 0, ob->lay);
@@ -4696,35 +3513,6 @@ static void add_render_object(Render *re, Object *ob, Object *par, DupliObject *
                                add_volume(re, obr, ma);
                }
        }
-
-       /* and one render object per particle system */
-       if (ob->particlesystem.first) {
-               psysindex= 1;
-               for (psys=ob->particlesystem.first; psys; psys=psys->next, psysindex++) {
-                       if (!psys_check_enabled(ob, psys, G.is_rendering))
-                               continue;
-                       
-                       obr= RE_addRenderObject(re, ob, par, index, psysindex, ob->lay);
-                       if ((dob && !dob->animated) || (ob->transflag & OB_RENDER_DUPLI)) {
-                               obr->flag |= R_INSTANCEABLE;
-                               copy_m4_m4(obr->obmat, ob->obmat);
-                       }
-                       if (dob)
-                               psys->flag |= PSYS_USE_IMAT;
-                       init_render_object_data(re, obr, timeoffset);
-                       if (!(re->r.scemode & R_VIEWPORT_PREVIEW))
-                               psys_render_restore(ob, psys);
-                       psys->flag &= ~PSYS_USE_IMAT;
-
-                       /* only add instance for objects that have not been used for dupli */
-                       if (!(ob->transflag & OB_RENDER_DUPLI)) {
-                               obi = RE_addRenderInstance(re, obr, ob, par, index, psysindex, NULL, ob->lay, dob);
-                               if (dob) set_dupli_tex_mat(re, obi, dob, omat);
-                       }
-                       else
-                               find_dupli_instances(re, obr, dob);
-               }
-       }
 }
 
 /* par = pointer to duplicator parent, needed for object lookup table */
@@ -4845,11 +3633,8 @@ static int allow_render_object(Render *re, Object *ob, int nolamps, int onlysele
        if (is_object_hidden(re, ob))
                return 0;
 
-       /* Only handle dupli-hiding here if there is no particle systems. Else, let those handle show/noshow. */
-       if (!ob->particlesystem.first) {
-               if ((ob->transflag & OB_DUPLI) && !(ob->transflag & OB_DUPLIFRAMES)) {
-                       return 0;
-               }
+       if ((ob->transflag & OB_DUPLI) && !(ob->transflag & OB_DUPLIFRAMES)) {
+               return 0;
        }
        
        /* don't add non-basic meta objects, ends up having renderobjects with no geometry */
@@ -4867,7 +3652,6 @@ static int allow_render_object(Render *re, Object *ob, int nolamps, int onlysele
 
 static int allow_render_dupli_instance(Render *UNUSED(re), DupliObject *dob, Object *obd)
 {
-       ParticleSystem *psys;
        Material *ma;
        short a, *totmaterial;
 
@@ -4883,10 +3667,6 @@ static int allow_render_dupli_instance(Render *UNUSED(re), DupliObject *dob, Obj
                }
        }
 
-       for (psys=obd->particlesystem.first; psys; psys=psys->next)
-               if (!ELEM(psys->part->ren_as, PART_DRAW_BB, PART_DRAW_LINE, PART_DRAW_PATH, PART_DRAW_OB, PART_DRAW_GR))
-                       return 0;
-
        /* don't allow lamp, animated duplis, or radio render */
        return (render_object_type(obd->type) &&
                        (!(dob->type == OB_DUPLIGROUP) || !dob->animated));
@@ -4898,36 +3678,12 @@ static void dupli_render_particle_set(Render *re, Object *ob, int timeoffset, in
         * settings before calling object_duplilist, to get render level duplis */
        Group *group;
        GroupObject *go;
-       ParticleSystem *psys;
-       DerivedMesh *dm;
 
        if (re->r.scemode & R_VIEWPORT_PREVIEW)
                return;
 
        if (level >= MAX_DUPLI_RECUR)
                return;
-       
-       if (ob->transflag & OB_DUPLIPARTS) {
-               for (psys=ob->particlesystem.first; psys; psys=psys->next) {
-                       if (ELEM(psys->part->ren_as, PART_DRAW_OB, PART_DRAW_GR)) {
-                               if (enable)
-                                       psys_render_set(ob, psys, re->viewmat, re->winmat, re->winx, re->winy, timeoffset);
-                               else
-                                       psys_render_restore(ob, psys);
-                       }
-               }
-
-               if (enable) {
-                       /* this is to make sure we get render level duplis in groups:
-                        * the derivedmesh must be created before init_render_mesh,
-                        * since object_duplilist does dupliparticles before that */
-                       dm = mesh_create_derived_render(re->scene, ob, CD_MASK_RENDER_INTERNAL);
-                       dm->release(dm);
-
-                       for (psys=ob->particlesystem.first; psys; psys=psys->next)
-                               psys_get_modifier(ob, psys)->flag &= ~eParticleSystemFlag_psys_updated;
-               }
-       }
 
        if (ob->dup_group==NULL) return;
        group= ob->dup_group;
@@ -5066,9 +3822,7 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
                                                continue;
 
                                        if (allow_render_dupli_instance(re, dob, obd)) {
-                                               ParticleSystem *psys;
                                                ObjectRen *obr = NULL;
-                                               int psysindex;
                                                float mat[4][4];
 
                                                obi=NULL;
@@ -5099,29 +3853,6 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
                                                        }
                                                }
 
-                                               /* same logic for particles, each particle system has it's own object, so
-                                                * need to go over them separately */
-                                               psysindex= 1;
-                                               for (psys=obd->particlesystem.first; psys; psys=psys->next) {
-                                                       if (dob->type != OB_DUPLIGROUP || (obr=find_dupligroup_dupli(re, obd, psysindex))) {
-                                                               if (obi == NULL)
-                                                                       mul_m4_m4m4(mat, re->viewmat, dob->mat);
-                                                               obi = RE_addRenderInstance(re, NULL, obd, ob, dob->persistent_id[0], psysindex++, mat, obd->lay, dob);
-
-                                                               set_dupli_tex_mat(re, obi, dob, dob_extra->obmat);
-                                                               if (dob->type != OB_DUPLIGROUP) {
-                                                                       copy_v3_v3(obi->dupliorco, dob->orco);
-                                                                       obi->dupliuv[0]= dob->uv[0];
-                                                                       obi->dupliuv[1]= dob->uv[1];
-                                                               }
-                                                               else {
-                                                                       assign_dupligroup_dupli(re, obi, obr, dob);
-                                                                       if (obd->transflag & OB_RENDER_DUPLI)
-                                                                               find_dupli_instances(re, obr, dob);
-                                                               }
-                                                       }
-                                               }
-
                                                if (obi==NULL)
                                                        /* can't instance, just create the object */
                                                        init_render_object(re, obd, ob, dob, dob_extra->obmat, timeoffset);