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