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