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