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