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