9bccd128a5c3c3dd060a49266951f2a39bbf0ed3
[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 /* check for dl->flag, 1 or 2 should be replaced be the def's below */
35 #define STRUBI hack
36 #define DL_CYCLIC_U 1
37 #define DL_CYCLIC_V 2
38
39 #include <math.h>
40 #include <stdlib.h>
41 #include <stdio.h>
42 #include <string.h>
43 #include <limits.h>          /* for INT_MAX                 */
44
45 #include "blendef.h"
46 #include "MTC_matrixops.h"
47
48 #include "MEM_guardedalloc.h"
49
50 #include "BLI_arithb.h"
51 #include "BLI_blenlib.h"
52 #include "BLI_rand.h"
53
54 #include "DNA_scene_types.h"
55 #include "DNA_lamp_types.h"
56 #include "DNA_camera_types.h"
57 #include "DNA_material_types.h"
58 #include "DNA_curve_types.h"
59 #include "DNA_texture_types.h"
60 #include "DNA_lattice_types.h"
61 #include "DNA_effect_types.h"
62 #include "DNA_ika_types.h"
63 #include "DNA_armature_types.h"
64 #include "DNA_object_types.h"
65 #include "DNA_view3d_types.h"
66 #include "DNA_mesh_types.h"
67
68 #include "BKE_mesh.h"
69 #include "BKE_key.h"
70 #include "BKE_action.h"
71 #include "BKE_curve.h"
72 #include "BKE_armature.h"
73 #include "BKE_object.h"
74 #include "BKE_texture.h"
75 #include "BKE_material.h"
76 #include "BKE_main.h"
77 #include "BKE_mball.h"
78 #include "BKE_anim.h"
79 #include "BKE_global.h"
80 #include "BKE_effect.h"
81 #include "BKE_world.h"
82 #include "BKE_ipo.h"
83 #include "BKE_ika.h"
84 #include "BKE_displist.h"
85 #include "BKE_lattice.h"
86 #include "BKE_constraint.h"
87 #include "BKE_utildefines.h"
88 #include "BKE_subsurf.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 #ifdef HAVE_CONFIG_H
106 #include <config.h>
107 #endif
108
109 /* yafray: VertRen vertices are not transformed, transform is replaced with the identity matrix,
110  * since yafray needs the untransformed meshes to calculate orco texture space as in Blender.
111  * This is not true for lamps however, which use a copy of the original object matrix instead.
112  * Duplicated data objects & dupliframe/duplivert objects are only stored once,
113  * only the matrix is stored for all others, in yafray these objects are instances of the original.
114  * The main changes are in RE_rotateBlenderScene().
115  */
116
117 /* ------------------------------------------------------------------------- */
118 /* Local functions                                                           */
119 /* ------------------------------------------------------------------------- */
120 static Material *give_render_material(Object *ob, int nr);
121
122
123
124 /* blenderWorldManipulation.c */
125 static void split_u_renderfaces(int startvlak, int startvert, int usize, int plek, int cyclu);
126 static void split_v_renderfaces(int startvlak, int startvert, int usize, int vsize, int plek, int cyclu, int cyclv);
127 static int contrpuntnormr(float *n, float *puno);
128 static void normalenrender(int startvert, int startvlak);
129 static void as_addvert(VertRen *v1, VlakRen *vlr);
130 static void as_freevert(VertRen *ver);
131 static void autosmooth(int startvert, int startvlak, int degr);
132 static void make_render_halos(Object *ob, Mesh *me, Material *ma, float *extverts);
133 static int mesh_test_flipnorm(Object *ob, MFace *mface, VlakRen *vlr, float imat[][3]);
134 static void render_particle_system(Object *ob, PartEff *paf);
135 static void render_static_particle_system(Object *ob, PartEff *paf);
136 static void init_render_displist_mesh(Object *ob);
137 static int verghalo(const void *a1, const void *a2);
138 static void sort_halos(void);
139 static void init_render_mball(Object *ob);
140 static void init_render_mesh(Object *ob);
141 static void init_render_surf(Object *ob);
142 static void init_render_curve(Object *ob);
143 static int test_flipnorm(float *v1, float *v2, float *v3, VlakRen *vlr, float imat[][3]);
144 static void init_render_object(Object *ob);
145 static HaloRen *initstar(float *vec, float hasize);
146
147 /* more prototypes for autosmoothing below */
148
149
150 /* ------------------------------------------------------------------------- */
151 /* tool functions/defines for ad hoc simplification and possible future 
152    cleanup      */
153 /* ------------------------------------------------------------------------- */
154
155 #define UVTOINDEX(u,v) (startvlak + (u) * sizev + (v))
156 #define GETNORMAL(face,normal) CalcNormFloat4(face->v1->co, face->v2->co, face->v3->co, face->v4->co, normal)
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, force, alpha;
193 /*      float loc_far_var, loc_near_var; */
194         int x, y, z, sx, sy, sz, ex, ey, ez, maxjit, 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 = (256.0* 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 = 255;
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 //                      if(done > MAXVERT) {
313 //                              printf("Too many stars\n");
314 //                              break;
315 //                      }
316                         if(blender_test_break()) break;
317                 }
318 //              if(done > MAXVERT) break;
319
320                 if(blender_test_break()) break;
321         }
322         if (termfunc) termfunc();
323 }
324
325 /* ------------------------------------------------------------------------ */
326 /* more star stuff */
327 static HaloRen *initstar(float *vec, float hasize)
328 {
329         HaloRen *har;
330         float hoco[4];
331
332         RE_projectverto(vec, hoco);
333
334         if(     (R.r.mode & R_PANORAMA) ||  RE_testclip(hoco)==0 ) {
335                 har= RE_findOrAddHalo(R.tothalo++);
336         
337                 /* projectvert is done in function zbufvlaggen again, because of parts */
338                 VECCOPY(har->co, vec);
339                 har->hasize= hasize;
340         
341                 har->zd= 0.0;
342         
343                 return har;
344         }
345         return NULL;
346 }
347
348
349
350 /* ------------------------------------------------------------------------- */
351
352 static void split_u_renderfaces(int startvlak, int startvert, int usize, int plek, int cyclu)
353 {
354         VlakRen *vlr;
355         VertRen *v1, *v2;
356         int a, v;
357
358         if(cyclu) cyclu= 1;
359
360         /* first give all involved vertices a pointer to the new one */
361         v= startvert+ plek*usize;
362         for(a=0; a<usize; a++) {
363                 v2= RE_findOrAddVert(R.totvert++);
364                 v1= RE_findOrAddVert(v++);
365                 *v2= *v1;
366                 v1->sticky= (float *)v2;
367         }
368
369         /* check involved faces and replace pointers */
370         v= startvlak+plek*(usize-1+cyclu);
371         for(a=1-cyclu; a<usize; a++) {
372                 vlr= RE_findOrAddVlak(v++);
373                 vlr->v1= (VertRen *)(vlr->v1->sticky);
374                 vlr->v2= (VertRen *)(vlr->v2->sticky);
375         }
376
377 }
378
379 /* ------------------------------------------------------------------------- */
380
381 static void split_v_renderfaces(int startvlak, int startvert, int usize, int vsize, int plek, int cyclu, int cyclv)
382 {
383         VlakRen *vlr;
384         VertRen *v1=0;
385         int a, vlak, ofs;
386
387         if(vsize<2) return;
388
389         /* check involved faces and create doubles */
390         /* because (evt) split_u already has been done, you cannot work with vertex->sticky pointers */
391         /* because faces do not share vertices anymore */
392
393         if(plek+cyclu==usize) plek= -1;
394
395         vlak= startvlak+(plek+cyclu);
396         ofs= (usize-1+cyclu);
397
398         for(a=1; a<vsize; a++) {
399
400                 vlr= RE_findOrAddVlak(vlak);
401                 if (vlr->v1 == 0) return; /* OOPS, when not cyclic */
402
403                 v1= RE_findOrAddVert(R.totvert++);
404                 *v1= *(vlr->v1);
405
406                 vlr->v1= v1;
407
408                 /* vlr= findOrAddVlak(vlak+1); */
409                 /* vlr->v1= v1; */
410
411                 if(a>1) {
412                         vlr= RE_findOrAddVlak(vlak-ofs);
413                         if(vlr->v4->sticky) {
414                                 v1= RE_findOrAddVert(R.totvert++);
415                                 *v1= *(vlr->v4);
416                                 vlr->v4= v1;
417                         }
418                         else vlr->v4= v1;
419                 }
420
421                 if(a== vsize-1) {
422                         if(cyclv) {
423                                 ;
424                         }
425                         else {
426                                 vlr= RE_findOrAddVlak(vlak);
427                                 v1= RE_findOrAddVert(R.totvert++);
428                                 *v1= *(vlr->v4);
429                                 vlr->v4= v1;
430                         }
431                 }
432
433                 vlak+= ofs;
434         }
435
436 }
437
438 /* ------------------------------------------------------------------------- */
439
440 static int contrpuntnormr(float *n, float *puno)
441 {
442         float inp;
443
444         inp=n[0]*puno[0]+n[1]*puno[1]+n[2]*puno[2];
445         if(inp<0.0) return 1;
446         return 0;
447 }
448
449 /* ------------------------------------------------------------------------- */
450
451 static void normalenrender(int startvert, int startvlak)
452 {
453         VlakRen *vlr;
454         VertRen *ver, *adrve1, *adrve2, *adrve3, *adrve4;
455         float n1[3], n2[3], n3[3], n4[3], *adrco, *tfl, fac, *temp;
456         int a;
457
458         if(R.totvlak==0 || R.totvert==0) return;
459         if(startvert==R.totvert || startvlak==R.totvlak) return;
460
461         adrco= (float *)MEM_callocN(12+4*sizeof(float)*(R.totvlak-startvlak), "normalen1");
462
463         tfl= adrco;
464         /* calculate cos of angles and point-masses */
465         for(a= startvlak; a<R.totvlak; a++) {
466                 vlr= RE_findOrAddVlak(a);
467
468                 adrve1= vlr->v1;
469                 adrve2= vlr->v2;
470                 adrve3= vlr->v3;
471                 adrve4= vlr->v4;
472
473                 VecSubf(n1, adrve2->co, adrve1->co);
474                 Normalise(n1);
475                 VecSubf(n2, adrve3->co, adrve2->co);
476                 Normalise(n2);
477                 if(adrve4==0) {
478                         VecSubf(n3, adrve1->co, adrve3->co);
479                         Normalise(n3);
480
481                         *(tfl++)= saacos(-n1[0]*n3[0]-n1[1]*n3[1]-n1[2]*n3[2]);
482                         *(tfl++)= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
483                         *(tfl++)= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
484                 }
485                 else {
486                         VecSubf(n3, adrve4->co, adrve3->co);
487                         Normalise(n3);
488                         VecSubf(n4, adrve1->co, adrve4->co);
489                         Normalise(n4);
490
491                         *(tfl++)= saacos(-n4[0]*n1[0]-n4[1]*n1[1]-n4[2]*n1[2]);
492                         *(tfl++)= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
493                         *(tfl++)= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
494                         *(tfl++)= saacos(-n3[0]*n4[0]-n3[1]*n4[1]-n3[2]*n4[2]);
495                 }
496         }
497
498         /* clear all vertex normals */
499         for(a=startvert; a<R.totvert; a++) {
500                 ver= RE_findOrAddVert(a);
501
502                 ver->n[0]=ver->n[1]=ver->n[2]= 0.0;
503         }
504
505         /* calculate normals and add it to the vertex normals (dutch: punt normaal) */
506         tfl= adrco;
507         for(a=startvlak; a<R.totvlak; a++) {
508                 vlr= RE_findOrAddVlak(a);
509
510                 adrve1= vlr->v1;
511                 adrve2= vlr->v2;
512                 adrve3= vlr->v3;
513                 adrve4= vlr->v4;
514
515                 temp= adrve1->n;
516                 fac= *(tfl++);
517                 if( vlr->flag & R_NOPUNOFLIP);
518                 else if( contrpuntnormr(vlr->n, temp) ) fac= -fac ;
519                 *(temp++) +=fac*vlr->n[0];
520                 *(temp++) +=fac*vlr->n[1];
521                 *(temp)   +=fac*vlr->n[2];
522
523                 temp= adrve2->n;
524                 fac= *(tfl++);
525                 if( vlr->flag & R_NOPUNOFLIP);
526                 else  if( contrpuntnormr(vlr->n, temp) ) fac= -fac ;
527                 *(temp++) +=fac*vlr->n[0];
528                 *(temp++) +=fac*vlr->n[1];
529                 *(temp)   +=fac*vlr->n[2];
530
531                 temp= adrve3->n;
532                 fac= *(tfl++);
533                 if( vlr->flag & R_NOPUNOFLIP);
534                 else if( contrpuntnormr(vlr->n, temp) ) fac= -fac ;
535                 *(temp++) +=fac*vlr->n[0];
536                 *(temp++) +=fac*vlr->n[1];
537                 *(temp)   +=fac*vlr->n[2];
538
539                 if(adrve4) {
540                         temp= adrve4->n;
541                         fac= *(tfl++);
542                         if( vlr->flag & R_NOPUNOFLIP);
543                         else if( contrpuntnormr(vlr->n, temp) ) fac= -fac ;
544                         *(temp++) +=fac*vlr->n[0];
545                         *(temp++) +=fac*vlr->n[1];
546                         *(temp)   +=fac*vlr->n[2];
547                 }
548         }
549
550         /* normalise vertex normals */
551         for(a=startvert; a<R.totvert; a++) {
552                 ver= RE_findOrAddVert(a);
553
554                 Normalise(ver->n);
555         }
556
557         /* vertex normal (puno) switch flags for during render */
558         for(a=startvlak; a<R.totvlak; a++) {
559                 vlr= RE_findOrAddVlak(a);
560
561                 if((vlr->flag & R_NOPUNOFLIP)==0) {
562                         adrve1= vlr->v1;
563                         adrve2= vlr->v2;
564                         adrve3= vlr->v3;
565                         adrve4= vlr->v4;
566         
567                         vlr->puno= 0;
568                         fac= vlr->n[0]*adrve1->n[0]+vlr->n[1]*adrve1->n[1]+vlr->n[2]*adrve1->n[2];
569                         if(fac<0.0) vlr->puno= 1;
570                         fac= vlr->n[0]*adrve2->n[0]+vlr->n[1]*adrve2->n[1]+vlr->n[2]*adrve2->n[2];
571                         if(fac<0.0) vlr->puno+= 2;
572                         fac= vlr->n[0]*adrve3->n[0]+vlr->n[1]*adrve3->n[1]+vlr->n[2]*adrve3->n[2];
573                         if(fac<0.0) vlr->puno+= 4;
574         
575                         if(adrve4) {
576                                 fac= vlr->n[0]*adrve4->n[0]+vlr->n[1]*adrve4->n[1]+vlr->n[2]*adrve4->n[2];
577                                 if(fac<0.0) vlr->puno+= 8;
578                         }
579                 }
580         }
581
582         MEM_freeN(adrco);
583 }
584
585 /* ------------------------------------------------------------------------- */
586 /* Autosmoothing:                                                            */
587 /* ------------------------------------------------------------------------- */
588
589 typedef struct ASvert {
590         int totface;
591         ListBase faces;
592 } ASvert;
593
594 typedef struct ASface {
595         struct ASface *next, *prev;
596         VlakRen *vlr[4];
597         VertRen *nver[4];
598 } ASface;
599
600 /* prototypes: */
601 static int as_testvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thresh);
602 static VertRen *as_findvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thresh);
603
604
605 static void as_addvert(VertRen *v1, VlakRen *vlr)
606 {
607         ASvert *asv;
608         ASface *asf;
609         int a;
610         
611         if(v1 == NULL) return;
612         
613         if(v1->svert==0) {
614                 v1->svert= MEM_callocN(sizeof(ASvert), "asvert");
615                 asv= v1->svert;
616                 asf= MEM_callocN(sizeof(ASface), "asface");
617                 BLI_addtail(&asv->faces, asf);
618         }
619         
620         asv= v1->svert;
621         asf= asv->faces.last;
622         for(a=0; a<4; a++) {
623                 if(asf->vlr[a]==0) {
624                         asf->vlr[a]= vlr;
625                         asv->totface++;
626                         break;
627                 }
628         }
629         
630         /* new face struct */
631         if(a==4) {
632                 asf= MEM_callocN(sizeof(ASface), "asface");
633                 BLI_addtail(&asv->faces, asf);
634                 asf->vlr[0]= vlr;
635                 asv->totface++;
636         }
637 }
638
639 static void as_freevert(VertRen *ver)
640 {
641         ASvert *asv;
642
643         asv= ver->svert;
644         BLI_freelistN(&asv->faces);
645         MEM_freeN(asv);
646         ver->svert= NULL;
647 }
648
649 static int as_testvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thresh) 
650 {
651         /* return 1: vertex needs a copy */
652         ASface *asf;
653         float inp;
654         int a;
655         
656         if(vlr==0) return 0;
657         
658         asf= asv->faces.first;
659         while(asf) {
660                 for(a=0; a<4; a++) {
661                         if(asf->vlr[a] && asf->vlr[a]!=vlr) {
662                                 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] );
663                                 if(inp < thresh) return 1;
664                         }
665                 }
666                 asf= asf->next;
667         }
668         
669         return 0;
670 }
671
672 static VertRen *as_findvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thresh) 
673 {
674         /* return when new vertex already was made */
675         ASface *asf;
676         float inp;
677         int a;
678         
679         asf= asv->faces.first;
680         while(asf) {
681                 for(a=0; a<4; a++) {
682                         if(asf->vlr[a] && asf->vlr[a]!=vlr) {
683                                 /* this face already made a copy for this vertex! */
684                                 if(asf->nver[a]) {
685                                         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] );
686                                         if(inp >= thresh) {
687                                                 return asf->nver[a];
688                                         }
689                                 }
690                         }
691                 }
692                 asf= asf->next;
693         }
694         
695         return NULL;
696 }
697
698 static void autosmooth(int startvert, int startvlak, int degr)
699 {
700         ASvert *asv;
701         ASface *asf;
702         VertRen *ver, *v1;
703         VlakRen *vlr;
704         float thresh;
705         int a, b, totvert;
706         
707         thresh= cos( M_PI*((float)degr)/180.0 );
708         
709         /* initialize */
710         for(a=startvert; a<R.totvert; a++) {
711                 ver= RE_findOrAddVert(a);
712                 ver->svert= 0;
713         }
714         
715         /* step one: construct listbase of all vertices and pointers to faces */
716         for(a=startvlak; a<R.totvlak; a++) {
717                 vlr= RE_findOrAddVlak(a);
718                 
719                 as_addvert(vlr->v1, vlr);
720                 as_addvert(vlr->v2, vlr);
721                 as_addvert(vlr->v3, vlr);
722                 as_addvert(vlr->v4, vlr);
723         }
724         
725         /* we now test all vertices, when faces have a normal too much different: they get a new vertex */
726         totvert= R.totvert;
727         for(a=startvert; a<totvert; a++) {
728                 ver= RE_findOrAddVert(a);
729                 asv= ver->svert;
730                 if(asv && asv->totface>1) {
731                         
732                         asf= asv->faces.first;
733                         while(asf) {
734                                 for(b=0; b<4; b++) {
735                                 
736                                         /* is there a reason to make a new vertex? */
737                                         vlr= asf->vlr[b];
738                                         if( as_testvertex(vlr, ver, asv, thresh) ) {
739                                                 
740                                                 /* already made a new vertex within threshold? */
741                                                 v1= as_findvertex(vlr, ver, asv, thresh);
742                                                 if(v1==0) {
743                                                         /* make a new vertex */
744                                                         v1= RE_findOrAddVert(R.totvert++);
745                                                         *v1= *ver;
746                                                         v1->svert= 0;
747                                                 }
748                                                 asf->nver[b]= v1;
749                                                 if(vlr->v1==ver) vlr->v1= v1;
750                                                 if(vlr->v2==ver) vlr->v2= v1;
751                                                 if(vlr->v3==ver) vlr->v3= v1;
752                                                 if(vlr->v4==ver) vlr->v4= v1;
753                                         }
754                                 }
755                                 asf= asf->next;
756                         }
757                 }
758         }
759         
760         /* free */
761         for(a=startvert; a<R.totvert; a++) {
762                 ver= RE_findOrAddVert(a);
763                 if(ver->svert) as_freevert(ver);
764         }
765         
766 }
767
768 /* ------------------------------------------------------------------------- */
769 /* End of autosmoothing:                                                     */
770 /* ------------------------------------------------------------------------- */
771
772 static void make_render_halos(Object *ob, Mesh *me, Material *ma, float *extverts)
773 {
774         HaloRen *har;
775         MVert *mvert;
776         float xn, yn, zn, nor[3], view[3];
777         float *orco, vec[3], hasize, mat[4][4], imat[3][3];
778         int start, end, a, ok;
779
780         MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
781         MTC_Mat3CpyMat4(imat, ob->imat);
782
783         R.flag |= R_HALO;
784         mvert= me->mvert;
785
786         orco= me->orco;
787
788         start= 0;
789         end= me->totvert;
790         set_buildvars(ob, &start, &end);
791         mvert+= start;
792         if(extverts) extverts+= 3*start;
793
794         ma->ren->seed1= ma->seed1;
795
796         for(a=start; a<end; a++, mvert++) {
797                 ok= 1;
798
799                 if(ok) {
800                         hasize= ma->hasize;
801
802                         if(extverts) {
803                                 VECCOPY(vec, extverts);
804                                 extverts+= 3;
805                         }
806                         else {
807                                 VECCOPY(vec, mvert->co);
808                         }
809                         MTC_Mat4MulVecfl(mat, vec);
810
811                         if(ma->mode & MA_HALOPUNO) {
812                                 xn= mvert->no[0];
813                                 yn= mvert->no[1];
814                                 zn= mvert->no[2];
815
816                                 /* transpose ! */
817                                 nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
818                                 nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
819                                 nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
820                                 Normalise(nor);
821
822                                 VECCOPY(view, vec);
823                                 Normalise(view);
824
825                                 zn= nor[0]*view[0]+nor[1]*view[1]+nor[2]*view[2];
826                                 if(zn>=0.0) hasize= 0.0;
827                                 else hasize*= zn*zn*zn*zn;
828                         }
829
830                         if(orco) har= RE_inithalo(ma, vec, 0, orco, hasize, 0);
831                         else har= RE_inithalo(ma, vec, 0, mvert->co, hasize, 0);
832                         if(har) har->lay= ob->lay;
833                 }
834                 if(orco) orco+= 3;
835                 ma->ren->seed1++;
836         }
837 }
838
839 /* ------------------------------------------------------------------------- */
840
841 static int test_flipnorm(float *v1, float *v2, float *v3, VlakRen *vlr, float imat[][3])
842 {
843         float nor[3], vec[3];
844         float xn;
845         
846         CalcNormFloat(v1, v2, v3, nor);
847         vec[0]= imat[0][0]*nor[0]+ imat[0][1]*nor[1]+ imat[0][2]*nor[2];
848         vec[1]= imat[1][0]*nor[0]+ imat[1][1]*nor[1]+ imat[1][2]*nor[2];
849         vec[2]= imat[2][0]*nor[0]+ imat[2][1]*nor[1]+ imat[2][2]*nor[2];
850
851         xn= vec[0]*vlr->n[0]+vec[1]*vlr->n[1]+vec[2]*vlr->n[2];
852
853         return (xn<0.0);
854 }
855
856 static int mesh_test_flipnorm(Object *ob, MFace *mface, VlakRen *vlr, float imat[][3])
857 {
858         DispList *dl;
859         Mesh *me= ob->data;
860         float *v1, *v2, *v3;    
861
862         dl= find_displist(&ob->disp, DL_VERTS);
863         if(dl) {
864                 v1= dl->verts + 3*mface->v1;
865                 v2= dl->verts + 3*mface->v2;
866                 v3= dl->verts + 3*mface->v3;
867         }
868         else {
869                 v1= (me->mvert+mface->v1)->co;
870                 v2= (me->mvert+mface->v2)->co;
871                 v3= (me->mvert+mface->v3)->co;
872         }
873         
874         return test_flipnorm(v1, v2, v3, vlr, imat);
875 }
876
877
878 /* ------------------------------------------------------------------------- */
879
880
881
882 /* ------------------------------------------------------------------------- */
883
884 static void render_particle_system(Object *ob, PartEff *paf)
885 {
886         Particle *pa=0;
887         HaloRen *har=0;
888         Material *ma=0;
889         float xn, yn, zn, imat[3][3], mat[4][4], hasize, ptime, ctime, vec[3], vec1[3], view[3], nor[3];
890         int a, mat_nr=1;
891
892         pa= paf->keys;
893         if(pa==0) {
894                 build_particle_system(ob);
895                 pa= paf->keys;
896                 if(pa==0) return;
897         }
898
899         ma= give_render_material(ob, 1);
900         if(ma==0) ma= &defmaterial;
901
902         MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
903         MTC_Mat4Invert(ob->imat, mat);  /* this is correct, for imat texture */
904
905         MTC_Mat4Invert(mat, R.viewmat); /* particles do not have a ob transform anymore */
906         MTC_Mat3CpyMat4(imat, mat);
907
908         R.flag |= R_HALO;
909
910         if(ob->ipoflag & OB_OFFS_PARTICLE) ptime= ob->sf;
911         else ptime= 0.0;
912         ctime= bsystem_time(ob, 0, (float)G.scene->r.cfra, ptime);
913         ma->ren->seed1= ma->seed1;
914
915         for(a=0; a<paf->totpart; a++, pa+=paf->totkey) {
916
917                 if(ctime > pa->time) {
918                         if(ctime < pa->time+pa->lifetime) {
919
920                                 /* watch it: also calculate the normal of a particle */
921                                 if(paf->stype==PAF_VECT || ma->mode & MA_HALO_SHADE) {
922                                         where_is_particle(paf, pa, ctime, vec);
923                                         MTC_Mat4MulVecfl(R.viewmat, vec);
924                                         where_is_particle(paf, pa, ctime+1.0, vec1);
925                                         MTC_Mat4MulVecfl(R.viewmat, vec1);
926                                 }
927                                 else {
928                                         where_is_particle(paf, pa, ctime, vec);
929                                         MTC_Mat4MulVecfl(R.viewmat, vec);
930                                 }
931
932                                 if(pa->mat_nr != mat_nr) {
933                                         mat_nr= pa->mat_nr;
934                                         ma= give_render_material(ob, mat_nr);
935                                         if(ma==0) ma= &defmaterial;
936                                 }
937
938                                 if(ma->ipo) {
939                                         /* correction for lifetime */
940                                         ptime= 100.0*(ctime-pa->time)/pa->lifetime;
941                                         calc_ipo(ma->ipo, ptime);
942                                         execute_ipo((ID *)ma, ma->ipo);
943                                 }
944
945                                 hasize= ma->hasize;
946
947                                 if(ma->mode & MA_HALOPUNO) {
948                                         xn= pa->no[0];
949                                         yn= pa->no[1];
950                                         zn= pa->no[2];
951
952                                         /* transpose ! */
953                                         nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
954                                         nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
955                                         nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
956                                         Normalise(nor);
957
958                                         VECCOPY(view, vec);
959                                         Normalise(view);
960
961                                         zn= nor[0]*view[0]+nor[1]*view[1]+nor[2]*view[2];
962                                         if(zn>=0.0) hasize= 0.0;
963                                         else hasize*= zn*zn*zn*zn;
964                                 }
965
966                                 if(paf->stype==PAF_VECT) har= RE_inithalo(ma, vec, vec1, pa->co, hasize, paf->vectsize);
967                                 else {
968                                         har= RE_inithalo(ma, vec, 0, pa->co, hasize, 0);
969                                         if(har && ma->mode & MA_HALO_SHADE) {
970                                                 VecSubf(har->no, vec, vec1);
971                                                 Normalise(har->no);
972                                         }
973                                 }
974                                 if(har) har->lay= ob->lay;
975                         }
976                 }
977                 ma->ren->seed1++;
978         }
979
980 }
981
982
983 /* ------------------------------------------------------------------------- */
984
985 static void render_static_particle_system(Object *ob, PartEff *paf)
986 {
987         Particle *pa=0;
988         HaloRen *har=0;
989         Material *ma=0;
990         float xn, yn, zn, imat[3][3], mat[4][4], hasize;
991         float mtime, ptime, ctime, vec[3], vec1[3], view[3], nor[3];
992         int a, mat_nr=1;
993
994         pa= paf->keys;
995         if(pa==0) {
996                 build_particle_system(ob);
997                 pa= paf->keys;
998                 if(pa==0) return;
999         }
1000
1001         ma= give_render_material(ob, 1);
1002         if(ma==0) ma= &defmaterial;
1003
1004         MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
1005         MTC_Mat4Invert(ob->imat, mat);  /* need to be that way, for imat texture */
1006
1007         MTC_Mat3CpyMat4(imat, ob->imat);
1008
1009         R.flag |= R_HALO;
1010
1011         if(ob->ipoflag & OB_OFFS_PARTICLE) ptime= ob->sf;
1012         else ptime= 0.0;
1013         ctime= bsystem_time(ob, 0, (float)G.scene->r.cfra, ptime);
1014         ma->ren->seed1= ma->seed1;
1015
1016         for(a=0; a<paf->totpart; a++, pa+=paf->totkey) {
1017
1018                 where_is_particle(paf, pa, pa->time, vec1);
1019                 MTC_Mat4MulVecfl(mat, vec1);
1020                 
1021                 mtime= pa->time+pa->lifetime+paf->staticstep-1;
1022                 
1023                 for(ctime= pa->time; ctime<mtime; ctime+=paf->staticstep) {
1024                         
1025                         /* make sure hair grows until the end.. */
1026                         if(ctime>pa->time+pa->lifetime) ctime= pa->time+pa->lifetime;
1027                         
1028
1029                         /* watch it: also calc the normal of a particle */
1030                         if(paf->stype==PAF_VECT || ma->mode & MA_HALO_SHADE) {
1031                                 where_is_particle(paf, pa, ctime+1.0, vec);
1032                                 MTC_Mat4MulVecfl(mat, vec);
1033                         }
1034                         else {
1035                                 where_is_particle(paf, pa, ctime, vec);
1036                                 MTC_Mat4MulVecfl(mat, vec);
1037                         }
1038
1039                         if(pa->mat_nr != mat_nr) {
1040                                 mat_nr= pa->mat_nr;
1041                                 ma= give_render_material(ob, mat_nr);
1042                                 if(ma==0) ma= &defmaterial;
1043                         }
1044
1045                         if(ma->ipo) {
1046                                 /* correction for lifetime */
1047                                 ptime= 100.0*(ctime-pa->time)/pa->lifetime;
1048                                 calc_ipo(ma->ipo, ptime);
1049                                 execute_ipo((ID *)ma, ma->ipo);
1050                         }
1051
1052                         hasize= ma->hasize;
1053
1054                         if(ma->mode & MA_HALOPUNO) {
1055                                 xn= pa->no[0];
1056                                 yn= pa->no[1];
1057                                 zn= pa->no[2];
1058
1059                                 /* transpose ! */
1060                                 nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
1061                                 nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
1062                                 nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
1063                                 Normalise(nor);
1064
1065                                 VECCOPY(view, vec);
1066                                 Normalise(view);
1067
1068                                 zn= nor[0]*view[0]+nor[1]*view[1]+nor[2]*view[2];
1069                                 if(zn>=0.0) hasize= 0.0;
1070                                 else hasize*= zn*zn*zn*zn;
1071                         }
1072
1073                         if(paf->stype==PAF_VECT) har= RE_inithalo(ma, vec, vec1, pa->co, hasize, paf->vectsize);
1074                         else {
1075                                 har= RE_inithalo(ma, vec, 0, pa->co, hasize, 0);
1076                                 if(har && (ma->mode & MA_HALO_SHADE)) {
1077                                         VecSubf(har->no, vec, vec1);
1078                                         Normalise(har->no);
1079                                         har->lay= ob->lay;
1080                                 }
1081                         }
1082
1083                         VECCOPY(vec1, vec);
1084                 }
1085                 ma->ren->seed1++;
1086         }
1087
1088 }
1089
1090 /* ------------------------------------------------------------------------- */
1091
1092 static void init_render_displist_mesh(Object *ob)
1093 {
1094         Mesh *me;
1095         DispList *dl;
1096         VlakRen *vlr;
1097         Material *matar[32];
1098         VertRen *ver, *v1, *v2, *v3, *v4;
1099         float xn, yn, zn;
1100         float mat[4][4], imat[3][3], *data, *nors, *orco=0, n1[3], flen;
1101         int a, b, flipnorm= -1,  need_orco=0, startvert, p1, p2, p3, p4;
1102         int old_totvert= R.totvert;
1103         int old_totvlak= R.totvlak;
1104
1105         me= ob->data;
1106
1107         /* yafray: set transform to identity matrix */
1108         if (R.r.mode & R_YAFRAY)
1109                 MTC_Mat4One(mat);
1110         else
1111                 MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
1112         MTC_Mat4Invert(ob->imat, mat);
1113         MTC_Mat3CpyMat4(imat, ob->imat);
1114
1115         /* material array */
1116         memset(matar, 0, sizeof(matar));
1117         matar[0]= &defmaterial;
1118         for(a=0; a<ob->totcol; a++) {
1119                 matar[a]= give_render_material(ob, a+1);
1120                 if(matar[a]==0) matar[a]= &defmaterial;
1121                 if(matar[a]->ren->texco & TEXCO_ORCO) {
1122                         need_orco= 1;
1123                 }
1124         }
1125
1126         dl= me->disp.first;
1127
1128         /* Force a displist rebuild if this is a subsurf and we have a different subdiv level */
1129
1130         if((dl==0) || ((me->subdiv != me->subdivr))) {
1131                 /* prevent subsurf called again for duplicate use of mesh, tface pointers change */
1132                 if(me->subdivdone!=me->subdivr) {
1133                         object_deform(ob);
1134                         subsurf_make_mesh(ob, me->subdivr);
1135                         me->subdivdone= me->subdivr;
1136                         dl = me->disp.first;
1137                 }
1138         }
1139
1140         if(dl==0) return;
1141
1142         if(need_orco) {
1143                 make_orco_displist_mesh(ob, me->subdivr);
1144                 orco= me->orco;
1145         }
1146
1147         while(dl) {
1148                 if(dl->type==DL_SURF) {
1149                         startvert= R.totvert;
1150                         a= dl->nr*dl->parts;
1151                         data= dl->verts;
1152                         nors= dl->nors;
1153                         
1154                         while(a--) {
1155                                 ver= RE_findOrAddVert(R.totvert++);
1156                                 VECCOPY(ver->co, data);
1157                                 if(orco) {
1158                                         ver->orco= orco;
1159                                         orco+= 3;
1160                                 }
1161                                 else {
1162                                         ver->orco= data;
1163                                 }
1164                                 
1165                                 MTC_Mat4MulVecfl(mat, ver->co);
1166                                 
1167                                 xn= nors[0];
1168                                 yn= nors[1];
1169                                 zn= nors[2];
1170                 
1171                                 /* transpose ! */
1172                                 ver->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
1173                                 ver->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
1174                                 ver->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
1175
1176                                 Normalise(ver->n);
1177                                                 
1178                                 data+= 3;
1179                                 nors+= 3;
1180                         }
1181
1182                         for(a=0; a<dl->parts; a++) {
1183
1184                                 DL_SURFINDEX(dl->flag & DL_CYCLIC_V, dl->flag & DL_CYCLIC_U, dl->nr, dl->parts);
1185                                 p1+= startvert;
1186                                 p2+= startvert;
1187                                 p3+= startvert;
1188                                 p4+= startvert;
1189
1190                                 for(; b<dl->nr; b++) {
1191                                         v1= RE_findOrAddVert(p1);
1192                                         v2= RE_findOrAddVert(p2);
1193                                         v3= RE_findOrAddVert(p3);
1194                                         v4= RE_findOrAddVert(p4);
1195
1196                                         flen= CalcNormFloat4(v1->co, v3->co, v4->co, v2->co, n1);
1197                                         if(flen!=0.0) {
1198                                                 vlr= RE_findOrAddVlak(R.totvlak++);
1199                                                 vlr->ob= ob;
1200                                                 vlr->v1= v1;
1201                                                 vlr->v2= v3;
1202                                                 vlr->v3= v4;
1203                                                 vlr->v4= v2;
1204                                                 VECCOPY(vlr->n, n1);
1205                                                 vlr->len= flen;
1206                                                 vlr->lay= ob->lay;
1207                                                 
1208                                                 vlr->mat= matar[ dl->col];
1209                                                 vlr->ec= ME_V1V2+ME_V2V3;
1210                                                 vlr->flag= ME_SMOOTH;
1211                                                 
1212                                                 if(flipnorm== -1) flipnorm= mesh_test_flipnorm(ob, me->mface, vlr, imat);
1213                                                 
1214                                                 if(flipnorm) {
1215                                                         vlr->n[0]= -vlr->n[0];
1216                                                         vlr->n[1]= -vlr->n[1];
1217                                                         vlr->n[2]= -vlr->n[2];
1218                                                 }
1219
1220                                                 /* vlr->flag |= R_NOPUNOFLIP; */
1221                                                 /* vlr->puno= 15; */
1222                                                 vlr->puno= 0;
1223                                         }
1224
1225                                         p4= p3;
1226                                         p3++;
1227                                         p2= p1;
1228                                         p1++;
1229                                 }
1230                         }
1231                 } else if (dl->type==DL_MESH) {
1232                         DispListMesh *dlm= dl->mesh;
1233                         int i;
1234                         
1235                         startvert= R.totvert;
1236                         for (i=0; i<dlm->totvert; i++) {
1237                                 MVert *mv= &dlm->mvert[i];
1238                                 
1239                                 ver= RE_findOrAddVert(R.totvert++);
1240                                 VECCOPY(ver->co, mv->co);
1241                                 MTC_Mat4MulVecfl(mat, ver->co);
1242                                 
1243                                 xn= mv->no[0];
1244                                 yn= mv->no[1];
1245                                 zn= mv->no[2];
1246
1247                                 /* transpose ! */
1248                                 ver->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
1249                                 ver->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
1250                                 ver->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
1251
1252                                 Normalise(ver->n);
1253                                 
1254                                 if (orco)
1255                                         ver->orco= &orco[i*3];
1256                         }
1257
1258                         for (i=0; i<dlm->totface; i++) {
1259                                 MFaceInt *mf= &dlm->mface[i];
1260                                 
1261                                 if (!mf->v3)
1262                                         continue;
1263                                         
1264                                 v1= RE_findOrAddVert(startvert+mf->v1);
1265                                 v2= RE_findOrAddVert(startvert+mf->v2);
1266                                 v3= RE_findOrAddVert(startvert+mf->v3);
1267
1268                                 if (mf->v4) {
1269                                         v4= RE_findOrAddVert(startvert+mf->v4);
1270                                         flen= CalcNormFloat4(v1->co, v2->co, v3->co, v4->co, n1);
1271                                 } else { 
1272                                         v4= 0;
1273                                         flen= CalcNormFloat(v1->co, v2->co, v3->co, n1);
1274                                 }
1275
1276                                 if(flen!=0.0) {
1277                                         vlr= RE_findOrAddVlak(R.totvlak++);
1278                                         vlr->ob= ob;
1279                                         vlr->v1= v1;
1280                                         vlr->v2= v2;
1281                                         vlr->v3= v3;
1282                                         vlr->v4= v4;
1283
1284                                         VECCOPY(vlr->n, n1);
1285                                         vlr->len= flen;
1286                                         vlr->lay= ob->lay;
1287                                                 
1288                                         vlr->mat= matar[mf->mat_nr];
1289                                         vlr->flag= mf->flag;
1290                                         if(dlm->flag & ME_OPT_EDGES) vlr->ec= mf->edcode;
1291                                         else vlr->ec= ME_V1V2|ME_V2V3|ME_V3V4|ME_V4V1; 
1292                                         vlr->puno= mf->puno;
1293                                         
1294                                         if(flipnorm== -1) flipnorm= test_flipnorm(v1->co, v2->co, v3->co, vlr, imat);
1295
1296                                         if(flipnorm) {
1297                                                 vlr->n[0]= -vlr->n[0];
1298                                                 vlr->n[1]= -vlr->n[1];
1299                                                 vlr->n[2]= -vlr->n[2];
1300                                         }
1301                                         
1302                                         if (dlm->tface) {
1303                                                 vlr->tface= &dlm->tface[i];
1304                                                 vlr->vcol= vlr->tface->col;
1305                                         } else if (dlm->mcol)
1306                                                 vlr->vcol= (unsigned int *) &dlm->mcol[i*4];
1307                                 }
1308                         }
1309                 }
1310                 
1311                 dl= dl->next;
1312         }
1313
1314
1315         normalenrender(old_totvert, old_totvlak);
1316
1317 }
1318
1319 /* ------------------------------------------------------------------------- */
1320
1321 static int verghalo(const void *a1, const void *a2)
1322 {
1323         const struct halosort *x1=a1, *x2=a2;
1324         
1325         if( x1->z < x2->z ) return 1;
1326         else if( x1->z > x2->z) return -1;
1327         return 0;
1328 }
1329
1330 /* ------------------------------------------------------------------------- */
1331 extern int rblohalen;
1332 static void sort_halos(void)
1333 {
1334         struct halosort *hablock, *haso;
1335         HaloRen *har = NULL, **bloha;
1336         int a;
1337
1338         if(R.tothalo==0) return;
1339
1340         /* make datablock with halo pointers, sort */
1341         haso= hablock= MEM_mallocN(sizeof(struct halosort)*R.tothalo, "hablock");
1342
1343         for(a=0; a<R.tothalo; a++) {
1344                 if((a & 255)==0) har= R.bloha[a>>8];
1345                 else har++;
1346                 haso->har= har;
1347                 haso->z= har->zs;
1348                 haso++;
1349         }
1350
1351         qsort(hablock, R.tothalo, sizeof(struct halosort), verghalo);
1352
1353         /* re-assamble R.bloha */
1354
1355         bloha= R.bloha;
1356         R.bloha= (HaloRen **)MEM_callocN(sizeof(void *)*(rblohalen),"Bloha");
1357
1358         haso= hablock;
1359         for(a=0; a<R.tothalo; a++) {
1360                 har= RE_findOrAddHalo(a);
1361                 *har= *(haso->har);
1362
1363                 haso++;
1364         }
1365
1366         /* free */
1367         a= 0;
1368         while(bloha[a]) {
1369                 MEM_freeN(bloha[a]);
1370                 a++;
1371         }
1372         MEM_freeN(bloha);
1373         MEM_freeN(hablock);
1374
1375 }
1376
1377
1378
1379 static Material *give_render_material(Object *ob, int nr)
1380 {
1381         Object *temp;
1382
1383         if(ob->flag & OB_FROMDUPLI) {
1384                 temp= (Object *)ob->id.newid;
1385                 if(temp && temp->type==OB_FONT) {
1386                         ob= temp;
1387                 }
1388         }
1389
1390         return give_current_material(ob, nr);
1391 }
1392
1393 /* ------------------------------------------------------------------------- */
1394 static void init_render_mball(Object *ob)
1395 {
1396         DispList *dl, *dlo;
1397         VertRen *ver;
1398         VlakRen *vlr, *vlr1;
1399         Material *ma;
1400         float *data, *nors, mat[4][4], imat[3][3], xn, yn, zn;
1401         int a, need_orco, startvert, *index;
1402
1403         if (ob!=find_basis_mball(ob))
1404                 return;
1405
1406         /* yafray: set transform to identity matrix */
1407         if (R.r.mode & R_YAFRAY)
1408                 MTC_Mat4One(mat);
1409         else
1410                 MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
1411         MTC_Mat4Invert(ob->imat, mat);
1412         MTC_Mat3CpyMat4(imat, ob->imat);
1413
1414         ma= give_render_material(ob, 1);
1415         if(ma==0) ma= &defmaterial;
1416
1417         need_orco= 0;
1418         if(ma->ren->texco & TEXCO_ORCO) {
1419                 need_orco= 1;
1420         }
1421
1422         dlo= ob->disp.first;
1423         if(dlo) BLI_remlink(&ob->disp, dlo);
1424
1425         makeDispList(ob);
1426         dl= ob->disp.first;
1427         if(dl==0) return;
1428
1429         startvert= R.totvert;
1430         data= dl->verts;
1431         nors= dl->nors;
1432
1433         for(a=0; a<dl->nr; a++, data+=3, nors+=3) {
1434
1435                 ver= RE_findOrAddVert(R.totvert++);
1436                 VECCOPY(ver->co, data);
1437                 MTC_Mat4MulVecfl(mat, ver->co);
1438
1439                 /* render normals are inverted in render */
1440                 xn= -nors[0];
1441                 yn= -nors[1];
1442                 zn= -nors[2];
1443
1444                 /* transpose ! */
1445                 ver->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
1446                 ver->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
1447                 ver->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
1448                 Normalise(ver->n);
1449
1450                 if(need_orco) ver->orco= data;
1451         }
1452
1453         index= dl->index;
1454         for(a=0; a<dl->parts; a++, index+=4) {
1455
1456                 vlr= RE_findOrAddVlak(R.totvlak++);
1457                 vlr->ob= ob;
1458                 vlr->v1= RE_findOrAddVert(startvert+index[0]);
1459                 vlr->v2= RE_findOrAddVert(startvert+index[1]);
1460                 vlr->v3= RE_findOrAddVert(startvert+index[2]);
1461                 vlr->v4= 0;
1462
1463                 /* render normal are inverted */
1464                 vlr->len= CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->n);
1465
1466                 vlr->mface= 0;
1467                 vlr->mat= ma;
1468                 vlr->puno= 0;
1469                 vlr->flag= ME_SMOOTH+R_NOPUNOFLIP;
1470                 vlr->ec= 0;
1471                 vlr->lay= ob->lay;
1472
1473                 /* mball -too bad- always has triangles, because quads can be non-planar */
1474                 if(index[3]) {
1475                         vlr1= RE_findOrAddVlak(R.totvlak++);
1476                         *vlr1= *vlr;
1477                         vlr1->v2= vlr1->v3;
1478                         vlr1->v3= RE_findOrAddVert(startvert+index[3]);
1479                         vlr->len= CalcNormFloat(vlr1->v1->co, vlr1->v2->co, vlr1->v3->co, vlr1->n);
1480                 }
1481         }
1482
1483         if(need_orco) {
1484                 /* store displist and scale */
1485                 make_orco_mball(ob);
1486                 if(dlo) BLI_addhead(&ob->disp, dlo);
1487
1488         }
1489         else {
1490                 freedisplist(&ob->disp);
1491                 if(dlo) BLI_addtail(&ob->disp, dlo);
1492         }
1493 }
1494 /* ------------------------------------------------------------------------- */
1495 /* convert */
1496 static void init_render_mesh(Object *ob)
1497 {
1498         MFace *mface;
1499         MVert *mvert;
1500         Mesh *me;
1501         VlakRen *vlr, *vlr1;
1502         VertRen *ver;
1503         Material *ma;
1504         MSticky *ms;
1505         PartEff *paf;
1506         DispList *dl;
1507         TFace *tface;
1508         unsigned int *vertcol;
1509         float xn, yn, zn, nor[3], imat[3][3], mat[4][4];
1510         float *extverts=0, *orco;
1511         int a, a1, ok, do_puno, need_orco=0, totvlako, totverto, vertofs;
1512         int start, end, flipnorm, do_autosmooth=0;
1513
1514         me= ob->data;
1515         if (rendermesh_uses_displist(me) && me->subdivr>0) {
1516                 init_render_displist_mesh(ob);
1517                 return;
1518         }
1519
1520    paf = give_parteff(ob);
1521         if(paf) {
1522                 if(paf->flag & PAF_STATIC) render_static_particle_system(ob, paf);
1523                 else render_particle_system(ob, paf);
1524                 return;
1525         }
1526
1527         /* object_deform changes imat */
1528         do_puno= object_deform(ob);
1529
1530         /* yafray: set transform to identity matrix */
1531         if (R.r.mode & R_YAFRAY)
1532                 MTC_Mat4One(mat);
1533         else
1534                 MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
1535         MTC_Mat4Invert(ob->imat, mat);
1536         MTC_Mat3CpyMat4(imat, ob->imat);
1537
1538         if(me->totvert==0) return;
1539         mvert= me->mvert;
1540
1541         dl= find_displist(&ob->disp, DL_VERTS);
1542         if(dl) extverts= dl->verts;
1543
1544         totvlako= R.totvlak;
1545         totverto= R.totvert;
1546
1547         if(me->key) do_puno= 1;
1548
1549         if(ob->effect.first) {
1550                 Effect *eff= ob->effect.first;
1551                 while(eff) {
1552                         if(eff->type==EFF_WAVE) do_puno= 1;
1553                         eff= eff->next;
1554                 }
1555         }
1556
1557         if(me->orco==0) {
1558                 need_orco= 0;
1559                 for(a=1; a<=ob->totcol; a++) {
1560                         ma= give_render_material(ob, a);
1561                         if(ma) {
1562                                 if(ma->ren->texco & TEXCO_ORCO) {
1563                                         need_orco= 1;
1564                                         break;
1565                                 }
1566                         }
1567                 }
1568                 if(need_orco) {
1569                         make_orco_mesh(me);
1570                 }
1571         }
1572         
1573         orco= me->orco;
1574         ms= me->msticky;
1575         tface= me->tface;
1576         if(tface) vertcol= ((TFace *)me->tface)->col;
1577         else vertcol= (unsigned int *)me->mcol;
1578
1579         ma= give_render_material(ob, 1);
1580         if(ma==0) ma= &defmaterial;
1581
1582
1583         if(ma->mode & MA_HALO) {
1584                 make_render_halos(ob, me, ma, extverts);
1585         }
1586         else {
1587
1588                 for(a=0; a<me->totvert; a++, mvert++) {
1589
1590                         ver= RE_findOrAddVert(R.totvert++);
1591                         if(extverts) {
1592                                 VECCOPY(ver->co, extverts);
1593                                 extverts+= 3;
1594                         }
1595                         else {
1596                                 VECCOPY(ver->co, mvert->co);
1597                         }
1598                         MTC_Mat4MulVecfl(mat, ver->co);
1599
1600                         xn= mvert->no[0];
1601                         yn= mvert->no[1];
1602                         zn= mvert->no[2];
1603                         if(do_puno==0) {
1604                                 /* transpose ! */
1605                                 ver->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
1606                                 ver->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
1607                                 ver->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
1608                                 Normalise(ver->n);
1609                         }
1610                         if(orco) {
1611                                 ver->orco= orco;
1612                                 orco+=3;
1613                         }
1614                         if(ms) {
1615                                 ver->sticky= (float *)ms;
1616                                 ms++;
1617                         }
1618                 }
1619                 /* still to do for keys: the correct local texture coordinate */
1620
1621                 flipnorm= -1;
1622                 /* test for a flip in the matrix: then flip face normal as well */
1623
1624                 /* faces in order of color blocks */
1625                 vertofs= R.totvert- me->totvert;
1626                 for(a1=0; (a1<ob->totcol || (a1==0 && ob->totcol==0)); a1++) {
1627
1628                         ma= give_render_material(ob, a1+1);
1629                         if(ma==0) ma= &defmaterial;
1630                         
1631                         /* test for 100% transparant */
1632                         ok= 1;
1633                         if(ma->alpha==0.0 && ma->spectra==0.0) {
1634                                 ok= 0;
1635                                 /* texture on transparency? */
1636                                 for(a=0; a<8; a++) {
1637                                         if(ma->mtex[a] && ma->mtex[a]->tex) {
1638                                                 if(ma->mtex[a]->mapto & MAP_ALPHA) ok= 1;
1639                                         }
1640                                 }
1641                         }
1642
1643                         if(ok) {
1644                                 /* radio faces need autosmooth, to separate shared vertices in corners */
1645                                 if(R.r.mode & R_RADIO)
1646                                         if(ma->mode & MA_RADIO) 
1647                                                 do_autosmooth= 1;
1648                                 
1649                                 start= 0;
1650                                 end= me->totface;
1651                                 set_buildvars(ob, &start, &end);
1652                                 mvert= me->mvert;
1653                                 mface= me->mface;
1654                                 mface+= start;
1655                                 if(tface) {
1656                                         tface= me->tface;
1657                                         tface+= start;
1658                                 }
1659                                 
1660                                 for(a=start; a<end; a++, mface++) {
1661
1662                                         if( mface->mat_nr==a1 ) {
1663
1664                                                 if(mface->v3) {
1665
1666                                                         vlr= RE_findOrAddVlak(R.totvlak++);
1667                                                         vlr->ob= ob;
1668                                                         vlr->v1= RE_findOrAddVert(vertofs+mface->v1);
1669                                                         vlr->v2= RE_findOrAddVert(vertofs+mface->v2);
1670                                                         vlr->v3= RE_findOrAddVert(vertofs+mface->v3);
1671                                                         if(mface->v4) vlr->v4= RE_findOrAddVert(vertofs+mface->v4);
1672                                                         else vlr->v4= 0;
1673
1674                                                         /* render normalen are inverted in render */
1675                                                         if(vlr->v4) vlr->len= CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co,
1676                                                             vlr->v1->co, vlr->n);
1677                                                         else vlr->len= CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co,
1678                                                             vlr->n);
1679                                                         vlr->mface= mface;
1680                                                         vlr->mat= ma;
1681                                                         vlr->puno= mface->puno;
1682                                                         vlr->flag= mface->flag;
1683                                                         if((me->flag & ME_NOPUNOFLIP) || (ma->mode & MA_RAYTRANSP)) {
1684                                                                 vlr->flag |= R_NOPUNOFLIP;
1685                                                                 vlr->puno= 15;
1686                                                         }
1687                                                         vlr->ec= mface->edcode;
1688                                                         vlr->lay= ob->lay;
1689
1690                                                         if(vlr->len==0) R.totvlak--;
1691                                                         else {
1692                                                                 if(flipnorm== -1) {     /* per object test once */
1693                                                                         flipnorm= mesh_test_flipnorm(ob, mface, vlr, imat);
1694                                                                 }
1695                                                                 if(flipnorm) {
1696                                                                         vlr->n[0]= -vlr->n[0];
1697                                                                         vlr->n[1]= -vlr->n[1];
1698                                                                         vlr->n[2]= -vlr->n[2];
1699                                                                 }
1700
1701                                                                 if(vertcol) {
1702                                                                         if(tface) vlr->vcol= vertcol+sizeof(TFace)*a/4; /* vertcol is int */
1703                                                                         else vlr->vcol= vertcol+sizeof(int)*a;
1704                                                                 }
1705                                                                 else vlr->vcol= 0;
1706                                                                 
1707                                                                 vlr->tface= tface;
1708                                                                 
1709                                                                 /* test if rendering as a quad or triangle */
1710                                                                 if(vlr->v4) {
1711
1712                                                                         if(ma->mode & MA_WIRE);
1713                                                                         else {
1714                                                                                 CalcNormFloat(vlr->v4->co, vlr->v3->co, vlr->v1->co, nor);
1715                                                                                 if(flipnorm) {
1716                                                                                         nor[0]= -nor[0];
1717                                                                                         nor[1]= -nor[1];
1718                                                                                         nor[2]= -nor[2];
1719                                                                                 }
1720                                                                 
1721                                                                                 xn= nor[0]*vlr->n[0] + nor[1]*vlr->n[1] + nor[2]*vlr->n[2];
1722                                                                                 if( xn < 0.9990 ) {
1723                                                                                         /* recalc this nor, previous calc was with calcnormfloat4 */
1724                                                                                         if(flipnorm) CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->n);
1725                                                                                         else CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n);
1726                                                                                         
1727                                                                                         vlr1= RE_findOrAddVlak(R.totvlak++);
1728                                                                                         *vlr1= *vlr;
1729                                                                                         vlr1->flag |= R_FACE_SPLIT;
1730                                                                                         VECCOPY(vlr1->n, nor);
1731                                                                                         vlr1->v2= vlr->v3;
1732                                                                                         vlr1->v3= vlr->v4;
1733                                                                                         vlr->v4= vlr1->v4= 0;
1734                                                                 
1735                                                                                         vlr1->puno= 0;
1736                                                                                         if(vlr->puno & ME_FLIPV1) vlr1->puno |= ME_FLIPV1;
1737                                                                                         if(vlr->puno & ME_FLIPV3) vlr1->puno |= ME_FLIPV2;
1738                                                                                         if(vlr->puno & ME_FLIPV4) vlr1->puno |= ME_FLIPV3;
1739                                                                 
1740                                                                                 }
1741                                                                         }
1742                                                                 }
1743                                                         }
1744                                                 }
1745                                                 else if(mface->v2 && (ma->mode & MA_WIRE)) {
1746                                                         vlr= RE_findOrAddVlak(R.totvlak++);
1747                                                         vlr->ob= ob;
1748                                                         vlr->v1= RE_findOrAddVert(vertofs+mface->v1);
1749                                                         vlr->v2= RE_findOrAddVert(vertofs+mface->v2);
1750                                                         vlr->v3= vlr->v2;
1751                                                         vlr->v4= 0;
1752
1753                                                         vlr->n[0]=vlr->n[1]=vlr->n[2]= 0.0;
1754
1755                                                         vlr->mface= mface;
1756                                                         vlr->mat= ma;
1757                                                         vlr->puno= mface->puno;
1758                                                         vlr->flag= mface->flag;
1759                                                         vlr->ec= ME_V1V2;
1760                                                         vlr->lay= ob->lay;
1761                                                 }
1762                                         }
1763                                         
1764                                         if(tface) tface++;
1765                                 }
1766                         }
1767                 }
1768         }
1769         
1770         if(do_autosmooth || (me->flag & ME_AUTOSMOOTH)) {
1771                 autosmooth(totverto, totvlako, me->smoothresh);
1772                 do_puno= 1;
1773         }
1774         
1775         if(do_puno) normalenrender(totverto, totvlako);
1776
1777 }
1778
1779 /* ------------------------------------------------------------------------- */
1780
1781 static void area_lamp_vectors(LampRen *lar)
1782 {
1783         float xsize= 0.5*lar->area_size, ysize= 0.5*lar->area_sizey;
1784
1785         /* corner vectors */
1786         lar->area[0][0]= lar->co[0] - xsize*lar->mat[0][0] - ysize*lar->mat[1][0];
1787         lar->area[0][1]= lar->co[1] - xsize*lar->mat[0][1] - ysize*lar->mat[1][1];
1788         lar->area[0][2]= lar->co[2] - xsize*lar->mat[0][2] - ysize*lar->mat[1][2];      
1789
1790         /* corner vectors */
1791         lar->area[1][0]= lar->co[0] - xsize*lar->mat[0][0] + ysize*lar->mat[1][0];
1792         lar->area[1][1]= lar->co[1] - xsize*lar->mat[0][1] + ysize*lar->mat[1][1];
1793         lar->area[1][2]= lar->co[2] - xsize*lar->mat[0][2] + ysize*lar->mat[1][2];      
1794
1795         /* corner vectors */
1796         lar->area[2][0]= lar->co[0] + xsize*lar->mat[0][0] + ysize*lar->mat[1][0];
1797         lar->area[2][1]= lar->co[1] + xsize*lar->mat[0][1] + ysize*lar->mat[1][1];
1798         lar->area[2][2]= lar->co[2] + xsize*lar->mat[0][2] + ysize*lar->mat[1][2];      
1799
1800         /* corner vectors */
1801         lar->area[3][0]= lar->co[0] + xsize*lar->mat[0][0] - ysize*lar->mat[1][0];
1802         lar->area[3][1]= lar->co[1] + xsize*lar->mat[0][1] - ysize*lar->mat[1][1];
1803         lar->area[3][2]= lar->co[2] + xsize*lar->mat[0][2] - ysize*lar->mat[1][2];      
1804         /* only for correction button size, matrix size works on energy */
1805         lar->areasize= lar->dist*lar->dist/(4.0*xsize*ysize);
1806 }
1807
1808 /* If lar takes more lamp data, the decoupling will be better. */
1809 void RE_add_render_lamp(Object *ob, int doshadbuf)
1810 {
1811         Lamp *la;
1812         LampRen *lar, **temp;
1813         float mat[4][4], hoek, xn, yn;
1814         int c;
1815         static int rlalen=LAMPINITSIZE; /*number of currently allocated lampren pointers*/
1816         
1817         if(R.totlamp>=rlalen) { /* Need more Lamp pointers....*/
1818                 printf("Alocating %i more lamp groups, %i total.\n", 
1819                         LAMPINITSIZE, rlalen+LAMPINITSIZE);
1820                 temp=R.la;
1821                 R.la=(LampRen**)MEM_callocN(sizeof(void*)*(rlalen+LAMPINITSIZE) , "renderlamparray");
1822                 memcpy(R.la, temp, rlalen*sizeof(void*));
1823                 memset(&(R.la[R.totlamp]), 0, LAMPINITSIZE*sizeof(void*));
1824                 rlalen+=LAMPINITSIZE;  
1825                 MEM_freeN(temp);        
1826         }
1827         
1828         la= ob->data;
1829         lar= (LampRen *)MEM_callocN(sizeof(LampRen),"lampren");
1830         R.la[R.totlamp++]= lar;
1831
1832         /* yafray: in this case the lamp matrix is a copy of the object matrix */
1833         if (R.r.mode & R_YAFRAY)
1834                 MTC_Mat4CpyMat4(mat, ob->obmat);
1835         else
1836                 MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
1837         MTC_Mat4Invert(ob->imat, mat);
1838
1839         MTC_Mat3CpyMat4(lar->mat, mat);
1840         MTC_Mat3CpyMat4(lar->imat, ob->imat);
1841
1842         lar->bufsize = la->bufsize;
1843         lar->samp = la->samp;
1844         lar->soft = la->soft;
1845         lar->shadhalostep = la->shadhalostep;
1846         lar->clipsta = la->clipsta;
1847         lar->clipend = la->clipend;
1848         lar->bias = la->bias;
1849
1850         lar->type= la->type;
1851         lar->mode= la->mode;
1852
1853         lar->energy= la->energy;
1854         lar->energy= la->energy;
1855         if(la->mode & LA_NEG) lar->energy= -lar->energy;
1856
1857         lar->vec[0]= -mat[2][0];
1858         lar->vec[1]= -mat[2][1];
1859         lar->vec[2]= -mat[2][2];
1860         Normalise(lar->vec);
1861         lar->co[0]= mat[3][0];
1862         lar->co[1]= mat[3][1];
1863         lar->co[2]= mat[3][2];
1864         lar->dist= la->dist;
1865         lar->haint= la->haint;
1866         lar->distkw= lar->dist*lar->dist;
1867         lar->r= lar->energy*la->r;
1868         lar->g= lar->energy*la->g;
1869         lar->b= lar->energy*la->b;
1870         lar->k= la->k;
1871
1872         // area
1873         lar->ray_samp= la->ray_samp;
1874         lar->ray_sampy= la->ray_sampy;
1875         lar->ray_sampz= la->ray_sampz;
1876
1877         lar->area_size= la->area_size;
1878         lar->area_sizey= la->area_sizey;
1879         lar->area_sizez= la->area_sizez;
1880
1881         lar->area_shape= la->area_shape;
1882         lar->ray_samp_type= la->ray_samp_type;
1883
1884         if(lar->type==LA_AREA) {
1885                 switch(lar->area_shape) {
1886                 case LA_AREA_SQUARE:
1887                         lar->ray_totsamp= lar->ray_samp*lar->ray_samp;
1888                         lar->ray_sampy= lar->ray_samp;
1889                         lar->area_sizey= lar->area_size;
1890                         break;
1891                 case LA_AREA_RECT:
1892                         lar->ray_totsamp= lar->ray_samp*lar->ray_sampy;
1893                         break;
1894                 case LA_AREA_CUBE:
1895                         lar->ray_totsamp= lar->ray_samp*lar->ray_samp*lar->ray_samp;
1896                         lar->ray_sampy= lar->ray_samp;
1897                         lar->ray_sampz= lar->ray_samp;
1898                         lar->area_sizey= lar->area_size;
1899                         lar->area_sizez= lar->area_size;
1900                         break;
1901                 case LA_AREA_BOX:
1902                         lar->ray_totsamp= lar->ray_samp*lar->ray_sampy*lar->ray_sampz;
1903                         break;
1904                 }
1905
1906                 area_lamp_vectors(lar);
1907         }
1908         else lar->ray_totsamp= 0;
1909
1910         lar->spotsi= la->spotsize;
1911         if(lar->mode & LA_HALO) {
1912                 if(lar->spotsi>170.0) lar->spotsi= 170.0;
1913         }
1914         lar->spotsi= cos( M_PI*lar->spotsi/360.0 );
1915         lar->spotbl= (1.0-lar->spotsi)*la->spotblend;
1916
1917         memcpy(lar->mtex, la->mtex, 8*4);
1918
1919         lar->lay= ob->lay;
1920
1921         lar->ld1= la->att1;
1922         lar->ld2= la->att2;
1923
1924         if(lar->type==LA_SPOT) {
1925
1926                 Normalise(lar->imat[0]);
1927                 Normalise(lar->imat[1]);
1928                 Normalise(lar->imat[2]);
1929
1930                 xn= saacos(lar->spotsi);
1931                 xn= sin(xn)/cos(xn);
1932                 lar->spottexfac= 1.0/(xn);
1933
1934                 if(lar->mode & LA_ONLYSHADOW) {
1935                         if((lar->mode & LA_SHAD)==0) lar->mode -= LA_ONLYSHADOW;
1936                 }
1937
1938         }
1939
1940
1941         /* set flag for spothalo en initvars */
1942         if(la->type==LA_SPOT && (la->mode & LA_HALO)) {
1943                 if(la->haint>0.0) {
1944                         R.flag |= R_LAMPHALO;
1945
1946                         /* camera position (0,0,0) rotate around lamp */
1947                         lar->sh_invcampos[0]= -lar->co[0];
1948                         lar->sh_invcampos[1]= -lar->co[1];
1949                         lar->sh_invcampos[2]= -lar->co[2];
1950                         MTC_Mat3MulVecfl(lar->imat, lar->sh_invcampos);
1951
1952                         /* z factor, for a normalized volume */
1953                         hoek= saacos(lar->spotsi);
1954                         xn= lar->spotsi;
1955                         yn= sin(hoek);
1956                         lar->sh_zfac= yn/xn;
1957                         /* pre-scale */
1958                         lar->sh_invcampos[2]*= lar->sh_zfac;
1959
1960                 }
1961         }
1962
1963         for(c=0; c<6; c++) {
1964                 if(la->mtex[c] && la->mtex[c]->tex) {
1965                         lar->mode |= LA_TEXTURE;
1966
1967                         if(R.flag & R_RENDERING) {
1968                                 if(R.osa) {
1969                                         if(la->mtex[c]->tex->type==TEX_IMAGE) lar->mode |= LA_OSATEX;
1970                                 }
1971                         }
1972                 }
1973         }
1974
1975         /* yafray: shadowbuffers only needed for internal render */
1976         if ((R.r.mode & R_YAFRAY)==0)
1977         {
1978                 if( (R.r.mode & R_SHADOW) && (lar->mode & LA_SHAD) && (la->type==LA_SPOT) && doshadbuf ) {
1979                 /* Per lamp, one shadow buffer is made. */
1980                         RE_initshadowbuf(lar, ob->obmat);
1981                 }
1982         }
1983
1984         lar->org= MEM_dupallocN(lar);
1985 }
1986
1987 /* ------------------------------------------------------------------------- */
1988 static void init_render_surf(Object *ob)
1989 {
1990         Nurb *nu=0;
1991         Curve *cu;
1992         ListBase displist;
1993         DispList *dl;
1994         VertRen *ver, *v1, *v2, *v3, *v4;
1995         VlakRen *vlr;
1996         Material *matar[32];
1997         float *data, *fp, *orco, n1[3], flen, mat[4][4];
1998         int len, a, need_orco=0, startvlak, startvert, p1, p2, p3, p4;
1999 #ifdef STRUBI
2000         int u, v;
2001         int sizeu, sizev;
2002         VlakRen *vlr1, *vlr2, *vlr3;
2003         float n2[3], vn[3];
2004         int index;
2005 #endif
2006
2007         cu= ob->data;
2008         nu= cu->nurb.first;
2009         if(nu==0) return;
2010
2011         /* yafray: set transform to identity matrix */
2012         if (R.r.mode & R_YAFRAY)
2013                 MTC_Mat4One(mat);
2014         else
2015                 MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
2016         MTC_Mat4Invert(ob->imat, mat);
2017
2018         /* material array */
2019         memset(matar, 0, 4*32);
2020         matar[0]= &defmaterial;
2021         for(a=0; a<ob->totcol; a++) {
2022                 matar[a]= give_render_material(ob, a+1);
2023                 if(matar[a]==0) matar[a]= &defmaterial;
2024                 if(matar[a] && matar[a]->ren->texco & TEXCO_ORCO) {
2025                         need_orco= 1;
2026                 }
2027         }
2028
2029         if(ob->parent && (ob->parent->type==OB_IKA || ob->parent->type==OB_LATTICE)) need_orco= 1;
2030
2031         if(cu->orco==0 && need_orco) make_orco_surf(cu);
2032         orco= cu->orco;
2033
2034         /* make a complete new displist, the base-displist can be different */
2035         displist.first= displist.last= 0;
2036         nu= cu->nurb.first;
2037         while(nu) {
2038                 if(nu->pntsv>1) {
2039         //              if (dl->flag & DL_CYCLIC_V) {
2040                         len= nu->resolu*nu->resolv;
2041                         /* makeNurbfaces wants zeros */
2042
2043                         dl= MEM_callocN(sizeof(DispList)+len*3*sizeof(float), "makeDispList1");
2044                         dl->verts= MEM_callocN(len*3*sizeof(float), "makeDispList01");
2045                         BLI_addtail(&displist, dl);
2046
2047                         dl->parts= nu->resolu;  /* switched order, makeNurbfaces works that way... */
2048                         dl->nr= nu->resolv;
2049                         dl->col= nu->mat_nr;
2050                         dl->rt= nu->flag;
2051
2052                         data= dl->verts;
2053                         dl->type= DL_SURF;
2054                         /* if nurbs cyclic (u/v) set flags in displist accordingly */
2055                         if(nu->flagv & 1) dl->flag |= DL_CYCLIC_V;      
2056                         if(nu->flagu & 1) dl->flag |= DL_CYCLIC_U;
2057
2058                         makeNurbfaces(nu, data);
2059                 }
2060                 nu= nu->next;
2061         }
2062
2063         if(ob->parent && ob->parent->type==OB_LATTICE) {
2064                 init_latt_deform(ob->parent, ob);
2065                 dl= displist.first;
2066                 while(dl) {
2067
2068                         fp= dl->verts;
2069                         len= dl->nr*dl->parts;
2070                         for(a=0; a<len; a++, fp+=3)  calc_latt_deform(fp);
2071
2072                         dl= dl->next;
2073                 }
2074                 end_latt_deform();
2075         }
2076         
2077 #ifdef __NLA
2078         if(ob->parent && ob->parent->type==OB_ARMATURE) {
2079 /*              bArmature *arm= ob->parent->data; */
2080                 init_armature_deform(ob->parent, ob);
2081                 dl= displist.first;
2082                 while(dl) {
2083
2084                         fp= dl->verts;
2085                         len= dl->nr*dl->parts;
2086                         for(a=0; a<len; a++, fp+=3)
2087                                 calc_armature_deform(ob->parent, fp, a);
2088
2089                         dl= dl->next;
2090                 }
2091         }
2092 #endif
2093
2094         if(ob->parent && ob->parent->type==OB_IKA) {
2095                 Ika *ika= ob->parent->data;
2096                 
2097                 init_skel_deform(ob->parent, ob);
2098                 dl= displist.first;
2099                 while(dl) {
2100
2101                         fp= dl->verts;
2102                         len= dl->nr*dl->parts;
2103                         for(a=0; a<len; a++, fp+=3)  calc_skel_deform(ika, fp);
2104
2105                         dl= dl->next;
2106                 }
2107         }
2108
2109         dl= displist.first;
2110         /* walk along displaylist and create rendervertices/-faces */
2111         while(dl) {
2112 #ifdef STRUBI
2113 /* watch out: u ^= y, v ^= x !! */
2114                 if(dl->type==DL_SURF) {
2115                         startvert= R.totvert;
2116                         sizeu = dl->parts; sizev = dl->nr; 
2117
2118                         data= dl->verts;
2119                         for (u = 0; u < sizeu; u++) {
2120                                 v1 = RE_findOrAddVert(R.totvert++); /* save this for possible V wrapping */
2121                                 VECCOPY(v1->co, data); data += 3;
2122                                 if(orco) {
2123                                         v1->orco= orco; orco+= 3;
2124                                 }       
2125                                 MTC_Mat4MulVecfl(mat, v1->co);
2126
2127                                 for (v = 1; v < sizev; v++) {
2128                                         ver= RE_findOrAddVert(R.totvert++);
2129                                         VECCOPY(ver->co, data); data += 3;
2130                                         if(orco) {
2131                                                 ver->orco= orco; orco+= 3;
2132                                         }       
2133                                         MTC_Mat4MulVecfl(mat, ver->co);
2134                                 }
2135                                 /* if V-cyclic, add extra vertices at end of the row */
2136                                 if (dl->flag & DL_CYCLIC_V) {
2137                                         ver= RE_findOrAddVert(R.totvert++);
2138                                         VECCOPY(ver->co, v1->co);
2139                                         ver->orco= orco;
2140                                         orco+= 3;
2141                                 }       
2142                         }       
2143
2144                         if (dl->flag & DL_CYCLIC_V)  sizev++; /* adapt U dimension */
2145
2146
2147                         /* if U cyclic, add extra row at end of column */
2148                         if (dl->flag & DL_CYCLIC_U) {
2149                                 for (v = 0; v < sizev; v++) {
2150                                         v1= RE_findOrAddVert(startvert + v);
2151                                         ver= RE_findOrAddVert(R.totvert++);
2152                                         VECCOPY(ver->co, v1->co);
2153                                         ver->orco= orco;
2154                                         orco +=3;
2155
2156                                 }
2157                                 sizeu++;
2158                         }       
2159                                         
2160
2161
2162
2163                         startvlak= R.totvlak;
2164
2165                         /* process generic surface */
2166                         for(u = 0; u < sizeu - 1; u++) {
2167
2168 /*                              DL_SURFINDEX(dl->flag & DL_CYCLIC_U, dl->flag & DL_CYCLIC_V, dl->nr, dl->parts);
2169                                 DL_SURFINDEX(0, 0, dl->nr, dl->parts);
2170 */
2171
2172
2173 /*
2174                                 
2175                         ^       ()----p4----p3----()
2176                         |       |     |     |     |
2177                         u       |     |     |     |
2178                                 |     |     |     |
2179                                 ()----p1----p2----()
2180                                        v ->
2181 */
2182
2183                                 p1 = startvert + u * sizev; /* walk through face list */
2184                                 p2 = p1 + 1;
2185                                 p3 = p2 + sizev;
2186                                 p4 = p3 - 1;
2187
2188
2189                                 for(v = 0; v < sizev - 1; v++) {
2190                                         v1= RE_findOrAddVert(p1);
2191                                         v2= RE_findOrAddVert(p2);
2192                                         v3= RE_findOrAddVert(p3);
2193                                         v4= RE_findOrAddVert(p4);
2194
2195                                         flen= CalcNormFloat4(v1->co, v2->co, v3->co, v4->co, n1);
2196 /* flen can be 0 if there are double nurbs control vertices 
2197         so zero area faces can be generated
2198         ->> there is at the moment no proper way to fix this except
2199         generating empty render faces */
2200
2201 //                                      if(flen!=0.0) {
2202                                                 vlr= RE_findOrAddVlak(R.totvlak++);
2203                                                 vlr->ob= ob;
2204                                                 vlr->v1= v1; vlr->v2= v2; vlr->v3= v3; vlr->v4= v4;
2205                                                 VECCOPY(vlr->n, n1);
2206                                                 vlr->len= flen;
2207                                                 vlr->lay= ob->lay;
2208                                                 vlr->mat= matar[ dl->col];
2209                                                 vlr->ec= ME_V1V2+ME_V2V3;
2210                                                 vlr->flag= dl->rt;
2211                                                 if( (cu->flag & CU_NOPUNOFLIP) || (vlr->mat->mode & MA_RAYTRANSP)) {
2212                                                         vlr->flag |= R_NOPUNOFLIP;
2213                                                         vlr->puno= 15;
2214                                                 }
2215 //                                      }
2216
2217                                         VecAddf(v1->n, v1->n, n1);
2218                                         VecAddf(v2->n, v2->n, n1);
2219                                         VecAddf(v3->n, v3->n, n1);
2220                                         VecAddf(v4->n, v4->n, n1);
2221
2222                                         p1++; p2++; p3++; p4++;
2223                                 }
2224                         }       
2225                         /* fix normals for U resp. V cyclic faces */
2226                         sizeu--; sizev--;  /* dec size for face array */
2227                         if (dl->flag & DL_CYCLIC_U) {
2228
2229                                 for (v = 0; v < sizev; v++)
2230                                 {
2231                                         /* optimize! :*/
2232                                         index = startvlak + v;
2233                                         // vlr= RE_findOrAddVlak(index + (sizeu-1) * sizev);
2234                                         vlr= RE_findOrAddVlak(UVTOINDEX(sizeu - 1, v));
2235                                         GETNORMAL(vlr, n1);
2236                                         vlr1= RE_findOrAddVlak(UVTOINDEX(0, v));
2237                                         GETNORMAL(vlr1, n2);
2238                                         VecAddf(vlr1->v1->n, vlr1->v1->n, n1);
2239                                         VecAddf(vlr1->v2->n, vlr1->v2->n, n1);
2240                                         VecAddf(vlr->v3->n, vlr->v3->n, n2);
2241                                         VecAddf(vlr->v4->n, vlr->v4->n, n2);
2242                                 }
2243                         }
2244                         if (dl->flag & DL_CYCLIC_V) {
2245
2246                                 for (u = 0; u < sizeu; u++)
2247                                 {
2248                                         /* optimize! :*/
2249                                         index = startvlak + u * sizev;
2250                                         //vlr= RE_findOrAddVlak(index);
2251                                         vlr= RE_findOrAddVlak(UVTOINDEX(u, 0));
2252                                         GETNORMAL(vlr, n1);
2253                                         vlr1= RE_findOrAddVlak(UVTOINDEX(u, sizev-1));
2254                                         // vlr1= RE_findOrAddVlak(index + (sizev - 1));
2255                                         GETNORMAL(vlr1, n2);
2256                                         VecAddf(vlr1->v2->n, vlr1->v2->n, n1);
2257                                         VecAddf(vlr1->v3->n, vlr1->v3->n, n1);
2258                                         VecAddf(vlr->v1->n, vlr->v1->n, n2);
2259                                         VecAddf(vlr->v4->n, vlr->v4->n, n2);
2260                                 }
2261                         }
2262                         /* last vertex is an extra case: 
2263
2264                         ^       ()----()----()----()
2265                         |       |     |     ||     |
2266                         u       |     |(0,n)||(0,0)|
2267                                 |     |     ||     |
2268                                 ()====()====[]====()
2269                                 |     |     ||     |
2270                                 |     |(m,n)||(m,0)|
2271                                 |     |     ||     |
2272                                 ()----()----()----()
2273                                        v ->
2274
2275                         vertex [] is no longer shared, therefore distribute
2276                         normals of the surrounding faces to all of the duplicates of []
2277                         */
2278
2279                         if (dl->flag & DL_CYCLIC_U && dl->flag & DL_CYCLIC_V)
2280                         {
2281                                 vlr= RE_findOrAddVlak(UVTOINDEX(sizeu - 1, sizev - 1)); /* (m,n) */
2282                                 GETNORMAL(vlr, n1);
2283                                 vlr1= RE_findOrAddVlak(UVTOINDEX(0,0));  /* (0,0) */
2284                                 GETNORMAL(vlr1, vn);
2285                                 VecAddf(vn, vn, n1);
2286                                 vlr2= RE_findOrAddVlak(UVTOINDEX(0, sizev-1)); /* (0,n) */
2287                                 GETNORMAL(vlr2, n1);
2288                                 VecAddf(vn, vn, n1);
2289                                 vlr3= RE_findOrAddVlak(UVTOINDEX(sizeu-1, 0)); /* (m,0) */
2290                                 GETNORMAL(vlr3, n1);
2291                                 VecAddf(vn, vn, n1);
2292                                 VECCOPY(vlr->v3->n, vn);
2293                                 VECCOPY(vlr1->v1->n, vn);
2294                                 VECCOPY(vlr2->v2->n, vn);
2295                                 VECCOPY(vlr3->v4->n, vn);
2296                         }
2297                         for(a = startvert; a < R.totvert; a++) {
2298                                 ver= RE_findOrAddVert(a);
2299                                 Normalise(ver->n);
2300                         }
2301
2302
2303                 }
2304 #else
2305
2306                 if(dl->type==DL_SURF) {
2307                         startvert= R.totvert;
2308                         a= dl->nr*dl->parts;
2309                         data= dl->verts;
2310                         while(a--) {
2311                                 ver= RE_findOrAddVert(R.totvert++);
2312                                 VECCOPY(ver->co, data);
2313                                 if(orco) {
2314                                         ver->orco= orco;
2315                                         orco+= 3;
2316                                 }
2317                                 MTC_Mat4MulVecfl(mat, ver->co);
2318                                 data+= 3;
2319                         }
2320
2321                         startvlak= R.totvlak;
2322
2323                         for(a=0; a<dl->parts; a++) {
2324
2325                                 DL_SURFINDEX(dl->flag & DL_CYCLIC_V, dl->flag & DL_CYCLIC_U, dl->nr, dl->parts);
2326                                 p1+= startvert;
2327                                 p2+= startvert;
2328                                 p3+= startvert;
2329                                 p4+= startvert;
2330
2331                                 for(; b<dl->nr; b++) {
2332                                         v1= RE_findOrAddVert(p1);
2333                                         v2= RE_findOrAddVert(p2);
2334                                         v3= RE_findOrAddVert(p3);
2335                                         v4= RE_findOrAddVert(p4);
2336
2337                                         flen= CalcNormFloat4(v1->co, v3->co, v4->co, v2->co, n1);
2338                                         if(flen!=0.0) {
2339                                                 vlr= RE_findOrAddVlak(R.totvlak++);
2340                                                 vlr->ob= ob;
2341                                                 vlr->v1= v1;
2342                                                 vlr->v2= v3;
2343                                                 vlr->v3= v4;
2344                                                 vlr->v4= v2;
2345                                                 VECCOPY(vlr->n, n1);
2346                                                 vlr->len= flen;
2347                                                 vlr->lay= ob->lay;
2348                                                 vlr->mat= matar[ dl->col];
2349                                                 vlr->ec= ME_V1V2+ME_V2V3;
2350                                                 vlr->flag= dl->rt;
2351                                                 if( (cu->flag & CU_NOPUNOFLIP) || (vlr->mat->mode & MA_RAYTRANSP)) {
2352                                                         vlr->flag |= R_NOPUNOFLIP;
2353                                                         vlr->puno= 15;
2354                                                 }
2355                                         }
2356
2357                                         VecAddf(v1->n, v1->n, n1);
2358                                         VecAddf(v2->n, v2->n, n1);
2359                                         VecAddf(v3->n, v3->n, n1);
2360                                         VecAddf(v4->n, v4->n, n1);
2361
2362                                         p4= p3;
2363                                         p3++;
2364                                         p2= p1;
2365                                         p1++;
2366                                 }
2367                         }
2368
2369                         for(a=startvert; a<R.totvert; a++) {
2370                                 ver= RE_findOrAddVert(a);
2371                                 Normalise(ver->n);
2372                         }
2373
2374
2375                 }
2376 #endif
2377                 dl= dl->next;
2378         }
2379         freedisplist(&displist);
2380 }
2381
2382 static void init_render_curve(Object *ob)
2383 {
2384         Ika *ika=0;
2385
2386         Lattice *lt=0;
2387         Curve *cu;
2388         VertRen *ver;
2389         VlakRen *vlr;
2390         ListBase dlbev;
2391         Nurb *nu=0;
2392         DispList *dlb, *dl;
2393         BevList *bl;
2394         BevPoint *bevp;
2395         Material *matar[32];
2396         float len, *data, *fp, *fp1, fac;
2397         float n[3], vec[3], widfac, size[3], mat[4][4];
2398         int nr, startvert, startvlak, a, b, p1, p2, p3, p4;
2399         int totvert, frontside, need_orco=0, firststartvert, *index;
2400
2401         cu= ob->data;
2402         nu= cu->nurb.first;
2403         if(nu==0) return;
2404
2405         /* test displist */
2406         if(cu->disp.first==0) makeDispList(ob);
2407         dl= cu->disp.first;
2408         if(cu->disp.first==0) return;
2409
2410         if(dl->type!=DL_INDEX3) {
2411                 curve_to_filledpoly(cu, &cu->disp);
2412         }
2413
2414         if(cu->bev.first==0) makeBevelList(ob);
2415
2416         firststartvert= R.totvert;
2417
2418         /* yafray: set transform to identity matrix */
2419         if (R.r.mode & R_YAFRAY)
2420                 MTC_Mat4One(mat);
2421         else
2422                 MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
2423         MTC_Mat4Invert(ob->imat, mat);
2424
2425         /* material array */
2426         memset(matar, 0, 4*32);
2427         matar[0]= &defmaterial;
2428         for(a=0; a<ob->totcol; a++) {
2429                 matar[a]= give_render_material(ob, a+1);
2430                 if(matar[a]==0) matar[a]= &defmaterial;
2431                 if(matar[a]->ren->texco & TEXCO_ORCO) {
2432                         need_orco= 1;
2433                 }
2434         }
2435
2436         /* bevelcurve in displist */
2437         dlbev.first= dlbev.last= 0;
2438
2439         if(cu->ext1!=0.0 || cu->ext2!=0.0 || cu->bevobj!=0) {
2440                 makebevelcurve(ob, &dlbev);
2441         }
2442
2443         /* uv orcos? count amount of points and malloc */
2444         if(need_orco && (cu->flag & CU_UV_ORCO)) {
2445                 if(cu->flag & CU_PATH);
2446                 else {
2447                         totvert= 0;
2448                         bl= cu->bev.first;
2449                         while(bl) {
2450                                 dlb= dlbev.first;
2451                                 while(dlb) {
2452                                         totvert+= dlb->nr*bl->nr;
2453                                         dlb= dlb->next;
2454                                 }
2455                                 bl= bl->next;
2456                         }
2457
2458                         if(totvert) {
2459                                 fp= cu->orco= MEM_mallocN(3*sizeof(float)*totvert, "cu->orco");
2460         
2461                                 bl= cu->bev.first;
2462                                 while(bl) {
2463                                         dlb= dlbev.first;
2464                                         while(dlb) {
2465                                                 for(b=0; b<dlb->nr; b++) {
2466                                                         fac= (2.0*b/(float)(dlb->nr-1)) - 1.0;
2467                                                         for(a=0; a<bl->nr; a++, fp+=3) {
2468                                                                 fp[0]= (2.0*a/(float)(bl->nr-1)) - 1.0;
2469                                                                 fp[1]= fac;
2470                                                                 fp[2]= 0.0;
2471                                                         }
2472                                                 }
2473                                                 dlb= dlb->next;
2474                                         }
2475                                         bl= bl->next;
2476                                 }
2477                         }
2478                 }
2479         }
2480
2481         if(ob->parent && ob->parent->type==OB_LATTICE) {
2482                 lt= ob->parent->data;
2483                 init_latt_deform(ob->parent, ob);
2484                 need_orco= 1;
2485         }
2486         
2487         if(ob->parent && ob->parent->type==OB_IKA) {
2488                 ika= ob->parent->data;
2489                 init_skel_deform(ob->parent, ob);
2490                 need_orco= 1;
2491         }
2492
2493         if(ob->parent && ob->parent->type==OB_ARMATURE) {
2494                 init_armature_deform(ob->parent, ob);
2495                 need_orco= 1;
2496         }
2497
2498         /* do keypos? NOTE: watch it : orcos */
2499
2500         /* effect on text? */
2501
2502         /* boundboxclip still todo */
2503
2504         /* side faces of poly:  work with bevellist */
2505         widfac= (cu->width-1.0);
2506
2507         bl= cu->bev.first;
2508         nu= cu->nurb.first;
2509         while(bl) {
2510
2511                 if(dlbev.first) {    /* otherwise just a poly */
2512
2513                         dlb= dlbev.first;   /* bevel loop */
2514                         while(dlb) {
2515                                 data= MEM_mallocN(3*sizeof(float)*dlb->nr*bl->nr, "init_render_curve3");
2516                                 fp= data;
2517
2518                                 /* for each point at bevelcurve do the entire poly */
2519                                 fp1= dlb->verts;
2520                                 b= dlb->nr;
2521                                 while(b--) {
2522
2523                                         bevp= (BevPoint *)(bl+1);
2524                                         a= bl->nr;
2525                                         while(a--) {
2526
2527                                                 if(cu->flag & CU_3D) {
2528                                                         vec[0]= fp1[1]+widfac;
2529                                                         vec[1]= fp1[2];
2530                                                         vec[2]= 0.0;
2531
2532                                                         MTC_Mat3MulVecfl(bevp->mat, vec);
2533
2534                                                         fp[0]= bevp->x+ vec[0];
2535                                                         fp[1]= bevp->y+ vec[1];
2536                                                         fp[2]= bevp->z+ vec[2];
2537                                                 }
2538                                                 else {
2539
2540                                                         fp[0]= bevp->x+ (widfac+fp1[1])*bevp->sina;
2541                                                         fp[1]= bevp->y+ (widfac+fp1[1])*bevp->cosa;
2542                                                         fp[2]= bevp->z+ fp1[2];
2543                                                         /* do not MatMul here: polyfill should work uniform, independent which frame */
2544                                                 }
2545                                                 fp+= 3;
2546                                                 bevp++;
2547                                         }
2548                                         fp1+=3;
2549                                 }
2550
2551                                 /* make render vertices */
2552                                 fp= data;
2553                                 startvert= R.totvert;
2554                                 nr= dlb->nr*bl->nr;
2555
2556                                 while(nr--) {
2557                                         ver= RE_findOrAddVert(R.totvert++);
2558                                         
2559                                         if(lt) calc_latt_deform(fp);
2560                                         else if(ika) calc_skel_deform(ika, fp);
2561                                         
2562                                         VECCOPY(ver->co, fp);
2563                                         MTC_Mat4MulVecfl(mat, ver->co);
2564                                         fp+= 3;
2565                                 }
2566
2567                                 startvlak= R.totvlak;
2568
2569                                 for(a=0; a<dlb->nr; a++) {
2570
2571                                         frontside= (a >= dlb->nr/2);
2572
2573                                         DL_SURFINDEX(bl->poly>0, dlb->type==DL_POLY, bl->nr, dlb->nr);
2574                                         p1+= startvert;
2575                                         p2+= startvert;
2576                                         p3+= startvert;
2577                                         p4+= startvert;
2578
2579                                         for(; b<bl->nr; b++) {
2580
2581                                                 vlr= RE_findOrAddVlak(R.totvlak++);
2582                                                 vlr->ob= ob;
2583                                                 vlr->v1= RE_findOrAddVert(p2);
2584                                                 vlr->v2= RE_findOrAddVert(p1);
2585                                                 vlr->v3= RE_findOrAddVert(p3);
2586                                                 vlr->v4= RE_findOrAddVert(p4);
2587                                                 vlr->ec= ME_V2V3+ME_V3V4;
2588                                                 if(a==0) vlr->ec+= ME_V1V2;
2589
2590                                                 vlr->flag= nu->flag;
2591                                                 vlr->lay= ob->lay;
2592
2593                                                 /* this is not really scientific: the vertices
2594                                                  * 2, 3 en 4 seem to give better vertexnormals than 1 2 3:
2595                                                  * front and backside treated different!!
2596                                                  */
2597
2598                                                 if(frontside)
2599                                                         vlr->len= CalcNormFloat(vlr->v2->co, vlr->v3->co, vlr->v4->co, vlr->n);
2600                                                 else 
2601                                                         vlr->len= CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->n);
2602
2603                                                 vlr->mat= matar[ nu->mat_nr ];
2604
2605                                                 p4= p3;
2606                                                 p3++;
2607                                                 p2= p1;
2608                                                 p1++;
2609
2610                                         }
2611
2612                                 }
2613
2614                                 /* make double points: SPLIT POLY */
2615                                 if(dlb->nr==4 && cu->bevobj==0) {
2616                                         split_u_renderfaces(startvlak, startvert, bl->nr, 1, bl->poly>0);
2617                                         split_u_renderfaces(startvlak, startvert, bl->nr, 2, bl->poly>0);
2618                                 }
2619                                 /* make double points: SPLIT BEVELS */
2620                                 bevp= (BevPoint *)(bl+1);
2621                                 for(a=0; a<bl->nr; a++) {
2622                                         if(bevp->f1)
2623                                                 split_v_renderfaces(startvlak, startvert, bl->nr, dlb->nr, a, bl->poly>0,
2624                                                     dlb->type==DL_POLY);
2625                                         bevp++;
2626                                 }
2627
2628                                 /* vertex normals */
2629                                 for(a= startvlak; a<R.totvlak; a++) {
2630                                         vlr= RE_findOrAddVlak(a);
2631
2632                                         VecAddf(vlr->v1->n, vlr->v1->n, vlr->n);
2633                                         VecAddf(vlr->v3->n, vlr->v3->n, vlr->n);
2634                                         VecAddf(vlr->v2->n, vlr->v2->n, vlr->n);
2635                                         VecAddf(vlr->v4->n, vlr->v4->n, vlr->n);
2636                                 }
2637                                 for(a=startvert; a<R.totvert; a++) {
2638                                         ver= RE_findOrAddVert(a);
2639                                         len= Normalise(ver->n);
2640                                         if(len==0.0) ver->sticky= (float *)1;
2641                                         else ver->sticky= 0;
2642                                 }
2643                                 for(a= startvlak; a<R.totvlak; a++) {
2644                                         vlr= RE_findOrAddVlak(a);
2645                                         if(vlr->v1->sticky) VECCOPY(vlr->v1->n, vlr->n);
2646                                         if(vlr->v2->sticky) VECCOPY(vlr->v2->n, vlr->n);
2647                                         if(vlr->v3->sticky) VECCOPY(vlr->v3->n, vlr->n);
2648                                         if(vlr->v4->sticky) VECCOPY(vlr->v4->n, vlr->n);
2649                                 }
2650
2651                                 dlb= dlb->next;
2652
2653                                 MEM_freeN(data);
2654                         }
2655
2656                 }
2657                 bl= bl->next;
2658                 nu= nu->next;
2659         }
2660
2661         if(dlbev.first) {
2662                 freedisplist(&dlbev);
2663         }
2664
2665         if(cu->flag & CU_PATH) return;
2666
2667         /* from displist the filled faces can be extracted */
2668         dl= cu->disp.first;
2669
2670         while(dl) {
2671                 if(dl->type==DL_INDEX3) {
2672
2673                         startvert= R.totvert;
2674                         data= dl->verts;
2675
2676                         n[0]= ob->imat[0][2];
2677                         n[1]= ob->imat[1][2];
2678                         n[2]= ob->imat[2][2];
2679                         Normalise(n);
2680
2681                         for(a=0; a<dl->nr; a++, data+=3) {
2682
2683                                 ver= RE_findOrAddVert(R.totvert++);
2684                                 VECCOPY(ver->co, data);
2685                                 MTC_Mat4MulVecfl(mat, ver->co);
2686
2687                                 VECCOPY(ver->n, n);
2688                         }
2689
2690                         startvlak= R.totvlak;
2691                         index= dl->index;
2692                         for(a=0; a<dl->parts; a++, index+=3) {
2693
2694                                 vlr= RE_findOrAddVlak(R.totvlak++);
2695                                 vlr->v1= RE_findOrAddVert(startvert+index[0]);
2696                                 vlr->v2= RE_findOrAddVert(startvert+index[1]);
2697                                 vlr->v3= RE_findOrAddVert(startvert+index[2]);
2698                                 vlr->v4= 0;
2699
2700                                 VECCOPY(vlr->n, n);
2701
2702                                 vlr->mface= 0;
2703                                 vlr->mat= matar[ dl->col ];
2704                                 vlr->puno= 0;
2705                                 vlr->flag= 0;
2706                                 vlr->ec= 0;
2707                                 vlr->lay= ob->lay;
2708                         }
2709
2710                 }
2711                 dl= dl->next;
2712         }
2713
2714         if(lt) {
2715                 end_latt_deform();
2716         }
2717
2718         if(need_orco) { /* the stupid way: should be replaced; taking account for keys! */
2719
2720                 VECCOPY(size, cu->size);
2721
2722                 nr= R.totvert-firststartvert;
2723                 if(nr) {
2724                         if(cu->orco) {
2725                                 fp= cu->orco;
2726                                 while(nr--) {
2727                                         ver= RE_findOrAddVert(firststartvert++);
2728                                         ver->orco= fp;
2729                                         fp+= 3;
2730                                 }
2731                         }
2732                         else {
2733                                 fp= cu->orco= MEM_mallocN(sizeof(float)*3*nr, "cu orco");
2734                                 while(nr--) {
2735                                         ver= RE_findOrAddVert(firststartvert++);
2736                                         ver->orco= fp;
2737
2738                                         VECCOPY(fp, ver->co);
2739                                         MTC_Mat4MulVecfl(ob->imat, fp);
2740
2741                                         fp[0]= (fp[0]-cu->loc[0])/size[0];
2742                                         fp[1]= (fp[1]-cu->loc[1])/size[1];
2743                                         fp[2]= (fp[2]-cu->loc[2])/size[2];
2744                                         fp+= 3;
2745                                 }
2746                         }
2747                 }
2748         }
2749 }
2750
2751 static void init_render_object(Object *ob)
2752 {
2753         float mat[4][4];
2754
2755         ob->flag |= OB_DONE;
2756
2757         if(ob->type==OB_LAMP)
2758                 RE_add_render_lamp(ob, 1);
2759         else if ELEM(ob->type, OB_FONT, O