Random number generator: replace a bunch of usage of the global random number
[blender.git] / source / blender / render / intern / source / convertblender.c
index 46ab3aeb21ff00006caf76a43f3bf663d2bcf99d..76179b25871d09990fabfc70771efd32d36fbd16 100644 (file)
 #include "BLI_memarena.h"
 #include "BLI_ghash.h"
 #include "BLI_linklist.h"
+#ifdef WITH_FREESTYLE
+#  include "BLI_edgehash.h"
+#endif
+
+#include "BLF_translation.h"
 
 #include "DNA_armature_types.h"
 #include "DNA_camera_types.h"
 /* or for checking vertex normal flips */
 #define FLT_EPSILON10 1.19209290e-06F
 
+/* could enable at some point but for now there are far too many conversions */
+#ifdef __GNUC__
+#  pragma GCC diagnostic ignored "-Wdouble-promotion"
+#endif
+
 /* ------------------------------------------------------------------------- */
 
 /* Stuff for stars. This sits here because it uses gl-things. Part of
@@ -145,6 +155,7 @@ static HaloRen *initstar(Render *re, ObjectRen *obr, const float vec[3], float h
        har->hasize= hasize;
        
        har->zd= 0.0;
+       har->pool = re->pool;
        
        return har;
 }
@@ -156,7 +167,7 @@ static HaloRen *initstar(Render *re, ObjectRen *obr, const float vec[3], float h
  */
 
 void RE_make_stars(Render *re, Scene *scenev3d, void (*initfunc)(void),
-                                  void (*vertexfunc)(float*),  void (*termfunc)(void))
+                   void (*vertexfunc)(float *),  void (*termfunc)(void))
 {
        extern unsigned char hash[512];
        ObjectRen *obr= NULL;
@@ -165,6 +176,7 @@ void RE_make_stars(Render *re, Scene *scenev3d, void (*initfunc)(void),
        Scene *scene;
        Object *camera;
        Camera *cam;
+       RNG *rng;
        double dblrand, hlfrand;
        float vec[4], fx, fy, fz;
        float fac, starmindist, clipend;
@@ -227,20 +239,22 @@ void RE_make_stars(Render *re, Scene *scenev3d, void (*initfunc)(void),
        hlfrand = 2.0 * dblrand;
        
        if (initfunc) {
-               initfunc();     
+               initfunc();
        }
 
        if (re) /* add render object for stars */
                obr= RE_addRenderObject(re, NULL, NULL, 0, 0, 0);
        
+       rng = BLI_rng_new(0);
+       
        for (x = sx, fx = sx * stargrid; x <= ex; x++, fx += stargrid) {
                for (y = sy, fy = sy * stargrid; y <= ey; y++, fy += stargrid) {
                        for (z = sz, fz = sz * stargrid; z <= ez; z++, fz += stargrid) {
 
-                               BLI_srand((hash[z & 0xff] << 24) + (hash[y & 0xff] << 16) + (hash[x & 0xff] << 8));
-                               vec[0] = fx + (hlfrand * BLI_drand()) - dblrand;
-                               vec[1] = fy + (hlfrand * BLI_drand()) - dblrand;
-                               vec[2] = fz + (hlfrand * BLI_drand()) - dblrand;
+                               BLI_rng_seed(rng, (hash[z & 0xff] << 24) + (hash[y & 0xff] << 16) + (hash[x & 0xff] << 8));
+                               vec[0] = fx + (hlfrand * BLI_rng_get_double(rng)) - dblrand;
+                               vec[1] = fy + (hlfrand * BLI_rng_get_double(rng)) - dblrand;
+                               vec[2] = fz + (hlfrand * BLI_rng_get_double(rng)) - dblrand;
                                vec[3] = 1.0;
                                
                                if (vertexfunc) {
@@ -270,7 +284,7 @@ void RE_make_stars(Render *re, Scene *scenev3d, void (*initfunc)(void),
                                        
                                        
                                        if (alpha != 0.0f) {
-                                               fac = force * BLI_drand();
+                                               fac = force * BLI_rng_get_double(rng);
                                                
                                                har = initstar(re, obr, vec, fac);
                                                
@@ -279,9 +293,9 @@ void RE_make_stars(Render *re, Scene *scenev3d, void (*initfunc)(void),
                                                        har->add= 255;
                                                        har->r = har->g = har->b = 1.0;
                                                        if (maxjit) {
-                                                               har->r += ((maxjit * BLI_drand()) ) - maxjit;
-                                                               har->g += ((maxjit * BLI_drand()) ) - maxjit;
-                                                               har->b += ((maxjit * BLI_drand()) ) - maxjit;
+                                                               har->r += ((maxjit * BLI_rng_get_double(rng)) ) - maxjit;
+                                                               har->g += ((maxjit * BLI_rng_get_double(rng)) ) - maxjit;
+                                                               har->b += ((maxjit * BLI_rng_get_double(rng)) ) - maxjit;
                                                        }
                                                        har->hard = 32;
                                                        har->lay= -1;
@@ -310,6 +324,8 @@ void RE_make_stars(Render *re, Scene *scenev3d, void (*initfunc)(void),
 
        if (obr)
                re->tothalo += obr->tothalo;
+
+       BLI_rng_free(rng);
 }
 
 
@@ -364,7 +380,7 @@ static void split_v_renderfaces(ObjectRen *obr, int startvlak, int UNUSED(startv
 
                        if (v==0) {
                                vlr->v1 = RE_vertren_copy(obr, vlr->v1);
-                       } 
+                       }
                }
        }
 }
@@ -446,7 +462,7 @@ static void calc_edge_stress(Render *UNUSED(re), ObjectRen *obr, Mesh *me)
 }
 
 /* gets tangent from tface or orco */
-static void calc_tangent_vector(ObjectRen *obr, VertexTangent **vtangents, MemArena *arena, VlakRen *vlr, int do_nmap_tangent, int do_tangent)
+static void calc_tangent_vector(ObjectRen *obr, VlakRen *vlr, int do_tangent)
 {
        MTFace *tface= RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0);
        VertRen *v1=vlr->v1, *v2=vlr->v2, *v3=vlr->v3, *v4=vlr->v4;
@@ -481,12 +497,6 @@ static void calc_tangent_vector(ObjectRen *obr, VertexTangent **vtangents, MemAr
                add_v3_v3(tav, tang);
        }
        
-       if (do_nmap_tangent) {
-               sum_or_add_vertex_tangent(arena, &vtangents[v1->index], tang, uv1);
-               sum_or_add_vertex_tangent(arena, &vtangents[v2->index], tang, uv2);
-               sum_or_add_vertex_tangent(arena, &vtangents[v3->index], tang, uv3);
-       }
-
        if (v4) {
                tangent_from_uv(uv1, uv3, uv4, v1->co, v3->co, v4->co, vlr->n, tang);
                
@@ -498,12 +508,6 @@ static void calc_tangent_vector(ObjectRen *obr, VertexTangent **vtangents, MemAr
                        tav= RE_vertren_get_tangent(obr, v4, 1);
                        add_v3_v3(tav, tang);
                }
-
-               if (do_nmap_tangent) {
-                       sum_or_add_vertex_tangent(arena, &vtangents[v1->index], tang, uv1);
-                       sum_or_add_vertex_tangent(arena, &vtangents[v3->index], tang, uv3);
-                       sum_or_add_vertex_tangent(arena, &vtangents[v4->index], tang, uv4);
-               }
        }
 }
 
@@ -521,62 +525,68 @@ typedef struct {
 /* interface */
 #include "mikktspace.h"
 
-static int GetNumFaces(const SMikkTSpaceContext * pContext)
+static int GetNumFaces(const SMikkTSpaceContext *pContext)
 {
-       SRenderMeshToTangent * pMesh = (SRenderMeshToTangent *) pContext->m_pUserData;
+       SRenderMeshToTangent *pMesh = (SRenderMeshToTangent *) pContext->m_pUserData;
        return pMesh->obr->totvlak;
 }
 
-static int GetNumVertsOfFace(const SMikkTSpaceContext * pContext, const int face_num)
+static int GetNumVertsOfFace(const SMikkTSpaceContext *pContext, const int face_num)
 {
-       SRenderMeshToTangent * pMesh = (SRenderMeshToTangent *) pContext->m_pUserData;
+       SRenderMeshToTangent *pMesh = (SRenderMeshToTangent *) pContext->m_pUserData;
        VlakRen *vlr= RE_findOrAddVlak(pMesh->obr, face_num);
        return vlr->v4!=NULL ? 4 : 3;
 }
 
-static void GetPosition(const SMikkTSpaceContext * pContext, float fPos[], const int face_num, const int vert_index)
+static void GetPosition(const SMikkTSpaceContext *pContext, float r_co[3], const int face_num, const int vert_index)
 {
        //assert(vert_index>=0 && vert_index<4);
-       SRenderMeshToTangent * pMesh = (SRenderMeshToTangent *) pContext->m_pUserData;
+       SRenderMeshToTangent *pMesh = (SRenderMeshToTangent *) pContext->m_pUserData;
        VlakRen *vlr= RE_findOrAddVlak(pMesh->obr, face_num);
-       const float *co= (&vlr->v1)[vert_index]->co;
-       copy_v3_v3(fPos, co);
+       const float *co = (&vlr->v1)[vert_index]->co;
+       copy_v3_v3(r_co, co);
 }
 
-static void GetTextureCoordinate(const SMikkTSpaceContext * pContext, float fUV[], const int face_num, const int vert_index)
+static void GetTextureCoordinate(const SMikkTSpaceContext *pContext, float r_uv[2], const int face_num, const int vert_index)
 {
        //assert(vert_index>=0 && vert_index<4);
-       SRenderMeshToTangent * pMesh = (SRenderMeshToTangent *) pContext->m_pUserData;
+       SRenderMeshToTangent *pMesh = (SRenderMeshToTangent *) pContext->m_pUserData;
        VlakRen *vlr= RE_findOrAddVlak(pMesh->obr, face_num);
        MTFace *tface= RE_vlakren_get_tface(pMesh->obr, vlr, pMesh->obr->actmtface, NULL, 0);
        const float *coord;
        
-       if (tface != NULL) {
+       if (tface  != NULL) {
                coord= tface->uv[vert_index];
-               fUV[0]= coord[0]; fUV[1]= coord[1];
+               copy_v2_v2(r_uv, coord);
        }
-       else if ((coord= (&vlr->v1)[vert_index]->orco)) {
-               map_to_sphere(&fUV[0], &fUV[1], coord[0], coord[1], coord[2]);
+       else if ((coord = (&vlr->v1)[vert_index]->orco)) {
+               map_to_sphere(&r_uv[0], &r_uv[1], coord[0], coord[1], coord[2]);
        }
        else { /* else we get un-initialized value, 0.0 ok default? */
-               fUV[0]= fUV[1]= 0.0f;
+               zero_v2(r_uv);
        }
 }
 
-static void GetNormal(const SMikkTSpaceContext * pContext, float fNorm[], const int face_num, const int vert_index)
+static void GetNormal(const SMikkTSpaceContext *pContext, float r_no[3], const int face_num, const int vert_index)
 {
        //assert(vert_index>=0 && vert_index<4);
-       SRenderMeshToTangent * pMesh = (SRenderMeshToTangent *) pContext->m_pUserData;
+       SRenderMeshToTangent *pMesh = (SRenderMeshToTangent *) pContext->m_pUserData;
        VlakRen *vlr= RE_findOrAddVlak(pMesh->obr, face_num);
-       const float *n= (&vlr->v1)[vert_index]->n;
-       copy_v3_v3(fNorm, n);
+
+       if (vlr->flag & ME_SMOOTH) {
+               const float *n = (&vlr->v1)[vert_index]->n;
+               copy_v3_v3(r_no, n);
+       }
+       else {
+               negate_v3_v3(r_no, vlr->n);
+       }
 }
-static void SetTSpace(const SMikkTSpaceContext * pContext, const float fvTangent[], const float fSign, const int face_num, const int iVert)
+static void SetTSpace(const SMikkTSpaceContext *pContext, const float fvTangent[3], const float fSign, const int face_num, const int iVert)
 {
        //assert(vert_index>=0 && vert_index<4);
-       SRenderMeshToTangent * pMesh = (SRenderMeshToTangent *) pContext->m_pUserData;
-       VlakRen *vlr= RE_findOrAddVlak(pMesh->obr, face_num);
-       float * ftang= RE_vlakren_get_nmap_tangent(pMesh->obr, vlr, 1);
+       SRenderMeshToTangent *pMesh = (SRenderMeshToTangent *) pContext->m_pUserData;
+       VlakRen *vlr = RE_findOrAddVlak(pMesh->obr, face_num);
+       float *ftang = RE_vlakren_get_nmap_tangent(pMesh->obr, vlr, 1);
        if (ftang!=NULL) {
                copy_v3_v3(&ftang[iVert*4+0], fvTangent);
                ftang[iVert*4+3]=fSign;
@@ -585,17 +595,8 @@ static void SetTSpace(const SMikkTSpaceContext * pContext, const float fvTangent
 
 static void calc_vertexnormals(Render *UNUSED(re), ObjectRen *obr, int do_tangent, int do_nmap_tangent)
 {
-       MemArena *arena= NULL;
-       VertexTangent **vtangents= NULL;
        int a;
 
-       if (do_nmap_tangent) {
-               arena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "nmap tangent arena");
-               BLI_memarena_use_calloc(arena);
-
-               vtangents= MEM_callocN(sizeof(VertexTangent*)*obr->totvert, "VertexTangent");
-       }
-
                /* clear all vertex normals */
        for (a=0; a<obr->totvert; a++) {
                VertRen *ver= RE_findOrAddVert(obr, a);
@@ -613,10 +614,10 @@ static void calc_vertexnormals(Render *UNUSED(re), ObjectRen *obr, int do_tangen
                        accumulate_vertex_normals(vlr->v1->n, vlr->v2->n, vlr->v3->n, n4,
                                vlr->n, vlr->v1->co, vlr->v2->co, vlr->v3->co, c4);
                }
-               if (do_nmap_tangent || do_tangent) {
+               if (do_tangent) {
                        /* tangents still need to be calculated for flat faces too */
                        /* weighting removed, they are not vertexnormals */
-                       calc_tangent_vector(obr, vtangents, arena, vlr, do_nmap_tangent, do_tangent);
+                       calc_tangent_vector(obr, vlr, do_tangent);
                }
        }
 
@@ -630,32 +631,6 @@ static void calc_vertexnormals(Render *UNUSED(re), ObjectRen *obr, int do_tangen
                        if (is_zero_v3(vlr->v3->n)) copy_v3_v3(vlr->v3->n, vlr->n);
                        if (vlr->v4 && is_zero_v3(vlr->v4->n)) copy_v3_v3(vlr->v4->n, vlr->n);
                }
-
-               if (do_nmap_tangent) {
-                       VertRen *v1=vlr->v1, *v2=vlr->v2, *v3=vlr->v3, *v4=vlr->v4;
-                       MTFace *tface= RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0);
-
-                       if (tface) {
-                               int k=0;
-                               float *vtang, *ftang= RE_vlakren_get_nmap_tangent(obr, vlr, 1);
-
-                               vtang= find_vertex_tangent(vtangents[v1->index], tface->uv[0]);
-                               copy_v3_v3(ftang, vtang);
-                               normalize_v3(ftang);
-                               vtang= find_vertex_tangent(vtangents[v2->index], tface->uv[1]);
-                               copy_v3_v3(ftang+4, vtang);
-                               normalize_v3(ftang+4);
-                               vtang= find_vertex_tangent(vtangents[v3->index], tface->uv[2]);
-                               copy_v3_v3(ftang+8, vtang);
-                               normalize_v3(ftang+8);
-                               if (v4) {
-                                       vtang= find_vertex_tangent(vtangents[v4->index], tface->uv[3]);
-                                       copy_v3_v3(ftang+12, vtang);
-                                       normalize_v3(ftang+12);
-                               }
-                               for (k=0; k<4; k++) ftang[4*k+3]=1;
-                       }
-               }
        }
        
        /* normalize vertex normals */
@@ -675,6 +650,7 @@ static void calc_vertexnormals(Render *UNUSED(re), ObjectRen *obr, int do_tangen
                }
        }
 
+       /* normal mapping tangent with mikktspace */
        if (do_nmap_tangent != FALSE) {
                SRenderMeshToTangent mesh2tangent;
                SMikkTSpaceContext sContext;
@@ -696,11 +672,6 @@ static void calc_vertexnormals(Render *UNUSED(re), ObjectRen *obr, int do_tangen
 
                genTangSpaceDefault(&sContext);
        }
-
-       if (arena)
-               BLI_memarena_free(arena);
-       if (vtangents)
-               MEM_freeN(vtangents);
 }
 
 /* ------------------------------------------------------------------------- */
@@ -799,7 +770,7 @@ static VertRen *as_findvertex(VlakRen *vlr, VertRen *UNUSED(ver), ASvert *asv, f
 
 /* note; autosmooth happens in object space still, after applying autosmooth we rotate */
 /* note2; actually, when original mesh and displist are equal sized, face normals are from original mesh */
-static void autosmooth(Render *UNUSED(re), ObjectRen *obr, float mat[][4], int degr)
+static void autosmooth(Render *UNUSED(re), ObjectRen *obr, float mat[4][4], int degr)
 {
        ASvert *asv, *asverts;
        ASface *asf;
@@ -882,7 +853,7 @@ static void autosmooth(Render *UNUSED(re), ObjectRen *obr, float mat[][4], int d
                        else 
                                normal_tri_v3(vlr->n, vlr->v3->co, vlr->v2->co, vlr->v1->co);
                }
-       }               
+       }
 }
 
 /* ------------------------------------------------------------------------- */
@@ -955,7 +926,7 @@ static void flag_render_node_material(Render *re, bNodeTree *ntree)
 {
        bNode *node;
 
-       for (node=ntree->nodes.first; node; node= node->next) {
+       for (node = ntree->nodes.first; node; node = node->next) {
                if (node->id) {
                        if (GS(node->id->name)==ID_MA) {
                                Material *ma= (Material *)node->id;
@@ -1570,9 +1541,12 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
        int i, a, k, max_k=0, totpart, do_simplify = FALSE, do_surfacecache = FALSE, use_duplimat = FALSE;
        int totchild=0;
        int seed, path_nbr=0, orco1=0, num;
-       int totface, *origindex = 0;
+       int totface;
        char **uv_name=0;
 
+       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;
@@ -1613,7 +1587,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
 
        psys->flag |= PSYS_DRAWING;
 
-       rng= rng_new(psys->seed);
+       rng= BLI_rng_new(psys->seed);
 
        totpart=psys->totpart;
 
@@ -1742,9 +1716,13 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
                                        do_surfacecache = TRUE;
 
                        totface= psmd->dm->getNumTessFaces(psmd->dm);
-                       origindex= psmd->dm->getTessFaceDataArray(psmd->dm, CD_ORIGINDEX);
+                       index_mf_to_mpoly = psmd->dm->getTessFaceDataArray(psmd->dm, CD_ORIGINDEX);
+                       index_mp_to_orig = psmd->dm->getPolyDataArray(psmd->dm, CD_ORIGINDEX);
+                       if (index_mf_to_mpoly == NULL) {
+                               index_mp_to_orig = NULL;
+                       }
                        for (a=0; a<totface; a++)
-                               strandbuf->totbound= MAX2(strandbuf->totbound, (origindex)? origindex[a]: 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");
@@ -1763,7 +1741,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
 
 /* 3. start creating renderable things */
        for (a=0, pa=pars; a<totpart+totchild; a++, pa++, seed++) {
-               random = rng_getFloat(rng);
+               random = BLI_rng_get_float(rng);
                /* setup per particle individual stuff */
                if (a<totpart) {
                        if (pa->flag & PARS_UNEXIST) continue;
@@ -1855,7 +1833,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
                        do_simplify = psys_render_simplify_params(psys, cpa, simplify);
 
                        if (strandbuf) {
-                               int orignum= (origindex)? origindex[cpa->num]: cpa->num;
+                               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) {
                                        sbound= strandbuf->bound + orignum;
@@ -1939,7 +1917,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
                                        copy_v3_v3(state.vel, (cache+k)->vel);
                                }
                                else
-                                       continue;       
+                                       continue;
 
                                if (k > 0)
                                        curlen += len_v3v3((cache+k-1)->co, (cache+k)->co);
@@ -2099,7 +2077,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
        if (states)
                MEM_freeN(states);
        
-       rng_free(rng);
+       BLI_rng_free(rng);
 
        psys->flag &= ~PSYS_DRAWING;
 
@@ -2219,7 +2197,7 @@ static short test_for_displace(Render *re, Object *ob)
        return 0;
 }
 
-static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, VertRen *vr, int vindex, float *scale, float mat[][4], float imat[][3])
+static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, VertRen *vr, int vindex, float *scale, float mat[4][4], float imat[3][3])
 {
        MTFace *tface;
        short texco= shi->mat->texco;
@@ -2318,7 +2296,7 @@ static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, Ve
        return;
 }
 
-static void displace_render_face(Render *re, ObjectRen *obr, VlakRen *vlr, float *scale, float mat[][4], float imat[][3])
+static void displace_render_face(Render *re, ObjectRen *obr, VlakRen *vlr, float *scale, float mat[4][4], float imat[3][3])
 {
        ShadeInput shi;
 
@@ -2367,13 +2345,13 @@ static void displace_render_face(Render *re, ObjectRen *obr, VlakRen *vlr, float
        /* Recalculate the face normal  - if flipped before, flip now */
        if (vlr->v4) {
                normal_quad_v3(vlr->n, vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co);
-       }       
+       }
        else {
                normal_tri_v3(vlr->n, vlr->v3->co, vlr->v2->co, vlr->v1->co);
        }
 }
 
-static void do_displacement(Render *re, ObjectRen *obr, float mat[][4], float imat[][3])
+static void do_displacement(Render *re, ObjectRen *obr, float mat[4][4], float imat[3][3])
 {
        VertRen *vr;
        VlakRen *vlr;
@@ -2536,7 +2514,7 @@ static int dl_surf_to_renderdata(ObjectRen *obr, DispList *dl, Material **matar,
                copy_v3_v3(v1->co, data); data += 3;
                if (orco) {
                        v1->orco= orco; orco+= 3; orcoret++;
-               }       
+               }
                mul_m4_v3(mat, v1->co);
                
                for (v = 1; v < sizev; v++) {
@@ -2544,7 +2522,7 @@ static int dl_surf_to_renderdata(ObjectRen *obr, DispList *dl, Material **matar,
                        copy_v3_v3(ver->co, data); data += 3;
                        if (orco) {
                                ver->orco= orco; orco+= 3; orcoret++;
-                       }       
+                       }
                        mul_m4_v3(mat, ver->co);
                }
                /* if V-cyclic, add extra vertices at end of the row */
@@ -2554,8 +2532,8 @@ static int dl_surf_to_renderdata(ObjectRen *obr, DispList *dl, Material **matar,
                        if (orco) {
                                ver->orco= orco; orco+=3; orcoret++; //orcobase + 3*(u*sizev + 0);
                        }
-               }       
-       }       
+               }
+       }
        
        /* Done before next loop to get corner vert */
        if (dl->flag & DL_CYCL_U) nsizev++;
@@ -2608,7 +2586,7 @@ static int dl_surf_to_renderdata(ObjectRen *obr, DispList *dl, Material **matar,
                        
                        p1++; p2++; p3++; p4++;
                }
-       }       
+       }
        /* fix normals for U resp. V cyclic faces */
        sizeu--; sizev--;  /* dec size for face array */
        if (dl->flag & DL_CYCL_V) {
@@ -2686,6 +2664,11 @@ static void init_render_dm(DerivedMesh *dm, Render *re, ObjectRen *obr,
        MVert *mvert = NULL;
        MFace *mface;
        Material *ma;
+#ifdef WITH_FREESTYLE
+       const int *index_mf_to_mpoly = NULL;
+       const int *index_mp_to_orig = NULL;
+       FreestyleFace *ffa = NULL;
+#endif
        /* Curve *cu= ELEM(ob->type, OB_FONT, OB_CURVE) ? ob->data : NULL; */
 
        mvert= dm->getVertArray(dm);
@@ -2716,6 +2699,15 @@ static void init_render_dm(DerivedMesh *dm, Render *re, ObjectRen *obr,
                        end= dm->getNumTessFaces(dm);
                        mface= dm->getTessFaceArray(dm);
 
+#ifdef WITH_FREESTYLE
+                       if(ob->type == OB_MESH) {
+                               Mesh *me= ob->data;
+                               index_mf_to_mpoly= dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
+                               index_mp_to_orig= dm->getPolyDataArray(dm, CD_ORIGINDEX);
+                               ffa= CustomData_get_layer(&me->pdata, CD_FREESTYLE_FACE);
+                       }
+#endif
+
                        for (a=0; a<end; a++, mface++) {
                                int v1, v2, v3, v4, flag;
 
@@ -2744,6 +2736,15 @@ static void init_render_dm(DerivedMesh *dm, Render *re, ObjectRen *obr,
                                        vlr->mat= ma;
                                        vlr->flag= flag;
                                        vlr->ec= 0; /* mesh edges rendered separately */
+#ifdef WITH_FREESTYLE
+                                       if (ffa) {
+                                               int index = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a;
+                                               vlr->freestyle_face_mark= (ffa[index].flag & FREESTYLE_FACE_MARK) ? 1 : 0;
+                                       }
+                                       else {
+                                               vlr->freestyle_face_mark= 0;
+                                       }
+#endif
 
                                        if (len==0) obr->totvlak--;
                                        else {
@@ -2811,11 +2812,11 @@ static void init_render_surf(Render *re, ObjectRen *obr, int timeoffset)
 
        if (ob->parent && (ob->parent->type==OB_LATTICE)) need_orco= 1;
 
-       BKE_displist_make_surf(re->scene, ob, &displist, &dm, 1, 0);
+       BKE_displist_make_surf(re->scene, ob, &displist, &dm, 1, 0, 1);
 
        if (dm) {
                if (need_orco) {
-                       orco= BKE_displist_make_orco(re->scene, ob, dm, 1);
+                       orco= BKE_displist_make_orco(re->scene, ob, dm, 1, 1);
                        if (orco) {
                                set_object_orco(re, ob, orco);
                        }
@@ -2853,7 +2854,7 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
        ListBase disp={NULL, NULL};
        Material **matar;
        float *data, *fp, *orco=NULL;
-       float n[3], mat[4][4];
+       float n[3], mat[4][4], nmat[4][4];
        int nr, startvert, a, b;
        int need_orco=0, totmat;
 
@@ -2861,13 +2862,18 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
        if (ob->type==OB_FONT && cu->str==NULL) return;
        else if (ob->type==OB_CURVE && cu->nurb.first==NULL) return;
 
-       BKE_displist_make_curveTypes_forRender(re->scene, ob, &disp, &dm, 0);
+       BKE_displist_make_curveTypes_forRender(re->scene, ob, &disp, &dm, 0, 1);
        dl= disp.first;
        if (dl==NULL) return;
        
        mult_m4_m4m4(mat, re->viewmat, ob->obmat);
        invert_m4_m4(ob->imat, mat);
 
+       /* local object -> world space transform for normals */
+       copy_m4_m4(nmat, mat);
+       transpose_m4(nmat);
+       invert_m4(nmat);
+
        /* material array */
        totmat= ob->totcol+1;
        matar= MEM_callocN(sizeof(Material*)*totmat, "init_render_surf matar");
@@ -2881,7 +2887,7 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
 
        if (dm) {
                if (need_orco) {
-                       orco= BKE_displist_make_orco(re->scene, ob, dm, 1);
+                       orco= BKE_displist_make_orco(re->scene, ob, dm, 1, 1);
                        if (orco) {
                                set_object_orco(re, ob, orco);
                        }
@@ -2892,7 +2898,7 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
        }
        else {
                if (need_orco) {
-                 orco= get_object_orco(re, ob);
+                       orco = get_object_orco(re, ob);
                }
 
                while (dl) {
@@ -2924,14 +2930,20 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
                                        zero_v3(n);
                                        index= dl->index;
                                        for (a=0; a<dl->parts; a++, index+=3) {
+                                               int v1 = index[0], v2 = index[1], v3 = index[2];
+                                               float *co1 = &dl->verts[v1 * 3],
+                                                     *co2 = &dl->verts[v2 * 3],
+                                                     *co3 = &dl->verts[v3 * 3];
+
                                                vlr= RE_findOrAddVlak(obr, obr->totvlak++);
-                                               vlr->v1= RE_findOrAddVert(obr, startvert+index[0]);
-                                               vlr->v2= RE_findOrAddVert(obr, startvert+index[1]);
-                                               vlr->v3= RE_findOrAddVert(obr, startvert+index[2]);
+                                               vlr->v1= RE_findOrAddVert(obr, startvert + v1);
+                                               vlr->v2= RE_findOrAddVert(obr, startvert + v2);
+                                               vlr->v3= RE_findOrAddVert(obr, startvert + v3);
                                                vlr->v4= NULL;
 
-                                               if (area_tri_v3(vlr->v3->co, vlr->v2->co, vlr->v1->co)>FLT_EPSILON) {
-                                                       normal_tri_v3(tmp, vlr->v3->co, vlr->v2->co, vlr->v1->co);
+                                               /* to prevent float accuracy issues, we calculate normal in local object space (not world) */
+                                               if (area_tri_v3(co3, co2, co1)>FLT_EPSILON10) {
+                                                       normal_tri_v3(tmp, co3, co2, co1);
                                                        add_v3_v3(n, tmp);
                                                }
 
@@ -2940,6 +2952,8 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
                                                vlr->ec= 0;
                                        }
 
+                                       /* transform normal to world space */
+                                       mul_m4_v3(nmat, n);
                                        normalize_v3(n);
 
                                        /* vertex normals */
@@ -3192,7 +3206,12 @@ static void init_camera_inside_volumes(Render *re)
 {
        ObjectInstanceRen *obi;
        VolumeOb *vo;
-       float co[3] = {0.f, 0.f, 0.f};
+       /* coordinates are all in camera space, so camera coordinate is zero. we also
+        * add an offset for the clip start, however note that with clip start it's
+        * actually impossible to do a single 'inside' test, since there will not be
+        * a single point where all camera rays start from, though for small clip start
+        * they will be close together. */
+       float co[3] = {0.f, 0.f, -re->clipsta};
 
        for (vo= re->volumes.first; vo; vo= vo->next) {
                for (obi= re->instancetable.first; obi; obi= obi->next) {
@@ -3233,6 +3252,47 @@ static void add_volume(Render *re, ObjectRen *obr, Material *ma)
        BLI_addtail(&re->volumes, vo);
 }
 
+#ifdef WITH_FREESTYLE
+static EdgeHash *make_freestyle_edge_mark_hash(Mesh *me, DerivedMesh *dm)
+{
+       EdgeHash *edge_hash= NULL;
+       FreestyleEdge *fed;
+       MEdge *medge;
+       int totedge, a;
+       int *index;
+
+       medge = dm->getEdgeArray(dm);
+       totedge = dm->getNumEdges(dm);
+       index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
+       fed = CustomData_get_layer(&me->edata, CD_FREESTYLE_EDGE);
+       if (fed) {
+               edge_hash = BLI_edgehash_new();
+               if (!index) {
+                       BLI_assert(me->totedge == totedge);
+                       for (a = 0; a < me->totedge; a++) {
+                               if (fed[a].flag & FREESTYLE_EDGE_MARK)
+                                       BLI_edgehash_insert(edge_hash, medge[a].v1, medge[a].v2, medge+a);
+                       }
+               }
+               else {
+                       for (a = 0; a < totedge; a++) {
+                               if (index[a] == ORIGINDEX_NONE)
+                                       continue;
+                               if (fed[index[a]].flag & FREESTYLE_EDGE_MARK)
+                                       BLI_edgehash_insert(edge_hash, medge[a].v1, medge[a].v2, medge+a);
+                       }
+               }
+       }
+       return edge_hash;
+}
+
+static int has_freestyle_edge_mark(EdgeHash *edge_hash, int v1, int v2)
+{
+       MEdge *medge= BLI_edgehash_lookup(edge_hash, v1, v2);
+       return (!medge) ? 0 : 1;
+}
+#endif
+
 static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
 {
        Object *ob= obr->ob;
@@ -3246,12 +3306,15 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
        CustomDataMask mask;
        float xn, yn, zn,  imat[3][3], mat[4][4];  //nor[3],
        float *orco=0;
-       int need_orco=0, need_stress=0, need_nmap_tangent=0, need_tangent=0;
+       int need_orco=0, need_stress=0, need_nmap_tangent=0, need_tangent=0, need_origindex=0;
        int a, a1, ok, vertofs;
        int end, do_autosmooth = FALSE, totvert = 0;
        int use_original_normals = FALSE;
        int recalc_normals = 0; /* false by default */
        int negative_scale;
+#ifdef WITH_FREESTYLE
+       FreestyleFace *ffa;
+#endif
 
        me= ob->data;
 
@@ -3274,11 +3337,11 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
                        /* normalmaps, test if tangents needed, separated from shading */
                        if (ma->mode_l & MA_TANGENT_V) {
                                need_tangent= 1;
-                               if (me->mtface==NULL)
+                               if (me->mtpoly==NULL)
                                        need_orco= 1;
                        }
                        if (ma->mode_l & MA_NORMAP_TANG) {
-                               if (me->mtface==NULL) {
+                               if (me->mtpoly==NULL) {
                                        need_orco= 1;
                                        need_tangent= 1;
                                }
@@ -3289,13 +3352,17 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
 
        if (re->flag & R_NEED_TANGENT) {
                /* exception for tangent space baking */
-               if (me->mtface==NULL) {
+               if (me->mtpoly==NULL) {
                        need_orco= 1;
                        need_tangent= 1;
                }
                need_nmap_tangent= 1;
        }
        
+       /* origindex currently only used when baking to vertex colors */
+       if (re->flag & R_BAKING && re->r.bake_flag & R_BAKE_VCOL)
+               need_origindex= 1;
+
        /* check autosmooth and displacement, we then have to skip only-verts optimize */
        do_autosmooth |= (me->flag & ME_AUTOSMOOTH);
        if (do_autosmooth)
@@ -3308,6 +3375,10 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
                if (need_orco)
                        mask |= CD_MASK_ORCO;
 
+#ifdef WITH_FREESTYLE
+       mask |= CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE;
+#endif
+
        dm= mesh_create_derived_render(re->scene, ob, mask);
        if (dm==NULL) return;   /* in case duplicated object fails? */
 
@@ -3333,6 +3404,17 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
                make_render_halos(re, obr, me, totvert, mvert, ma, orco);
        }
        else {
+               const int *index_vert_orig = NULL;
+               const int *index_mf_to_mpoly = NULL;
+               const int *index_mp_to_orig = NULL;
+               if (need_origindex) {
+                       index_vert_orig = dm->getVertDataArray(dm, CD_ORIGINDEX);
+                       /* double lookup for faces -> polys */
+#ifdef WITH_FREESTYLE
+                       index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
+                       index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
+#endif
+               }
 
                for (a=0; a<totvert; a++, mvert++) {
                        ver= RE_findOrAddVert(obr, obr->totvert++);
@@ -3349,9 +3431,28 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
                                ver->orco= orco;
                                orco+=3;
                        }
+
+                       if (need_origindex) {
+                               int *origindex;
+                               origindex = RE_vertren_get_origindex(obr, ver, 1);
+
+                               /* Use orig index array if it's available (e.g. in the presence
+                                * of modifiers). */
+                               if (index_vert_orig)
+                                       *origindex = index_vert_orig[a];
+                               else
+                                       *origindex = a;
+                       }
                }
                
                if (!timeoffset) {
+#ifdef WITH_FREESTYLE
+                       EdgeHash *edge_hash;
+
+                       /* create a hash table of Freestyle edge marks */
+                       edge_hash = make_freestyle_edge_mark_hash(me, dm);
+#endif
+
                        /* store customdata names, because DerivedMesh is freed */
                        RE_set_customdata_names(obr, &dm->faceData);
 
@@ -3388,6 +3489,11 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
                                if (ok) {
                                        end= dm->getNumTessFaces(dm);
                                        mface= dm->getTessFaceArray(dm);
+#ifdef WITH_FREESTYLE
+                                       index_mf_to_mpoly= dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
+                                       index_mp_to_orig= dm->getPolyDataArray(dm, CD_ORIGINDEX);
+                                       ffa= CustomData_get_layer(&me->pdata, CD_FREESTYLE_FACE);
+#endif
                                        
                                        for (a=0; a<end; a++, mface++) {
                                                int v1, v2, v3, v4, flag;
@@ -3409,6 +3515,31 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
                                                        if (v4) vlr->v4= RE_findOrAddVert(obr, vertofs+v4);
                                                        else vlr->v4= 0;
 
+#ifdef WITH_FREESTYLE
+                                                       /* Freestyle edge/face marks */
+                                                       if (edge_hash) {
+                                                               int edge_mark = 0;
+
+                                                               if (has_freestyle_edge_mark(edge_hash, v1, v2)) edge_mark |= R_EDGE_V1V2;
+                                                               if (has_freestyle_edge_mark(edge_hash, v2, v3)) edge_mark |= R_EDGE_V2V3;
+                                                               if (!v4) {
+                                                                       if (has_freestyle_edge_mark(edge_hash, v3, v1)) edge_mark |= R_EDGE_V3V1;
+                                                               }
+                                                               else {
+                                                                       if (has_freestyle_edge_mark(edge_hash, v3, v4)) edge_mark |= R_EDGE_V3V4;
+                                                                       if (has_freestyle_edge_mark(edge_hash, v4, v1)) edge_mark |= R_EDGE_V4V1;
+                                                               }
+                                                               vlr->freestyle_edge_mark= edge_mark;
+                                                       }
+                                                       if (ffa) {
+                                                               int index = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a;
+                                                               vlr->freestyle_face_mark= (ffa[index].flag & FREESTYLE_FACE_MARK) ? 1 : 0;
+                                                       }
+                                                       else {
+                                                               vlr->freestyle_face_mark= 0;
+                                                       }
+#endif
+
                                                        /* render normals are inverted in render */
                                                        if (use_original_normals) {
                                                                MFace *mf= me->mface+a;
@@ -3470,11 +3601,32 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
                                                                                }
                                                                        }
                                                                }
+
+                                                               if (need_origindex) {
+                                                                       /* Find original index of mpoly for this tessface. Options:
+                                                                        * - Modified mesh; two-step look up from tessface -> modified mpoly -> original mpoly
+                                                                        * - OR Tesselated mesh; look up from tessface -> mpoly
+                                                                        * - OR Failsafe; tessface == mpoly. Could probably assert(false) in this case? */
+                                                                       int *origindex;
+                                                                       origindex = RE_vlakren_get_origindex(obr, vlr, 1);
+                                                                       if (index_mf_to_mpoly && index_mp_to_orig)
+                                                                               *origindex = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a);
+                                                                       else if (index_mf_to_mpoly)
+                                                                               *origindex = index_mf_to_mpoly[a];
+                                                                       else
+                                                                               *origindex = a;
+                                                               }
                                                        }
                                                }
                                        }
                                }
                        }
+
+#ifdef WITH_FREESTYLE
+                       /* release the hash table of Freestyle edge marks */
+                       if (edge_hash)
+                               BLI_edgehash_free(edge_hash, NULL);
+#endif
                        
                        /* exception... we do edges for wire mode. potential conflict when faces exist... */
                        end= dm->getNumEdges(dm);
@@ -3554,7 +3706,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
 /* Lamps and Shadowbuffers                                                                                                      */
 /* ------------------------------------------------------------------------- */
 
-static void initshadowbuf(Render *re, LampRen *lar, float mat[][4])
+static void initshadowbuf(Render *re, LampRen *lar, float mat[4][4])
 {
        struct ShadBuf *shb;
        float viewinv[4][4];
@@ -3616,22 +3768,22 @@ static void area_lamp_vectors(LampRen *lar)
        /* corner vectors */
        lar->area[0][0]= lar->co[0] - xsize*lar->mat[0][0] - ysize*lar->mat[1][0];
        lar->area[0][1]= lar->co[1] - xsize*lar->mat[0][1] - ysize*lar->mat[1][1];
-       lar->area[0][2]= lar->co[2] - xsize*lar->mat[0][2] - ysize*lar->mat[1][2];      
+       lar->area[0][2]= lar->co[2] - xsize*lar->mat[0][2] - ysize*lar->mat[1][2];
 
        /* corner vectors */
        lar->area[1][0]= lar->co[0] - xsize*lar->mat[0][0] + ysize*lar->mat[1][0];
        lar->area[1][1]= lar->co[1] - xsize*lar->mat[0][1] + ysize*lar->mat[1][1];
-       lar->area[1][2]= lar->co[2] - xsize*lar->mat[0][2] + ysize*lar->mat[1][2];      
+       lar->area[1][2]= lar->co[2] - xsize*lar->mat[0][2] + ysize*lar->mat[1][2];
 
        /* corner vectors */
        lar->area[2][0]= lar->co[0] + xsize*lar->mat[0][0] + ysize*lar->mat[1][0];
        lar->area[2][1]= lar->co[1] + xsize*lar->mat[0][1] + ysize*lar->mat[1][1];
-       lar->area[2][2]= lar->co[2] + xsize*lar->mat[0][2] + ysize*lar->mat[1][2];      
+       lar->area[2][2]= lar->co[2] + xsize*lar->mat[0][2] + ysize*lar->mat[1][2];
 
        /* corner vectors */
        lar->area[3][0]= lar->co[0] + xsize*lar->mat[0][0] - ysize*lar->mat[1][0];
        lar->area[3][1]= lar->co[1] + xsize*lar->mat[0][1] - ysize*lar->mat[1][1];
-       lar->area[3][2]= lar->co[2] + xsize*lar->mat[0][2] - ysize*lar->mat[1][2];      
+       lar->area[3][2]= lar->co[2] + xsize*lar->mat[0][2] - ysize*lar->mat[1][2];
        /* only for correction button size, matrix size works on energy */
        lar->areasize= lar->dist*lar->dist/(4.0f*xsize*ysize);
 }
@@ -3989,18 +4141,10 @@ static void set_renderlayer_lightgroups(Render *re, Scene *sce)
 void init_render_world(Render *re)
 {
        int a;
-       char *cp;
        
        if (re->scene && re->scene->world) {
                re->wrld= *(re->scene->world);
-               
-               cp= (char *)&re->wrld.fastcol;
-               
-               cp[0]= 255.0f*re->wrld.horr;
-               cp[1]= 255.0f*re->wrld.horg;
-               cp[2]= 255.0f*re->wrld.horb;
-               cp[3]= 1;
-               
+
                copy_v3_v3(re->grvec, re->viewmat[2]);
                normalize_v3(re->grvec);
                copy_m3_m4(re->imat, re->viewinv);
@@ -4164,6 +4308,26 @@ static void split_quads(ObjectRen *obr, int dir)
                                }
                                vlr->v4 = vlr1->v4 = NULL;
                                
+#ifdef WITH_FREESTYLE
+                               /* Freestyle edge marks */
+                               if (vlr->flag & R_DIVIDE_24) {
+                                       vlr1->freestyle_edge_mark=
+                                               ((vlr->freestyle_edge_mark & R_EDGE_V2V3) ? R_EDGE_V1V2 : 0) |
+                                               ((vlr->freestyle_edge_mark & R_EDGE_V3V4) ? R_EDGE_V2V3 : 0);
+                                       vlr->freestyle_edge_mark=
+                                               ((vlr->freestyle_edge_mark & R_EDGE_V1V2) ? R_EDGE_V1V2 : 0) |
+                                               ((vlr->freestyle_edge_mark & R_EDGE_V4V1) ? R_EDGE_V3V1 : 0);
+                               }
+                               else {
+                                       vlr1->freestyle_edge_mark=
+                                               ((vlr->freestyle_edge_mark & R_EDGE_V3V4) ? R_EDGE_V2V3 : 0) |
+                                               ((vlr->freestyle_edge_mark & R_EDGE_V4V1) ? R_EDGE_V3V1 : 0);
+                                       vlr->freestyle_edge_mark=
+                                               ((vlr->freestyle_edge_mark & R_EDGE_V1V2) ? R_EDGE_V1V2 : 0) |
+                                               ((vlr->freestyle_edge_mark & R_EDGE_V2V3) ? R_EDGE_V2V3 : 0);
+                               }
+#endif
+
                                /* new normals */
                                normal_tri_v3(vlr->n, vlr->v3->co, vlr->v2->co, vlr->v1->co);
                                normal_tri_v3(vlr1->n, vlr1->v3->co, vlr1->v2->co, vlr1->v1->co);
@@ -4274,6 +4438,26 @@ static void check_non_flat_quads(ObjectRen *obr)
                                        /* new normals */
                                        normal_tri_v3(vlr->n, vlr->v3->co, vlr->v2->co, vlr->v1->co);
                                        normal_tri_v3(vlr1->n, vlr1->v3->co, vlr1->v2->co, vlr1->v1->co);
+
+#ifdef WITH_FREESTYLE
+                                       /* Freestyle edge marks */
+                                       if (vlr->flag & R_DIVIDE_24) {
+                                               vlr1->freestyle_edge_mark=
+                                                       ((vlr->freestyle_edge_mark & R_EDGE_V2V3) ? R_EDGE_V1V2 : 0) |
+                                                       ((vlr->freestyle_edge_mark & R_EDGE_V3V4) ? R_EDGE_V2V3 : 0);
+                                               vlr->freestyle_edge_mark=
+                                                       ((vlr->freestyle_edge_mark & R_EDGE_V1V2) ? R_EDGE_V1V2 : 0) |
+                                                       ((vlr->freestyle_edge_mark & R_EDGE_V4V1) ? R_EDGE_V3V1 : 0);
+                                       }
+                                       else {
+                                               vlr1->freestyle_edge_mark=
+                                                       ((vlr->freestyle_edge_mark & R_EDGE_V3V4) ? R_EDGE_V2V3 : 0) |
+                                                       ((vlr->freestyle_edge_mark & R_EDGE_V4V1) ? R_EDGE_V3V1 : 0);
+                                               vlr->freestyle_edge_mark=
+                                                       ((vlr->freestyle_edge_mark & R_EDGE_V1V2) ? R_EDGE_V1V2 : 0) |
+                                                       ((vlr->freestyle_edge_mark & R_EDGE_V2V3) ? R_EDGE_V2V3 : 0);
+                                       }
+#endif
                                }
                                /* clear the flag when not divided */
                                else vlr->flag &= ~R_DIVIDE_24;
@@ -4332,7 +4516,7 @@ static void finalize_render_object(Render *re, ObjectRen *obr, int timeoffset)
                                
                                /* compute average bounding box of strandpoint itself (width) */
                                if (obr->strandbuf->flag & R_STRAND_B_UNITS)
-                                       obr->strandbuf->maxwidth= MAX2(obr->strandbuf->ma->strand_sta, obr->strandbuf->ma->strand_end);
+                                       obr->strandbuf->maxwidth = max_ff(obr->strandbuf->ma->strand_sta, obr->strandbuf->ma->strand_end);
                                else
                                        obr->strandbuf->maxwidth= 0.0f;
                                
@@ -4537,7 +4721,7 @@ static void add_render_object(Render *re, Object *ob, Object *par, DupliObject *
        ParticleSystem *psys;
        int show_emitter, allow_render= 1, index, psysindex, i;
 
-       index= (dob)? dob->index: 0;
+       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 */
@@ -4712,10 +4896,12 @@ void RE_Database_Free(Render *re)
 static int allow_render_object(Render *re, Object *ob, int nolamps, int onlyselected, Object *actob)
 {
        /* override not showing object when duplis are used with particles */
-       if (ob->transflag & OB_DUPLIPARTS)
-               ; /* let particle system(s) handle showing vs. not showing */
-       else if ((ob->transflag & OB_DUPLI) && !(ob->transflag & OB_DUPLIFRAMES))
+       if (ob->transflag & OB_DUPLIPARTS) {
+               /* pass */  /* let particle system(s) handle showing vs. not showing */
+       }
+       else 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 */
        if (ob->type == OB_MBALL && ob!=BKE_mball_basis_find(re->scene, ob))
@@ -4742,7 +4928,7 @@ static int allow_render_dupli_instance(Render *UNUSED(re), DupliObject *dob, Obj
 
        if (totmaterial) {
                for (a= 0; a<*totmaterial; a++) {
-                       ma= give_current_material(obd, a);
+                       ma= give_current_material(obd, a + 1);
                        if (ma && (ma->material_type == MA_TYPE_HALO))
                                return 0;
                }
@@ -4933,7 +5119,8 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
                                                 * a dupligroup that has already been created before */
                                                if (dob->type != OB_DUPLIGROUP || (obr=find_dupligroup_dupli(re, obd, 0))) {
                                                        mult_m4_m4m4(mat, re->viewmat, dob->mat);
-                                                       obi= RE_addRenderInstance(re, NULL, obd, ob, dob->index, 0, mat, obd->lay);
+                                                                                                               /* ob = particle system, use that layer */
+                                                       obi= RE_addRenderInstance(re, NULL, obd, ob, dob->persistent_id[0], 0, mat, ob->lay); 
 
                                                        /* fill in instance variables for texturing */
                                                        set_dupli_tex_mat(re, obi, dob);
@@ -4960,7 +5147,7 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
                                                        if (dob->type != OB_DUPLIGROUP || (obr=find_dupligroup_dupli(re, obd, psysindex))) {
                                                                if (obi == NULL)
                                                                        mult_m4_m4m4(mat, re->viewmat, dob->mat);
-                                                               obi= RE_addRenderInstance(re, NULL, obd, ob, dob->index, psysindex++, mat, obd->lay);
+                                                               obi= RE_addRenderInstance(re, NULL, obd, ob, dob->persistent_id[0], psysindex++, mat, obd->lay);
 
                                                                set_dupli_tex_mat(re, obi, dob);
                                                                if (dob->type != OB_DUPLIGROUP) {
@@ -5053,8 +5240,8 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
                 * following calls don't depend on 'RE_SetCamera' */
                RE_SetCamera(re, camera);
 
-               normalize_m4(camera->obmat);
-               invert_m4_m4(mat, camera->obmat);
+               normalize_m4_m4(mat, camera->obmat);
+               invert_m4(mat);
                RE_SetView(re, mat);
                camera->recalc= OB_RECALC_OB; /* force correct matrix for scaled cameras */
        }
@@ -5098,7 +5285,7 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
                tothalo= re->tothalo;
                if (!re->test_break(re->tbh)) {
                        if (re->wrld.mode & WO_STARS) {
-                               re->i.infostr= "Creating Starfield";
+                               re->i.infostr = IFACE_("Creating Starfield");
                                re->stats_draw(re->sdh, &re->i);
                                RE_make_stars(re, NULL, NULL, NULL, NULL);
                        }
@@ -5107,7 +5294,7 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
                
                init_camera_inside_volumes(re);
                
-               re->i.infostr= "Creating Shadowbuffers";
+               re->i.infostr = IFACE_("Creating Shadowbuffers");
                re->stats_draw(re->sdh, &re->i);
 
                /* SHADOW BUFFER */
@@ -5157,7 +5344,7 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
        else
                re->i.convertdone = TRUE;
        
-       re->i.infostr= NULL;
+       re->i.infostr = NULL;
        re->stats_draw(re->sdh, &re->i);
 }
 
@@ -5167,7 +5354,7 @@ void RE_DataBase_ApplyWindow(Render *re)
        project_renderdata(re, projectverto, 0, 0, 0);
 }
 
-void RE_DataBase_GetView(Render *re, float mat[][4])
+void RE_DataBase_GetView(Render *re, float mat[4][4])
 {
        copy_m4_m4(mat, re->viewmat);
 }
@@ -5203,8 +5390,8 @@ static void database_fromscene_vectors(Render *re, Scene *scene, unsigned int la
        
        /* if no camera, viewmat should have been set! */
        if (camera) {
-               normalize_m4(camera->obmat);
-               invert_m4_m4(mat, camera->obmat);
+               normalize_m4_m4(mat, camera->obmat);
+               invert_m4(mat);
                RE_SetView(re, mat);
        }
        
@@ -5334,7 +5521,7 @@ static float *calculate_strandsurface_speedvectors(Render *re, ObjectInstanceRen
                        calculate_speedvector(vec, 1, winsq, winroot, mesh->co[a], ho, winspeed[a]);
                }
 
-               return (float*)winspeed;
+               return (float *)winspeed;
        }
 
        return NULL;
@@ -5570,7 +5757,7 @@ void RE_Database_FromScene_Vectors(Render *re, Main *bmain, Scene *sce, unsigned
        ListBase strandsurface;
        int step;
        
-       re->i.infostr= "Calculating previous frame vectors";
+       re->i.infostr = IFACE_("Calculating previous frame vectors");
        re->r.mode |= R_SPEED;
        
        speedvector_project(re, NULL, NULL, NULL);      /* initializes projection code */
@@ -5589,10 +5776,10 @@ void RE_Database_FromScene_Vectors(Render *re, Main *bmain, Scene *sce, unsigned
        
        if (!re->test_break(re->tbh)) {
                /* creates entire dbase */
-               re->i.infostr= "Calculating next frame vectors";
+               re->i.infostr = IFACE_("Calculating next frame vectors");
                
                database_fromscene_vectors(re, sce, lay, +1);
-       }       
+       }
        /* copy away vertex info */
        copy_dbase_object_vectors(re, &newtable);
        
@@ -5637,7 +5824,7 @@ void RE_Database_FromScene_Vectors(Render *re, Main *bmain, Scene *sce, unsigned
                                                ok= 1;
                                }
                                if (ok==0) {
-                                       printf("speed table: missing object %s\n", obi->ob->id.name+2);
+                                       printf("speed table: missing object %s\n", obi->ob->id.name + 2);
                                        continue;
                                }
 
@@ -5653,7 +5840,7 @@ void RE_Database_FromScene_Vectors(Render *re, Main *bmain, Scene *sce, unsigned
                                        if (obi->totvector==oldobi->totvector)
                                                calculate_speedvectors(re, obi, oldobi->vectors, step);
                                        else
-                                               printf("Warning: object %s has different amount of vertices or strands on other frame\n", obi->ob->id.name+2);
+                                               printf("Warning: object %s has different amount of vertices or strands on other frame\n", obi->ob->id.name + 2);
                                }  /* not fluidsim */
 
                                oldobi= oldobi->next;
@@ -5675,7 +5862,7 @@ void RE_Database_FromScene_Vectors(Render *re, Main *bmain, Scene *sce, unsigned
                }
        }
        
-       re->i.infostr= NULL;
+       re->i.infostr = NULL;
        re->stats_draw(re->sdh, &re->i);
 }
 
@@ -5743,8 +5930,8 @@ void RE_Database_Baking(Render *re, Main *bmain, Scene *scene, unsigned int lay,
        
        /* if no camera, set unit */
        if (camera) {
-               normalize_m4(camera->obmat);
-               invert_m4_m4(mat, camera->obmat);
+               normalize_m4_m4(mat, camera->obmat);
+               invert_m4(mat);
                RE_SetView(re, mat);
        }
        else {