6 * ***** BEGIN GPL LICENSE BLOCK *****
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23 * All rights reserved.
25 * The Original Code is: all of this file.
27 * Contributor(s): none yet.
29 * ***** END GPL LICENSE BLOCK *****
32 /** \file blender/blenkernel/intern/displist.c
41 #include "MEM_guardedalloc.h"
43 #include "DNA_curve_types.h"
44 #include "DNA_meshdata_types.h"
45 #include "DNA_scene_types.h"
46 #include "DNA_object_types.h"
47 #include "DNA_material_types.h"
49 #include "BLI_blenlib.h"
51 #include "BLI_editVert.h"
52 #include "BLI_scanfill.h"
53 #include "BLI_utildefines.h"
55 #include "BKE_global.h"
56 #include "BKE_displist.h"
57 #include "BKE_cdderivedmesh.h"
58 #include "BKE_object.h"
59 #include "BKE_mball.h"
60 #include "BKE_material.h"
61 #include "BKE_curve.h"
65 #include "BKE_lattice.h"
66 #include "BKE_modifier.h"
68 #include "RE_pipeline.h"
69 #include "RE_shader_ext.h"
71 #include "BLO_sys_types.h" // for intptr_t support
73 #include "ED_curve.h" /* for BKE_curve_nurbs */
75 extern Material defmaterial; /* material.c */
77 static void boundbox_displist(Object *ob);
79 void free_disp_elem(DispList *dl)
82 if(dl->verts) MEM_freeN(dl->verts);
83 if(dl->nors) MEM_freeN(dl->nors);
84 if(dl->index) MEM_freeN(dl->index);
85 if(dl->col1) MEM_freeN(dl->col1);
86 if(dl->col2) MEM_freeN(dl->col2);
87 if(dl->bevelSplitFlag) MEM_freeN(dl->bevelSplitFlag);
92 void freedisplist(ListBase *lb)
104 DispList *find_displist_create(ListBase *lb, int type)
110 if(dl->type==type) return dl;
114 dl= MEM_callocN(sizeof(DispList), "find_disp");
121 DispList *find_displist(ListBase *lb, int type)
127 if(dl->type==type) return dl;
134 int displist_has_faces(ListBase *lb)
137 for(dl= lb->first; dl; dl= dl->next) {
138 if ELEM3(dl->type, DL_INDEX3, DL_INDEX4, DL_SURF)
144 void copy_displist(ListBase *lbn, ListBase *lb)
153 dln= MEM_dupallocN(dl);
154 BLI_addtail(lbn, dln);
155 dln->verts= MEM_dupallocN(dl->verts);
156 dln->nors= MEM_dupallocN(dl->nors);
157 dln->index= MEM_dupallocN(dl->index);
158 dln->col1= MEM_dupallocN(dl->col1);
159 dln->col2= MEM_dupallocN(dl->col2);
161 if(dl->bevelSplitFlag)
162 dln->bevelSplitFlag= MEM_dupallocN(dl->bevelSplitFlag);
168 void addnormalsDispList(ListBase *lb)
171 float *vdata, *ndata, nor[3];
172 float *v1, *v2, *v3, *v4;
173 float *n1, *n2, *n3, *n4;
174 int a, b, p1, p2, p3, p4;
180 if(dl->type==DL_INDEX3) {
182 dl->nors= MEM_callocN(sizeof(float)*3, "dlnors");
183 if(dl->verts[2] < 0.0f) dl->nors[2]= -1.0f;
184 else dl->nors[2]= 1.0f;
187 else if(dl->type==DL_SURF) {
189 dl->nors= MEM_callocN(sizeof(float)*3*dl->nr*dl->parts, "dlnors");
194 for(a=0; a<dl->parts; a++) {
196 if (surfindex_displist(dl, a, &b, &p1, &p2, &p3, &p4)==0)
208 for(; b<dl->nr; b++) {
210 normal_quad_v3( nor,v1, v3, v4, v2);
235 void count_displist(ListBase *lb, int *totvert, int *totface)
244 *totvert+= dl->nr*dl->parts;
245 *totface+= (dl->nr-1)*(dl->parts-1);
250 *totface+= dl->parts;
254 *totvert+= dl->nr*dl->parts;
261 int surfindex_displist(DispList *dl, int a, int *b, int *p1, int *p2, int *p3, int *p4)
263 if((dl->flag & DL_CYCL_V)==0 && a==(dl->parts)-1) {
267 if(dl->flag & DL_CYCL_U) {
269 (*p2)= (*p1)+ dl->nr-1;
270 (*p3)= (*p1)+ dl->nr;
271 (*p4)= (*p2)+ dl->nr;
276 (*p4)= (*p2)+ dl->nr;
277 (*p3)= (*p1)+ dl->nr;
281 if( (dl->flag & DL_CYCL_V) && a==dl->parts-1) { \
282 (*p3)-= dl->nr*dl->parts; \
283 (*p4)-= dl->nr*dl->parts; \
289 /* ***************************** shade displist. note colors now are in rgb(a) order ******************** */
291 /* create default shade input... save cpu cycles with ugly global */
292 /* XXXX bad code warning: local ShadeInput initialize... */
293 static ShadeInput shi;
294 static void init_fastshade_shadeinput(Render *re)
296 memset(&shi, 0, sizeof(ShadeInput));
297 shi.lay= RE_GetScene(re)->lay;
299 shi.passflag= SCE_PASS_COMBINED;
300 shi.combinedflag= -1;
303 static Render *fastshade_get_render(Scene *UNUSED(scene))
305 // XXX 2.5: this crashes combined with previewrender
306 // due to global R so disabled for now
308 /* XXX ugly global still, but we can't do preview while rendering */
311 Render *re= RE_GetRender("_Shade View_");
313 re= RE_NewRender("_Shade View_");
315 RE_Database_Baking(re, scene, 0, 0); /* 0= no faces */
324 /* called on file reading */
325 void fastshade_free_render(void)
327 Render *re= RE_GetRender("_Shade View_");
330 RE_Database_Free(re);
335 static int fastshade_customdata_layer_num(int n, int active)
337 /* make the active layer the first */
338 if (n == active) return 0;
339 else if (n < active) return n+1;
343 static void fastshade_customdata(CustomData *fdata, int a, int j, Material *ma)
345 CustomDataLayer *layer;
347 int index, n, needuv= ma->texco & TEXCO_UV;
353 for(index=0; index<fdata->totlayer; index++) {
354 layer= &fdata->layers[index];
356 if(needuv && layer->type == CD_MTFACE && shi.totuv < MAX_MTFACE) {
357 n= fastshade_customdata_layer_num(shi.totuv, layer->active_rnd);
358 mtface= &((MTFace*)layer->data)[a];
360 shi.uv[shi.totuv].uv[0]= 2.0f*mtface->uv[j][0]-1.0f;
361 shi.uv[shi.totuv].uv[1]= 2.0f*mtface->uv[j][1]-1.0f;
362 shi.uv[shi.totuv].uv[2]= 1.0f;
364 shi.uv[shi.totuv].name= layer->name;
367 else if(layer->type == CD_MCOL && shi.totcol < MAX_MCOL) {
368 n= fastshade_customdata_layer_num(shi.totcol, layer->active_rnd);
369 vertcol= (char*)&((MCol*)layer->data)[a*4 + j];
371 shi.col[shi.totcol].col[0]= ((float)vertcol[3])/255.0f;
372 shi.col[shi.totcol].col[1]= ((float)vertcol[2])/255.0f;
373 shi.col[shi.totcol].col[2]= ((float)vertcol[1])/255.0f;
375 shi.col[shi.totcol].name= layer->name;
380 if(needuv && shi.totuv == 0)
381 VECCOPY(shi.uv[0].uv, shi.lo);
384 VECCOPY(shi.vcol, shi.col[0].col);
387 static void fastshade(float *co, float *nor, float *orco, Material *ma, char *col1, char *col2)
396 VECCOPY(shi.vno, shi.vn);
397 VECCOPY(shi.facenor, shi.vn);
400 VECCOPY(shi.lo, orco);
402 if(ma->texco & TEXCO_GLOB) {
403 VECCOPY(shi.gl, shi.lo);
405 if(ma->texco & TEXCO_WINDOW) {
406 VECCOPY(shi.winco, shi.lo);
408 if(ma->texco & TEXCO_STICKY) {
409 VECCOPY(shi.sticky, shi.lo);
411 if(ma->texco & TEXCO_OBJECT) {
412 VECCOPY(shi.co, shi.lo);
414 if(ma->texco & TEXCO_NORM) {
415 VECCOPY(shi.orn, shi.vn);
417 if(ma->texco & TEXCO_REFL) {
418 float inp= 2.0f * (shi.vn[2]);
419 shi.ref[0]= (inp*shi.vn[0]);
420 shi.ref[1]= (inp*shi.vn[1]);
421 shi.ref[2]= (-1.0f + inp*shi.vn[2]);
425 shi.mat= ma; /* set each time... node shaders change it */
426 RE_shade_external(NULL, &shi, &shr);
428 a= 256.0f*(shr.combined[0]);
429 col1[0]= CLAMPIS(a, 0, 255);
430 a= 256.0f*(shr.combined[1]);
431 col1[1]= CLAMPIS(a, 0, 255);
432 a= 256.0f*(shr.combined[2]);
433 col1[2]= CLAMPIS(a, 0, 255);
436 shi.vn[0]= -shi.vn[0];
437 shi.vn[1]= -shi.vn[1];
438 shi.vn[2]= -shi.vn[2];
440 shi.mat= ma; /* set each time... node shaders change it */
441 RE_shade_external(NULL, &shi, &shr);
443 a= 256.0f*(shr.combined[0]);
444 col2[0]= CLAMPIS(a, 0, 255);
445 a= 256.0f*(shr.combined[1]);
446 col2[1]= CLAMPIS(a, 0, 255);
447 a= 256.0f*(shr.combined[2]);
448 col2[2]= CLAMPIS(a, 0, 255);
452 static void init_fastshade_for_ob(Render *re, Object *ob, int *need_orco_r, float mat[4][4], float imat[3][3])
455 float amb[3]= {0.0f, 0.0f, 0.0f};
458 /* initialize globals in render */
459 RE_shade_external(re, NULL, NULL);
461 /* initialize global here */
462 init_fastshade_shadeinput(re);
464 RE_DataBase_GetView(re, tmat);
465 mul_m4_m4m4(mat, ob->obmat, tmat);
467 invert_m4_m4(tmat, mat);
468 copy_m3_m4(imat, tmat);
469 if(ob->transflag & OB_NEG_SCALE) mul_m3_fl(imat, -1.0);
471 if (need_orco_r) *need_orco_r= 0;
472 for(a=0; a<ob->totcol; a++) {
473 Material *ma= give_current_material(ob, a+1);
475 init_render_material(ma, 0, amb);
477 if(ma->texco & TEXCO_ORCO) {
478 if (need_orco_r) *need_orco_r= 1;
484 static void end_fastshade_for_ob(Object *ob)
488 for(a=0; a<ob->totcol; a++) {
489 Material *ma= give_current_material(ob, a+1);
491 end_render_material(ma);
496 static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, unsigned int **col1_r, unsigned int **col2_r)
502 unsigned int *col1, *col2;
503 float *orco, *vnors, *nors, imat[3][3], mat[4][4], vec[3];
504 int a, i, need_orco, totface, totvert;
505 CustomDataMask dataMask = CD_MASK_BAREMESH | CD_MASK_MCOL
506 | CD_MASK_MTFACE | CD_MASK_NORMAL;
509 init_fastshade_for_ob(re, ob, &need_orco, mat, imat);
512 dataMask |= CD_MASK_ORCO;
515 dm = mesh_get_derived_deform(RE_GetScene(re), ob, dataMask);
517 dm = mesh_get_derived_final(RE_GetScene(re), ob, dataMask);
519 mvert = dm->getVertArray(dm);
520 mface = dm->getTessFaceArray(dm);
521 nors = dm->getTessFaceDataArray(dm, CD_NORMAL);
522 totvert = dm->getNumVerts(dm);
523 totface = dm->getNumTessFaces(dm);
524 orco= dm->getVertDataArray(dm, CD_ORCO);
530 *col1_r = col1 = MEM_mallocN(sizeof(*col1)*totface*4, "col1");
532 if (col2_r && (me->flag & ME_TWOSIDED))
533 col2 = MEM_mallocN(sizeof(*col2)*totface*4, "col2");
537 if (col2_r) *col2_r = col2;
541 vnors= MEM_mallocN(totvert*3*sizeof(float), "vnors disp");
542 for (a=0; a<totvert; a++) {
543 MVert *mv = &mvert[a];
544 float *vn= &vnors[a*3];
550 vn[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
551 vn[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
552 vn[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
556 for (i=0; i<totface; i++) {
557 MFace *mf= &mface[i];
558 Material *ma= give_current_material(ob, mf->mat_nr+1);
559 int j, vidx[4], nverts= mf->v4?4:3;
560 unsigned char *col1base= (unsigned char*) &col1[i*4];
561 unsigned char *col2base= (unsigned char*) (col2?&col2[i*4]:NULL);
564 if(ma==NULL) ma= &defmaterial;
572 VECCOPY(nor, &nors[i*3]);
575 normal_quad_v3( nor,mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co);
577 normal_tri_v3( nor,mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co);
580 n1[0]= imat[0][0]*nor[0]+imat[0][1]*nor[1]+imat[0][2]*nor[2];
581 n1[1]= imat[1][0]*nor[0]+imat[1][1]*nor[1]+imat[1][2]*nor[2];
582 n1[2]= imat[2][0]*nor[0]+imat[2][1]*nor[1]+imat[2][2]*nor[2];
585 for (j=0; j<nverts; j++) {
586 MVert *mv= &mvert[vidx[j]];
587 char *col1= (char*)&col1base[j*4];
588 char *col2= (char*)(col2base?&col2base[j*4]:NULL);
589 float *vn = (mf->flag & ME_SMOOTH)?&vnors[3*vidx[j]]:n1;
591 mul_v3_m4v3(vec, mat, mv->co);
593 mul_v3_v3fl(vec, vn, 0.001f);
595 fastshade_customdata(&dm->faceData, i, j, ma);
596 fastshade(vec, vn, orco?&orco[vidx[j]*3]:mv->co, ma, col1, col2);
603 end_fastshade_for_ob(ob);
606 void shadeMeshMCol(Scene *scene, Object *ob, Mesh *me)
608 Render *re= fastshade_get_render(scene);
611 unsigned int *mcol= (unsigned int*)me->mcol;
614 mesh_create_shadedColors(re, ob, 1, &mcol, NULL);
615 me->mcol= (MCol*)mcol;
618 for(cp= (char *)me->mcol, a= 4*me->totface; a>0; a--, cp+=4) {
619 SWAP(char, cp[0], cp[3]);
620 SWAP(char, cp[1], cp[2]);
625 /* has base pointer, to check for layer */
626 /* called from drawobject.c */
627 void shadeDispList(Scene *scene, Base *base)
629 Object *ob= base->object;
633 float imat[3][3], mat[4][4], vec[3];
634 float *fp, *nor, n1[3];
638 re= fastshade_get_render(scene);
642 dl = find_displist(&ob->disp, DL_VERTCOL);
644 BLI_remlink(&ob->disp, dl);
648 if(ob->type==OB_MESH) {
649 dl= MEM_callocN(sizeof(DispList), "displistshade");
650 dl->type= DL_VERTCOL;
652 mesh_create_shadedColors(re, ob, 0, &dl->col1, &dl->col2);
654 /* add dl to ob->disp after mesh_create_shadedColors, because it
655 might indirectly free ob->disp */
656 BLI_addtail(&ob->disp, dl);
660 init_fastshade_for_ob(re, ob, &need_orco, mat, imat);
662 if (ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
664 /* now we need the normals */
668 dlob= MEM_callocN(sizeof(DispList), "displistshade");
669 BLI_addtail(&ob->disp, dlob);
670 dlob->type= DL_VERTCOL;
671 dlob->parts= dl->parts;
674 if(dl->type==DL_INDEX3) {
675 col1= dlob->col1= MEM_mallocN(sizeof(int)*dl->nr, "col1");
678 col1= dlob->col1= MEM_mallocN(sizeof(int)*dl->parts*dl->nr, "col1");
682 ma= give_current_material(ob, dl->col+1);
683 if(ma==NULL) ma= &defmaterial;
685 if(dl->type==DL_INDEX3) {
687 /* there's just one normal */
688 n1[0]= imat[0][0]*dl->nors[0]+imat[0][1]*dl->nors[1]+imat[0][2]*dl->nors[2];
689 n1[1]= imat[1][0]*dl->nors[0]+imat[1][1]*dl->nors[1]+imat[1][2]*dl->nors[2];
690 n1[2]= imat[2][0]*dl->nors[0]+imat[2][1]*dl->nors[1]+imat[2][2]*dl->nors[2];
697 mul_v3_m4v3(vec, mat, fp);
699 fastshade(vec, n1, fp, ma, (char *)col1, NULL);
705 else if(dl->type==DL_SURF) {
712 mul_v3_m4v3(vec, mat, fp);
714 n1[0]= imat[0][0]*nor[0]+imat[0][1]*nor[1]+imat[0][2]*nor[2];
715 n1[1]= imat[1][0]*nor[0]+imat[1][1]*nor[1]+imat[1][2]*nor[2];
716 n1[2]= imat[2][0]*nor[0]+imat[2][1]*nor[1]+imat[2][2]*nor[2];
719 fastshade(vec, n1, fp, ma, (char *)col1, NULL);
721 fp+= 3; nor+= 3; col1++;
728 else if(ob->type==OB_MBALL) {
729 /* there are normals already */
734 if(dl->type==DL_INDEX4) {
736 if(dl->col1) MEM_freeN(dl->col1);
737 col1= dl->col1= MEM_mallocN(sizeof(int)*dl->nr, "col1");
739 ma= give_current_material(ob, dl->col+1);
740 if(ma==NULL) ma= &defmaterial;
747 mul_v3_m4v3(vec, mat, fp);
750 n1[0]= imat[0][0]*nor[0]+imat[0][1]*nor[1]+imat[0][2]*nor[2];
751 n1[1]= imat[1][0]*nor[0]+imat[1][1]*nor[1]+imat[1][2]*nor[2];
752 n1[2]= imat[2][0]*nor[0]+imat[2][1]*nor[1]+imat[2][2]*nor[2];
755 fastshade(vec, n1, fp, ma, (char *)col1, NULL);
757 fp+= 3; col1++; nor+= 3;
765 end_fastshade_for_ob(ob);
769 /* frees render and shade part of displists */
770 /* note: dont do a shade again, until a redraw happens */
771 void reshadeall_displist(Scene *scene)
776 fastshade_free_render();
778 for(base= scene->base.first; base; base= base->next) {
781 if(ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL))
782 freedisplist(&ob->disp);
784 if(base->lay & scene->lay) {
785 /* Metaballs have standard displist at the Object */
786 if(ob->type==OB_MBALL) shadeDispList(scene, base);
791 /* ****************** make displists ********************* */
793 static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase, int forRender)
797 BezTriple *bezt, *prevbezt;
806 if(forRender && cu->resolu_ren!=0)
807 resolu= cu->resolu_ren;
811 if(!check_valid_nurb_u(nu));
812 else if(nu->type == CU_BEZIER) {
817 if(nu->flagu & CU_NURB_CYCLIC) a++;
822 if(a==0 && (nu->flagu & CU_NURB_CYCLIC)) bezt= nu->bezt;
824 if(prevbezt->h2==HD_VECT && bezt->h1==HD_VECT) len++;
827 if(a==0 && (nu->flagu & CU_NURB_CYCLIC)==0) len++;
833 dl= MEM_callocN(sizeof(DispList), "makeDispListbez");
834 /* len+1 because of 'forward_diff_bezier' function */
835 dl->verts= MEM_callocN( (len+1)*3*sizeof(float), "dlverts");
836 BLI_addtail(dispbase, dl);
840 dl->charidx= nu->charidx;
844 if(nu->flagu & CU_NURB_CYCLIC) {
857 if(a==0 && dl->type== DL_POLY) bezt= nu->bezt;
859 if(prevbezt->h2==HD_VECT && bezt->h1==HD_VECT) {
860 VECCOPY(data, prevbezt->vec[1]);
866 forward_diff_bezier( prevbezt->vec[1][j],
870 data+j, resolu, 3*sizeof(float));
876 if(a==0 && dl->type==DL_SEGM) {
877 VECCOPY(data, bezt->vec[1]);
884 else if(nu->type == CU_NURBS) {
885 len= (resolu*SEGMENTSU(nu));
887 dl= MEM_callocN(sizeof(DispList), "makeDispListsurf");
888 dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
889 BLI_addtail(dispbase, dl);
894 dl->charidx = nu->charidx;
897 if(nu->flagu & CU_NURB_CYCLIC) dl->type= DL_POLY;
898 else dl->type= DL_SEGM;
899 makeNurbcurve(nu, data, NULL, NULL, NULL, resolu, 3*sizeof(float));
901 else if(nu->type == CU_POLY) {
903 dl= MEM_callocN(sizeof(DispList), "makeDispListpoly");
904 dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
905 BLI_addtail(dispbase, dl);
909 dl->charidx = nu->charidx;
912 if(nu->flagu & CU_NURB_CYCLIC) dl->type= DL_POLY;
913 else dl->type= DL_SEGM;
918 VECCOPY(data, bp->vec);
929 void filldisplist(ListBase *dispbase, ListBase *to, int flipnormal)
931 EditVert *eve, *v1, *vlast;
933 DispList *dlnew=NULL, *dl;
935 int colnr=0, charidx=0, cont=1, tot, a, *index, nextcol= 0;
938 if(dispbase==NULL) return;
939 if(dispbase->first==NULL) return;
946 BLI_begin_edgefill();
951 if(dl->type==DL_POLY) {
952 if(charidx<dl->charidx) cont= 1;
953 else if(charidx==dl->charidx) { /* character with needed index */
955 /* make editverts and edges */
963 eve= BLI_addfillvert(f1);
966 if(vlast==NULL) v1= eve;
968 BLI_addfilledge(vlast, eve);
973 if(eve!=NULL && v1!=NULL) {
974 BLI_addfilledge(eve, v1);
976 } else if (colnr<dl->col) {
977 /* got poly with next material at current char */
986 if(totvert && (tot= BLI_edgefill(0))) { // XXX (obedit && obedit->actcol)?(obedit->actcol-1):0)) {
988 dlnew= MEM_callocN(sizeof(DispList), "filldisplist");
989 dlnew->type= DL_INDEX3;
994 dlnew->index= MEM_mallocN(tot*3*sizeof(int), "dlindex");
995 dlnew->verts= MEM_mallocN(totvert*3*sizeof(float), "dlverts");
1000 eve= fillvertbase.first;
1002 VECCOPY(f1, eve->co);
1006 eve->tmp.l = totvert;
1013 efa= fillfacebase.first;
1014 index= dlnew->index;
1016 index[0]= (intptr_t)efa->v1->tmp.l;
1017 index[1]= (intptr_t)efa->v2->tmp.l;
1018 index[2]= (intptr_t)efa->v3->tmp.l;
1021 SWAP(int, index[0], index[2]);
1028 BLI_addhead(to, dlnew);
1034 /* stay at current char but fill polys with next material */
1037 /* switch to next char and start filling from first material */
1043 /* do not free polys, needed for wireframe display */
1047 static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase)
1049 ListBase front, back;
1050 DispList *dl, *dlnew;
1054 front.first= front.last= back.first= back.last= NULL;
1056 dl= dispbase->first;
1058 if(dl->type==DL_SURF) {
1059 if( (dl->flag & DL_CYCL_V) && (dl->flag & DL_CYCL_U)==0 ) {
1060 if( (cu->flag & CU_BACK) && (dl->flag & DL_BACK_CURVE) ) {
1061 dlnew= MEM_callocN(sizeof(DispList), "filldisp");
1062 BLI_addtail(&front, dlnew);
1063 dlnew->verts= fp1= MEM_mallocN(sizeof(float)*3*dl->parts, "filldisp1");
1064 dlnew->nr= dl->parts;
1066 dlnew->type= DL_POLY;
1067 dlnew->col= dl->col;
1068 dlnew->charidx = dl->charidx;
1080 if( (cu->flag & CU_FRONT) && (dl->flag & DL_FRONT_CURVE) ) {
1081 dlnew= MEM_callocN(sizeof(DispList), "filldisp");
1082 BLI_addtail(&back, dlnew);
1083 dlnew->verts= fp1= MEM_mallocN(sizeof(float)*3*dl->parts, "filldisp1");
1084 dlnew->nr= dl->parts;
1086 dlnew->type= DL_POLY;
1087 dlnew->col= dl->col;
1088 dlnew->charidx= dl->charidx;
1090 fp= dl->verts+3*(dl->nr-1);
1105 filldisplist(&front, dispbase, 1);
1106 filldisplist(&back, dispbase, 0);
1108 freedisplist(&front);
1109 freedisplist(&back);
1111 filldisplist(dispbase, dispbase, 0);
1115 static void curve_to_filledpoly(Curve *cu, ListBase *UNUSED(nurb), ListBase *dispbase)
1117 if(cu->flag & CU_3D) return;
1119 if(dispbase->first && ((DispList*) dispbase->first)->type==DL_SURF) {
1120 bevels_to_filledpoly(cu, dispbase);
1123 filldisplist(dispbase, dispbase, 0);
1129 - first point left, last point right
1130 - based on subdivided points in original curve, not on points in taper curve (still)
1132 float calc_taper(Scene *scene, Object *taperobj, int cur, int tot)
1136 if(taperobj==NULL || taperobj->type!=OB_CURVE) return 1.0;
1138 dl= taperobj->disp.first;
1140 makeDispListCurveTypes(scene, taperobj, 0);
1141 dl= taperobj->disp.first;
1144 float fac= ((float)cur)/(float)(tot-1);
1145 float minx, dx, *fp;
1148 /* horizontal size */
1150 dx= dl->verts[3*(dl->nr-1)] - minx;
1154 for(a=0; a<dl->nr; a++, fp+=3) {
1155 if( (fp[0]-minx)/dx >= fac) {
1156 /* interpolate with prev */
1158 float fac1= (fp[-3]-minx)/dx;
1159 float fac2= (fp[0]-minx)/dx;
1161 return fp[1]*(fac1-fac)/(fac1-fac2) + fp[-2]*(fac-fac2)/(fac1-fac2);
1166 return fp[-2]; // last y coord
1173 void makeDispListMBall(Scene *scene, Object *ob)
1175 if(!ob || ob->type!=OB_MBALL) return;
1177 // XXX: mball stuff uses plenty of global variables
1178 // while this is unchanged updating during render is unsafe
1179 if(G.rendering) return;
1181 freedisplist(&(ob->disp));
1183 if(ob->type==OB_MBALL) {
1184 if(ob==find_basis_mball(scene, ob)) {
1185 metaball_polygonize(scene, ob, &ob->disp);
1186 tex_space_mball(ob);
1188 object_deform_mball(ob, &ob->disp);
1192 boundbox_displist(ob);
1195 void makeDispListMBall_forRender(Scene *scene, Object *ob, ListBase *dispbase)
1197 metaball_polygonize(scene, ob, dispbase);
1198 tex_space_mball(ob);
1200 object_deform_mball(ob, dispbase);
1203 static ModifierData *curve_get_tesselate_point(Scene *scene, Object *ob, int forRender, int editmode)
1205 ModifierData *md = modifiers_getVirtualModifierList(ob);
1206 ModifierData *preTesselatePoint;
1209 if(forRender) required_mode = eModifierMode_Render;
1210 else required_mode = eModifierMode_Realtime;
1212 if(editmode) required_mode |= eModifierMode_Editmode;
1214 preTesselatePoint = NULL;
1215 for (; md; md=md->next) {
1216 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1218 if (!modifier_isEnabled(scene, md, required_mode)) continue;
1219 if (mti->type == eModifierTypeType_Constructive) return preTesselatePoint;
1221 if (ELEM3(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_MeshDeform)) {
1222 preTesselatePoint = md;
1224 /* this modifiers are moving point of tesselation automatically
1225 (some of them even can't be applied on tesselated curve), set flag
1226 for incformation button in modifier's header */
1227 md->mode |= eModifierMode_ApplyOnSpline;
1228 } else if(md->mode&eModifierMode_ApplyOnSpline) {
1229 preTesselatePoint = md;
1233 return preTesselatePoint;
1236 static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, float (**originalVerts_r)[3], float (**deformedVerts_r)[3], int *numVerts_r)
1238 ModifierData *md = modifiers_getVirtualModifierList(ob);
1239 ModifierData *preTesselatePoint;
1240 Curve *cu= ob->data;
1241 ListBase *nurb= BKE_curve_nurbs(cu);
1243 int editmode = (!forRender && cu->editnurb);
1244 float (*originalVerts)[3] = NULL;
1245 float (*deformedVerts)[3] = NULL;
1246 float *keyVerts= NULL;
1249 if(forRender) required_mode = eModifierMode_Render;
1250 else required_mode = eModifierMode_Realtime;
1252 preTesselatePoint = curve_get_tesselate_point(scene, ob, forRender, editmode);
1254 if(editmode) required_mode |= eModifierMode_Editmode;
1256 if(cu->editnurb==NULL) {
1257 keyVerts= do_ob_key(scene, ob);
1260 /* split coords from key data, the latter also includes
1261 tilts, which is passed through in the modifier stack.
1262 this is also the reason curves do not use a virtual
1263 shape key modifier yet. */
1264 deformedVerts= curve_getKeyVertexCos(cu, nurb, keyVerts);
1265 originalVerts= MEM_dupallocN(deformedVerts);
1269 if (preTesselatePoint) {
1270 for (; md; md=md->next) {
1271 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1275 if ((md->mode & required_mode) != required_mode) continue;
1276 if (mti->isDisabled && mti->isDisabled(md, forRender)) continue;
1277 if (mti->type!=eModifierTypeType_OnlyDeform) continue;
1279 if (!deformedVerts) {
1280 deformedVerts = curve_getVertexCos(cu, nurb, &numVerts);
1281 originalVerts = MEM_dupallocN(deformedVerts);
1284 mti->deformVerts(md, ob, NULL, deformedVerts, numVerts, forRender, editmode);
1286 if (md==preTesselatePoint)
1292 curve_applyVertexCos(cu, nurb, deformedVerts);
1293 if (keyVerts) /* these are not passed through modifier stack */
1294 curve_applyKeyVertexTilts(cu, nurb, keyVerts);
1297 MEM_freeN(keyVerts);
1299 *originalVerts_r = originalVerts;
1300 *deformedVerts_r = deformedVerts;
1301 *numVerts_r = numVerts;
1304 static float (*displist_get_allverts (ListBase *dispbase, int *totvert))[3]
1307 float (*allverts)[3], *fp;
1311 for (dl=dispbase->first; dl; dl=dl->next)
1312 *totvert+= (dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr;
1314 allverts= MEM_mallocN((*totvert)*sizeof(float)*3, "displist_get_allverts allverts");
1315 fp= (float*)allverts;
1316 for (dl=dispbase->first; dl; dl=dl->next) {
1317 int offs= 3 * ((dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr);
1318 memcpy(fp, dl->verts, sizeof(float) * offs);
1325 static void displist_apply_allverts(ListBase *dispbase, float (*allverts)[3])
1330 fp= (float*)allverts;
1331 for (dl=dispbase->first; dl; dl=dl->next) {
1332 int offs= 3 * ((dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr);
1333 memcpy(dl->verts, fp, sizeof(float) * offs);
1338 static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispbase,
1339 DerivedMesh **derivedFinal, int forRender, float (*originalVerts)[3], float (*deformedVerts)[3])
1341 ModifierData *md = modifiers_getVirtualModifierList(ob);
1342 ModifierData *preTesselatePoint;
1343 Curve *cu= ob->data;
1344 ListBase *nurb= BKE_curve_nurbs(cu);
1345 int required_mode = 0, totvert = 0;
1346 int editmode = (!forRender && cu->editnurb);
1347 DerivedMesh *dm= NULL, *ndm;
1348 float (*vertCos)[3] = NULL;
1350 if(forRender) required_mode = eModifierMode_Render;
1351 else required_mode = eModifierMode_Realtime;
1353 preTesselatePoint = curve_get_tesselate_point(scene, ob, forRender, editmode);
1355 if(editmode) required_mode |= eModifierMode_Editmode;
1357 if (preTesselatePoint) {
1358 md = preTesselatePoint->next;
1361 if (derivedFinal && *derivedFinal) {
1362 (*derivedFinal)->release (*derivedFinal);
1365 for (; md; md=md->next) {
1366 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1370 if ((md->mode & required_mode) != required_mode) continue;
1371 if (mti->isDisabled && mti->isDisabled(md, forRender)) continue;
1373 if (mti->type == eModifierTypeType_OnlyDeform ||
1374 (mti->type == eModifierTypeType_DeformOrConstruct && !dm)) {
1377 totvert = dm->getNumVerts(dm);
1378 vertCos = MEM_mallocN(sizeof(*vertCos) * totvert, "dfmv");
1379 dm->getVertCos(dm, vertCos);
1382 mti->deformVerts(md, ob, dm, vertCos, totvert, forRender, editmode);
1385 vertCos= displist_get_allverts(dispbase, &totvert);
1388 mti->deformVerts(md, ob, NULL, vertCos, totvert, forRender, editmode);
1391 if (!derivedFinal) {
1392 /* makeDisplistCurveTypes could be used for beveling, where derived mesh */
1393 /* is totally unnecessary, so we could stop modifiers applying */
1394 /* when we found constructive modifier but derived mesh is unwanted result */
1400 DerivedMesh *tdm = CDDM_copy(dm, 0);
1404 CDDM_apply_vert_coords(dm, vertCos);
1405 CDDM_calc_normals(dm);
1409 displist_apply_allverts(dispbase, vertCos);
1412 if (ELEM(ob->type, OB_CURVE, OB_FONT) && (cu->flag & CU_DEFORM_FILL)) {
1413 curve_to_filledpoly(cu, nurb, dispbase);
1416 dm= CDDM_from_curve_customDB(ob, dispbase);
1418 CDDM_calc_normals(dm);
1422 /* Vertex coordinates were applied to necessary data, could free it */
1427 ndm = mti->applyModifier(md, ob, dm, forRender, editmode);
1430 /* Modifier returned a new derived mesh */
1432 if (dm && dm != ndm) /* Modifier */
1441 DerivedMesh *tdm = CDDM_copy(dm, 0);
1445 CDDM_apply_vert_coords(dm, vertCos);
1446 CDDM_calc_normals(dm);
1449 displist_apply_allverts(dispbase, vertCos);
1456 (*derivedFinal) = dm;
1459 if (deformedVerts) {
1460 curve_applyVertexCos(ob->data, nurb, originalVerts);
1461 MEM_freeN(originalVerts);
1462 MEM_freeN(deformedVerts);
1466 static void displist_surf_indices(DispList *dl)
1468 int a, b, p1, p2, p3, p4;
1473 index=dl->index= MEM_mallocN( 4*sizeof(int)*(dl->parts+1)*(dl->nr+1), "index array nurbs");
1475 for(a=0; a<dl->parts; a++) {
1477 if (surfindex_displist(dl, a, &b, &p1, &p2, &p3, &p4)==0)
1480 for(; b<dl->nr; b++, index+=4) {
1496 static DerivedMesh *create_orco_dm(Scene *scene, Object *ob)
1499 ListBase disp= {NULL, NULL};
1501 /* OrcoDM should be created from underformed disp lists */
1502 makeDispListCurveTypes_forOrco(scene, ob, &disp);
1503 dm= CDDM_from_curve_customDB(ob, &disp);
1505 freedisplist(&disp);
1510 static void add_orco_dm(Scene *scene, Object *ob, DerivedMesh *dm, DerivedMesh *orcodm)
1512 float (*orco)[3], (*layerorco)[3];
1514 Curve *cu= ob->data;
1516 totvert= dm->getNumVerts(dm);
1519 orco= MEM_callocN(sizeof(float)*3*totvert, "dm orco");
1521 if(orcodm->getNumVerts(orcodm) == totvert)
1522 orcodm->getVertCos(orcodm, orco);
1524 dm->getVertCos(dm, orco);
1527 orco= (float(*)[3])make_orco_curve(scene, ob);
1530 for(a=0; a<totvert; a++) {
1531 float *co = orco[a];
1532 co[0] = (co[0]-cu->loc[0])/cu->size[0];
1533 co[1] = (co[1]-cu->loc[1])/cu->size[1];
1534 co[2] = (co[2]-cu->loc[2])/cu->size[2];
1537 if((layerorco = DM_get_vert_data_layer(dm, CD_ORCO))) {
1538 memcpy(layerorco, orco, sizeof(float)*totvert);
1542 DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, orco);
1545 static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *derivedFinal, int forRender)
1547 /* this function represents logic of mesh's orcodm calculation */
1548 /* for displist-based objects */
1550 ModifierData *md = modifiers_getVirtualModifierList(ob);
1551 ModifierData *preTesselatePoint;
1552 Curve *cu= ob->data;
1554 int editmode = (!forRender && cu->editnurb);
1555 DerivedMesh *ndm, *orcodm= NULL;
1557 if(forRender) required_mode = eModifierMode_Render;
1558 else required_mode = eModifierMode_Realtime;
1560 preTesselatePoint = curve_get_tesselate_point(scene, ob, forRender, editmode);
1562 if(editmode) required_mode |= eModifierMode_Editmode;
1564 if (preTesselatePoint) {
1565 md = preTesselatePoint->next;
1568 for (; md; md=md->next) {
1569 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1573 if ((md->mode & required_mode) != required_mode) continue;
1574 if (mti->isDisabled && mti->isDisabled(md, forRender)) continue;
1575 if (mti->type!=eModifierTypeType_Constructive) continue;
1578 orcodm= create_orco_dm(scene, ob);
1580 ndm = mti->applyModifier(md, ob, orcodm, forRender, 0);
1583 /* if the modifier returned a new dm, release the old one */
1584 if(orcodm && orcodm != ndm) {
1585 orcodm->release(orcodm);
1591 /* add an orco layer if needed */
1592 add_orco_dm(scene, ob, derivedFinal, orcodm);
1595 orcodm->release(orcodm);
1598 void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase,
1599 DerivedMesh **derivedFinal, int forRender, int forOrco)
1603 Curve *cu = ob->data;
1608 float (*originalVerts)[3];
1609 float (*deformedVerts)[3];
1611 if(!forRender && cu->editnurb)
1612 nubase= ED_curve_editnurbs(cu);
1617 curve_calc_modifiers_pre(scene, ob, forRender, &originalVerts, &deformedVerts, &numVerts);
1619 for (nu=nubase->first; nu; nu=nu->next) {
1620 if(forRender || nu->hide==0) {
1621 int resolu= nu->resolu, resolv= nu->resolv;
1624 if(cu->resolu_ren) resolu= cu->resolu_ren;
1625 if(cu->resolv_ren) resolv= cu->resolv_ren;
1629 len= SEGMENTSU(nu)*resolu;
1631 dl= MEM_callocN(sizeof(DispList), "makeDispListsurf");
1632 dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
1634 BLI_addtail(dispbase, dl);
1637 dl->col= nu->mat_nr;
1638 dl->charidx= nu->charidx;
1640 /* dl->rt will be used as flag for render face and */
1641 /* CU_2D conflicts with R_NOPUNOFLIP */
1642 dl->rt= nu->flag & ~CU_2D;
1645 if(nu->flagu & CU_NURB_CYCLIC) dl->type= DL_POLY;
1646 else dl->type= DL_SEGM;
1648 makeNurbcurve(nu, data, NULL, NULL, NULL, resolu, 3*sizeof(float));
1651 len= (nu->pntsu*resolu) * (nu->pntsv*resolv);
1653 dl= MEM_callocN(sizeof(DispList), "makeDispListsurf");
1654 dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
1655 BLI_addtail(dispbase, dl);
1657 dl->col= nu->mat_nr;
1658 dl->charidx= nu->charidx;
1660 /* dl->rt will be used as flag for render face and */
1661 /* CU_2D conflicts with R_NOPUNOFLIP */
1662 dl->rt= nu->flag & ~CU_2D;
1667 dl->parts= (nu->pntsu*resolu); /* in reverse, because makeNurbfaces works that way */
1668 dl->nr= (nu->pntsv*resolv);
1669 if(nu->flagv & CU_NURB_CYCLIC) dl->flag|= DL_CYCL_U; /* reverse too! */
1670 if(nu->flagu & CU_NURB_CYCLIC) dl->flag|= DL_CYCL_V;
1672 makeNurbfaces(nu, data, 0, resolu, resolv);
1674 /* gl array drawing: using indices */
1675 displist_surf_indices(dl);
1680 /* make copy of 'undeformed" displist for texture space calculation
1681 actually, it's not totally undeformed -- pre-tesselation modifiers are
1682 already applied, thats how it worked for years, so keep for compatibility (sergey) */
1683 copy_displist(&cu->disp, dispbase);
1686 tex_space_curve(cu);
1690 curve_calc_modifiers_post(scene, ob, dispbase, derivedFinal,
1691 forRender, originalVerts, deformedVerts);
1694 static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispbase,
1695 DerivedMesh **derivedFinal, int forRender, int forOrco)
1697 Curve *cu = ob->data;
1699 /* we do allow duplis... this is only displist on curve level */
1700 if(!ELEM3(ob->type, OB_SURF, OB_CURVE, OB_FONT)) return;
1702 if(ob->type==OB_SURF) {
1703 makeDispListSurf(scene, ob, dispbase, derivedFinal, forRender, forOrco);
1705 else if (ELEM(ob->type, OB_CURVE, OB_FONT)) {
1708 float (*originalVerts)[3];
1709 float (*deformedVerts)[3];
1712 nubase= BKE_curve_nurbs(cu);
1714 BLI_freelistN(&(cu->bev));
1716 if(cu->path) free_path(cu->path);
1719 if(ob->type==OB_FONT) BKE_text_to_curve(scene, ob, 0);
1721 if(!forOrco) curve_calc_modifiers_pre(scene, ob, forRender, &originalVerts, &deformedVerts, &numVerts);
1725 /* If curve has no bevel will return nothing */
1726 makebevelcurve(scene, ob, &dlbev, forRender);
1728 /* no bevel or extrude, and no width correction? */
1729 if (!dlbev.first && cu->width==1.0f) {
1730 curve_to_displist(cu, nubase, dispbase, forRender);
1732 float widfac= cu->width - 1.0f;
1733 BevList *bl= cu->bev.first;
1734 Nurb *nu= nubase->first;
1736 for (; bl && nu; bl=bl->next,nu=nu->next) {
1742 if (bl->nr) { /* blank bevel lists can happen */
1744 /* exception handling; curve without bevel or extrude, with width correction */
1745 if(dlbev.first==NULL) {
1746 dl= MEM_callocN(sizeof(DispList), "makeDispListbev");
1747 dl->verts= MEM_callocN(3*sizeof(float)*bl->nr, "dlverts");
1748 BLI_addtail(dispbase, dl);
1750 if(bl->poly!= -1) dl->type= DL_POLY;
1751 else dl->type= DL_SEGM;
1753 if(dl->type==DL_SEGM) dl->flag = (DL_FRONT_CURVE|DL_BACK_CURVE);
1757 dl->col= nu->mat_nr;
1758 dl->charidx= nu->charidx;
1760 /* dl->rt will be used as flag for render face and */
1761 /* CU_2D conflicts with R_NOPUNOFLIP */
1762 dl->rt= nu->flag & ~CU_2D;
1765 bevp= (BevPoint *)(bl+1);
1768 data[0]= bevp->vec[0]+widfac*bevp->sina;
1769 data[1]= bevp->vec[1]+widfac*bevp->cosa;
1770 data[2]= bevp->vec[2];
1778 for (dlb=dlbev.first; dlb; dlb=dlb->next) {
1780 /* for each part of the bevel use a separate displblock */
1781 dl= MEM_callocN(sizeof(DispList), "makeDispListbev1");
1782 dl->verts= data= MEM_callocN(3*sizeof(float)*dlb->nr*bl->nr, "dlverts");
1783 BLI_addtail(dispbase, dl);
1787 dl->flag= dlb->flag & (DL_FRONT_CURVE|DL_BACK_CURVE);
1788 if(dlb->type==DL_POLY) dl->flag |= DL_CYCL_U;
1789 if(bl->poly>=0) dl->flag |= DL_CYCL_V;
1793 dl->col= nu->mat_nr;
1794 dl->charidx= nu->charidx;
1796 /* dl->rt will be used as flag for render face and */
1797 /* CU_2D conflicts with R_NOPUNOFLIP */
1798 dl->rt= nu->flag & ~CU_2D;
1800 dl->bevelSplitFlag= MEM_callocN(sizeof(*dl->col2)*((bl->nr+0x1F)>>5), "bevelSplitFlag");
1802 /* for each point of poly make a bevel piece */
1803 bevp= (BevPoint *)(bl+1);
1804 for(a=0; a<bl->nr; a++,bevp++) {
1806 if (cu->taperobj==NULL) {
1807 if ( (cu->bevobj!=NULL) || !((cu->flag & CU_FRONT) || (cu->flag & CU_BACK)) )
1810 fac = calc_taper(scene, cu->taperobj, a, bl->nr);
1813 if (bevp->split_tag) {
1814 dl->bevelSplitFlag[a>>5] |= 1<<(a&0x1F);
1817 /* rotate bevel piece and write in data */
1819 for (b=0; b<dlb->nr; b++,fp1+=3,data+=3) {
1820 if(cu->flag & CU_3D) {
1823 vec[0]= fp1[1]+widfac;
1827 mul_qt_v3(bevp->quat, vec);
1829 data[0]= bevp->vec[0] + fac*vec[0];
1830 data[1]= bevp->vec[1] + fac*vec[1];
1831 data[2]= bevp->vec[2] + fac*vec[2];
1834 data[0]= bevp->vec[0] + fac*(widfac+fp1[1])*bevp->sina;
1835 data[1]= bevp->vec[1] + fac*(widfac+fp1[1])*bevp->cosa;
1836 data[2]= bevp->vec[2] + fac*fp1[2];
1841 /* gl array drawing: using indices */
1842 displist_surf_indices(dl);
1848 freedisplist(&dlbev);
1851 if (!(cu->flag & CU_DEFORM_FILL)) {
1852 curve_to_filledpoly(cu, nubase, dispbase);
1855 if(cu->flag & CU_PATH) calc_curvepath(ob);
1857 /* make copy of 'undeformed" displist for texture space calculation
1858 actually, it's not totally undeformed -- pre-tesselation modifiers are
1859 already applied, thats how it worked for years, so keep for compatibility (sergey) */
1860 copy_displist(&cu->disp, dispbase);
1863 tex_space_curve(cu);
1866 if(!forOrco) curve_calc_modifiers_post(scene, ob, dispbase, derivedFinal, forRender, originalVerts, deformedVerts);
1868 if (cu->flag & CU_DEFORM_FILL && !ob->derivedFinal) {
1869 curve_to_filledpoly(cu, nubase, dispbase);
1874 void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco)
1876 Curve *cu= ob->data;
1879 freedisplist(&(ob->disp));
1880 dispbase= &(ob->disp);
1881 freedisplist(dispbase);
1883 /* free displist used for textspace */
1884 freedisplist(&cu->disp);
1886 do_makeDispListCurveTypes(scene, ob, dispbase, &ob->derivedFinal, 0, forOrco);
1888 if (ob->derivedFinal) {
1889 DM_set_object_boundbox (ob, ob->derivedFinal);
1891 boundbox_displist (ob);
1893 /* if there is no derivedMesh, object's boundbox is unneeded */
1901 void makeDispListCurveTypes_forRender(Scene *scene, Object *ob, ListBase *dispbase,
1902 DerivedMesh **derivedFinal, int forOrco)
1904 do_makeDispListCurveTypes(scene, ob, dispbase, derivedFinal, 1, forOrco);
1907 void makeDispListCurveTypes_forOrco(struct Scene *scene, struct Object *ob, struct ListBase *dispbase)
1909 do_makeDispListCurveTypes(scene, ob, dispbase, NULL, 1, 1);
1912 /* add Orco layer to the displist object which has got derived mesh and return orco */
1913 float *makeOrcoDispList(Scene *scene, Object *ob, DerivedMesh *derivedFinal, int forRender) {
1916 if (derivedFinal == NULL)
1917 derivedFinal= ob->derivedFinal;
1919 if (!derivedFinal->getVertDataArray(derivedFinal, CD_ORCO)) {
1920 curve_calc_orcodm(scene, ob, derivedFinal, forRender);
1923 orco= derivedFinal->getVertDataArray(derivedFinal, CD_ORCO);
1926 orco= MEM_dupallocN(orco);
1932 /* this is confusing, there's also min_max_object, appplying the obmat... */
1933 static void boundbox_displist(Object *ob)
1936 float min[3], max[3];
1941 INIT_MINMAX(min, max);
1943 if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
1944 Curve *cu= ob->data;
1947 if(cu->bb==NULL) cu->bb= MEM_callocN(sizeof(BoundBox), "boundbox");
1953 if(dl->type==DL_INDEX3) tot= dl->nr;
1954 else tot= dl->nr*dl->parts;
1957 for(a=0; a<tot; a++, vert+=3) {
1959 DO_MINMAX(vert, min, max);
1966 /* there's no geometry in displist, use zero-sized boundbox */
1974 boundbox_set_from_min_max(bb, min, max);