Orange: tuesday sync with bf-blender
[blender.git] / source / blender / renderconverter / intern / convertBlenderScene.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  * Interface to transform the Blender scene into renderable data.
32  */
33
34 #include <math.h>
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include <string.h>
38 #include <limits.h>          /* for INT_MAX                 */
39
40 #include "blendef.h"
41 #include "MTC_matrixops.h"
42
43 #include "MEM_guardedalloc.h"
44
45 #include "BLI_arithb.h"
46 #include "BLI_blenlib.h"
47 #include "BLI_rand.h"
48 #include "BLI_memarena.h"
49 #include "BLI_ghash.h"
50
51 #include "DNA_armature_types.h"
52 #include "DNA_camera_types.h"
53 #include "DNA_material_types.h"
54 #include "DNA_curve_types.h"
55 #include "DNA_effect_types.h"
56 #include "DNA_group_types.h"
57 #include "DNA_lamp_types.h"
58 #include "DNA_lattice_types.h"
59 #include "DNA_mesh_types.h"
60 #include "DNA_meshdata_types.h"
61 #include "DNA_meta_types.h"
62 #include "DNA_object_types.h"
63 #include "DNA_object_force.h"
64 #include "DNA_scene_types.h"
65 #include "DNA_texture_types.h"
66 #include "DNA_view3d_types.h"
67
68 #include "BKE_anim.h"
69 #include "BKE_armature.h"
70 #include "BKE_action.h"
71 #include "BKE_curve.h"
72 #include "BKE_constraint.h"
73 #include "BKE_displist.h"
74 #include "BKE_deform.h"
75 #include "BKE_DerivedMesh.h"
76 #include "BKE_effect.h"
77 #include "BKE_global.h"
78 #include "BKE_group.h"
79 #include "BKE_key.h"
80 #include "BKE_ipo.h"
81 #include "BKE_lattice.h"
82 #include "BKE_material.h"
83 #include "BKE_main.h"
84 #include "BKE_mball.h"
85 #include "BKE_mesh.h"
86 #include "BKE_object.h"
87 #include "BKE_scene.h"
88 #include "BKE_subsurf.h"
89 #include "BKE_texture.h"
90 #include "BKE_utildefines.h"
91 #include "BKE_world.h"
92
93 #include "render.h"
94
95 #include "RE_renderconverter.h"
96
97 #include "BIF_space.h"
98 #include "BIF_screen.h"
99 #include "BIF_editkey.h"
100
101 #include "BSE_sequence.h"
102
103 #include "nla.h"
104
105 #include "BPY_extern.h"
106
107 #include "butspace.h"
108
109 #include "radio.h"
110 #include "YafRay_Api.h"
111
112 extern void error (char *fmt, ...);  /* defined in BIF_toolbox.h, but we dont need to include the rest */ 
113
114 /* yafray: Identity transform 'hack' removed, exporter now transforms vertices back to world.
115  * Same is true for lamp coords & vec.
116  * Duplicated data objects & dupliframe/duplivert objects are only stored once,
117  * only the matrix is stored for all others, in yafray these objects are instances of the original.
118  * The main changes are in RE_rotateBlenderScene().
119  */
120
121 /* ------------------------------------------------------------------------- */
122 /* Local functions                                                           */
123 /* ------------------------------------------------------------------------- */
124 static Material *give_render_material(Object *ob, int nr);
125 static short test_for_displace(Object *ob);
126 static void do_displacement(Object *ob, int startface, int numface, int startvert, int numvert );
127
128 /* ------------------------------------------------------------------------- */
129 /* tool functions/defines for ad hoc simplification and possible future 
130    cleanup      */
131 /* ------------------------------------------------------------------------- */
132
133 #define UVTOINDEX(u,v) (startvlak + (u) * sizev + (v))
134 /*
135
136 NOTE THAT U/V COORDINATES ARE SOMETIMES SWAPPED !!
137         
138 ^       ()----p4----p3----()
139 |       |     |     |     |
140 u       |     |  F1 |  F2 |
141         |     |     |     |
142         ()----p1----p2----()
143                v ->
144 */
145
146 /* ------------------------------------------------------------------------- */
147
148 /* Stuff for stars. This sits here because it uses gl-things. Part of
149    this code may move down to the converter.  */
150 /* ------------------------------------------------------------------------- */
151 /* this is a bad beast, since it is misused by the 3d view drawing as well. */
152
153 /* more star stuff, here used to be a cliptest, removed for envmap render or panorama... */
154 static HaloRen *initstar(float *vec, float hasize)
155 {
156         HaloRen *har;
157         float hoco[4];
158         
159         RE_projectverto(vec, hoco);
160         
161         har= RE_findOrAddHalo(R.tothalo++);
162         
163         /* projectvert is done in function zbufvlaggen again, because of parts */
164         VECCOPY(har->co, vec);
165         har->hasize= hasize;
166         
167         har->zd= 0.0;
168         
169         return har;
170 }
171
172 extern unsigned char hash[512];
173
174 /* there must be a 'fixed' amount of stars generated between
175  *         near and far
176  * all stars must by preference lie on the far and solely
177  *        differ in clarity/color
178  */
179
180 void RE_make_stars(void (*initfunc)(void),
181                                    void (*vertexfunc)(float*),
182                                    void (*termfunc)(void))
183 {
184         HaloRen *har;
185         double dblrand, hlfrand;
186         float vec[4], fx, fy, fz;
187         float fac, starmindist, clipend;
188         float mat[4][4], stargrid, maxrand, maxjit, force, alpha;
189 /*      float loc_far_var, loc_near_var; */
190         int x, y, z, sx, sy, sz, ex, ey, ez, done = 0;
191         Camera * camera;
192
193         if(initfunc) R.wrld= *(G.scene->world);
194
195         stargrid = R.wrld.stardist;             /* distance between stars */
196         maxrand = 2.0;                                          /* amount a star can be shifted (in grid units) */
197         maxjit = (R.wrld.starcolnoise);                 /* amount a color is being shifted */
198
199 /*      loc_far_var = R.far; */
200 /*      loc_near_var = R.near; */
201
202
203         /* size of stars */
204         force = ( R.wrld.starsize );
205
206         /* minimal free space (starting at camera) */
207         starmindist= R.wrld.starmindist;
208
209         if (stargrid <= 0.10) return;
210
211         if (!initfunc) R.flag |= R_HALO;
212         else stargrid *= 1.0;                           /* then it draws fewer */
213
214
215         MTC_Mat4Invert(mat, R.viewmat);
216
217         /* BOUNDING BOX CALCULATION
218          * bbox goes from z = loc_near_var | loc_far_var,
219          * x = -z | +z,
220          * y = -z | +z
221          */
222
223         camera = G.scene->camera->data;
224         clipend = camera->clipend;
225
226         /* convert to grid coordinates */
227
228         sx = ((mat[3][0] - clipend) / stargrid) - maxrand;
229         sy = ((mat[3][1] - clipend) / stargrid) - maxrand;
230         sz = ((mat[3][2] - clipend) / stargrid) - maxrand;
231
232         ex = ((mat[3][0] + clipend) / stargrid) + maxrand;
233         ey = ((mat[3][1] + clipend) / stargrid) + maxrand;
234         ez = ((mat[3][2] + clipend) / stargrid) + maxrand;
235
236         dblrand = maxrand * stargrid;
237         hlfrand = 2.0 * dblrand;
238
239         if (initfunc) {
240                 initfunc();     
241         }
242
243         for (x = sx, fx = sx * stargrid; x <= ex; x++, fx += stargrid) {
244                 for (y = sy, fy = sy * stargrid; y <= ey ; y++, fy += stargrid) {
245                         for (z = sz, fz = sz * stargrid; z <= ez; z++, fz += stargrid) {
246
247                                 BLI_srand((hash[z & 0xff] << 24) + (hash[y & 0xff] << 16) + (hash[x & 0xff] << 8));
248                                 vec[0] = fx + (hlfrand * BLI_drand()) - dblrand;
249                                 vec[1] = fy + (hlfrand * BLI_drand()) - dblrand;
250                                 vec[2] = fz + (hlfrand * BLI_drand()) - dblrand;
251                                 vec[3] = 1.0;
252
253                                 if (vertexfunc) {
254                                         if(done & 1) vertexfunc(vec);
255                                         done++;
256                                 }
257                                 else {
258                                         MTC_Mat4MulVecfl(R.viewmat, vec);
259
260                                         /* in vec are global coordinates
261                                          * calculate distance to camera
262                                          * and using that, define the alpha
263                                          */
264
265                                         {
266                                                 float tx, ty, tz;
267
268                                                 tx = vec[0];
269                                                 ty = vec[1];
270                                                 tz = vec[2];
271
272                                                 alpha = sqrt(tx * tx + ty * ty + tz * tz);
273
274                                                 if (alpha >= clipend) alpha = 0.0;
275                                                 else if (alpha <= starmindist) alpha = 0.0;
276                                                 else if (alpha <= 2.0 * starmindist) {
277                                                         alpha = (alpha - starmindist) / starmindist;
278                                                 } else {
279                                                         alpha -= 2.0 * starmindist;
280                                                         alpha /= (clipend - 2.0 * starmindist);
281                                                         alpha = 1.0 - alpha;
282                                                 }
283                                         }
284
285
286                                         if (alpha != 0.0) {
287                                                 fac = force * BLI_drand();
288
289                                                 har = initstar(vec, fac);
290
291                                                 if (har) {
292                                                         har->alfa = sqrt(sqrt(alpha));
293                                                         har->add= 255;
294                                                         har->r = har->g = har->b = 1.0;
295                                                         if (maxjit) {
296                                                                 har->r += ((maxjit * BLI_drand()) ) - maxjit;
297                                                                 har->g += ((maxjit * BLI_drand()) ) - maxjit;
298                                                                 har->b += ((maxjit * BLI_drand()) ) - maxjit;
299                                                         }
300                                                         har->hard = 32;
301
302                                                         har->type |= HA_ONLYSKY;
303                                                         done++;
304                                                 }
305                                         }
306                                 }
307                         }
308                         /* do not call blender_test_break() here, since it is used in UI as well, confusing the callback system */
309                         /* main cause is G.afbreek of course, a global again... (ton) */
310                 }
311         }
312         if (termfunc) termfunc();
313 }
314
315 /* ------------------------------------------------------------------------- */
316
317 static void split_v_renderfaces(int startvlak, int startvert, int usize, int vsize, int uIndex, int cyclu, int cyclv)
318 {
319         int vLen = vsize-1+(!!cyclv);
320         int uLen = usize-1+(!!cyclu);
321         int v;
322
323         for (v=0; v<vLen; v++) {
324                 VlakRen *vlr = RE_findOrAddVlak(startvlak + vLen*uIndex + v);
325                 VertRen *vert = RE_findOrAddVert(R.totvert++);
326
327                 if (cyclv) {
328                         *vert = *vlr->v2;
329                         vlr->v2 = vert;
330
331                         if (v==vLen-1) {
332                                 VlakRen *vlr = RE_findOrAddVlak(startvlak + vLen*uIndex + 0);
333                                 vlr->v1 = vert;
334                         } else {
335                                 VlakRen *vlr = RE_findOrAddVlak(startvlak + vLen*uIndex + v+1);
336                                 vlr->v1 = vert;
337                         }
338                 } else {
339                         *vert = *vlr->v2;
340                         vlr->v2 = vert;
341
342                         if (v<vLen-1) {
343                                 VlakRen *vlr = RE_findOrAddVlak(startvlak + vLen*uIndex + v+1);
344                                 vlr->v1 = vert;
345                         }
346
347                         if (v==0) {
348                                 vert = RE_findOrAddVert(R.totvert++);
349                                 *vert = *vlr->v1;
350                                 vlr->v1 = vert;
351                         } 
352                 }
353         }
354 }
355
356 #if 0
357 static void DBG_show_shared_render_faces(int firstvert, int firstface)
358 {
359         int i;
360
361         for (i=firstvert; i<R.totvert; i++) {
362                 VertRen *ver = RE_findOrAddVert(i);
363
364                 ver->n[0] = ver->n[1] = ver->n[2] = 0.0;
365                 ver->sticky = 0;
366         }
367
368         for (i=firstface; i<R.totvlak; i++) {
369                 VlakRen *vlr = RE_findOrAddVlak(i);
370                 float cent[3];
371
372                 if (vlr->v4) {
373                         CalcCent4f(cent, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co);
374                         VecAddf(vlr->v4->n, vlr->v4->n, cent);
375                         vlr->v4->sticky = (float*) (((int) vlr->v4->sticky) + 1);
376                 } else {
377                         CalcCent3f(cent, vlr->v1->co, vlr->v2->co, vlr->v3->co);
378                 }
379
380                 VecAddf(vlr->v1->n, vlr->v1->n, cent);
381                 VecAddf(vlr->v2->n, vlr->v2->n, cent);
382                 VecAddf(vlr->v3->n, vlr->v3->n, cent);
383
384                 vlr->v1->sticky = (float*) (((int) vlr->v1->sticky) + 1);
385                 vlr->v2->sticky = (float*) (((int) vlr->v2->sticky) + 1);
386                 vlr->v3->sticky = (float*) (((int) vlr->v3->sticky) + 1);
387         }
388
389         for (i=firstvert; i<R.totvert; i++) {
390                 VertRen *ver = RE_findOrAddVert(i);
391
392                 VecMulf(ver->n, 1.f/(int) ver->sticky);
393
394                 VecLerpf(ver->co, ver->co, ver->n, 0.3);
395                 ver->sticky = 0;
396         }
397
398         calc_vertexnormals(firstvert, firstface);
399 }
400 #endif
401
402 /* ------------------------------------------------------------------------- */
403
404 static int contrpuntnormr(float *n, float *puno)
405 {
406         float inp;
407
408         inp=n[0]*puno[0]+n[1]*puno[1]+n[2]*puno[2];
409         if(inp<0.0) return 1;
410         return 0;
411 }
412
413 /* ------------------------------------------------------------------------- */
414
415 static void calc_vertexnormals(int startvert, int startvlak)
416 {
417         int a;
418
419                 /* clear all vertex normals */
420         for(a=startvert; a<R.totvert; a++) {
421                 VertRen *ver= RE_findOrAddVert(a);
422                 ver->n[0]=ver->n[1]=ver->n[2]= 0.0;
423         }
424
425                 /* calculate cos of angles and point-masses */
426         for(a=startvlak; a<R.totvlak; a++) {
427                 VlakRen *vlr= RE_findOrAddVlak(a);
428                 if(vlr->flag & ME_SMOOTH) {
429                         VertRen *adrve1= vlr->v1;
430                         VertRen *adrve2= vlr->v2;
431                         VertRen *adrve3= vlr->v3;
432                         VertRen *adrve4= vlr->v4;
433                         float n1[3], n2[3], n3[3], n4[3];
434                         float fac1, fac2, fac3, fac4;
435
436                         VecSubf(n1, adrve2->co, adrve1->co);
437                         Normalise(n1);
438                         VecSubf(n2, adrve3->co, adrve2->co);
439                         Normalise(n2);
440                         if(adrve4==0) {
441                                 VecSubf(n3, adrve1->co, adrve3->co);
442                                 Normalise(n3);
443
444                                 fac1= saacos(-n1[0]*n3[0]-n1[1]*n3[1]-n1[2]*n3[2]);
445                                 fac2= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
446                                 fac3= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
447                         }
448                         else {
449                                 VecSubf(n3, adrve4->co, adrve3->co);
450                                 Normalise(n3);
451                                 VecSubf(n4, adrve1->co, adrve4->co);
452                                 Normalise(n4);
453
454                                 fac1= saacos(-n4[0]*n1[0]-n4[1]*n1[1]-n4[2]*n1[2]);
455                                 fac2= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
456                                 fac3= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
457                                 fac4= saacos(-n3[0]*n4[0]-n3[1]*n4[1]-n3[2]*n4[2]);
458
459                                 if(!(vlr->flag & R_NOPUNOFLIP)) {
460                                         if( contrpuntnormr(vlr->n, adrve4->n) ) fac4= -fac4;
461                                 }
462
463                                 adrve4->n[0] +=fac4*vlr->n[0];
464                                 adrve4->n[1] +=fac4*vlr->n[1];
465                                 adrve4->n[2] +=fac4*vlr->n[2];
466                         }
467
468                         if(!(vlr->flag & R_NOPUNOFLIP)) {
469                                 if( contrpuntnormr(vlr->n, adrve1->n) ) fac1= -fac1;
470                                 if( contrpuntnormr(vlr->n, adrve2->n) ) fac2= -fac2;
471                                 if( contrpuntnormr(vlr->n, adrve3->n) ) fac3= -fac3;
472                         }
473
474                         adrve1->n[0] +=fac1*vlr->n[0];
475                         adrve1->n[1] +=fac1*vlr->n[1];
476                         adrve1->n[2] +=fac1*vlr->n[2];
477
478                         adrve2->n[0] +=fac2*vlr->n[0];
479                         adrve2->n[1] +=fac2*vlr->n[1];
480                         adrve2->n[2] +=fac2*vlr->n[2];
481
482                         adrve3->n[0] +=fac3*vlr->n[0];
483                         adrve3->n[1] +=fac3*vlr->n[1];
484                         adrve3->n[2] +=fac3*vlr->n[2];
485                 }
486         }
487
488                 /* do solid faces */
489         for(a=startvlak; a<R.totvlak; a++) {
490                 VlakRen *vlr= RE_findOrAddVlak(a);
491                 if((vlr->flag & ME_SMOOTH)==0) {
492                         float *f1= vlr->v1->n;
493                         if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
494                         f1= vlr->v2->n;
495                         if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
496                         f1= vlr->v3->n;
497                         if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
498                         if(vlr->v4) {
499                                 f1= vlr->v4->n;
500                                 if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
501                         }                       
502                 }
503         }
504         
505                 /* normalise vertex normals */
506         for(a=startvert; a<R.totvert; a++) {
507                 VertRen *ver= RE_findOrAddVert(a);
508                 Normalise(ver->n);
509         }
510
511                 /* vertex normal (puno) switch flags for during render */
512         for(a=startvlak; a<R.totvlak; a++) {
513                 VlakRen *vlr= RE_findOrAddVlak(a);
514
515                 if((vlr->flag & R_NOPUNOFLIP)==0) {
516                         VertRen *adrve1= vlr->v1;
517                         VertRen *adrve2= vlr->v2;
518                         VertRen *adrve3= vlr->v3;
519                         VertRen *adrve4= vlr->v4;
520                         vlr->puno &= ~15;
521                         if ((vlr->n[0]*adrve1->n[0]+vlr->n[1]*adrve1->n[1]+vlr->n[2]*adrve1->n[2])<0.0) vlr->puno= 1;
522                         if ((vlr->n[0]*adrve2->n[0]+vlr->n[1]*adrve2->n[1]+vlr->n[2]*adrve2->n[2])<0.0) vlr->puno+= 2;
523                         if ((vlr->n[0]*adrve3->n[0]+vlr->n[1]*adrve3->n[1]+vlr->n[2]*adrve3->n[2])<0.0) vlr->puno+= 4;
524                         if(adrve4) {
525                                 if((vlr->n[0]*adrve4->n[0]+vlr->n[1]*adrve4->n[1]+vlr->n[2]*adrve4->n[2])<0.0) vlr->puno+= 8;
526                         }
527                 }
528         }
529 }
530
531 /* ------------------------------------------------------------------------- */
532 /* Autosmoothing:                                                            */
533 /* ------------------------------------------------------------------------- */
534
535 typedef struct ASvert {
536         int totface;
537         ListBase faces;
538 } ASvert;
539
540 typedef struct ASface {
541         struct ASface *next, *prev;
542         VlakRen *vlr[4];
543         VertRen *nver[4];
544 } ASface;
545
546 /* prototypes: */
547 static int as_testvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thresh);
548 static VertRen *as_findvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thresh);
549
550
551 static void as_addvert(VertRen *v1, VlakRen *vlr)
552 {
553         ASvert *asv;
554         ASface *asf;
555         int a;
556         
557         if(v1 == NULL) return;
558         
559         if(v1->svert==0) {
560                 v1->svert= MEM_callocN(sizeof(ASvert), "asvert");
561                 asv= v1->svert;
562                 asf= MEM_callocN(sizeof(ASface), "asface");
563                 BLI_addtail(&asv->faces, asf);
564         }
565         
566         asv= v1->svert;
567         asf= asv->faces.last;
568         for(a=0; a<4; a++) {
569                 if(asf->vlr[a]==0) {
570                         asf->vlr[a]= vlr;
571                         asv->totface++;
572                         break;
573                 }
574         }
575         
576         /* new face struct */
577         if(a==4) {
578                 asf= MEM_callocN(sizeof(ASface), "asface");
579                 BLI_addtail(&asv->faces, asf);
580                 asf->vlr[0]= vlr;
581                 asv->totface++;
582         }
583 }
584
585 static void as_freevert(VertRen *ver)
586 {
587         ASvert *asv;
588
589         asv= ver->svert;
590         BLI_freelistN(&asv->faces);
591         MEM_freeN(asv);
592         ver->svert= NULL;
593 }
594
595 static int as_testvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thresh) 
596 {
597         /* return 1: vertex needs a copy */
598         ASface *asf;
599         float inp;
600         int a;
601         
602         if(vlr==0) return 0;
603         
604         asf= asv->faces.first;
605         while(asf) {
606                 for(a=0; a<4; a++) {
607                         if(asf->vlr[a] && asf->vlr[a]!=vlr) {
608                                 inp= fabs( vlr->n[0]*asf->vlr[a]->n[0] + vlr->n[1]*asf->vlr[a]->n[1] + vlr->n[2]*asf->vlr[a]->n[2] );
609                                 if(inp < thresh) return 1;
610                         }
611                 }
612                 asf= asf->next;
613         }
614         
615         return 0;
616 }
617
618 static VertRen *as_findvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thresh) 
619 {
620         /* return when new vertex already was made */
621         ASface *asf;
622         float inp;
623         int a;
624         
625         asf= asv->faces.first;
626         while(asf) {
627                 for(a=0; a<4; a++) {
628                         if(asf->vlr[a] && asf->vlr[a]!=vlr) {
629                                 /* this face already made a copy for this vertex! */
630                                 if(asf->nver[a]) {
631                                         inp= fabs( vlr->n[0]*asf->vlr[a]->n[0] + vlr->n[1]*asf->vlr[a]->n[1] + vlr->n[2]*asf->vlr[a]->n[2] );
632                                         if(inp >= thresh) {
633                                                 return asf->nver[a];
634                                         }
635                                 }
636                         }
637                 }
638                 asf= asf->next;
639         }
640         
641         return NULL;
642 }
643
644 static void autosmooth(int startvert, int startvlak, int degr)
645 {
646         ASvert *asv;
647         ASface *asf;
648         VertRen *ver, *v1;
649         VlakRen *vlr;
650         float thresh;
651         int a, b, totvert;
652         
653         thresh= cos( M_PI*((float)degr)/180.0 );
654         
655         /* initialize */
656         for(a=startvert; a<R.totvert; a++) {
657                 ver= RE_findOrAddVert(a);
658                 ver->svert= 0;
659         }
660         
661         /* step one: construct listbase of all vertices and pointers to faces */
662         for(a=startvlak; a<R.totvlak; a++) {
663                 vlr= RE_findOrAddVlak(a);
664                 
665                 as_addvert(vlr->v1, vlr);
666                 as_addvert(vlr->v2, vlr);
667                 as_addvert(vlr->v3, vlr);
668                 as_addvert(vlr->v4, vlr);
669         }
670         
671         /* we now test all vertices, when faces have a normal too much different: they get a new vertex */
672         totvert= R.totvert;
673         for(a=startvert; a<totvert; a++) {
674                 ver= RE_findOrAddVert(a);
675                 asv= ver->svert;
676                 if(asv && asv->totface>1) {
677                         
678                         asf= asv->faces.first;
679                         while(asf) {
680                                 for(b=0; b<4; b++) {
681                                 
682                                         /* is there a reason to make a new vertex? */
683                                         vlr= asf->vlr[b];
684                                         if( as_testvertex(vlr, ver, asv, thresh) ) {
685                                                 
686                                                 /* already made a new vertex within threshold? */
687                                                 v1= as_findvertex(vlr, ver, asv, thresh);
688                                                 if(v1==0) {
689                                                         /* make a new vertex */
690                                                         v1= RE_findOrAddVert(R.totvert++);
691                                                         *v1= *ver;
692                                                         v1->svert= 0;
693                                                 }
694                                                 asf->nver[b]= v1;
695                                                 if(vlr->v1==ver) vlr->v1= v1;
696                                                 if(vlr->v2==ver) vlr->v2= v1;
697                                                 if(vlr->v3==ver) vlr->v3= v1;
698                                                 if(vlr->v4==ver) vlr->v4= v1;
699                                         }
700                                 }
701                                 asf= asf->next;
702                         }
703                 }
704         }
705         
706         /* free */
707         for(a=startvert; a<R.totvert; a++) {
708                 ver= RE_findOrAddVert(a);
709                 if(ver->svert) as_freevert(ver);
710         }
711         
712 }
713
714 /* ------------------------------------------------------------------------- */
715 /* End of autosmoothing:                                                     */
716 /* ------------------------------------------------------------------------- */
717
718 /* ------------------------------------------------------------------------- */
719 /* Orco hash                                                                                                                             */
720 /* ------------------------------------------------------------------------- */
721
722
723 static GHash *g_orco_hash = NULL;
724
725 static float *get_object_orco(Object *ob)
726 {
727         float *orco;
728         
729         if (!g_orco_hash)
730                 g_orco_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
731         
732         orco = BLI_ghash_lookup(g_orco_hash, ob);
733         
734         if (!orco) {
735                 if (ob->type==OB_MESH) {
736                         orco = mesh_create_orco_render(ob);
737                 } else if (ELEM(ob->type, OB_CURVE, OB_FONT)) {
738                         orco = make_orco_curve(ob);
739                 } else if (ob->type==OB_SURF) {
740                         orco = make_orco_surf(ob);
741                 }
742                 
743                 if (orco)
744                         BLI_ghash_insert(g_orco_hash, ob, orco);
745         }
746         
747         return orco;
748 }
749 static void free_mesh_orco_hash(void) 
750 {
751         if (g_orco_hash) {
752                 BLI_ghash_free(g_orco_hash, NULL, (GHashValFreeFP)MEM_freeN);
753                 g_orco_hash = NULL;
754         }
755 }
756
757 /* ******************** END ORCO HASH ***************** */
758
759
760 static void make_render_halos(Object *ob, Mesh *me, int totvert, MVert *mvert, Material *ma, float *orco)
761 {
762         HaloRen *har;
763         float xn, yn, zn, nor[3], view[3];
764         float vec[3], hasize, mat[4][4], imat[3][3];
765         int a, ok, seed= ma->seed1;
766
767         MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
768         MTC_Mat3CpyMat4(imat, ob->imat);
769
770         R.flag |= R_HALO;
771
772         for(a=0; a<totvert; a++, mvert++) {
773                 ok= 1;
774
775                 if(ok) {
776                         hasize= ma->hasize;
777
778                         VECCOPY(vec, mvert->co);
779                         MTC_Mat4MulVecfl(mat, vec);
780
781                         if(ma->mode & MA_HALOPUNO) {
782                                 xn= mvert->no[0];
783                                 yn= mvert->no[1];
784                                 zn= mvert->no[2];
785
786                                 /* transpose ! */
787                                 nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
788                                 nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
789                                 nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
790                                 Normalise(nor);
791
792                                 VECCOPY(view, vec);
793                                 Normalise(view);
794
795                                 zn= nor[0]*view[0]+nor[1]*view[1]+nor[2]*view[2];
796                                 if(zn>=0.0) hasize= 0.0;
797                                 else hasize*= zn*zn*zn*zn;
798                         }
799
800                         if(orco) har= RE_inithalo(ma, vec, NULL, orco, hasize, 0.0, seed);
801                         else har= RE_inithalo(ma, vec, NULL, mvert->co, hasize, 0.0, seed);
802                         if(har) har->lay= ob->lay;
803                 }
804                 if(orco) orco+= 3;
805                 seed++;
806         }
807 }
808
809 /* ------------------------------------------------------------------------- */
810
811
812 static void render_particle_system(Object *ob, PartEff *paf)
813 {
814         Particle *pa=0;
815         HaloRen *har=0;
816         Material *ma=0;
817         float xn, yn, zn, imat[3][3], mat[4][4], hasize, stime, ptime, ctime, vec[3], vec1[3], view[3], nor[3];
818         int a, mat_nr=1, seed;
819
820         pa= paf->keys;
821         if(pa==NULL || paf->disp!=100) {
822                 build_particle_system(ob);
823                 pa= paf->keys;
824                 if(pa==NULL) return;
825         }
826
827         ma= give_render_material(ob, paf->omat);
828
829         MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
830         MTC_Mat4Invert(ob->imat, mat);  /* this is correct, for imat texture */
831
832         MTC_Mat4Invert(mat, R.viewmat); /* particles do not have a ob transform anymore */
833         MTC_Mat3CpyMat4(imat, mat);
834
835         R.flag |= R_HALO;
836
837         if(ob->ipoflag & OB_OFFS_PARTICLE) ptime= ob->sf;
838         else ptime= 0.0;
839         ctime= bsystem_time(ob, 0, (float)G.scene->r.cfra, ptime);
840         seed= ma->seed1;
841
842         for(a=0; a<paf->totpart; a++, pa+=paf->totkey, seed++) {
843
844                 /* offset time for calculating normal */
845                 stime= ctime;
846                 ptime= ctime+1.0f;
847                 if(ctime < pa->time) {
848                         if(paf->flag & PAF_UNBORN)
849                                 ptime= pa->time+1.0f;
850                         else
851                                 continue;
852                 }
853                 if(ctime > pa->time+pa->lifetime) {
854                         if(paf->flag & PAF_DIED)
855                                 stime= pa->time+pa->lifetime-1.0f;
856                         else
857                                 continue;
858                 }
859                 
860                 /* watch it: also calculate the normal of a particle */
861                 if(paf->stype==PAF_VECT || ma->mode & MA_HALO_SHADE) {
862                         where_is_particle(paf, pa, stime, vec);
863                         MTC_Mat4MulVecfl(R.viewmat, vec);
864                         where_is_particle(paf, pa, ptime, vec1);
865                         MTC_Mat4MulVecfl(R.viewmat, vec1);
866                 }
867                 else {
868                         where_is_particle(paf, pa, ctime, vec);
869                         MTC_Mat4MulVecfl(R.viewmat, vec);
870                 }
871
872                 if(pa->mat_nr != mat_nr) {
873                         mat_nr= pa->mat_nr;
874                         ma= give_render_material(ob, mat_nr);
875                 }
876
877                 if(ma->ipo) {
878                         /* correction for lifetime */
879                         ptime= 100.0*(ctime-pa->time)/pa->lifetime;
880                         calc_ipo(ma->ipo, ptime);
881                         execute_ipo((ID *)ma, ma->ipo);
882                 }
883
884                 hasize= ma->hasize;
885
886                 if(ma->mode & MA_HALOPUNO) {
887                         xn= pa->no[0];
888                         yn= pa->no[1];
889                         zn= pa->no[2];
890
891                         /* transpose ! */
892                         nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
893                         nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
894                         nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
895                         Normalise(nor);
896
897                         VECCOPY(view, vec);
898                         Normalise(view);
899
900                         zn= nor[0]*view[0]+nor[1]*view[1]+nor[2]*view[2];
901                         if(zn>=0.0) hasize= 0.0;
902                         else hasize*= zn*zn*zn*zn;
903                 }
904
905                 if(paf->stype==PAF_VECT) har= RE_inithalo(ma, vec, vec1, pa->co, hasize, paf->vectsize, seed);
906                 else {
907                         har= RE_inithalo(ma, vec, NULL, pa->co, hasize, 0.0, seed);
908                         if(har && ma->mode & MA_HALO_SHADE) {
909                                 VecSubf(har->no, vec, vec1);
910                                 Normalise(har->no);
911                         }
912                 }
913                 if(har) har->lay= ob->lay;
914         }
915
916         /* restore material */
917         for(a=1; a<=ob->totcol; a++) {
918                 ma= give_render_material(ob, a);
919                 if(ma) do_mat_ipo(ma);
920         }
921         
922         if(paf->disp!=100) {
923                 MEM_freeN(paf->keys);
924                 paf->keys= NULL;
925         }
926 }
927
928
929 /* ------------------------------------------------------------------------- */
930
931 /* when objects are duplicated, they are freed immediate, but still might be
932 in use for render... */
933 static Object *vlr_set_ob(Object *ob)
934 {
935         if(ob->flag & OB_FROMDUPLI) return (Object *)ob->id.newid;
936         return ob;
937 }
938
939 /* ------------------------------------------------------------------------- */
940
941 static void static_particle_strand(Object *ob, Material *ma, float *orco, float *vec, float *vec1, float ctime, int first)
942 {
943         static VertRen *v1= NULL, *v2= NULL;
944         VlakRen *vlr;
945         float nor[3], cross[3], w, dx, dy;
946         int flag;
947         
948         VecSubf(nor, vec, vec1);
949         Normalise(nor);         // nor needed as tangent 
950         Crossf(cross, vec, nor);
951         
952         /* turn cross in pixelsize */
953         w= vec[2]*R.winmat[2][3] + R.winmat[3][3];
954         
955         dx= R.rectx*cross[0]*R.winmat[0][0]/w;
956         dy= R.recty*cross[1]*R.winmat[1][1]/w;
957         w= sqrt(dx*dx + dy*dy);
958         if(w!=0.0f) {
959                 float fac;
960                 if(ma->strand_ease!=0.0f) {
961                         if(ma->strand_ease<0.0f)
962                                 fac= pow(ctime, 1.0+ma->strand_ease);
963                         else
964                                 fac= pow(ctime, 1.0/(1.0f-ma->strand_ease));
965                 }
966                 else fac= ctime;
967                 
968                 VecMulf(cross, ((1.0f-fac)*ma->strand_sta + (fac)*ma->strand_end)/w);
969         }
970         
971         if(ma->mode & MA_TANGENT_STR)
972                 flag= R_SMOOTH|R_NOPUNOFLIP|R_STRAND|R_TANGENT;
973         else
974                 flag= R_SMOOTH|R_STRAND;
975         
976         /* first two vertices */
977         if(first) {
978                 v1= RE_findOrAddVert(R.totvert++);
979                 v2= RE_findOrAddVert(R.totvert++);
980                 
981                 VECCOPY(v1->co, vec);
982                 VecAddf(v1->co, v1->co, cross);
983                 VECCOPY(v1->n, nor);
984                 v1->orco= orco;
985                 v1->accum= -1.0f;       // accum abuse for strand texco
986                 
987                 VECCOPY(v2->co, vec);
988                 VecSubf(v2->co, v2->co, cross);
989                 VECCOPY(v2->n, nor);
990                 v2->orco= orco;
991                 v2->accum= v1->accum;
992         }
993         else {
994                 
995                 vlr= RE_findOrAddVlak(R.totvlak++);
996                 vlr->flag= flag;
997                 vlr->ob= vlr_set_ob(ob);
998                 vlr->v1= v1;
999                 vlr->v2= v2;
1000                 vlr->v3= RE_findOrAddVert(R.totvert++);
1001                 vlr->v4= RE_findOrAddVert(R.totvert++);
1002                 
1003                 v1= vlr->v4; // cycle
1004                 v2= vlr->v3; // cycle
1005                 
1006                 VECCOPY(vlr->v4->co, vec);
1007                 VecAddf(vlr->v4->co, vlr->v4->co, cross);
1008                 VECCOPY(vlr->v4->n, nor);
1009                 vlr->v4->orco= orco;
1010                 vlr->v4->accum= -1.0f + 2.0f*ctime;     // accum abuse for strand texco
1011                 
1012                 VECCOPY(vlr->v3->co, vec);
1013                 VecSubf(vlr->v3->co, vlr->v3->co, cross);
1014                 VECCOPY(vlr->v3->n, nor);
1015                 vlr->v3->orco= orco;
1016                 vlr->v3->accum= vlr->v4->accum;
1017                 
1018                 CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n);
1019                 
1020                 vlr->mat= ma;
1021                 vlr->ec= ME_V2V3;
1022                 vlr->lay= ob->lay;
1023         }
1024 }
1025
1026 static void render_static_particle_system(Object *ob, PartEff *paf)
1027 {
1028         Particle *pa=0;
1029         HaloRen *har=0;
1030         Material *ma=0;
1031         VertRen *v1= NULL, *v2= NULL;
1032         VlakRen *vlr;
1033         float xn, yn, zn, imat[3][3], mat[4][4], hasize;
1034         float mtime, ptime, ctime, vec[3], vec1[3], view[3], nor[3];
1035         float *orco= NULL, loc_tex[3], size_tex[3];
1036         int a, mat_nr=1, seed, totvlako, totverto, first;
1037
1038         pa= paf->keys;
1039         if(pa==NULL || (paf->flag & PAF_ANIMATED) || paf->disp!=100) {
1040                 build_particle_system(ob);
1041                 pa= paf->keys;
1042                 if(pa==NULL) return;
1043         }
1044
1045         totvlako= R.totvlak;
1046         totverto= R.totvert;
1047         
1048         ma= give_render_material(ob, paf->omat);
1049         if(ma->mode & MA_HALO)
1050                 R.flag |= R_HALO;
1051
1052         MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
1053         MTC_Mat4Invert(ob->imat, mat);  /* need to be that way, for imat texture */
1054
1055         MTC_Mat3CpyMat4(imat, ob->imat);
1056         
1057         /* orcos */
1058         if(!(ma->mode & (MA_HALO|MA_WIRE))) {
1059                 orco= MEM_mallocN(3*sizeof(float)*paf->totpart, "static particle orcos");
1060                 if (!g_orco_hash)
1061                         g_orco_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
1062                 BLI_ghash_insert(g_orco_hash, paf, orco);       /* pointer is particles, otherwise object uses it */
1063         }
1064         
1065         mesh_get_texspace(ob->data, loc_tex, NULL, size_tex);
1066         
1067         if(ob->ipoflag & OB_OFFS_PARTICLE) ptime= ob->sf;
1068         else ptime= 0.0;
1069         ctime= bsystem_time(ob, 0, (float)G.scene->r.cfra, ptime);
1070         seed= ma->seed1;
1071
1072         for(a=0; a<paf->totpart; a++, pa+=paf->totkey) {
1073                 
1074                 where_is_particle(paf, pa, pa->time, vec1);
1075                 if(orco) {
1076                         orco[0] = (vec1[0]-loc_tex[0])/size_tex[0];
1077                         orco[1] = (vec1[1]-loc_tex[1])/size_tex[1];
1078                         orco[2] = (vec1[2]-loc_tex[2])/size_tex[2];
1079                 }
1080                 mtime= pa->time+pa->lifetime+paf->staticstep-1;
1081                 
1082                 first= 1;
1083                 for(ctime= pa->time; ctime<mtime; ctime+=paf->staticstep) {
1084                         
1085                         /* make sure hair grows until the end.. */
1086                         if(ctime>pa->time+pa->lifetime) ctime= pa->time+pa->lifetime;
1087                         
1088                         /* watch it: also calc the normal of a particle */
1089                         if(paf->stype==PAF_VECT || ma->mode & MA_HALO_SHADE) {
1090                                 where_is_particle(paf, pa, ctime+1.0, vec);
1091                                 MTC_Mat4MulVecfl(mat, vec);
1092                         }
1093                         else {
1094                                 where_is_particle(paf, pa, ctime, vec);
1095                                 MTC_Mat4MulVecfl(mat, vec);
1096                         }
1097
1098                         if(pa->mat_nr != mat_nr) {
1099                                 mat_nr= pa->mat_nr;
1100                                 ma= give_render_material(ob, mat_nr);
1101                         }
1102                         
1103                         /* wires */
1104                         if(ma->mode & MA_WIRE) {
1105                                 if(ctime == pa->time) {
1106                                         v1= RE_findOrAddVert(R.totvert++);
1107                                         VECCOPY(v1->co, vec);
1108                                 }
1109                                 else {
1110                                         vlr= RE_findOrAddVlak(R.totvlak++);
1111                                         vlr->ob= vlr_set_ob(ob);
1112                                         vlr->v1= v1;
1113                                         vlr->v2= RE_findOrAddVert(R.totvert++);
1114                                         vlr->v3= vlr->v2;
1115                                         vlr->v4= NULL;
1116                                         
1117                                         v1= vlr->v2; // cycle
1118                                         VECCOPY(v1->co, vec);
1119                                         
1120                                         VecSubf(vlr->n, vec, vec1);
1121                                         Normalise(vlr->n);
1122                                         VECCOPY(v1->n, vlr->n);
1123                                         
1124                                         vlr->mat= ma;
1125                                         vlr->ec= ME_V1V2;
1126                                         vlr->lay= ob->lay;
1127                                 }
1128                         }
1129                         else {
1130                                 if(ma->ipo) {
1131                                         /* correction for lifetime */
1132                                         ptime= 100.0*(ctime-pa->time)/pa->lifetime;
1133                                         calc_ipo(ma->ipo, ptime);
1134                                         execute_ipo((ID *)ma, ma->ipo);
1135                                 }
1136                                 
1137                                 if(ma->mode & MA_HALO) {
1138                                         hasize= ma->hasize;
1139
1140                                         if(ma->mode & MA_HALOPUNO) {
1141                                                 xn= pa->no[0];
1142                                                 yn= pa->no[1];
1143                                                 zn= pa->no[2];
1144
1145                                                 /* transpose ! */
1146                                                 nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
1147                                                 nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
1148                                                 nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
1149                                                 Normalise(nor);
1150
1151                                                 VECCOPY(view, vec);
1152                                                 Normalise(view);
1153
1154                                                 zn= nor[0]*view[0]+nor[1]*view[1]+nor[2]*view[2];
1155                                                 if(zn>=0.0) hasize= 0.0;
1156                                                 else hasize*= zn*zn*zn*zn;
1157                                         }
1158
1159                                         if(paf->stype==PAF_VECT) har= RE_inithalo(ma, vec, vec1, pa->co, hasize, paf->vectsize, seed);
1160                                         else {
1161                                                 har= RE_inithalo(ma, vec, NULL, pa->co, hasize, 0.0, seed);
1162                                                 if(har && (ma->mode & MA_HALO_SHADE)) {
1163                                                         VecSubf(har->no, vec, vec1);
1164                                                         Normalise(har->no);
1165                                                         har->lay= ob->lay;
1166                                                 }
1167                                         }
1168                                         if(har) har->lay= ob->lay;
1169                                 }
1170                                 else {  /* generate pixel sized hair strand */
1171                                         static_particle_strand(ob, ma, orco, vec, vec1, (ctime-pa->time)/(mtime-pa->time), first);
1172                                 }
1173                         }
1174                         
1175                         VECCOPY(vec1, vec);
1176                         first= 0;
1177                 }
1178                 
1179                 seed++;
1180                 if(orco) orco+=3;
1181         }
1182
1183         if(paf->disp!=100) {
1184                 MEM_freeN(paf->keys);
1185                 paf->keys= NULL;
1186         }
1187
1188         if((ma->mode & MA_TANGENT_STR)==0)
1189                 calc_vertexnormals(totverto, totvlako);
1190 }
1191
1192
1193 /* ------------------------------------------------------------------------- */
1194
1195 static int verghalo(const void *a1, const void *a2)
1196 {
1197         const struct halosort *x1=a1, *x2=a2;
1198         
1199         if( x1->z < x2->z ) return 1;
1200         else if( x1->z > x2->z) return -1;
1201         return 0;
1202 }
1203
1204 /* ------------------------------------------------------------------------- */
1205 extern int rblohalen;
1206 static void sort_halos(void)
1207 {
1208         struct halosort *hablock, *haso;
1209         HaloRen *har = NULL, **bloha;
1210         int a;
1211
1212         if(R.tothalo==0) return;
1213
1214         /* make datablock with halo pointers, sort */
1215         haso= hablock= MEM_mallocN(sizeof(struct halosort)*R.tothalo, "hablock");
1216
1217         for(a=0; a<R.tothalo; a++) {
1218                 if((a & 255)==0) har= R.bloha[a>>8];
1219                 else har++;
1220                 haso->har= har;
1221                 haso->z= har->zs;
1222                 haso++;
1223         }
1224
1225         qsort(hablock, R.tothalo, sizeof(struct halosort), verghalo);
1226
1227         /* re-assamble R.bloha */
1228
1229         bloha= R.bloha;
1230         R.bloha= (HaloRen **)MEM_callocN(sizeof(void *)*(rblohalen),"Bloha");
1231
1232         haso= hablock;
1233         for(a=0; a<R.tothalo; a++) {
1234                 har= RE_findOrAddHalo(a);
1235                 *har= *(haso->har);
1236
1237                 haso++;
1238         }
1239
1240         /* free */
1241         a= 0;
1242         while(bloha[a]) {
1243                 MEM_freeN(bloha[a]);
1244                 a++;
1245         }
1246         MEM_freeN(bloha);
1247         MEM_freeN(hablock);
1248
1249 }
1250
1251
1252
1253 static Material *give_render_material(Object *ob, int nr)
1254 {
1255         extern Material defmaterial;    // initrender.c
1256         Object *temp;
1257         Material *ma;
1258
1259         if(ob->flag & OB_FROMDUPLI) {
1260                 temp= (Object *)ob->id.newid;
1261                 if(temp && temp->type==OB_FONT) {
1262                         ob= temp;
1263                 }
1264         }
1265
1266         ma= give_current_material(ob, nr);
1267         if(ma==NULL) ma= &defmaterial;
1268
1269         return ma;
1270 }
1271
1272 /* ------------------------------------------------------------------------- */
1273 static void init_render_mball(Object *ob)
1274 {
1275         DispList *dl, *dlo;
1276         VertRen *ver;
1277         VlakRen *vlr, *vlr1;
1278         Material *ma;
1279         float *data, *nors, mat[4][4], imat[3][3], xn, yn, zn;
1280         int a, need_orco, startvert, *index;
1281
1282         if (ob!=find_basis_mball(ob))
1283                 return;
1284
1285         MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
1286         MTC_Mat4Invert(ob->imat, mat);
1287         MTC_Mat3CpyMat4(imat, ob->imat);
1288
1289         ma= give_render_material(ob, 1);
1290
1291         need_orco= 0;
1292         if(ma->texco & TEXCO_ORCO) {
1293                 need_orco= 1;
1294         }
1295
1296         dlo= ob->disp.first;
1297         if(dlo) BLI_remlink(&ob->disp, dlo);
1298
1299         makeDispListMBall(ob);
1300         dl= ob->disp.first;
1301         if(dl==0) return;
1302
1303         startvert= R.totvert;
1304         data= dl->verts;
1305         nors= dl->nors;
1306
1307         for(a=0; a<dl->nr; a++, data+=3, nors+=3) {
1308
1309                 ver= RE_findOrAddVert(R.totvert++);
1310                 VECCOPY(ver->co, data);
1311                 MTC_Mat4MulVecfl(mat, ver->co);
1312
1313                 xn= nors[0];
1314                 yn= nors[1];
1315                 zn= nors[2];
1316
1317                 /* transpose ! */
1318                 ver->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
1319                 ver->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
1320                 ver->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
1321                 Normalise(ver->n);
1322                 //if(ob->transflag & OB_NEG_SCALE) VecMulf(ver->n. -1.0);
1323                 
1324                 if(need_orco) ver->orco= data;
1325         }
1326
1327         index= dl->index;
1328         for(a=0; a<dl->parts; a++, index+=4) {
1329
1330                 vlr= RE_findOrAddVlak(R.totvlak++);
1331                 vlr->ob= vlr_set_ob(ob);
1332                 vlr->v1= RE_findOrAddVert(startvert+index[0]);
1333                 vlr->v2= RE_findOrAddVert(startvert+index[1]);
1334                 vlr->v3= RE_findOrAddVert(startvert+index[2]);
1335                 vlr->v4= 0;
1336
1337                 if(ob->transflag & OB_NEG_SCALE) 
1338                         CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->n);
1339                 else
1340                         CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n);
1341
1342                 vlr->mat= ma;
1343                 vlr->flag= ME_SMOOTH+R_NOPUNOFLIP;
1344                 vlr->ec= 0;
1345                 vlr->lay= ob->lay;
1346
1347                 /* mball -too bad- always has triangles, because quads can be non-planar */
1348                 if(index[3]) {
1349                         vlr1= RE_findOrAddVlak(R.totvlak++);
1350                         *vlr1= *vlr;
1351                         vlr1->v2= vlr1->v3;
1352                         vlr1->v3= RE_findOrAddVert(startvert+index[3]);
1353                         if(ob->transflag & OB_NEG_SCALE) 
1354                                 CalcNormFloat(vlr1->v1->co, vlr1->v2->co, vlr1->v3->co, vlr1->n);
1355                         else
1356                                 CalcNormFloat(vlr1->v3->co, vlr1->v2->co, vlr1->v1->co, vlr1->n);
1357                 }
1358         }
1359
1360         if(need_orco) {
1361                 /* store displist and scale */
1362                 make_orco_mball(ob);
1363                 if(dlo) BLI_addhead(&ob->disp, dlo);
1364
1365         }
1366         else {
1367                 freedisplist(&ob->disp);
1368                 if(dlo) BLI_addtail(&ob->disp, dlo);
1369         }
1370 }
1371 /* ------------------------------------------------------------------------- */
1372 /* convert */
1373
1374
1375 static void init_render_mesh(Object *ob)
1376 {
1377         Mesh *me;
1378         MVert *mvert = NULL;
1379         MFace *mface;
1380         VlakRen *vlr; //, *vlr1;
1381         VertRen *ver;
1382         Material *ma;
1383         MSticky *ms = NULL;
1384         PartEff *paf;
1385         DispListMesh *dlm = NULL;
1386         DerivedMesh *dm;
1387         unsigned int *vertcol;
1388         float xn, yn, zn,  imat[3][3], mat[4][4];  //nor[3],
1389         float *orco=0;
1390         int a, a1, ok, need_orco=0, totvlako, totverto, vertofs;
1391         int end, do_autosmooth=0, totvert = 0, dm_needsfree;
1392         
1393         me= ob->data;
1394
1395         paf = give_parteff(ob);
1396         if(paf) {
1397                 /* warning; build_particle_system does modifier calls itself */
1398                 if(paf->flag & PAF_STATIC) render_static_particle_system(ob, paf);
1399                 else render_particle_system(ob, paf);
1400                 if((paf->flag & PAF_SHOWE)==0) return;
1401         }
1402
1403         MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
1404         MTC_Mat4Invert(ob->imat, mat);
1405         MTC_Mat3CpyMat4(imat, ob->imat);
1406
1407         if(me->totvert==0) {
1408                 return;
1409         }
1410         
1411         totvlako= R.totvlak;
1412         totverto= R.totvert;
1413
1414         need_orco= 0;
1415         for(a=1; a<=ob->totcol; a++) {
1416                 ma= give_render_material(ob, a);
1417                 if(ma) {
1418                         if(ma->texco & TEXCO_ORCO) {
1419                                 need_orco= 1;
1420                                 break;
1421                         }
1422                 }
1423         }
1424         
1425         if(need_orco) orco = get_object_orco(ob);
1426         
1427         /* duplicators don't call modifier stack */
1428         if(ob->flag&OB_FROMDUPLI) {
1429                 dm= ob->derivedFinal;
1430                 dm_needsfree= 0;
1431         }
1432         else {
1433                 dm = mesh_create_derived_render(ob);
1434                 dm_needsfree= 1;
1435         }
1436         
1437         if(dm==NULL) return;    /* in case duplicated object fails? */
1438         
1439         dlm = dm->convertToDispListMesh(dm, 1);
1440
1441         mvert= dlm->mvert;
1442         totvert= dlm->totvert;
1443
1444         ms = (totvert==me->totvert)?me->msticky:NULL;
1445         
1446         ma= give_render_material(ob, 1);
1447
1448         if(ma->mode & MA_HALO) {
1449                 make_render_halos(ob, me, totvert, mvert, ma, orco);
1450         }
1451         else {
1452
1453                 for(a=0; a<totvert; a++, mvert++) {
1454                         ver= RE_findOrAddVert(R.totvert++);
1455                         VECCOPY(ver->co, mvert->co);
1456                         MTC_Mat4MulVecfl(mat, ver->co);
1457
1458                         if(orco) {
1459                                 ver->orco= orco;
1460                                 orco+=3;
1461                         }
1462                         if(ms) {
1463                                 ver->sticky= (float *)ms;
1464                                 ms++;
1465                         }
1466                 }
1467                 /* still to do for keys: the correct local texture coordinate */
1468
1469                 /* faces in order of color blocks */
1470                 vertofs= R.totvert - totvert;
1471                 for(a1=0; (a1<ob->totcol || (a1==0 && ob->totcol==0)); a1++) {
1472
1473                         ma= give_render_material(ob, a1+1);
1474                         
1475                         /* test for 100% transparant */
1476                         ok= 1;
1477                         if(ma->alpha==0.0 && ma->spectra==0.0) {
1478                                 ok= 0;
1479                                 /* texture on transparency? */
1480                                 for(a=0; a<MAX_MTEX; a++) {
1481                                         if(ma->mtex[a] && ma->mtex[a]->tex) {
1482                                                 if(ma->mtex[a]->mapto & MAP_ALPHA) ok= 1;
1483                                         }
1484                                 }
1485                         }
1486                         
1487                         /* if wire material, and we got edges, don't do the faces */
1488                         if(ma->mode & MA_WIRE) {
1489                                 end= dlm?dlm->totedge:me->totedge;
1490                                 if(end) ok= 0;
1491                         }
1492
1493                         if(ok) {
1494                                 TFace *tface= NULL;
1495
1496                                 /* radio faces need autosmooth, to separate shared vertices in corners */
1497                                 if(R.r.mode & R_RADIO)
1498                                         if(ma->mode & MA_RADIO) 
1499                                                 do_autosmooth= 1;
1500                                 
1501                                 end= dlm?dlm->totface:me->totface;
1502                                 if (dlm) {
1503                                         mface= dlm->mface;
1504                                         if (dlm->tface) {
1505                                                 tface= dlm->tface;
1506                                                 vertcol= NULL;
1507                                         } else if (dlm->mcol) {
1508                                                 vertcol= (unsigned int *)dlm->mcol;
1509                                         } else {
1510                                                 vertcol= NULL;
1511                                         }
1512                                 } else {
1513                                         mface= me->mface;
1514                                         if (me->tface) {
1515                                                 tface= me->tface;
1516                                                 vertcol= NULL;
1517                                         } else if (me->mcol) {
1518                                                 vertcol= (unsigned int *)me->mcol;
1519                                         } else {
1520                                                 vertcol= NULL;
1521                                         }
1522                                 }
1523
1524                                 for(a=0; a<end; a++) {
1525                                         int v1, v2, v3, v4, flag;
1526                                         
1527                                         if( mface->mat_nr==a1 ) {
1528                                                 float len;
1529                                                         
1530                                                 v1= mface->v1;
1531                                                 v2= mface->v2;
1532                                                 v3= mface->v3;
1533                                                 v4= mface->v4;
1534                                                 flag= mface->flag & ME_SMOOTH;
1535                                                 
1536                                                 vlr= RE_findOrAddVlak(R.totvlak++);
1537                                                 vlr->ob= vlr_set_ob(ob);
1538                                                 vlr->v1= RE_findOrAddVert(vertofs+v1);
1539                                                 vlr->v2= RE_findOrAddVert(vertofs+v2);
1540                                                 vlr->v3= RE_findOrAddVert(vertofs+v3);
1541                                                 if(v4) vlr->v4= RE_findOrAddVert(vertofs+v4);
1542                                                 else vlr->v4= 0;
1543
1544                                                 /* render normals are inverted in render */
1545                                                 if(vlr->v4) len= CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co,
1546                                                         vlr->v1->co, vlr->n);
1547                                                 else len= CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co,
1548                                                         vlr->n);
1549
1550                                                 vlr->mat= ma;
1551                                                 vlr->flag= flag;
1552                                                 if((me->flag & ME_NOPUNOFLIP) ) {
1553                                                         vlr->flag |= R_NOPUNOFLIP;
1554                                                 }
1555                                                 vlr->ec= 0; /* mesh edges rendered separately */
1556                                                 vlr->lay= ob->lay;
1557
1558                                                 if(len==0) R.totvlak--;
1559                                                 else {
1560                                                         if(dlm) {
1561                                                                 if(tface) {
1562                                                                         vlr->tface= BLI_memarena_alloc(R.memArena, sizeof(*vlr->tface));
1563                                                                         vlr->vcol= vlr->tface->col;
1564                                                                         memcpy(vlr->tface, tface, sizeof(*tface));
1565                                                                 } 
1566                                                                 else if (vertcol) {
1567                                                                         vlr->vcol= BLI_memarena_alloc(R.memArena, sizeof(int)*16);
1568                                                                         memcpy(vlr->vcol, vertcol+4*a, sizeof(int)*16);
1569                                                                 }
1570                                                         } else {
1571                                                                 if(tface) {
1572                                                                         vlr->vcol= tface->col;
1573                                                                         vlr->tface= tface;
1574                                                                 } 
1575                                                                 else if (vertcol) {
1576                                                                         vlr->vcol= vertcol+4*a;
1577                                                                 }
1578                                                         }
1579                                                 }
1580                                         }
1581
1582                                         mface++;
1583                                         if(tface) tface++;
1584                                 }
1585                         }
1586                 }
1587                 
1588                 /* exception... we do edges for wire mode. potential conflict when faces exist... */
1589                 end= dlm?dlm->totedge:me->totedge;
1590                 mvert= dlm?dlm->mvert:me->mvert;
1591                 ma= give_render_material(ob, 1);
1592                 if(end && (ma->mode & MA_WIRE)) {
1593                         MEdge *medge;
1594                         medge= dlm?dlm->medge:me->medge;
1595                         
1596                         for(a1=0; a1<end; a1++, medge++) {
1597                                 if (medge->flag&ME_EDGERENDER) {
1598                                         MVert *v0 = &mvert[medge->v1];
1599                                         MVert *v1 = &mvert[medge->v2];
1600
1601                                         vlr= RE_findOrAddVlak(R.totvlak++);
1602                                         vlr->ob= vlr_set_ob(ob);
1603                                         vlr->v1= RE_findOrAddVert(vertofs+medge->v1);
1604                                         vlr->v2= RE_findOrAddVert(vertofs+medge->v2);
1605                                         vlr->v3= vlr->v2;
1606                                         vlr->v4= NULL;
1607                                         
1608                                         xn= (v0->no[0]+v1->no[0]);
1609                                         yn= (v0->no[1]+v1->no[1]);
1610                                         zn= (v0->no[2]+v1->no[2]);
1611                                         /* transpose ! */
1612                                         vlr->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
1613                                         vlr->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
1614                                         vlr->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
1615                                         Normalise(vlr->n);
1616                                         
1617                                         vlr->mat= ma;
1618                                         vlr->flag= 0;
1619                                         vlr->ec= ME_V1V2;
1620                                         vlr->lay= ob->lay;
1621                                 }
1622                         }
1623                 }
1624         }
1625         
1626         if (test_for_displace( ob ) ) {
1627                 calc_vertexnormals(totverto, totvlako);
1628                 do_displacement(ob, totvlako, R.totvlak-totvlako, totverto, R.totvert-totverto);
1629         }
1630
1631         if(do_autosmooth || (me->flag & ME_AUTOSMOOTH)) {
1632                 autosmooth(totverto, totvlako, me->smoothresh);
1633         }
1634
1635         calc_vertexnormals(totverto, totvlako);
1636
1637         if(dlm) displistmesh_free(dlm);
1638         if(dm_needsfree) dm->release(dm);
1639 }
1640
1641 /* ------------------------------------------------------------------------- */
1642
1643 static void area_lamp_vectors(LampRen *lar)
1644 {
1645         float xsize= 0.5*lar->area_size, ysize= 0.5*lar->area_sizey;
1646
1647         /* corner vectors */
1648         lar->area[0][0]= lar->co[0] - xsize*lar->mat[0][0] - ysize*lar->mat[1][0];
1649         lar->area[0][1]= lar->co[1] - xsize*lar->mat[0][1] - ysize*lar->mat[1][1];
1650         lar->area[0][2]= lar->co[2] - xsize*lar->mat[0][2] - ysize*lar->mat[1][2];      
1651
1652         /* corner vectors */
1653         lar->area[1][0]= lar->co[0] - xsize*lar->mat[0][0] + ysize*lar->mat[1][0];
1654         lar->area[1][1]= lar->co[1] - xsize*lar->mat[0][1] + ysize*lar->mat[1][1];
1655         lar->area[1][2]= lar->co[2] - xsize*lar->mat[0][2] + ysize*lar->mat[1][2];      
1656
1657         /* corner vectors */
1658         lar->area[2][0]= lar->co[0] + xsize*lar->mat[0][0] + ysize*lar->mat[1][0];
1659         lar->area[2][1]= lar->co[1] + xsize*lar->mat[0][1] + ysize*lar->mat[1][1];
1660         lar->area[2][2]= lar->co[2] + xsize*lar->mat[0][2] + ysize*lar->mat[1][2];      
1661
1662         /* corner vectors */
1663         lar->area[3][0]= lar->co[0] + xsize*lar->mat[0][0] - ysize*lar->mat[1][0];
1664         lar->area[3][1]= lar->co[1] + xsize*lar->mat[0][1] - ysize*lar->mat[1][1];
1665         lar->area[3][2]= lar->co[2] + xsize*lar->mat[0][2] - ysize*lar->mat[1][2];      
1666         /* only for correction button size, matrix size works on energy */
1667         lar->areasize= lar->dist*lar->dist/(4.0*xsize*ysize);
1668 }
1669
1670 /* If lar takes more lamp data, the decoupling will be better. */
1671 void RE_add_render_lamp(Object *ob, int actual_render)
1672 {
1673         Lamp *la;
1674         LampRen *lar;
1675         GroupObject *go;
1676         float mat[4][4], hoek, xn, yn;
1677         int c;
1678
1679         /* prevent only shadow from rendering light, but only return on render, not preview */
1680         if(actual_render) {
1681                 if(la->mode & LA_ONLYSHADOW)
1682                         if((R.r.mode & R_SHADOW)==0)
1683                                 return;
1684         }
1685         
1686         go= MEM_callocN(sizeof(GroupObject), "groupobject");
1687         BLI_addtail(&R.lights, go);
1688         R.totlamp++;
1689         lar= (LampRen *)MEM_callocN(sizeof(LampRen),"lampren");
1690         go->lampren= lar;
1691         go->ob= ob;
1692
1693         MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
1694         MTC_Mat4Invert(ob->imat, mat);
1695
1696         MTC_Mat3CpyMat4(lar->mat, mat);
1697         MTC_Mat3CpyMat4(lar->imat, ob->imat);
1698
1699         la= ob->data;
1700         
1701         lar->bufsize = la->bufsize;
1702         lar->samp = la->samp;
1703         lar->soft = la->soft;
1704         lar->shadhalostep = la->shadhalostep;
1705         lar->clipsta = la->clipsta;
1706         lar->clipend = la->clipend;
1707         lar->bias = la->bias;
1708
1709         lar->type= la->type;
1710         lar->mode= la->mode;
1711
1712         lar->energy= la->energy;
1713         lar->energy= la->energy;
1714         if(la->mode & LA_NEG) lar->energy= -lar->energy;
1715
1716         lar->vec[0]= -mat[2][0];
1717         lar->vec[1]= -mat[2][1];
1718         lar->vec[2]= -mat[2][2];
1719         Normalise(lar->vec);
1720         lar->co[0]= mat[3][0];
1721         lar->co[1]= mat[3][1];
1722         lar->co[2]= mat[3][2];
1723         lar->dist= la->dist;
1724         lar->haint= la->haint;
1725         lar->distkw= lar->dist*lar->dist;
1726         lar->r= lar->energy*la->r;
1727         lar->g= lar->energy*la->g;
1728         lar->b= lar->energy*la->b;
1729         lar->k= la->k;
1730
1731         // area
1732         lar->ray_samp= la->ray_samp;
1733         lar->ray_sampy= la->ray_sampy;
1734         lar->ray_sampz= la->ray_sampz;
1735
1736         lar->area_size= la->area_size;
1737         lar->area_sizey= la->area_sizey;
1738         lar->area_sizez= la->area_sizez;
1739
1740         lar->area_shape= la->area_shape;
1741         lar->ray_samp_type= la->ray_samp_type;
1742
1743         if(lar->type==LA_AREA) {
1744                 switch(lar->area_shape) {
1745                 case LA_AREA_SQUARE:
1746                         lar->ray_totsamp= lar->ray_samp*lar->ray_samp;
1747                         lar->ray_sampy= lar->ray_samp;
1748                         lar->area_sizey= lar->area_size;
1749                         break;
1750                 case LA_AREA_RECT:
1751                         lar->ray_totsamp= lar->ray_samp*lar->ray_sampy;
1752                         break;
1753                 case LA_AREA_CUBE:
1754                         lar->ray_totsamp= lar->ray_samp*lar->ray_samp*lar->ray_samp;
1755                         lar->ray_sampy= lar->ray_samp;
1756                         lar->ray_sampz= lar->ray_samp;
1757                         lar->area_sizey= lar->area_size;
1758                         lar->area_sizez= lar->area_size;
1759                         break;
1760                 case LA_AREA_BOX:
1761                         lar->ray_totsamp= lar->ray_samp*lar->ray_sampy*lar->ray_sampz;
1762                         break;
1763                 }
1764
1765                 area_lamp_vectors(lar);
1766         }
1767         else lar->ray_totsamp= 0;
1768         
1769         /* yafray: photonlight and other params */
1770         if (R.r.renderer==R_YAFRAY) {
1771                 lar->YF_numphotons = la->YF_numphotons;
1772                 lar->YF_numsearch = la->YF_numsearch;
1773                 lar->YF_phdepth = la->YF_phdepth;
1774                 lar->YF_useqmc = la->YF_useqmc;
1775                 lar->YF_causticblur = la->YF_causticblur;
1776                 lar->YF_ltradius = la->YF_ltradius;
1777                 lar->YF_bufsize = la->YF_bufsize;
1778                 lar->YF_glowint = la->YF_glowint;
1779                 lar->YF_glowofs = la->YF_glowofs;
1780                 lar->YF_glowtype = la->YF_glowtype;
1781         }
1782
1783         lar->spotsi= la->spotsize;
1784         if(lar->mode & LA_HALO) {
1785                 if(lar->spotsi>170.0) lar->spotsi= 170.0;
1786         }
1787         lar->spotsi= cos( M_PI*lar->spotsi/360.0 );
1788         lar->spotbl= (1.0-lar->spotsi)*la->spotblend;
1789
1790         memcpy(lar->mtex, la->mtex, MAX_MTEX*sizeof(void *));
1791
1792         lar->lay= ob->lay & 0xFFFFFF;   // higher 8 bits are localview layers
1793
1794         lar->ld1= la->att1;
1795         lar->ld2= la->att2;
1796
1797         if(lar->type==LA_SPOT) {
1798
1799                 Normalise(lar->imat[0]);
1800                 Normalise(lar->imat[1]);
1801                 Normalise(lar->imat[2]);
1802
1803                 xn= saacos(lar->spotsi);
1804                 xn= sin(xn)/cos(xn);
1805                 lar->spottexfac= 1.0/(xn);
1806
1807                 if(lar->mode & LA_ONLYSHADOW) {
1808                         if((lar->mode & (LA_SHAD|LA_SHAD_RAY))==0) lar->mode -= LA_ONLYSHADOW;
1809                 }
1810
1811         }
1812
1813         /* set flag for spothalo en initvars */
1814         if(la->type==LA_SPOT && (la->mode & LA_HALO)) {
1815                 if(la->haint>0.0) {
1816                         R.flag |= R_LAMPHALO;
1817
1818                         /* camera position (0,0,0) rotate around lamp */
1819                         lar->sh_invcampos[0]= -lar->co[0];
1820                         lar->sh_invcampos[1]= -lar->co[1];
1821                         lar->sh_invcampos[2]= -lar->co[2];
1822                         MTC_Mat3MulVecfl(lar->imat, lar->sh_invcampos);
1823
1824                         /* z factor, for a normalized volume */
1825                         hoek= saacos(lar->spotsi);
1826                         xn= lar->spotsi;
1827                         yn= sin(hoek);
1828                         lar->sh_zfac= yn/xn;
1829                         /* pre-scale */
1830                         lar->sh_invcampos[2]*= lar->sh_zfac;
1831
1832                 }
1833         }
1834
1835         for(c=0; c<MAX_MTEX; c++) {
1836                 if(la->mtex[c] && la->mtex[c]->tex) {
1837                         lar->mode |= LA_TEXTURE;
1838
1839                         if(R.flag & R_RENDERING) {
1840                                 if(R.osa) {
1841                                         if(la->mtex[c]->tex->type==TEX_IMAGE) lar->mode |= LA_OSATEX;
1842                                 }
1843                         }
1844                 }
1845         }
1846
1847         /* yafray: shadowbuffers and jitter only needed for internal render */
1848         if (actual_render && R.r.renderer==R_INTERN) {
1849                 if(R.r.mode & R_SHADOW) {
1850                         if (la->type==LA_SPOT && (lar->mode & LA_SHAD) ) {
1851                                 /* Per lamp, one shadow buffer is made. */
1852                                 Mat4CpyMat4(mat, ob->obmat);
1853                                 RE_initshadowbuf(lar, mat);     // mat is altered
1854                         }
1855                         else if(la->type==LA_AREA && (lar->mode & LA_SHAD_RAY) ) {
1856                                 init_jitter_plane(lar);
1857                         }
1858                 }
1859         }
1860         
1861         /* yafray: shadow flag should not be cleared, only used with internal renderer */
1862         if (R.r.renderer==R_INTERN) {
1863                 /* to make sure we can check ray shadow easily in the render code */
1864                 if(lar->mode & LA_SHAD_RAY) {
1865                         if( (R.r.mode & R_RAYTRACE)==0)
1866                                 lar->mode &= ~LA_SHAD_RAY;
1867                 }
1868         }
1869 }
1870
1871 /* ------------------------------------------------------------------------- */
1872 static void init_render_surf(Object *ob)
1873 {
1874         extern Material defmaterial;    // initrender.c
1875         Nurb *nu=0;
1876         Curve *cu;
1877         ListBase displist;
1878         DispList *dl;
1879         VertRen *ver, *v1, *v2, *v3, *v4;
1880         VlakRen *vlr;
1881         Material *matar[32];
1882         float *data, *orco=NULL, *orcobase=NULL, n1[3], flen, mat[4][4];
1883         int a, need_orco=0, startvlak, startvert, p1, p2, p3, p4;
1884         int u, v;
1885         int sizeu, sizev;
1886         VlakRen *vlr1, *vlr2, *vlr3;
1887         float  vn[3]; // n2[3],
1888
1889         cu= ob->data;
1890         nu= cu->nurb.first;
1891         if(nu==0) return;
1892
1893         MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
1894         MTC_Mat4Invert(ob->imat, mat);
1895
1896         /* material array */
1897         memset(matar, 0, 4*32);
1898         matar[0]= &defmaterial;
1899         for(a=0; a<ob->totcol; a++) {
1900                 matar[a]= give_render_material(ob, a+1);
1901                 if(matar[a] && matar[a]->texco & TEXCO_ORCO) {
1902                         need_orco= 1;
1903                 }
1904         }
1905
1906         if(ob->parent && (ob->parent->type==OB_LATTICE)) need_orco= 1;
1907
1908         if(need_orco) orcobase= orco= get_object_orco(ob);
1909
1910         displist.first= displist.last= 0;
1911         makeDispListSurf(ob, &displist, 1);
1912
1913         dl= displist.first;
1914         /* walk along displaylist and create rendervertices/-faces */
1915         while(dl) {
1916                         /* watch out: u ^= y, v ^= x !! */
1917                 if(dl->type==DL_SURF) {
1918                         int nsizeu, nsizev;
1919
1920                         startvert= R.totvert;
1921                         nsizeu = sizeu = dl->parts; nsizev = sizev = dl->nr; 
1922
1923                         data= dl->verts;
1924                         for (u = 0; u < sizeu; u++) {
1925                                 v1 = RE_findOrAddVert(R.totvert++); /* save this for possible V wrapping */
1926                                 VECCOPY(v1->co, data); data += 3;
1927                                 if(orco) {
1928                                         v1->orco= orco; orco+= 3;
1929                                 }       
1930                                 MTC_Mat4MulVecfl(mat, v1->co);
1931
1932                                 for (v = 1; v < sizev; v++) {
1933                                         ver= RE_findOrAddVert(R.totvert++);
1934                                         VECCOPY(ver->co, data); data += 3;
1935                                         if(orco) {
1936                                                 ver->orco= orco; orco+= 3;
1937                                         }       
1938                                         MTC_Mat4MulVecfl(mat, ver->co);
1939                                 }
1940                                 /* if V-cyclic, add extra vertices at end of the row */
1941                                 if (dl->flag & DL_CYCL_U) {
1942                                         ver= RE_findOrAddVert(R.totvert++);
1943                                         VECCOPY(ver->co, v1->co);
1944                                         if(orco) {
1945                                                 ver->orco= orcobase + 3*(u*sizev + 0);
1946                                         }
1947                                 }       
1948                         }       
1949
1950                                 /* Done before next loop to get corner vert */
1951                         if (dl->flag & DL_CYCL_U) nsizev++;
1952                         if (dl->flag & DL_CYCL_V) nsizeu++;
1953
1954                         /* if U cyclic, add extra row at end of column */
1955                         if (dl->flag & DL_CYCL_V) {
1956                                 for (v = 0; v < nsizev; v++) {
1957                                         v1= RE_findOrAddVert(startvert + v);
1958                                         ver= RE_findOrAddVert(R.totvert++);
1959                                         VECCOPY(ver->co, v1->co);
1960                                         if(orco) {
1961                                                 ver->orco= orcobase + 3*(0*sizev + v);
1962                                         }
1963                                 }
1964                         }
1965                         
1966                         sizeu = nsizeu;
1967                         sizev = nsizev;
1968
1969                         startvlak= R.totvlak;
1970
1971                         for(u = 0; u < sizeu - 1; u++) {
1972                                 p1 = startvert + u * sizev; /* walk through face list */
1973                                 p2 = p1 + 1;
1974                                 p3 = p2 + sizev;
1975                                 p4 = p3 - 1;
1976
1977                                 for(v = 0; v < sizev - 1; v++) {
1978                                         v1= RE_findOrAddVert(p1);
1979                                         v2= RE_findOrAddVert(p2);
1980                                         v3= RE_findOrAddVert(p3);
1981                                         v4= RE_findOrAddVert(p4);
1982
1983                                         vlr= RE_findOrAddVlak(R.totvlak++);
1984                                         vlr->ob= vlr_set_ob(ob);
1985                                         vlr->v1= v1; vlr->v2= v2; vlr->v3= v3; vlr->v4= v4;
1986                                         
1987                                         flen= CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, n1);
1988                                         VECCOPY(vlr->n, n1);
1989                                         
1990                                         vlr->lay= ob->lay;
1991                                         vlr->mat= matar[ dl->col];
1992                                         vlr->ec= ME_V1V2+ME_V2V3;
1993                                         vlr->flag= dl->rt;
1994                                         if( (cu->flag & CU_NOPUNOFLIP) ) {
1995                                                 vlr->flag |= R_NOPUNOFLIP;
1996                                         }
1997
1998                                         VecAddf(v1->n, v1->n, n1);
1999                                         VecAddf(v2->n, v2->n, n1);
2000                                         VecAddf(v3->n, v3->n, n1);
2001                                         VecAddf(v4->n, v4->n, n1);
2002
2003                                         p1++; p2++; p3++; p4++;
2004                                 }
2005                         }       
2006                         /* fix normals for U resp. V cyclic faces */
2007                         sizeu--; sizev--;  /* dec size for face array */
2008                         if (dl->flag & DL_CYCL_V) {
2009
2010                                 for (v = 0; v < sizev; v++)
2011                                 {
2012                                         /* optimize! :*/
2013                                         vlr= RE_findOrAddVlak(UVTOINDEX(sizeu - 1, v));
2014                                         vlr1= RE_findOrAddVlak(UVTOINDEX(0, v));
2015                                         VecAddf(vlr1->v1->n, vlr1->v1->n, vlr->n);
2016                                         VecAddf(vlr1->v2->n, vlr1->v2->n, vlr->n);
2017                                         VecAddf(vlr->v3->n, vlr->v3->n, vlr1->n);
2018                                         VecAddf(vlr->v4->n, vlr->v4->n, vlr1->n);
2019                                 }
2020                         }
2021                         if (dl->flag & DL_CYCL_U) {
2022
2023                                 for (u = 0; u < sizeu; u++)
2024                                 {
2025                                         /* optimize! :*/
2026                                         vlr= RE_findOrAddVlak(UVTOINDEX(u, 0));
2027                                         vlr1= RE_findOrAddVlak(UVTOINDEX(u, sizev-1));
2028                                         VecAddf(vlr1->v2->n, vlr1->v2->n, vlr->n);
2029                                         VecAddf(vlr1->v3->n, vlr1->v3->n, vlr->n);
2030                                         VecAddf(vlr->v1->n, vlr->v1->n, vlr1->n);
2031                                         VecAddf(vlr->v4->n, vlr->v4->n, vlr1->n);
2032                                 }
2033                         }
2034                         /* last vertex is an extra case: 
2035
2036                         ^       ()----()----()----()
2037                         |       |     |     ||     |
2038                         u       |     |(0,n)||(0,0)|
2039                                 |     |     ||     |
2040                                 ()====()====[]====()
2041                                 |     |     ||     |
2042                                 |     |(m,n)||(m,0)|
2043                                 |     |     ||     |
2044                                 ()----()----()----()
2045                                        v ->
2046
2047                         vertex [] is no longer shared, therefore distribute
2048                         normals of the surrounding faces to all of the duplicates of []
2049                         */
2050
2051                         if ((dl->flag & DL_CYCL_V) && (dl->flag & DL_CYCL_U))
2052                         {
2053                                 vlr= RE_findOrAddVlak(UVTOINDEX(sizeu - 1, sizev - 1)); /* (m,n) */
2054                                 vlr1= RE_findOrAddVlak(UVTOINDEX(0,0));  /* (0,0) */
2055                                 VecAddf(vn, vlr->n, vlr1->n);
2056                                 vlr2= RE_findOrAddVlak(UVTOINDEX(0, sizev-1)); /* (0,n) */
2057                                 VecAddf(vn, vn, vlr2->n);
2058                                 vlr3= RE_findOrAddVlak(UVTOINDEX(sizeu-1, 0)); /* (m,0) */
2059                                 VecAddf(vn, vn, vlr3->n);
2060                                 VECCOPY(vlr->v3->n, vn);
2061                                 VECCOPY(vlr1->v1->n, vn);
2062                                 VECCOPY(vlr2->v2->n, vn);
2063                                 VECCOPY(vlr3->v4->n, vn);
2064                         }
2065                         for(a = startvert; a < R.totvert; a++) {
2066                                 ver= RE_findOrAddVert(a);
2067                                 Normalise(ver->n);
2068                         }
2069
2070
2071                 }
2072
2073                 dl= dl->next;
2074         }
2075         freedisplist(&displist);
2076 }
2077
2078 static void init_render_curve(Object *ob)
2079 {
2080         extern Material defmaterial;    // initrender.c
2081         Curve *cu;
2082         VertRen *ver;
2083         VlakRen *vlr;
2084         DispList *dl;
2085         Material *matar[32];
2086         float len, *data, *fp, *orco=NULL;
2087         float n[3], mat[4][4];
2088         int nr, startvert, startvlak, a, b;
2089         int frontside, need_orco=0;
2090
2091         cu= ob->data;
2092         if(cu->nurb.first==NULL) return;
2093
2094         /* no modifier call here, is in makedisp */
2095
2096         /* test displist */
2097         if(cu->disp.first==0) makeDispListCurveTypes(ob, 0);
2098         dl= cu->disp.first;
2099         if(cu->disp.first==0) return;
2100
2101         MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
2102         MTC_Mat4Invert(ob->imat, mat);
2103
2104         /* material array */
2105         memset(matar, 0, 4*32);
2106         matar[0]= &defmaterial;
2107         for(a=0; a<ob->totcol; a++) {
2108                 matar[a]= give_render_material(ob, a+1);
2109                 if(matar[a]->texco & TEXCO_ORCO) {
2110                         need_orco= 1;
2111                 }
2112         }
2113
2114         if(need_orco) orco= get_object_orco(ob);
2115
2116         dl= cu->disp.first;
2117         while(dl) {
2118                 if(dl->type==DL_INDEX3) {
2119                         int *index;
2120
2121                         startvert= R.totvert;
2122                         data= dl->verts;
2123
2124                         n[0]= ob->imat[0][2];
2125                         n[1]= ob->imat[1][2];
2126                         n[2]= ob->imat[2][2];
2127                         Normalise(n);
2128
2129                         /* copy first, rotate later for comparision trick */
2130                         for(a=0; a<dl->nr; a++, data+=3) {
2131                                 ver= RE_findOrAddVert(R.totvert++);
2132                                 VECCOPY(ver->co, data);
2133                                 MTC_Mat4MulVecfl(mat, ver->co);
2134
2135                                 if(ver->co[2] < 0.0) {
2136                                         VECCOPY(ver->n, n);
2137                                         ver->sticky = (float*) 1;
2138                                 }
2139                                 else {
2140                                         ver->n[0]= -n[0]; ver->n[1]= -n[1]; ver->n[2]= -n[2];
2141                                         ver->sticky = (float*) 0;
2142                                 }
2143
2144                                 if (orco) {
2145                                         ver->orco = orco;
2146                                         orco += 3;
2147                                 }
2148                         }
2149
2150                         startvlak= R.totvlak;
2151                         index= dl->index;
2152                         for(a=0; a<dl->parts; a++, index+=3) {
2153
2154                                 vlr= RE_findOrAddVlak(R.totvlak++);
2155                                 vlr->ob = vlr_set_ob(ob);       /* yafray: correction for curve rendering, obptr was not set */
2156                                 vlr->v1= RE_findOrAddVert(startvert+index[0]);
2157                                 vlr->v2= RE_findOrAddVert(startvert+index[1]);
2158                                 vlr->v3= RE_findOrAddVert(startvert+index[2]);
2159                                 vlr->v4= NULL;
2160                                 
2161                                 if(vlr->v1->sticky) {
2162                                         VECCOPY(vlr->n, n);
2163                                 }
2164                                 else {
2165                                         vlr->n[0]= -n[0]; vlr->n[1]= -n[1]; vlr->n[2]= -n[2];
2166                                 }
2167                                 
2168                                 vlr->mat= matar[ dl->col ];
2169                                 vlr->flag= 0;
2170                                 if( (cu->flag & CU_NOPUNOFLIP) ) {
2171                                         vlr->flag |= R_NOPUNOFLIP;
2172                                 }
2173                                 vlr->ec= 0;
2174                                 vlr->lay= ob->lay;
2175                         }
2176                 }
2177                 else if (dl->type==DL_SURF) {
2178                         int p1,p2,p3,p4;
2179                         float *surforco = orco;
2180
2181                         fp= dl->verts;
2182                         startvert= R.totvert;
2183                         nr= dl->nr*dl->parts;
2184
2185                         while(nr--) {
2186                                 ver= RE_findOrAddVert(R.totvert++);
2187                                         
2188                                 VECCOPY(ver->co, fp);
2189                                 MTC_Mat4MulVecfl(mat, ver->co);
2190                                 fp+= 3;
2191
2192                                 if (orco) {
2193                                         ver->orco = orco;
2194                                         orco += 3;
2195                                 }
2196                         }
2197
2198                         startvlak= R.totvlak;
2199
2200                         for(a=0; a<dl->parts; a++) {
2201
2202                                 frontside= (a >= dl->nr/2);
2203
2204                                 DL_SURFINDEX(dl->flag & DL_CYCL_U, dl->flag & DL_CYCL_V, dl->nr, dl->parts);
2205                                 p1+= startvert;
2206                                 p2+= startvert;
2207                                 p3+= startvert;
2208                                 p4+= startvert;
2209
2210                                 for(; b<dl->nr; b++) {
2211                                         vlr= RE_findOrAddVlak(R.totvlak++);
2212                                         vlr->ob= vlr_set_ob(ob);
2213                                         vlr->v1= RE_findOrAddVert(p2);
2214                                         vlr->v2= RE_findOrAddVert(p1);
2215                                         vlr->v3= RE_findOrAddVert(p3);
2216                                         vlr->v4= RE_findOrAddVert(p4);
2217                                         vlr->ec= ME_V2V3+ME_V3V4;
2218                                         if(a==0) vlr->ec+= ME_V1V2;
2219
2220                                         vlr->flag= dl->rt;
2221                                         vlr->lay= ob->lay;
2222
2223                                         /* this is not really scientific: the vertices
2224                                                 * 2, 3 en 4 seem to give better vertexnormals than 1 2 3:
2225                                                 * front and backside treated different!!
2226                                                 */
2227
2228                                         if(frontside)
2229                                                 CalcNormFloat(vlr->v2->co, vlr->v3->co, vlr->v4->co, vlr->n);
2230                                         else 
2231                                                 CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->n);
2232
2233                                         vlr->mat= matar[ dl->col ];
2234
2235                                         p4= p3;
2236                                         p3++;
2237                                         p2= p1;
2238                                         p1++;
2239                                 }
2240                         }
2241
2242                         if (dl->bevelSplitFlag) {
2243                                 for(a=0; a<dl->parts-1+!!(dl->flag&DL_CYCL_V); a++)
2244                                         if(dl->bevelSplitFlag[a>>5]&(1<<(a&0x1F)))
2245                                                 split_v_renderfaces(startvlak, startvert, dl->parts, dl->nr, a, dl->flag&DL_CYCL_V, dl->flag&DL_CYCL_U);
2246                         }
2247
2248                         /* vertex normals */
2249                         for(a= startvlak; a<R.totvlak; a++) {
2250                                 vlr= RE_findOrAddVlak(a);
2251
2252                                 VecAddf(vlr->v1->n, vlr->v1->n, vlr->n);
2253                                 VecAddf(vlr->v3->n, vlr->v3->n, vlr->n);
2254                                 VecAddf(vlr->v2->n, vlr->v2->n, vlr->n);
2255                                 VecAddf(vlr->v4->n, vlr->v4->n, vlr->n);
2256                         }
2257                         for(a=startvert; a<R.totvert; a++) {
2258                                 ver= RE_findOrAddVert(a);
2259                                 len= Normalise(ver->n);
2260                                 if(len==0.0) ver->sticky= (float *)1;
2261                                 else ver->sticky= 0;
2262                         }
2263                         for(a= startvlak; a<R.totvlak; a++) {
2264                                 vlr= RE_findOrAddVlak(a);
2265                                 if(vlr->v1->sticky) VECCOPY(vlr->v1->n, vlr->n);
2266                                 if(vlr->v2->sticky) VECCOPY(vlr->v2->n, vlr->n);
2267                                 if(vlr->v3->sticky) VECCOPY(vlr->v3->n, vlr->n);
2268                                 if(vlr->v4->sticky) VECCOPY(vlr->v4->n, vlr->n);
2269                         }
2270                 }
2271
2272                 dl= dl->next;
2273         }
2274 }
2275
2276 /* prevent phong interpolation for giving ray shadow errors (terminator problem) */
2277 static void set_phong_threshold(Object *ob, int startface, int numface, int startvert, int numvert )
2278 {
2279 //      VertRen *ver;
2280         VlakRen *vlr;
2281         float thresh= 0.0, dot;
2282         int tot=0, i;
2283         
2284         /* Added check for 'pointy' situations, only dotproducts of 0.9 and larger 
2285            are taken into account. This threshold is meant to work on smooth geometry, not
2286            for extreme cases (ton) */
2287         
2288         for(i=startface; i<startface+numface; i++) {
2289                 vlr= RE_findOrAddVlak(i);
2290                 if(vlr->flag & R_SMOOTH) {
2291                         dot= INPR(vlr->n, vlr->v1->n);
2292                         dot= ABS(dot);
2293                         if(dot>0.9) {
2294                                 thresh+= dot; tot++;
2295                         }
2296                         dot= INPR(vlr->n, vlr->v2->n);
2297                         dot= ABS(dot);
2298                         if(dot>0.9) {
2299                                 thresh+= dot; tot++;
2300                         }
2301
2302                         dot= INPR(vlr->n, vlr->v3->n);
2303                         dot= ABS(dot);
2304                         if(dot>0.9) {
2305                                 thresh+= dot; tot++;
2306                         }
2307
2308                         if(vlr->v4) {
2309                                 dot= INPR(vlr->n, vlr->v4->n);
2310                                 dot= ABS(dot);
2311                                 if(dot>0.9) {
2312                                         thresh+= dot; tot++;
2313                                 }
2314                         }
2315                 }
2316         }
2317         
2318         if(tot) {
2319                 thresh/= (float)tot;
2320                 ob->smoothresh= cos(0.5*M_PI-acos(thresh));
2321         }
2322 }
2323
2324 static void init_render_object(Object *ob)
2325 {
2326         float mat[4][4];
2327         int startface, startvert;
2328         
2329         startface=R.totvlak;
2330         startvert=R.totvert;
2331
2332         ob->flag |= OB_DONE;
2333
2334         if(ob->type==OB_LAMP)
2335                 RE_add_render_lamp(ob, 1);
2336         else if ELEM(ob->type, OB_FONT, OB_CURVE)
2337                 init_render_curve(ob);
2338         else if(ob->type==OB_SURF)
2339                 init_render_surf(ob);
2340         else if(ob->type==OB_MESH)
2341                 init_render_mesh(ob);
2342         else if(ob->type==OB_MBALL)
2343                 init_render_mball(ob);
2344         else {
2345                 MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
2346                 MTC_Mat4Invert(ob->imat, mat);
2347         }
2348         
2349         /* generic post process here */
2350         if(startvert!=R.totvert) {
2351         
2352                 /* the exception below is because displace code now is in init_render_mesh call, 
2353                 I will look at means to have autosmooth enabled for all object types 
2354                 and have it as general postprocess, like displace */
2355                 if (ob->type!=OB_MESH && test_for_displace( ob ) ) 
2356                         do_displacement(ob, startface, R.totvlak-startface, startvert, R.totvert-startvert);
2357         
2358                 /* phong normal interpolation can cause error in tracing (terminator prob) */
2359                 ob->smoothresh= 0.0;
2360                 if( (R.r.mode & R_RAYTRACE) && (R.r.mode & R_SHADOW) ) 
2361                         set_phong_threshold(ob, startface, R.totvlak-startface, startvert, R.totvert-startvert);
2362         }
2363 }
2364
2365 void RE_freeRotateBlenderScene(void)
2366 {
2367         ShadBuf *shb;
2368         Object *ob = NULL;
2369         GroupObject *go;
2370         unsigned long *ztile;
2371         int a, b, v;
2372         char *ctile;
2373
2374         /* FREE */
2375         
2376         BLI_memarena_free(R.memArena);
2377         R.memArena = NULL;
2378         
2379         for(go= R.lights.first; go; go= go->next) {
2380                 struct LampRen *lar= go->lampren;
2381                 if(lar->shb) {
2382                         shb= lar->shb;
2383                         v= (shb->size*shb->size)/256;
2384                         ztile= shb->zbuf;
2385                         ctile= shb->cbuf;
2386                         for(b=0; b<v; b++, ztile++, ctile++) {
2387                                 if(*ctile) MEM_freeN((void *) *ztile);
2388                         }
2389                         
2390                         MEM_freeN(shb->zbuf);
2391                         MEM_freeN(shb->cbuf);
2392                         MEM_freeN(lar->shb);
2393                 }
2394                 if(lar->jitter) MEM_freeN(lar->jitter);
2395                 MEM_freeN(lar);
2396         }
2397         
2398         BLI_freelistN(&R.lights);
2399
2400         /* note; these pointer arrays were allocated, with last element NULL to stop loop */
2401         a=0;
2402         while(R.blove[a]) {
2403                 MEM_freeN(R.blove[a]);
2404                 R.blove[a]= NULL;
2405                 a++;
2406         }
2407
2408         a=0;
2409         while(R.blovl[a]) {
2410                 MEM_freeN(R.blovl[a]);
2411                 R.blovl[a]= NULL;
2412                 a++;
2413         }
2414         a=0;
2415         while(R.bloha[a]) {
2416                 MEM_freeN(R.bloha[a]);
2417                 R.bloha[a]= NULL;
2418                 a++;
2419         }
2420
2421         /* free orco. check all objects because of duplis and sets */
2422         ob= G.main->object.first;
2423         while(ob) {
2424                 if(ob->type==OB_MBALL) {
2425                         if(ob->disp.first && ob->disp.first!=ob->disp.last) {
2426                                 DispList *dl= ob->disp.first;
2427                                 BLI_remlink(&ob->disp, dl);
2428                                 freedisplist(&ob->disp);
2429                                 BLI_addtail(&ob->disp, dl);
2430                         }
2431                 }
2432                 ob= ob->id.next;
2433         }
2434
2435         free_mesh_orco_hash();
2436
2437         end_radio_render();
2438         if(R.wrld.aosphere) {
2439                 MEM_freeN(R.wrld.aosphere);
2440                 R.wrld.aosphere= NULL;
2441                 G.scene->world->aosphere= NULL;
2442         }
2443         
2444         R.totvlak=R.totvert=R.totlamp=R.tothalo= 0;
2445 }
2446
2447 /* per face check if all samples should be taken.
2448    if raytrace, do always for raytraced material, or when material full_osa set */
2449 static void set_fullsample_flag(void)
2450 {
2451         VlakRen *vlr;
2452         int a, trace;
2453
2454         trace= R.r.mode & R_RAYTRACE;
2455         
2456         for(a=R.totvlak-1; a>=0; a--) {
2457                 vlr= RE_findOrAddVlak(a);
2458                 
2459                 if(vlr->mat->mode & MA_FULL_OSA) vlr->flag |= R_FULL_OSA;
2460                 else if(trace) {
2461                         if(vlr->mat->mode & MA_SHLESS);
2462                         else if(vlr->mat->mode & (MA_RAYTRANSP|MA_RAYMIRROR|MA_SHADOW))
2463                                 vlr->flag |= R_FULL_OSA;
2464                 }
2465         }
2466 }
2467
2468 /* 10 times larger than normal epsilon, test it on default nurbs sphere with ray_transp */
2469 #ifdef FLT_EPSILON
2470 #undef FLT_EPSILON
2471 #endif
2472 #define FLT_EPSILON 1.19209290e-06F
2473
2474
2475 static void check_non_flat_quads(void)
2476 {
2477         VlakRen *vlr, *vlr1;
2478         VertRen *v1, *v2, *v3, *v4;
2479         float nor[3], xn, flen;
2480         int a;
2481
2482         for(a=R.totvlak-1; a>=0; a--) {
2483                 vlr= RE_findOrAddVlak(a);
2484                 
2485                 /* test if rendering as a quad or triangle, skip wire */
2486                 if(vlr->v4 && (vlr->flag & R_STRAND)==0 && (vlr->mat->mode & MA_WIRE)==0) {
2487                         
2488                         /* check if quad is actually triangle */
2489                         v1= vlr->v1;
2490                         v2= vlr->v2;
2491                         v3= vlr->v3;
2492                         v4= vlr->v4;
2493                         VECSUB(nor, v1->co, v2->co);
2494                         if( ABS(nor[0])<FLT_EPSILON &&  ABS(nor[1])<FLT_EPSILON && ABS(nor[2])<FLT_EPSILON ) {
2495                                 vlr->v1= v2;
2496                                 vlr->v2= v3;
2497                                 vlr->v3= v4;
2498                                 vlr->v4= NULL;
2499                         }
2500                         else {
2501                                 VECSUB(nor, v2->co, v3->co);
2502                                 if( ABS(nor[0])<FLT_EPSILON &&  ABS(nor[1])<FLT_EPSILON && ABS(nor[2])<FLT_EPSILON ) {
2503                                         vlr->v2= v3;
2504                                         vlr->v3= v4;
2505                                         vlr->v4= NULL;
2506                                 }
2507                                 else {
2508                                         VECSUB(nor, v3->co, v4->co);
2509                                         if( ABS(nor[0])<FLT_EPSILON &&  ABS(nor[1])<FLT_EPSILON && ABS(nor[2])<FLT_EPSILON ) {
2510                                                 vlr->v4= NULL;
2511                                         }
2512                                         else {
2513                                                 VECSUB(nor, v4->co, v1->co);
2514                                                 if( ABS(nor[0])<FLT_EPSILON &&  ABS(nor[1])<FLT_EPSILON && ABS(nor[2])<FLT_EPSILON ) {
2515                                                         vlr->v4= NULL;
2516                                                 }
2517                                         }
2518                                 }
2519                         }
2520                         
2521                         if(vlr->v4) {
2522                                 
2523                                 /* Face is divided along edge with the least gradient           */
2524                                 /* Flagged with R_DIVIDE_24 if divide is from vert 2 to 4       */
2525                                 /*              4---3           4---3 */
2526                                 /*              |\ 1|   or  |1 /| */
2527                                 /*              |0\ |           |/ 0| */
2528                                 /*              1---2           1---2   0 = orig face, 1 = new face */
2529                                 
2530                                 /* render normals are inverted in render! we calculate normal of single tria here */
2531                                 flen= CalcNormFloat(vlr->v4->co, vlr->v3->co, vlr->v1->co, nor);
2532                                 if(flen==0.0) CalcNormFloat(vlr->v4->co, vlr->v2->co, vlr->v1->co, nor);
2533                                 
2534                                 xn= nor[0]*vlr->n[0] + nor[1]*vlr->n[1] + nor[2]*vlr->n[2];
2535                                 if(ABS(xn) < 0.99995 ) {        // checked on noisy fractal grid
2536                                         float d1, d2;
2537                                         
2538                                         vlr1= RE_findOrAddVlak(R.totvlak++);
2539                                         *vlr1= *vlr;
2540                                         vlr1->flag |= R_FACE_SPLIT;
2541                                         
2542                                         /* split direction based on vnorms */
2543                                         CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, nor);
2544                                         d1= nor[0]*vlr->v1->n[0] + nor[1]*vlr->v1->n[1] + nor[2]*vlr->v1->n[2];
2545
2546                                         CalcNormFloat(vlr->v2->co, vlr->v3->co, vlr->v4->co, nor);
2547                                         d2= nor[0]*vlr->v2->n[0] + nor[1]*vlr->v2->n[1] + nor[2]*vlr->v2->n[2];
2548                                         
2549                                         if( fabs(d1) < fabs(d2) ) vlr->flag |= R_DIVIDE_24;
2550                                         else vlr->flag &= ~R_DIVIDE_24;
2551                                         
2552                                         /* new vertex pointers */
2553                                         if (vlr->flag & R_DIVIDE_24) {
2554                                                 vlr1->v1= vlr->v2;
2555                                                 vlr1->v2= vlr->v3;
2556                                                 vlr1->v3= vlr->v4;
2557
2558                                                 vlr->v3 = vlr->v4;
2559                                                 
2560                                                 vlr1->flag |= R_DIVIDE_24;
2561                                         }
2562                                         else {
2563                                                 vlr1->v1= vlr->v1;
2564                                                 vlr1->v2= vlr->v3;
2565                                                 vlr1->v3= vlr->v4;
2566                                                 
2567                                                 vlr1->flag &= ~R_DIVIDE_24;
2568                                         }
2569                                         vlr->v4 = vlr1->v4 = NULL;
2570                                         
2571                                         /* new normals */
2572                                         CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n);
2573                                         CalcNormFloat(vlr1->v3->co, vlr1->v2->co, vlr1->v1->co, vlr1->n);
2574                                         
2575                                         /* so later UV can be pulled from original tface, look for R_DIVIDE_24 for direction */
2576                                         vlr1->tface=vlr->tface; 
2577
2578                                 }
2579                                 /* clear the flag when not divided */
2580                                 else vlr->flag &= ~R_DIVIDE_24;
2581                         }
2582                 }
2583         }
2584 }
2585
2586 static void set_material_lightgroups(void)
2587 {
2588         GroupObject *go, *gol;
2589         Material *ma;
2590         
2591         /* it's a bit too many loops in loops... but will survive */
2592         for(ma= G.main->mat.first; ma; ma=ma->id.next) {
2593                 if(ma->group) {
2594                         for(go= ma->group->gobject.first; go; go= go->next) {
2595                                 for(gol= R.lights.first; gol; gol= gol->next) {
2596                                         if(gol->ob==go->ob) {
2597                                                 go->lampren= gol->lampren;
2598                                                 break;
2599                                         }
2600                                 }
2601                         }
2602                 }
2603         }
2604 }
2605
2606 extern int slurph_opt;  /* key.c */
2607 extern ListBase duplilist;
2608 void RE_rotateBlenderScene(void)
2609 {
2610         Base *base;
2611         Object *ob, *obd;
2612         Scene *sce;
2613         unsigned int lay;
2614         float mat[4][4];
2615
2616         if(G.scene->camera==NULL) return;
2617
2618         R.memArena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
2619         R.totvlak=R.totvert=R.totlamp=R.tothalo= 0;
2620         
2621         slurph_opt= 0;
2622
2623         /* in localview, lamps are using normal layers, objects only local bits */
2624         if(G.scene->lay & 0xFF000000) lay= G.scene->lay & 0xFF000000;
2625         else lay= G.scene->lay;
2626         
2627         /* applies changes fully */
2628         scene_update_for_newframe(G.scene, lay);
2629
2630         MTC_Mat4CpyMat4(R.viewinv, G.scene->camera->obmat);
2631         MTC_Mat4Ortho(R.viewinv);
2632         MTC_Mat4Invert(R.viewmat, R.viewinv);
2633
2634         RE_setwindowclip(1,-1); /*  no jit:(-1) */
2635
2636         /* clear imat flags */
2637         ob= G.main->object.first;
2638         while(ob) {
2639                 ob->flag &= ~OB_DO_IMAT;
2640                 ob= ob->id.next;
2641         }
2642
2643         init_render_world();    /* do first, because of ambient. also requires R.osa set correct */
2644         if( (R.wrld.mode & WO_AMB_OCC) && (R.r.mode & R_RAYTRACE) ) {
2645                 R.wrld.aosphere= MEM_mallocN(2*3*R.wrld.aosamp*R.wrld.aosamp*sizeof(float), "AO sphere");
2646                 /* we make twice the amount of samples, because only a hemisphere is used */
2647                 init_ao_sphere(R.wrld.aosphere, 2*R.wrld.aosamp*R.wrld.aosamp, 16);
2648                 
2649                 /* bah... init_render_world writes this over, and that is called/needed in envmap. */
2650                 G.scene->world->aosphere= R.wrld.aosphere;
2651         }
2652         init_render_textures();
2653         init_render_materials();
2654
2655         /* imat objects, OB_DO_IMAT can be set in init_render_materials
2656            has to be done here, since displace can have texture using Object map-input */
2657         ob= G.main->object.first;
2658         while(ob) {
2659                 if(ob->flag & OB_DO_IMAT) {
2660                         ob->flag &= ~OB_DO_IMAT;
2661                         MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
2662                         MTC_Mat4Invert(ob->imat, mat);
2663                 }
2664                 ob= ob->id.next;
2665         }
2666
2667         /* MAKE RENDER DATA */
2668
2669         /* each object should only be rendered once */
2670         ob= G.main->object.first;
2671         while(ob) {
2672                 ob->flag &= ~OB_DONE;
2673                 ob= ob->id.next;
2674         }
2675         
2676         sce= G.scene;
2677
2678         base= G.scene->base.first;
2679         while(base) {
2680
2681                 ob= base->object;
2682
2683                 if(ob->flag & OB_DONE) {
2684                         /* yafray: this object needs to be included in renderlist for duplivert instancing.
2685                                  This only works for dupliverts, dupliframes handled below.
2686                                  This is based on the assumption that OB_DONE is only set for duplivert objects,
2687                                  before scene conversion, there are no other flags set to indicate it's use as far as I know...
2688                                  NOT done for lamps, these are included as separate objects, see below.
2689                                  correction: also ignore lattices, armatures and camera's (.....) */
2690                         if ((ob->type!=OB_LATTICE) && (ob->type!=OB_ARMATURE) &&
2691                                         (ob->type!=OB_LAMP) && (ob->type!=OB_CAMERA) && (R.r.renderer==R_YAFRAY))
2692                         {
2693                                 printf("Adding %s to renderlist\n", ob->id.name);
2694                                 ob->flag &= ~OB_DONE;
2695                                 init_render_object(ob);
2696                                 ob->flag |= OB_DONE;
2697                         }
2698                 }
2699                 else {
2700                         if( (base->lay & lay) || (ob->type==OB_LAMP && (base->lay & G.scene->lay)) ) {
2701
2702                                 if(ob->transflag & OB_DUPLI) {
2703                                         /* exception: mballs! */
2704                                         /* yafray: Include at least one copy of a dupliframe object for yafray in the renderlist.
2705                                            mballs comment above true as well for yafray, they are not included, only all other object types */
2706                                         if (R.r.renderer==R_YAFRAY) {
2707                                                 if ((ob->type!=OB_MBALL) && ((ob->transflag & OB_DUPLIFRAMES)!=0)) {
2708                                                         printf("Object %s has OB_DUPLIFRAMES set, adding to renderlist\n", ob->id.name);
2709                                                         init_render_object(ob);
2710                                                 }
2711                                         }
2712                                         /* before make duplis, update particle for current frame */
2713                                         if(ob->transflag & OB_DUPLIVERTS) {
2714                                                 PartEff *paf= give_parteff(ob);
2715                                                 if(paf) {
2716                                                         if(paf->flag & PAF_ANIMATED) build_particle_system(ob);
2717                                                 }
2718                                         }
2719                                         
2720                                         make_duplilist(sce, ob);
2721                                         if(ob->type==OB_MBALL) {
2722                                                 init_render_object(ob);
2723                                         }
2724                                         else {
2725                                                 obd= duplilist.first;
2726                                                 if(obd) {
2727                                                         /* exception, in background render it doesnt make the displist */
2728                                                         if ELEM(obd->type, OB_CURVE, OB_SURF) {
2729                                                                 Curve *cu;
2730
2731                                                                 cu= obd->data;
2732                                                                 if(cu->disp.first==NULL) {
2733                                                                         obd->flag &= ~OB_FROMDUPLI;
2734                                                                         makeDispListCurveTypes(obd, 0);
2735                                                                         obd->flag |= OB_FROMDUPLI;
2736                                                                 }
2737                                                         }
2738                                                 }
2739
2740                                                 obd= duplilist.first;
2741                                                 while(obd) {
2742                                                         if(obd->type!=OB_MBALL) {
2743                                                                 /* yafray: special handling of duplivert objects for yafray:
2744                                                                    only the matrix is stored, together with the source object name.
2745                                                                          Since the original object is needed as well, it is included in the renderlist (see above)
2746                                                                          NOT done for lamps, these need to be included as normal lamps separately
2747                                                                          correction: also ignore lattices, armatures and cameras (....) */
2748                                                                 if ((obd->type!=OB_LATTICE) && (obd->type!=OB_ARMATURE) &&
2749                                                                                 (obd->type!=OB_LAMP) && (obd->type!=OB_CAMERA) && (R.r.renderer==R_YAFRAY))
2750                                                                 {
2751                                                                         printf("Adding dupli matrix for object %s\n", obd->id.name);
2752                                                                         YAF_addDupliMtx(obd);
2753                                                                 }
2754                                                                 else init_render_object(obd);
2755                                                         }
2756                                                         obd= obd->id.next;
2757                                                 }
2758                                         }
2759                                         free_duplilist();
2760                                 }
2761                                 else {
2762                                         /* yafray: if there are linked data objects (except lamps, empties or armatures),
2763                                            yafray only needs to know about one, the rest can be instanciated.
2764                                            The dupliMtx list is used for this purpose.
2765                                            Exception: objects which have object linked materials, these cannot be instanciated. */
2766                                         if ((R.r.renderer==R_YAFRAY) && (ob->colbits==0))
2767                                         {
2768                                                 /* Special case, parent object dupli's: ignore if object itself is lamp or parent is lattice or empty */
2769                                                 if (ob->parent) {
2770         &nbs