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