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