Dupli Bugfixes!
[blender-staging.git] / source / blender / render / intern / source / renderdatabase.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * Contributor(s): 2004-2006, Blender Foundation, full recode
24  *
25  * ***** END GPL/BL DUAL LICENSE BLOCK *****
26  */
27
28 /*
29  * Storage, retrieval and query of render specific data.
30  *
31  * All data from a Blender scene is converted by the renderconverter/
32  * into a special format that is used by the render module to make
33  * images out of. These functions interface to the render-specific
34  * database.  
35  *
36  * The blo{ha/ve/vl} arrays store pointers to blocks of 256 data
37  * entries each.
38  *
39  * The index of an entry is >>8 (the highest 24 * bits), to find an
40  * offset in a 256-entry block.
41  *
42  * - If the 256-entry block entry has an entry in the
43  * vertnodes/vlaknodes/bloha array of the current block, the i-th entry in
44  * that block is allocated to this entry.
45  *
46  * - If the entry has no block allocated for it yet, memory is
47  * allocated.
48  *
49  * The pointer to the correct entry is returned. Memory is guarateed
50  * to exist (as long as the malloc does not break). Since guarded
51  * allocation is used, memory _must_ be available. Otherwise, an
52  * exit(0) would occur.
53  * 
54  */
55
56 #include <limits.h>
57 #include <math.h>
58 #include <string.h>
59
60 #include "MEM_guardedalloc.h"
61 #include "BKE_utildefines.h"
62
63 #include "BLI_arithb.h"
64 #include "BLI_blenlib.h"
65 #include "BLI_ghash.h"
66 #include "BLI_memarena.h"
67
68 #include "DNA_material_types.h" 
69 #include "DNA_mesh_types.h" 
70 #include "DNA_meshdata_types.h" 
71 #include "DNA_texture_types.h" 
72
73 #include "BKE_customdata.h"
74 #include "BKE_texture.h" 
75 #include "BKE_DerivedMesh.h"
76
77 #include "RE_render_ext.h"      /* externtex */
78
79 #include "renderpipeline.h"
80 #include "render_types.h"
81 #include "renderdatabase.h"
82 #include "texture.h"
83 #include "strand.h"
84 #include "zbuf.h"
85
86 /* ------------------------------------------------------------------------- */
87
88 /* More dynamic allocation of options for render vertices and faces, so we dont
89    have to reserve this space inside vertices.
90    Important; vertices and faces, should have been created already (to get tables
91    checked) that's a reason why the calls demand VertRen/VlakRen * as arg, not
92    the index */
93
94 /* NOTE! the hardcoded table size 256 is used still in code for going quickly over vertices/faces */
95
96 #define RE_STICKY_ELEMS         2
97 #define RE_STRESS_ELEMS         1
98 #define RE_RAD_ELEMS            4
99 #define RE_STRAND_ELEMS         1
100 #define RE_TANGENT_ELEMS        3
101 #define RE_STRESS_ELEMS         1
102 #define RE_WINSPEED_ELEMS       4
103 #define RE_MTFACE_ELEMS         1
104 #define RE_MCOL_ELEMS           4
105 #define RE_UV_ELEMS                     2
106 #define RE_SURFNOR_ELEMS        3
107 #define RE_SIMPLIFY_ELEMS       2
108
109 float *RE_vertren_get_sticky(ObjectRen *obr, VertRen *ver, int verify)
110 {
111         float *sticky;
112         int nr= ver->index>>8;
113         
114         sticky= obr->vertnodes[nr].sticky;
115         if(sticky==NULL) {
116                 if(verify) 
117                         sticky= obr->vertnodes[nr].sticky= MEM_mallocN(256*RE_STICKY_ELEMS*sizeof(float), "sticky table");
118                 else
119                         return NULL;
120         }
121         return sticky + (ver->index & 255)*RE_STICKY_ELEMS;
122 }
123
124 float *RE_vertren_get_stress(ObjectRen *obr, VertRen *ver, int verify)
125 {
126         float *stress;
127         int nr= ver->index>>8;
128         
129         stress= obr->vertnodes[nr].stress;
130         if(stress==NULL) {
131                 if(verify) 
132                         stress= obr->vertnodes[nr].stress= MEM_mallocN(256*RE_STRESS_ELEMS*sizeof(float), "stress table");
133                 else
134                         return NULL;
135         }
136         return stress + (ver->index & 255)*RE_STRESS_ELEMS;
137 }
138
139 /* this one callocs! */
140 float *RE_vertren_get_rad(ObjectRen *obr, VertRen *ver, int verify)
141 {
142         float *rad;
143         int nr= ver->index>>8;
144         
145         rad= obr->vertnodes[nr].rad;
146         if(rad==NULL) {
147                 if(verify) 
148                         rad= obr->vertnodes[nr].rad= MEM_callocN(256*RE_RAD_ELEMS*sizeof(float), "rad table");
149                 else
150                         return NULL;
151         }
152         return rad + (ver->index & 255)*RE_RAD_ELEMS;
153 }
154
155 float *RE_vertren_get_strand(ObjectRen *obr, VertRen *ver, int verify)
156 {
157         float *strand;
158         int nr= ver->index>>8;
159         
160         strand= obr->vertnodes[nr].strand;
161         if(strand==NULL) {
162                 if(verify) 
163                         strand= obr->vertnodes[nr].strand= MEM_mallocN(256*RE_STRAND_ELEMS*sizeof(float), "strand table");
164                 else
165                         return NULL;
166         }
167         return strand + (ver->index & 255)*RE_STRAND_ELEMS;
168 }
169
170 /* needs calloc */
171 float *RE_vertren_get_tangent(ObjectRen *obr, VertRen *ver, int verify)
172 {
173         float *tangent;
174         int nr= ver->index>>8;
175         
176         tangent= obr->vertnodes[nr].tangent;
177         if(tangent==NULL) {
178                 if(verify) 
179                         tangent= obr->vertnodes[nr].tangent= MEM_callocN(256*RE_TANGENT_ELEMS*sizeof(float), "tangent table");
180                 else
181                         return NULL;
182         }
183         return tangent + (ver->index & 255)*RE_TANGENT_ELEMS;
184 }
185
186 /* needs calloc! not all renderverts have them */
187 /* also winspeed is exception, it is stored per instance */
188 float *RE_vertren_get_winspeed(ObjectInstanceRen *obi, VertRen *ver, int verify)
189 {
190         float *winspeed;
191         int totvector;
192         
193         winspeed= obi->vectors;
194         if(winspeed==NULL) {
195                 if(verify) {
196                         totvector= obi->obr->totvert + obi->obr->totstrand;
197                         winspeed= obi->vectors= MEM_callocN(totvector*RE_WINSPEED_ELEMS*sizeof(float), "winspeed table");
198                 }
199                 else
200                         return NULL;
201         }
202         return winspeed + ver->index*RE_WINSPEED_ELEMS;
203 }
204
205 VertRen *RE_vertren_copy(ObjectRen *obr, VertRen *ver)
206 {
207         VertRen *v1= RE_findOrAddVert(obr, obr->totvert++);
208         float *fp1, *fp2;
209         int index= v1->index;
210         
211         *v1= *ver;
212         v1->index= index;
213         
214         fp1= RE_vertren_get_sticky(obr, ver, 0);
215         if(fp1) {
216                 fp2= RE_vertren_get_sticky(obr, v1, 1);
217                 memcpy(fp2, fp1, RE_STICKY_ELEMS*sizeof(float));
218         }
219         fp1= RE_vertren_get_stress(obr, ver, 0);
220         if(fp1) {
221                 fp2= RE_vertren_get_stress(obr, v1, 1);
222                 memcpy(fp2, fp1, RE_STRESS_ELEMS*sizeof(float));
223         }
224         fp1= RE_vertren_get_rad(obr, ver, 0);
225         if(fp1) {
226                 fp2= RE_vertren_get_rad(obr, v1, 1);
227                 memcpy(fp2, fp1, RE_RAD_ELEMS*sizeof(float));
228         }
229         fp1= RE_vertren_get_strand(obr, ver, 0);
230         if(fp1) {
231                 fp2= RE_vertren_get_strand(obr, v1, 1);
232                 memcpy(fp2, fp1, RE_STRAND_ELEMS*sizeof(float));
233         }
234         fp1= RE_vertren_get_tangent(obr, ver, 0);
235         if(fp1) {
236                 fp2= RE_vertren_get_tangent(obr, v1, 1);
237                 memcpy(fp2, fp1, RE_TANGENT_ELEMS*sizeof(float));
238         }
239         return v1;
240 }
241
242 VertRen *RE_findOrAddVert(ObjectRen *obr, int nr)
243 {
244         VertTableNode *temp;
245         VertRen *v;
246         int a;
247
248         if(nr<0) {
249                 printf("error in findOrAddVert: %d\n",nr);
250                 return NULL;
251         }
252         a= nr>>8;
253         
254         if (a>=obr->vertnodeslen-1) {  /* Need to allocate more columns..., and keep last element NULL for free loop */
255                 temp= obr->vertnodes;
256                 
257                 obr->vertnodes= MEM_mallocN(sizeof(VertTableNode)*(obr->vertnodeslen+TABLEINITSIZE) , "vertnodes");
258                 if(temp) memcpy(obr->vertnodes, temp, obr->vertnodeslen*sizeof(VertTableNode));
259                 memset(obr->vertnodes+obr->vertnodeslen, 0, TABLEINITSIZE*sizeof(VertTableNode));
260                 
261                 obr->vertnodeslen+=TABLEINITSIZE; 
262                 if(temp) MEM_freeN(temp);       
263         }
264         
265         v= obr->vertnodes[a].vert;
266         if(v==NULL) {
267                 int i;
268                 
269                 v= (VertRen *)MEM_callocN(256*sizeof(VertRen),"findOrAddVert");
270                 obr->vertnodes[a].vert= v;
271                 
272                 for(i= (nr & 0xFFFFFF00), a=0; a<256; a++, i++) {
273                         v[a].index= i;
274                 }
275         }
276         v+= (nr & 255);
277         return v;
278 }
279
280 /* ------------------------------------------------------------------------ */
281
282 MTFace *RE_vlakren_get_tface(ObjectRen *obr, VlakRen *vlr, int n, char **name, int verify)
283 {
284         VlakTableNode *node;
285         int nr= vlr->index>>8, vlakindex= (vlr->index&255);
286         int index= (n<<8) + vlakindex;
287
288         node= &obr->vlaknodes[nr];
289
290         if(verify) {
291                 if(n>=node->totmtface) {
292                         MTFace *mtface= node->mtface;
293                         int size= size= (n+1)*256;
294
295                         node->mtface= MEM_callocN(size*sizeof(MTFace), "Vlak mtface");
296
297                         if(mtface) {
298                                 size= node->totmtface*256;
299                                 memcpy(node->mtface, mtface, size*sizeof(MTFace));
300                                 MEM_freeN(mtface);
301                         }
302
303                         node->totmtface= n+1;
304                 }
305         }
306         else {
307                 if(n>=node->totmtface)
308                         return NULL;
309
310                 if(name) *name= obr->mtface[n];
311         }
312
313         return node->mtface + index;
314 }
315
316 MCol *RE_vlakren_get_mcol(ObjectRen *obr, VlakRen *vlr, int n, char **name, int verify)
317 {
318         VlakTableNode *node;
319         int nr= vlr->index>>8, vlakindex= (vlr->index&255);
320         int index= (n<<8) + vlakindex;
321
322         node= &obr->vlaknodes[nr];
323
324         if(verify) {
325                 if(n>=node->totmcol) {
326                         MCol *mcol= node->mcol;
327                         int size= (n+1)*256;
328
329                         node->mcol= MEM_callocN(size*sizeof(MCol)*RE_MCOL_ELEMS, "Vlak mcol");
330
331                         if(mcol) {
332                                 size= node->totmcol*256;
333                                 memcpy(node->mcol, mcol, size*sizeof(MCol)*RE_MCOL_ELEMS);
334                                 MEM_freeN(mcol);
335                         }
336
337                         node->totmcol= n+1;
338                 }
339         }
340         else {
341                 if(n>=node->totmcol)
342                         return NULL;
343
344                 if(name) *name= obr->mcol[n];
345         }
346
347         return node->mcol + index*RE_MCOL_ELEMS;
348 }
349
350 float *RE_vlakren_get_surfnor(ObjectRen *obr, VlakRen *vlak, int verify)
351 {
352         float *surfnor;
353         int nr= vlak->index>>8;
354         
355         surfnor= obr->vlaknodes[nr].surfnor;
356         if(surfnor==NULL) {
357                 if(verify) 
358                         surfnor= obr->vlaknodes[nr].surfnor= MEM_callocN(256*RE_SURFNOR_ELEMS*sizeof(float), "surfnor table");
359                 else
360                         return NULL;
361         }
362         return surfnor + (vlak->index & 255)*RE_SURFNOR_ELEMS;
363 }
364
365 VlakRen *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr)
366 {
367         VlakRen *vlr1 = RE_findOrAddVlak(obr, obr->totvlak++);
368         MTFace *mtface, *mtface1;
369         MCol *mcol, *mcol1;
370         float *surfnor, *surfnor1;
371         int i, index = vlr1->index;
372         char *name;
373
374         *vlr1= *vlr;
375         vlr1->index= index;
376
377         for (i=0; (mtface=RE_vlakren_get_tface(obr, vlr, i, &name, 0)) != NULL; i++) {
378                 mtface1= RE_vlakren_get_tface(obr, vlr1, i, &name, 1);
379                 memcpy(mtface1, mtface, sizeof(MTFace)*RE_MTFACE_ELEMS);
380         }
381
382         for (i=0; (mcol=RE_vlakren_get_mcol(obr, vlr, i, &name, 0)) != NULL; i++) {
383                 mcol1= RE_vlakren_get_mcol(obr, vlr1, i, &name, 1);
384                 memcpy(mcol1, mcol, sizeof(MCol)*RE_MCOL_ELEMS);
385         }
386
387         surfnor= RE_vlakren_get_surfnor(obr, vlr, 0);
388         if(surfnor) {
389                 surfnor1= RE_vlakren_get_surfnor(obr, vlr1, 1);
390                 VECCOPY(surfnor1, surfnor);
391         }
392
393         return vlr1;
394 }
395
396 int RE_vlakren_get_normal(Render *re, ObjectInstanceRen *obi, VlakRen *vlr, float *nor)
397 {
398         float xn, yn, zn, v1[3];
399         float (*imat)[3]= obi->imat;
400         int flipped= 0;
401
402         if(obi->flag & R_TRANSFORMED) {
403                 xn= vlr->n[0];
404                 yn= vlr->n[1];
405                 zn= vlr->n[2];
406                 
407                 /* transpose! */
408                 nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
409                 nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
410                 nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
411                 Normalize(nor);
412         }
413         else
414                 VECCOPY(nor, vlr->n);
415
416         if((vlr->flag & R_NOPUNOFLIP)==0) {
417                 if(re->r.mode & R_ORTHO) {
418                         if(nor[2] > 0.0f)
419                                 flipped= 1;
420                 }
421                 else {
422                         VECCOPY(v1, vlr->v1->co);
423                         if(obi->flag & R_TRANSFORMED)
424                                 Mat4MulVecfl(obi->mat, v1);
425                         if(INPR(v1, nor) < 0.0f) {
426                                 flipped= 1;
427                         }
428                 }
429
430                 if(flipped) {
431                         nor[0]= -nor[0];
432                         nor[1]= -nor[1];
433                         nor[2]= -nor[2];
434                 }
435         }
436
437         return flipped;
438 }
439
440 void RE_set_customdata_names(ObjectRen *obr, CustomData *data)
441 {
442         /* CustomData layer names are stored per object here, because the
443            DerivedMesh which stores the layers is freed */
444         
445         CustomDataLayer *layer;
446         int numlayers, i, mtfn, mcn;
447
448         if (CustomData_has_layer(data, CD_MTFACE)) {
449                 numlayers= CustomData_number_of_layers(data, CD_MTFACE);
450                 obr->mtface= MEM_callocN(sizeof(*obr->mtface)*numlayers, "mtfacenames");
451         }
452
453         if (CustomData_has_layer(data, CD_MCOL)) {
454                 numlayers= CustomData_number_of_layers(data, CD_MCOL);
455                 obr->mcol= MEM_callocN(sizeof(*obr->mcol)*numlayers, "mcolnames");
456         }
457
458         for (i=0, mtfn=0, mcn=0; i < data->totlayer; i++) {
459                 layer= &data->layers[i];
460
461                 if (layer->type == CD_MTFACE) {
462                         strcpy(obr->mtface[mtfn++], layer->name);
463                         obr->actmtface= layer->active_rnd;
464                 }
465                 else if (layer->type == CD_MCOL) {
466                         strcpy(obr->mcol[mcn++], layer->name);
467                         obr->actmcol= layer->active_rnd;
468                 }
469         }
470 }
471
472 VlakRen *RE_findOrAddVlak(ObjectRen *obr, int nr)
473 {
474         VlakTableNode *temp;
475         VlakRen *v;
476         int a;
477
478         if(nr<0) {
479                 printf("error in findOrAddVlak: %d\n",nr);
480                 return obr->vlaknodes[0].vlak;
481         }
482         a= nr>>8;
483         
484         if (a>=obr->vlaknodeslen-1){  /* Need to allocate more columns..., and keep last element NULL for free loop */
485                 temp= obr->vlaknodes;
486                 
487                 obr->vlaknodes= MEM_mallocN(sizeof(VlakTableNode)*(obr->vlaknodeslen+TABLEINITSIZE) , "vlaknodes");
488                 if(temp) memcpy(obr->vlaknodes, temp, obr->vlaknodeslen*sizeof(VlakTableNode));
489                 memset(obr->vlaknodes+obr->vlaknodeslen, 0, TABLEINITSIZE*sizeof(VlakTableNode));
490
491                 obr->vlaknodeslen+=TABLEINITSIZE;  /*Does this really need to be power of 2?*/
492                 if(temp) MEM_freeN(temp);       
493         }
494
495         v= obr->vlaknodes[a].vlak;
496         
497         if(v==NULL) {
498                 int i;
499
500                 v= (VlakRen *)MEM_callocN(256*sizeof(VlakRen),"findOrAddVlak");
501                 obr->vlaknodes[a].vlak= v;
502
503                 for(i= (nr & 0xFFFFFF00), a=0; a<256; a++, i++)
504                         v[a].index= i;
505         }
506         v+= (nr & 255);
507         return v;
508 }
509
510 /* ------------------------------------------------------------------------ */
511
512 float *RE_strandren_get_surfnor(ObjectRen *obr, StrandRen *strand, int verify)
513 {
514         float *surfnor;
515         int nr= strand->index>>8;
516         
517         surfnor= obr->strandnodes[nr].surfnor;
518         if(surfnor==NULL) {
519                 if(verify) 
520                         surfnor= obr->strandnodes[nr].surfnor= MEM_callocN(256*RE_SURFNOR_ELEMS*sizeof(float), "surfnor table");
521                 else
522                         return NULL;
523         }
524         return surfnor + (strand->index & 255)*RE_SURFNOR_ELEMS;
525 }
526
527 float *RE_strandren_get_uv(ObjectRen *obr, StrandRen *strand, int n, char **name, int verify)
528 {
529         StrandTableNode *node;
530         int nr= strand->index>>8, strandindex= (strand->index&255);
531         int index= (n<<8) + strandindex;
532
533         node= &obr->strandnodes[nr];
534
535         if(verify) {
536                 if(n>=node->totuv) {
537                         float *uv= node->uv;
538                         int size= (n+1)*256;
539
540                         node->uv= MEM_callocN(size*sizeof(float)*RE_UV_ELEMS, "Strand uv");
541
542                         if(uv) {
543                                 size= node->totuv*256;
544                                 memcpy(node->uv, uv, size*sizeof(float)*RE_UV_ELEMS);
545                                 MEM_freeN(uv);
546                         }
547
548                         node->totuv= n+1;
549                 }
550         }
551         else {
552                 if(n>=node->totuv)
553                         return NULL;
554
555                 if(name) *name= obr->mtface[n];
556         }
557
558         return node->uv + index*RE_UV_ELEMS;
559 }
560
561 MCol *RE_strandren_get_mcol(ObjectRen *obr, StrandRen *strand, int n, char **name, int verify)
562 {
563         StrandTableNode *node;
564         int nr= strand->index>>8, strandindex= (strand->index&255);
565         int index= (n<<8) + strandindex;
566
567         node= &obr->strandnodes[nr];
568
569         if(verify) {
570                 if(n>=node->totmcol) {
571                         MCol *mcol= node->mcol;
572                         int size= (n+1)*256;
573
574                         node->mcol= MEM_callocN(size*sizeof(MCol)*RE_MCOL_ELEMS, "Strand mcol");
575
576                         if(mcol) {
577                                 size= node->totmcol*256;
578                                 memcpy(node->mcol, mcol, size*sizeof(MCol)*RE_MCOL_ELEMS);
579                                 MEM_freeN(mcol);
580                         }
581
582                         node->totmcol= n+1;
583                 }
584         }
585         else {
586                 if(n>=node->totmcol)
587                         return NULL;
588
589                 if(name) *name= obr->mcol[n];
590         }
591
592         return node->mcol + index*RE_MCOL_ELEMS;
593 }
594
595 float *RE_strandren_get_simplify(struct ObjectRen *obr, struct StrandRen *strand, int verify)
596 {
597         float *simplify;
598         int nr= strand->index>>8;
599         
600         simplify= obr->strandnodes[nr].simplify;
601         if(simplify==NULL) {
602                 if(verify) 
603                         simplify= obr->strandnodes[nr].simplify= MEM_callocN(256*RE_SIMPLIFY_ELEMS*sizeof(float), "simplify table");
604                 else
605                         return NULL;
606         }
607         return simplify + (strand->index & 255)*RE_SIMPLIFY_ELEMS;
608 }
609
610 /* winspeed is exception, it is stored per instance */
611 float *RE_strandren_get_winspeed(ObjectInstanceRen *obi, StrandRen *strand, int verify)
612 {
613         float *winspeed;
614         int totvector;
615         
616         winspeed= obi->vectors;
617         if(winspeed==NULL) {
618                 if(verify) {
619                         totvector= obi->obr->totvert + obi->obr->totstrand;
620                         winspeed= obi->vectors= MEM_callocN(totvector*RE_WINSPEED_ELEMS*sizeof(float), "winspeed table");
621                 }
622                 else
623                         return NULL;
624         }
625         return winspeed + (obi->obr->totvert + strand->index)*RE_WINSPEED_ELEMS;
626 }
627
628 StrandRen *RE_findOrAddStrand(ObjectRen *obr, int nr)
629 {
630         StrandTableNode *temp;
631         StrandRen *v;
632         int a;
633
634         if(nr<0) {
635                 printf("error in findOrAddStrand: %d\n",nr);
636                 return obr->strandnodes[0].strand;
637         }
638         a= nr>>8;
639         
640         if (a>=obr->strandnodeslen-1){  /* Need to allocate more columns..., and keep last element NULL for free loop */
641                 temp= obr->strandnodes;
642                 
643                 obr->strandnodes= MEM_mallocN(sizeof(StrandTableNode)*(obr->strandnodeslen+TABLEINITSIZE) , "strandnodes");
644                 if(temp) memcpy(obr->strandnodes, temp, obr->strandnodeslen*sizeof(StrandTableNode));
645                 memset(obr->strandnodes+obr->strandnodeslen, 0, TABLEINITSIZE*sizeof(StrandTableNode));
646
647                 obr->strandnodeslen+=TABLEINITSIZE;  /*Does this really need to be power of 2?*/
648                 if(temp) MEM_freeN(temp);       
649         }
650
651         v= obr->strandnodes[a].strand;
652         
653         if(v==NULL) {
654                 int i;
655
656                 v= (StrandRen *)MEM_callocN(256*sizeof(StrandRen),"findOrAddStrand");
657                 obr->strandnodes[a].strand= v;
658
659                 for(i= (nr & 0xFFFFFF00), a=0; a<256; a++, i++)
660                         v[a].index= i;
661         }
662         v+= (nr & 255);
663         return v;
664 }
665
666 StrandBuffer *RE_addStrandBuffer(ObjectRen *obr, int totvert)
667 {
668         StrandBuffer *strandbuf;
669
670         strandbuf= MEM_callocN(sizeof(StrandBuffer), "StrandBuffer");
671         strandbuf->vert= MEM_callocN(sizeof(StrandVert)*totvert, "StrandVert");
672         strandbuf->totvert= totvert;
673         strandbuf->obr= obr;
674
675         BLI_addtail(&obr->strandbufs, strandbuf);
676
677         return strandbuf;
678 }
679
680 /* ------------------------------------------------------------------------ */
681
682 ObjectRen *RE_addRenderObject(Render *re, Object *ob, Object *par, int index, int psysindex)
683 {
684         ObjectRen *obr= MEM_callocN(sizeof(ObjectRen), "object render struct");
685         
686         BLI_addtail(&re->objecttable, obr);
687         obr->ob= ob;
688         obr->par= par;
689         obr->index= index;
690         obr->psysindex= psysindex;
691
692         return obr;
693 }
694
695 void free_renderdata_vertnodes(VertTableNode *vertnodes)
696 {
697         int a;
698         
699         if(vertnodes==NULL) return;
700         
701         for(a=0; vertnodes[a].vert; a++) {
702                 MEM_freeN(vertnodes[a].vert);
703                 
704                 if(vertnodes[a].rad)
705                         MEM_freeN(vertnodes[a].rad);
706                 if(vertnodes[a].sticky)
707                         MEM_freeN(vertnodes[a].sticky);
708                 if(vertnodes[a].strand)
709                         MEM_freeN(vertnodes[a].strand);
710                 if(vertnodes[a].tangent)
711                         MEM_freeN(vertnodes[a].tangent);
712                 if(vertnodes[a].stress)
713                         MEM_freeN(vertnodes[a].stress);
714                 if(vertnodes[a].winspeed)
715                         MEM_freeN(vertnodes[a].winspeed);
716         }
717         
718         MEM_freeN(vertnodes);
719 }
720
721 void free_renderdata_vlaknodes(VlakTableNode *vlaknodes)
722 {
723         int a;
724         
725         if(vlaknodes==NULL) return;
726         
727         for(a=0; vlaknodes[a].vlak; a++) {
728                 MEM_freeN(vlaknodes[a].vlak);
729                 
730                 if(vlaknodes[a].mtface)
731                         MEM_freeN(vlaknodes[a].mtface);
732                 if(vlaknodes[a].mcol)
733                         MEM_freeN(vlaknodes[a].mcol);
734                 if(vlaknodes[a].surfnor)
735                         MEM_freeN(vlaknodes[a].surfnor);
736         }
737         
738         MEM_freeN(vlaknodes);
739 }
740
741 void free_renderdata_strandnodes(StrandTableNode *strandnodes)
742 {
743         int a;
744         
745         if(strandnodes==NULL) return;
746         
747         for(a=0; strandnodes[a].strand; a++) {
748                 MEM_freeN(strandnodes[a].strand);
749                 
750                 if(strandnodes[a].uv)
751                         MEM_freeN(strandnodes[a].uv);
752                 if(strandnodes[a].mcol)
753                         MEM_freeN(strandnodes[a].mcol);
754                 if(strandnodes[a].winspeed)
755                         MEM_freeN(strandnodes[a].winspeed);
756                 if(strandnodes[a].surfnor)
757                         MEM_freeN(strandnodes[a].surfnor);
758                 if(strandnodes[a].simplify)
759                         MEM_freeN(strandnodes[a].simplify);
760         }
761         
762         MEM_freeN(strandnodes);
763 }
764
765 void free_renderdata_tables(Render *re)
766 {
767         ObjectInstanceRen *obi;
768         ObjectRen *obr;
769         StrandBuffer *strandbuf;
770         int a=0;
771         
772         for(obr=re->objecttable.first; obr; obr=obr->next) {
773                 if(obr->vertnodes) {
774                         free_renderdata_vertnodes(obr->vertnodes);
775                         obr->vertnodes= NULL;
776                         obr->vertnodeslen= 0;
777                 }
778
779                 if(obr->vlaknodes) {
780                         free_renderdata_vlaknodes(obr->vlaknodes);
781                         obr->vlaknodes= NULL;
782                         obr->vlaknodeslen= 0;
783                         obr->totvlak= 0;
784                 }
785
786                 if(obr->bloha) {
787                         for(a=0; obr->bloha[a]; a++)
788                                 MEM_freeN(obr->bloha[a]);
789
790                         MEM_freeN(obr->bloha);
791                         obr->bloha= NULL;
792                         obr->blohalen= 0;
793                 }
794
795                 if(obr->strandnodes) {
796                         free_renderdata_strandnodes(obr->strandnodes);
797                         obr->strandnodes= NULL;
798                         obr->strandnodeslen= 0;
799                 }
800
801                 for(strandbuf=obr->strandbufs.first; strandbuf; strandbuf=strandbuf->next)
802                         if(strandbuf->vert) MEM_freeN(strandbuf->vert);
803                 BLI_freelistN(&obr->strandbufs);
804
805                 if(obr->mtface)
806                         MEM_freeN(obr->mtface);
807                 if(obr->mcol)
808                         MEM_freeN(obr->mcol);
809         }
810
811         if(re->objectinstance) {
812                 for(obi=re->instancetable.first; obi; obi=obi->next)
813                         if(obi->vectors)
814                                 MEM_freeN(obi->vectors);
815
816                 MEM_freeN(re->objectinstance);
817                 re->objectinstance= NULL;
818                 re->totinstance= 0;
819                 re->instancetable.first= re->instancetable.last= NULL;
820         }
821
822         if(re->sortedhalos) {
823                 MEM_freeN(re->sortedhalos);
824                 re->sortedhalos= NULL;
825         }
826
827         if(re->strandbuckets) {
828                 free_buckets(re->strandbuckets);
829                 re->strandbuckets= NULL;
830         }
831
832         BLI_freelistN(&re->customdata_names);
833         BLI_freelistN(&re->objecttable);
834         BLI_freelistN(&re->instancetable);
835 }
836
837 /* ------------------------------------------------------------------------ */
838
839 HaloRen *RE_findOrAddHalo(ObjectRen *obr, int nr)
840 {
841         HaloRen *h, **temp;
842         int a;
843
844         if(nr<0) {
845                 printf("error in findOrAddHalo: %d\n",nr);
846                 return NULL;
847         }
848         a= nr>>8;
849         
850         if (a>=obr->blohalen-1){  /* Need to allocate more columns..., and keep last element NULL for free loop */
851                 //printf("Allocating %i more halo groups.  %i total.\n", 
852                 //      TABLEINITSIZE, obr->blohalen+TABLEINITSIZE );
853                 temp=obr->bloha;
854                 
855                 obr->bloha=(HaloRen**)MEM_callocN(sizeof(void*)*(obr->blohalen+TABLEINITSIZE) , "Bloha");
856                 if(temp) memcpy(obr->bloha, temp, obr->blohalen*sizeof(void*));
857                 memset(&(obr->bloha[obr->blohalen]), 0, TABLEINITSIZE*sizeof(void*));
858                 obr->blohalen+=TABLEINITSIZE;  /*Does this really need to be power of 2?*/
859                 if(temp) MEM_freeN(temp);       
860         }
861         
862         h= obr->bloha[a];
863         if(h==NULL) {
864                 h= (HaloRen *)MEM_callocN(256*sizeof(HaloRen),"findOrAdHalo");
865                 obr->bloha[a]= h;
866         }
867         h+= (nr & 255);
868         return h;
869 }
870
871 /* ------------------------------------------------------------------------- */
872
873 HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma,   float *vec,   float *vec1, 
874                                   float *orco,   float hasize,   float vectsize, int seed)
875 {
876         HaloRen *har;
877         MTex *mtex;
878         float tin, tr, tg, tb, ta;
879         float xn, yn, zn, texvec[3], hoco[4], hoco1[4];
880
881         if(hasize==0.0) return NULL;
882
883         projectverto(vec, re->winmat, hoco);
884         if(hoco[3]==0.0) return NULL;
885         if(vec1) {
886                 projectverto(vec1, re->winmat, hoco1);
887                 if(hoco1[3]==0.0) return NULL;
888         }
889
890         har= RE_findOrAddHalo(obr, obr->tothalo++);
891         VECCOPY(har->co, vec);
892         har->hasize= hasize;
893
894         /* actual projectvert is done in function project_renderdata() because of parts/border/pano */
895         /* we do it here for sorting of halos */
896         zn= hoco[3];
897         har->xs= 0.5*re->winx*(hoco[0]/zn);
898         har->ys= 0.5*re->winy*(hoco[1]/zn);
899         har->zs= 0x7FFFFF*(hoco[2]/zn);
900         
901         har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn); 
902         
903         /* halovect */
904         if(vec1) {
905
906                 har->type |= HA_VECT;
907
908                 xn=  har->xs - 0.5*re->winx*(hoco1[0]/hoco1[3]);
909                 yn=  har->ys - 0.5*re->winy*(hoco1[1]/hoco1[3]);
910                 if(xn==0.0 || (xn==0.0 && yn==0.0)) zn= 0.0;
911                 else zn= atan2(yn, xn);
912
913                 har->sin= sin(zn);
914                 har->cos= cos(zn);
915                 zn= VecLenf(vec1, vec);
916
917                 har->hasize= vectsize*zn + (1.0-vectsize)*hasize;
918                 
919                 VecSubf(har->no, vec, vec1);
920                 Normalize(har->no);
921         }
922
923         if(ma->mode & MA_HALO_XALPHA) har->type |= HA_XALPHA;
924
925         har->alfa= ma->alpha;
926         har->r= ma->r;
927         har->g= ma->g;
928         har->b= ma->b;
929         har->add= (255.0*ma->add);
930         har->mat= ma;
931         har->hard= ma->har;
932         har->seed= seed % 256;
933
934         if(ma->mode & MA_STAR) har->starpoints= ma->starc;
935         if(ma->mode & MA_HALO_LINES) har->linec= ma->linec;
936         if(ma->mode & MA_HALO_RINGS) har->ringc= ma->ringc;
937         if(ma->mode & MA_HALO_FLARE) har->flarec= ma->flarec;
938
939
940         if(ma->mtex[0]) {
941
942                 if( (ma->mode & MA_HALOTEX) ) har->tex= 1;
943                 else {
944
945                         mtex= ma->mtex[0];
946                         VECCOPY(texvec, vec);
947
948                         if(mtex->texco & TEXCO_NORM) {
949                                 ;
950                         }
951                         else if(mtex->texco & TEXCO_OBJECT) {
952                                 /* texvec[0]+= imatbase->ivec[0]; */
953                                 /* texvec[1]+= imatbase->ivec[1]; */
954                                 /* texvec[2]+= imatbase->ivec[2]; */
955                                 /* Mat3MulVecfl(imatbase->imat, texvec); */
956                         }
957                         else {
958                                 if(orco) {
959                                         VECCOPY(texvec, orco);
960                                 }
961                         }
962
963                         externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta);
964
965                         yn= tin*mtex->colfac;
966                         zn= tin*mtex->varfac;
967
968                         if(mtex->mapto & MAP_COL) {
969                                 zn= 1.0-yn;
970                                 har->r= (yn*tr+ zn*ma->r);
971                                 har->g= (yn*tg+ zn*ma->g);
972                                 har->b= (yn*tb+ zn*ma->b);
973                         }
974                         if(mtex->texco & 16) {
975                                 har->alfa= tin;
976                         }
977                 }
978         }
979
980         return har;
981 }
982
983 HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Material *ma,   float *vec,   float *vec1, 
984                                   float *orco, float *uvco, float hasize, float vectsize, int seed)
985 {
986         HaloRen *har;
987         MTex *mtex;
988         float tin, tr, tg, tb, ta;
989         float xn, yn, zn, texvec[3], hoco[4], hoco1[4], in[3],tex[3],out[3];
990         int i;
991
992         if(hasize==0.0) return NULL;
993
994         projectverto(vec, re->winmat, hoco);
995         if(hoco[3]==0.0) return NULL;
996         if(vec1) {
997                 projectverto(vec1, re->winmat, hoco1);
998                 if(hoco1[3]==0.0) return NULL;
999         }
1000
1001         har= RE_findOrAddHalo(obr, obr->tothalo++);
1002         VECCOPY(har->co, vec);
1003         har->hasize= hasize;
1004
1005         /* actual projectvert is done in function project_renderdata() because of parts/border/pano */
1006         /* we do it here for sorting of halos */
1007         zn= hoco[3];
1008         har->xs= 0.5*re->winx*(hoco[0]/zn);
1009         har->ys= 0.5*re->winy*(hoco[1]/zn);
1010         har->zs= 0x7FFFFF*(hoco[2]/zn);
1011         
1012         har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn); 
1013         
1014         /* halovect */
1015         if(vec1) {
1016
1017                 har->type |= HA_VECT;
1018
1019                 xn=  har->xs - 0.5*re->winx*(hoco1[0]/hoco1[3]);
1020                 yn=  har->ys - 0.5*re->winy*(hoco1[1]/hoco1[3]);
1021                 if(xn==0.0 || (xn==0.0 && yn==0.0)) zn= 0.0;
1022                 else zn= atan2(yn, xn);
1023
1024                 har->sin= sin(zn);
1025                 har->cos= cos(zn);
1026                 zn= VecLenf(vec1, vec)*0.5;
1027
1028                 har->hasize= vectsize*zn + (1.0-vectsize)*hasize;
1029                 
1030                 VecSubf(har->no, vec, vec1);
1031                 Normalize(har->no);
1032         }
1033
1034         if(ma->mode & MA_HALO_XALPHA) har->type |= HA_XALPHA;
1035
1036         har->alfa= ma->alpha;
1037         har->r= ma->r;
1038         har->g= ma->g;
1039         har->b= ma->b;
1040         har->add= (255.0*ma->add);
1041         har->mat= ma;
1042         har->hard= ma->har;
1043         har->seed= seed % 256;
1044
1045         if(ma->mode & MA_STAR) har->starpoints= ma->starc;
1046         if(ma->mode & MA_HALO_LINES) har->linec= ma->linec;
1047         if(ma->mode & MA_HALO_RINGS) har->ringc= ma->ringc;
1048         if(ma->mode & MA_HALO_FLARE) har->flarec= ma->flarec;
1049
1050         if((ma->mode & MA_HALOTEX) && ma->mtex[0]){
1051                 har->tex= 1;
1052                 i=1;
1053         }
1054         
1055         for(i=0; i<MAX_MTEX; i++)
1056                 if(ma->mtex[i] && (ma->septex & (1<<i))==0) {
1057                         mtex= ma->mtex[i];
1058                         VECCOPY(texvec, vec);
1059
1060                         if(mtex->texco & TEXCO_NORM) {
1061                                 ;
1062                         }
1063                         else if(mtex->texco & TEXCO_OBJECT) {
1064                                 if(mtex->object){
1065                                         float imat[4][4];
1066                                         /* imat should really be cached somewhere before this */
1067                                         Mat4Invert(imat,mtex->object->obmat);
1068                                         Mat4MulVecfl(imat,texvec);
1069                                 }
1070                                 /* texvec[0]+= imatbase->ivec[0]; */
1071                                 /* texvec[1]+= imatbase->ivec[1]; */
1072                                 /* texvec[2]+= imatbase->ivec[2]; */
1073                                 /* Mat3MulVecfl(imatbase->imat, texvec); */
1074                         }
1075                         else if(mtex->texco & TEXCO_GLOB){
1076                                 VECCOPY(texvec,vec);
1077                         }
1078                         else if(mtex->texco & TEXCO_UV && uvco){
1079                                 int uv_index=CustomData_get_named_layer_index(&dm->faceData,CD_MTFACE,mtex->uvname);
1080                                 if(uv_index<0)
1081                                         uv_index=CustomData_get_active_layer_index(&dm->faceData,CD_MTFACE);
1082
1083                                 uv_index-=CustomData_get_layer_index(&dm->faceData,CD_MTFACE);
1084
1085                                 texvec[0]=2.0f*uvco[2*uv_index]-1.0f;
1086                                 texvec[1]=2.0f*uvco[2*uv_index+1]-1.0f;
1087                                 texvec[2]=0.0f;
1088                         }
1089                         else if(orco) {
1090                                 VECCOPY(texvec, orco);
1091                         }
1092
1093                         externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta);
1094
1095                         //yn= tin*mtex->colfac;
1096                         //zn= tin*mtex->varfac;
1097                         if(mtex->mapto & MAP_COL) {
1098                                 tex[0]=tr;
1099                                 tex[1]=tg;
1100                                 tex[2]=tb;
1101                                 out[0]=har->r;
1102                                 out[1]=har->g;
1103                                 out[2]=har->b;
1104
1105                                 texture_rgb_blend(in,tex,out,tin,mtex->colfac,mtex->blendtype);
1106                         //      zn= 1.0-yn;
1107                                 //har->r= (yn*tr+ zn*ma->r);
1108                                 //har->g= (yn*tg+ zn*ma->g);
1109                                 //har->b= (yn*tb+ zn*ma->b);
1110                                 har->r= in[0];
1111                                 har->g= in[1];
1112                                 har->b= in[2];
1113                         }
1114                         if(mtex->mapto & MAP_ALPHA)
1115                                 har->alfa = texture_value_blend(mtex->def_var,har->alfa,tin,mtex->varfac,mtex->blendtype,mtex->maptoneg & MAP_ALPHA);
1116                         if(mtex->mapto & MAP_HAR)
1117                                 har->hard = 1.0+126.0*texture_value_blend(mtex->def_var,((float)har->hard)/127.0,tin,mtex->varfac,mtex->blendtype,mtex->maptoneg & MAP_HAR);
1118                         if(mtex->mapto & MAP_RAYMIRR)
1119                                 har->hasize = 100.0*texture_value_blend(mtex->def_var,har->hasize/100.0,tin,mtex->varfac,mtex->blendtype,mtex->maptoneg & MAP_RAYMIRR);
1120                         /* now what on earth is this good for?? */
1121                         //if(mtex->texco & 16) {
1122                         //      har->alfa= tin;
1123                         //}
1124                 }
1125
1126         return har;
1127 }
1128
1129 /* -------------------------- operations on entire database ----------------------- */
1130
1131 /* ugly function for halos in panorama */
1132 static int panotestclip(Render *re, int do_pano, float *v)
1133 {
1134         /* to be used for halos en infos */
1135         float abs4;
1136         short c=0;
1137
1138         if(do_pano==0) return testclip(v);
1139
1140         abs4= fabs(v[3]);
1141
1142         if(v[2]< -abs4) c=16;           /* this used to be " if(v[2]<0) ", see clippz() */
1143         else if(v[2]> abs4) c+= 32;
1144
1145         if( v[1]>abs4) c+=4;
1146         else if( v[1]< -abs4) c+=8;
1147
1148         abs4*= re->xparts;
1149         if( v[0]>abs4) c+=2;
1150         else if( v[0]< -abs4) c+=1;
1151
1152         return c;
1153 }
1154
1155 /*
1156   This adds the hcs coordinates to vertices. It iterates over all
1157   vertices, halos and faces. After the conversion, we clip in hcs.
1158
1159   Elsewhere, all primites are converted to vertices. 
1160   Called in 
1161   - envmapping (envmap.c)
1162   - shadow buffering (shadbuf.c)
1163 */
1164
1165 void project_renderdata(Render *re, void (*projectfunc)(float *, float mat[][4], float *),  int do_pano, float xoffs, int do_buckets)
1166 {
1167         ObjectRen *obr;
1168         HaloRen *har = NULL;
1169         float zn, vec[3], hoco[4];
1170         int a;
1171
1172         if(do_pano) {
1173                 float panophi= xoffs;
1174                 
1175                 re->panosi= sin(panophi);
1176                 re->panoco= cos(panophi);
1177         }
1178
1179         for(obr=re->objecttable.first; obr; obr=obr->next) {
1180                 /* calculate view coordinates (and zbuffer value) */
1181                 for(a=0; a<obr->tothalo; a++) {
1182                         if((a & 255)==0) har= obr->bloha[a>>8];
1183                         else har++;
1184
1185                         if(do_pano) {
1186                                 vec[0]= re->panoco*har->co[0] + re->panosi*har->co[2];
1187                                 vec[1]= har->co[1];
1188                                 vec[2]= -re->panosi*har->co[0] + re->panoco*har->co[2];
1189                         }
1190                         else {
1191                                 VECCOPY(vec, har->co);
1192                         }
1193
1194                         projectfunc(vec, re->winmat, hoco);
1195                         
1196                         /* we clip halos less critical, but not for the Z */
1197                         hoco[0]*= 0.5;
1198                         hoco[1]*= 0.5;
1199                         
1200                         if( panotestclip(re, do_pano, hoco) ) {
1201                                 har->miny= har->maxy= -10000;   /* that way render clips it */
1202                         }
1203                         else if(hoco[3]<0.0) {
1204                                 har->miny= har->maxy= -10000;   /* render clips it */
1205                         }
1206                         else /* do the projection...*/
1207                         {
1208                                 /* bring back hocos */
1209                                 hoco[0]*= 2.0;
1210                                 hoco[1]*= 2.0;
1211                                 
1212                                 zn= hoco[3];
1213                                 har->xs= 0.5*re->winx*(1.0+hoco[0]/zn); /* the 0.5 negates the previous 2...*/
1214                                 har->ys= 0.5*re->winy*(1.0+hoco[1]/zn);
1215                         
1216                                 /* this should be the zbuffer coordinate */
1217                                 har->zs= 0x7FFFFF*(hoco[2]/zn);
1218                                 /* taking this from the face clip functions? seems ok... */
1219                                 har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn);
1220                                 
1221                                 vec[0]+= har->hasize;
1222                                 projectfunc(vec, re->winmat, hoco);
1223                                 vec[0]-= har->hasize;
1224                                 zn= hoco[3];
1225                                 har->rad= fabs(har->xs- 0.5*re->winx*(1.0+hoco[0]/zn));
1226                         
1227                                 /* this clip is not really OK, to prevent stars to become too large */
1228                                 if(har->type & HA_ONLYSKY) {
1229                                         if(har->rad>3.0) har->rad= 3.0;
1230                                 }
1231                         
1232                                 har->radsq= har->rad*har->rad;
1233                         
1234                                 har->miny= har->ys - har->rad/re->ycor;
1235                                 har->maxy= har->ys + har->rad/re->ycor;
1236                         
1237                                 /* the Zd value is still not really correct for pano */
1238                         
1239                                 vec[2]-= har->hasize;   /* z negative, otherwise it's clipped */
1240                                 projectfunc(vec, re->winmat, hoco);
1241                                 zn= hoco[3];
1242                                 zn= fabs( (float)har->zs - 0x7FFFFF*(hoco[2]/zn));
1243                                 har->zd= CLAMPIS(zn, 0, INT_MAX);
1244                         
1245                         }
1246                         
1247                 }
1248         }
1249
1250         project_strands(re, projectfunc, do_pano, do_buckets);
1251 }
1252
1253 /* ------------------------------------------------------------------------- */
1254
1255 ObjectInstanceRen *RE_addRenderInstance(Render *re, ObjectRen *obr, Object *ob, Object *par, int index, int psysindex, float mat[][4])
1256 {
1257         ObjectInstanceRen *obi;
1258         float mat3[3][3];
1259
1260         obi= MEM_callocN(sizeof(ObjectInstanceRen), "ObjectInstanceRen");
1261         obi->obr= obr;
1262         obi->ob= ob;
1263         obi->par= par;
1264         obi->index= index;
1265         obi->psysindex= psysindex;
1266
1267         if(mat) {
1268                 Mat4CpyMat4(obi->mat, mat);
1269                 Mat3CpyMat4(mat3, mat);
1270                 Mat3Inv(obi->imat, mat3);
1271                 obi->flag |= R_DUPLI_TRANSFORMED;
1272         }
1273
1274         BLI_addtail(&re->instancetable, obi);
1275
1276         return obi;
1277 }
1278
1279 void RE_makeRenderInstances(Render *re)
1280 {
1281         ObjectInstanceRen *obi, *oldobi;
1282         ListBase newlist;
1283         int tot;
1284
1285         /* convert list of object instances to an array for index based lookup */
1286         tot= BLI_countlist(&re->instancetable);
1287         re->objectinstance= MEM_callocN(sizeof(ObjectInstanceRen)*tot, "ObjectInstance");
1288         re->totinstance= tot;
1289         newlist.first= newlist.last= NULL;
1290
1291         obi= re->objectinstance;
1292         for(oldobi=re->instancetable.first; oldobi; oldobi=oldobi->next) {
1293                 *obi= *oldobi;
1294
1295                 if(obi->obr) {
1296                         obi->prev= obi->next= NULL;
1297                         BLI_addtail(&newlist, obi);
1298                         obi++;
1299                 }
1300                 else
1301                         re->totinstance--;
1302         }
1303
1304         BLI_freelistN(&re->instancetable);
1305         re->instancetable= newlist;
1306 }
1307