Random number generator: replace a bunch of usage of the global random number
[blender.git] / source / blender / render / intern / source / convertblender.c
index 31d1fb93477c4d7edf2dfada785196e2af193a63..76179b25871d09990fabfc70771efd32d36fbd16 100644 (file)
@@ -176,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;
@@ -244,14 +245,16 @@ void RE_make_stars(Render *re, Scene *scenev3d, void (*initfunc)(void),
        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) {
@@ -281,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);
                                                
@@ -290,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;
@@ -321,6 +324,8 @@ void RE_make_stars(Render *re, Scene *scenev3d, void (*initfunc)(void),
 
        if (obr)
                re->tothalo += obr->tothalo;
+
+       BLI_rng_free(rng);
 }
 
 
@@ -2662,7 +2667,7 @@ static void init_render_dm(DerivedMesh *dm, Render *re, ObjectRen *obr,
 #ifdef WITH_FREESTYLE
        const int *index_mf_to_mpoly = NULL;
        const int *index_mp_to_orig = NULL;
-       FreestyleFace *ffa;
+       FreestyleFace *ffa = NULL;
 #endif
        /* Curve *cu= ELEM(ob->type, OB_FONT, OB_CURVE) ? ob->data : NULL; */
 
@@ -2693,10 +2698,14 @@ static void init_render_dm(DerivedMesh *dm, Render *re, ObjectRen *obr,
                        ma= give_render_material(re, ob, mat_iter+1);
                        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= dm->getPolyDataArray(dm, CD_FREESTYLE_FACE);
+                       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++) {
@@ -2731,7 +2740,8 @@ static void init_render_dm(DerivedMesh *dm, Render *re, ObjectRen *obr,
                                        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 {
+                                       }
+                                       else {
                                                vlr->freestyle_face_mark= 0;
                                        }
 #endif
@@ -2802,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);
                        }
@@ -2852,7 +2862,7 @@ 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;
        
@@ -2877,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);
                        }
@@ -3243,9 +3253,9 @@ static void add_volume(Render *re, ObjectRen *obr, Material *ma)
 }
 
 #ifdef WITH_FREESTYLE
-static EdgeHash *make_freestyle_edge_mark_hash(DerivedMesh *dm)
+static EdgeHash *make_freestyle_edge_mark_hash(Mesh *me, DerivedMesh *dm)
 {
-       EdgeHash *edge_hash= BLI_edgehash_new();
+       EdgeHash *edge_hash= NULL;
        FreestyleEdge *fed;
        MEdge *medge;
        int totedge, a;
@@ -3254,10 +3264,12 @@ static EdgeHash *make_freestyle_edge_mark_hash(DerivedMesh *dm)
        medge = dm->getEdgeArray(dm);
        totedge = dm->getNumEdges(dm);
        index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
-       fed = dm->getEdgeDataArray(dm, CD_FREESTYLE_EDGE);
+       fed = CustomData_get_layer(&me->edata, CD_FREESTYLE_EDGE);
        if (fed) {
+               edge_hash = BLI_edgehash_new();
                if (!index) {
-                       for (a = 0; a < totedge; a++) {
+                       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);
                        }
@@ -3363,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? */
 
@@ -3394,8 +3410,10 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
                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++) {
@@ -3432,7 +3450,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
                        EdgeHash *edge_hash;
 
                        /* create a hash table of Freestyle edge marks */
-                       edge_hash = make_freestyle_edge_mark_hash(dm);
+                       edge_hash = make_freestyle_edge_mark_hash(me, dm);
 #endif
 
                        /* store customdata names, because DerivedMesh is freed */
@@ -3474,7 +3492,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
 #ifdef WITH_FREESTYLE
                                        index_mf_to_mpoly= dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
                                        index_mp_to_orig= dm->getPolyDataArray(dm, CD_ORIGINDEX);
-                                       ffa= dm->getPolyDataArray(dm, CD_FREESTYLE_FACE);
+                                       ffa= CustomData_get_layer(&me->pdata, CD_FREESTYLE_FACE);
 #endif
                                        
                                        for (a=0; a<end; a++, mface++) {
@@ -3499,23 +3517,25 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
 
 #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 (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;
+                                                                       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 {
+                                                       }
+                                                       else {
                                                                vlr->freestyle_face_mark= 0;
                                                        }
 #endif
@@ -3604,7 +3624,8 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
 
 #ifdef WITH_FREESTYLE
                        /* release the hash table of Freestyle edge marks */
-                       BLI_edgehash_free(edge_hash, NULL);
+                       if (edge_hash)
+                               BLI_edgehash_free(edge_hash, NULL);
 #endif
                        
                        /* exception... we do edges for wire mode. potential conflict when faces exist... */
@@ -4287,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);