6 * ***** BEGIN GPL/BL DUAL 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. The Blender
12 * Foundation also sells licenses for use in proprietary software under
13 * the Blender License. See http://www.blender.org/BL/ for information
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software Foundation,
23 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
26 * All rights reserved.
28 * The Original Code is: all of this file.
30 * Contributor(s): none yet.
32 * ***** END GPL/BL DUAL LICENSE BLOCK *****
39 #include "MEM_guardedalloc.h"
41 #include "IMB_imbuf_types.h"
43 #include "DNA_texture_types.h"
44 #include "DNA_meta_types.h"
45 #include "DNA_curve_types.h"
46 #include "DNA_effect_types.h"
47 #include "DNA_listBase.h"
48 #include "DNA_lamp_types.h"
49 #include "DNA_object_types.h"
50 #include "DNA_object_force.h"
51 #include "DNA_mesh_types.h"
52 #include "DNA_meshdata_types.h"
53 #include "DNA_modifier_types.h"
54 #include "DNA_scene_types.h"
55 #include "DNA_image_types.h"
56 #include "DNA_material_types.h"
57 #include "DNA_view3d_types.h"
58 #include "DNA_lattice_types.h"
59 #include "DNA_key_types.h"
61 #include "BLI_blenlib.h"
62 #include "BLI_arithb.h"
63 #include "BLI_editVert.h"
64 #include "BLI_edgehash.h"
66 #include "BKE_bad_level_calls.h"
67 #include "BKE_utildefines.h"
68 #include "BKE_global.h"
69 #include "BKE_displist.h"
70 #include "BKE_deform.h"
71 #include "BKE_DerivedMesh.h"
72 #include "BKE_object.h"
73 #include "BKE_world.h"
75 #include "BKE_effect.h"
76 #include "BKE_mball.h"
77 #include "BKE_material.h"
78 #include "BKE_curve.h"
81 #include "BKE_screen.h"
82 #include "BKE_texture.h"
83 #include "BKE_library.h"
85 #include "BKE_lattice.h"
86 #include "BKE_scene.h"
87 #include "BKE_subsurf.h"
88 #include "BKE_modifier.h"
90 #include "RE_pipeline.h"
91 #include "RE_shader_ext.h"
94 static void boundbox_displist(Object *ob);
96 void displistmesh_free(DispListMesh *dlm)
98 // also check on mvert and mface, can be NULL after decimator (ton)
99 if (!dlm->dontFreeVerts && dlm->mvert) MEM_freeN(dlm->mvert);
100 if (!dlm->dontFreeNors && dlm->nors) MEM_freeN(dlm->nors);
101 if (!dlm->dontFreeOther) {
102 if (dlm->medge) MEM_freeN(dlm->medge);
103 if (dlm->mface) MEM_freeN(dlm->mface);
104 if (dlm->mcol) MEM_freeN(dlm->mcol);
105 if (dlm->tface) MEM_freeN(dlm->tface);
110 DispListMesh *displistmesh_copy(DispListMesh *odlm)
112 DispListMesh *ndlm= MEM_dupallocN(odlm);
113 ndlm->mvert= MEM_dupallocN(odlm->mvert);
114 if (odlm->medge) ndlm->medge= MEM_dupallocN(odlm->medge);
115 ndlm->mface= MEM_dupallocN(odlm->mface);
116 if (odlm->nors) ndlm->nors = MEM_dupallocN(odlm->nors);
117 if (odlm->mcol) ndlm->mcol= MEM_dupallocN(odlm->mcol);
118 if (odlm->tface) ndlm->tface= MEM_dupallocN(odlm->tface);
123 DispListMesh *displistmesh_copyShared(DispListMesh *odlm)
125 DispListMesh *ndlm= MEM_dupallocN(odlm);
126 ndlm->dontFreeNors = ndlm->dontFreeOther = ndlm->dontFreeVerts = 1;
131 void displistmesh_to_mesh(DispListMesh *dlm, Mesh *me)
133 /* We assume, rather courageously, that any
134 * shared data came from the mesh itself and so
135 * we can ignore the dlm->dontFreeOther flag.
138 if (me->mvert && dlm->mvert!=me->mvert) MEM_freeN(me->mvert);
139 if (me->mface && dlm->mface!=me->mface) MEM_freeN(me->mface);
140 if (me->tface && dlm->tface!=me->tface) MEM_freeN(me->tface);
141 if (me->mcol && dlm->mcol!=me->mcol) MEM_freeN(me->mcol);
142 if (me->medge && dlm->medge!=me->medge) MEM_freeN(me->medge);
148 if (dlm->totvert!=me->totvert) {
149 if (me->msticky) MEM_freeN(me->msticky);
152 if (me->dvert) free_dverts(me->dvert, me->totvert);
155 if(me->key) me->key->id.us--;
159 me->totface= dlm->totface;
160 me->totvert= dlm->totvert;
163 me->mvert= dlm->mvert;
164 me->mface= dlm->mface;
166 me->tface= dlm->tface;
171 me->totedge= dlm->totedge;
172 me->medge= dlm->medge;
175 if (dlm->nors && !dlm->dontFreeNors) MEM_freeN(dlm->nors);
180 void free_disp_elem(DispList *dl)
183 if(dl->verts) MEM_freeN(dl->verts);
184 if(dl->nors) MEM_freeN(dl->nors);
185 if(dl->index) MEM_freeN(dl->index);
186 if(dl->col1) MEM_freeN(dl->col1);
187 if(dl->col2) MEM_freeN(dl->col2);
188 if(dl->bevelSplitFlag) MEM_freeN(dl->bevelSplitFlag);
193 void freedisplist(ListBase *lb)
205 DispList *find_displist_create(ListBase *lb, int type)
211 if(dl->type==type) return dl;
215 dl= MEM_callocN(sizeof(DispList), "find_disp");
222 DispList *find_displist(ListBase *lb, int type)
228 if(dl->type==type) return dl;
235 int displist_has_faces(ListBase *lb)
241 if ELEM3(dl->type, DL_INDEX3, DL_INDEX4, DL_SURF)
248 void copy_displist(ListBase *lbn, ListBase *lb)
252 lbn->first= lbn->last= 0;
257 dln= MEM_dupallocN(dl);
258 BLI_addtail(lbn, dln);
259 dln->verts= MEM_dupallocN(dl->verts);
260 dln->nors= MEM_dupallocN(dl->nors);
261 dln->index= MEM_dupallocN(dl->index);
262 dln->col1= MEM_dupallocN(dl->col1);
263 dln->col2= MEM_dupallocN(dl->col2);
269 void addnormalsDispList(Object *ob, ListBase *lb)
272 float *vdata, *ndata, nor[3];
273 float *v1, *v2, *v3, *v4;
274 float *n1, *n2, *n3, *n4;
275 int a, b, p1, p2, p3, p4;
281 if(dl->type==DL_INDEX3) {
283 dl->nors= MEM_callocN(sizeof(float)*3, "dlnors");
284 if(dl->verts[2]<0.0) dl->nors[2]= -1.0;
285 else dl->nors[2]= 1.0;
288 else if(dl->type==DL_SURF) {
290 dl->nors= MEM_callocN(sizeof(float)*3*dl->nr*dl->parts, "dlnors");
295 for(a=0; a<dl->parts; a++) {
297 DL_SURFINDEX(dl->flag & DL_CYCL_U, dl->flag & DL_CYCL_V, dl->nr, dl->parts);
308 for(; b<dl->nr; b++) {
310 CalcNormFloat4(v1, v3, v4, v2, nor);
312 VecAddf(n1, n1, nor);
313 VecAddf(n2, n2, nor);
314 VecAddf(n3, n3, nor);
315 VecAddf(n4, n4, nor);
335 void count_displist(ListBase *lb, int *totvert, int *totface)
344 *totvert+= dl->nr*dl->parts;
345 *totface+= (dl->nr-1)*(dl->parts-1);
350 *totface+= dl->parts;
354 *totvert+= dl->nr*dl->parts;
362 /* ***************************** shade displist ******************** */
364 /* create default shade input... save cpu cycles with ugly global */
365 static ShadeInput shi;
366 static void init_fastshade_shadeinput(void)
369 memset(&shi, 0, sizeof(ShadeInput));
370 shi.lay= G.scene->lay;
374 static Render *fastshade_get_render(void)
376 Render *re= RE_GetRender("_Shade View_");
378 re= RE_NewRender("_Shade View_");
380 RE_Database_Shaded(re, G.scene);
385 /* called on file reading */
386 void fastshade_free_render(void)
388 Render *re= RE_GetRender("_Shade View_");
391 RE_Database_Free(re);
396 static void fastshade(float *co, float *nor, float *orco, Material *ma, char *col1, char *col2, char *vertcol)
402 shi.vcol[0]= ((float)vertcol[3])/255.0f;
403 shi.vcol[1]= ((float)vertcol[2])/255.0f;
404 shi.vcol[2]= ((float)vertcol[1])/255.0f;
411 VECCOPY(shi.vno, shi.vn);
414 VECCOPY(shi.lo, orco);
416 if(ma->texco & TEXCO_GLOB) {
417 VECCOPY(shi.gl, shi.lo);
419 if(ma->texco & TEXCO_WINDOW) {
420 VECCOPY(shi.winco, shi.lo);
422 if(ma->texco & TEXCO_STICKY) {
423 VECCOPY(shi.sticky, shi.lo);
425 if(ma->texco & TEXCO_UV) {
426 VECCOPY(shi.uv, shi.lo);
428 if(ma->texco & TEXCO_OBJECT) {
429 VECCOPY(shi.co, shi.lo);
431 if(ma->texco & TEXCO_NORM) {
432 VECCOPY(shi.orn, shi.vn);
434 if(ma->texco & TEXCO_REFL) {
435 float inp= 2.0*(shi.vn[2]);
436 shi.ref[0]= (inp*shi.vn[0]);
437 shi.ref[1]= (inp*shi.vn[1]);
438 shi.ref[2]= (-1.0+inp*shi.vn[2]);
442 shi.mat= ma; /* set each time... node shaders change it */
443 RE_shade_external(NULL, &shi, &shr);
445 VECADD(shr.combined, shr.diff, shr.spec);
447 a= 256.0f*(shr.combined[0]);
448 col1[3]= CLAMPIS(a, 0, 255);
449 a= 256.0f*(shr.combined[1]);
450 col1[2]= CLAMPIS(a, 0, 255);
451 a= 256.0f*(shr.combined[2]);
452 col1[1]= CLAMPIS(a, 0, 255);
455 shi.vn[0]= -shi.vn[0];
456 shi.vn[1]= -shi.vn[1];
457 shi.vn[2]= -shi.vn[2];
459 shi.mat= ma; /* set each time... node shaders change it */
460 RE_shade_external(NULL, &shi, &shr);
462 VECADD(shr.combined, shr.diff, shr.spec);
464 a= 256.0f*(shr.combined[0]);
465 col2[3]= CLAMPIS(a, 0, 255);
466 a= 256.0f*(shr.combined[1]);
467 col2[2]= CLAMPIS(a, 0, 255);
468 a= 256.0f*(shr.combined[2]);
469 col2[1]= CLAMPIS(a, 0, 255);
473 static void init_fastshade_for_ob(Render *re, Object *ob, int *need_orco_r, float mat[4][4], float imat[3][3])
476 float amb[3]= {0.0f, 0.0f, 0.0f};
479 /* initialize globals in render */
480 RE_shade_external(re, NULL, NULL);
482 /* initialize global here */
483 init_fastshade_shadeinput();
485 RE_DataBase_GetView(re, tmat);
486 Mat4MulMat4(mat, ob->obmat, tmat);
488 Mat4Invert(tmat, mat);
489 Mat3CpyMat4(imat, tmat);
490 if(ob->transflag & OB_NEG_SCALE) Mat3MulFloat((float *)imat, -1.0);
492 if (need_orco_r) *need_orco_r= 0;
493 for(a=0; a<ob->totcol; a++) {
494 Material *ma= give_current_material(ob, a+1);
496 init_render_material(ma, 0, amb);
498 if(ma->texco & TEXCO_ORCO) {
499 if (need_orco_r) *need_orco_r= 1;
505 static void end_fastshade_for_ob(Object *ob)
509 for(a=0; a<ob->totcol; a++) {
510 Material *ma= give_current_material(ob, a+1);
512 end_render_material(ma);
517 static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, unsigned int **col1_r, unsigned int **col2_r)
523 unsigned int *col1, *col2;
524 float *orco, *vnors, imat[3][3], mat[4][4], vec[3];
527 init_fastshade_for_ob(re, ob, &need_orco, mat, imat);
530 orco = mesh_create_orco(ob);
536 dm = mesh_get_derived_deform(ob, &dmNeedsFree);
538 dm = mesh_get_derived_final(ob, &dmNeedsFree);
540 dlm= dm->convertToDispListMesh(dm, 1);
542 col1 = MEM_mallocN(sizeof(*col1)*dlm->totface*4, "col1");
543 if (col2_r && (me->flag & ME_TWOSIDED)) {
544 col2 = MEM_mallocN(sizeof(*col2)*dlm->totface*4, "col1");
550 if (col2_r) *col2_r = col2;
553 vnors= MEM_mallocN(dlm->totvert*3*sizeof(float), "vnors disp");
554 for (a=0; a<dlm->totvert; a++) {
555 MVert *mv = &dlm->mvert[a];
556 float *vn= &vnors[a*3];
562 vn[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
563 vn[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
564 vn[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
568 for (i=0; i<dlm->totface; i++) {
569 MFace *mf= &dlm->mface[i];
570 int j, vidx[4], nverts= mf->v4?4:3;
571 unsigned char *col1base= (unsigned char*) &col1[i*4];
572 unsigned char *col2base= (unsigned char*) (col2?&col2[i*4]:NULL);
573 unsigned char *mcolbase;
574 Material *ma= give_current_material(ob, mf->mat_nr+1);
577 if(ma==NULL) ma= &defmaterial;
580 mcolbase = (unsigned char*) dlm->tface[i].col;
581 } else if (dlm->mcol) {
582 mcolbase = (unsigned char*) &dlm->mcol[i*4];
593 VECCOPY(nor, &dlm->nors[i*3]);
596 CalcNormFloat4(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, dlm->mvert[mf->v4].co, nor);
598 CalcNormFloat(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, nor);
601 n1[0]= imat[0][0]*nor[0]+imat[0][1]*nor[1]+imat[0][2]*nor[2];
602 n1[1]= imat[1][0]*nor[0]+imat[1][1]*nor[1]+imat[1][2]*nor[2];
603 n1[2]= imat[2][0]*nor[0]+imat[2][1]*nor[1]+imat[2][2]*nor[2];
606 for (j=0; j<nverts; j++) {
607 MVert *mv= &dlm->mvert[vidx[j]];
608 unsigned char *col1= &col1base[j*4];
609 unsigned char *col2= col2base?&col2base[j*4]:NULL;
610 unsigned char *mcol= mcolbase?&mcolbase[j*4]:NULL;
611 float *vn = (mf->flag & ME_SMOOTH)?&vnors[3*vidx[j]]:n1;
613 VECCOPY(vec, mv->co);
614 Mat4MulVecfl(mat, vec);
615 fastshade(vec, vn, orco?&orco[vidx[j]*3]:mv->co, ma, col1, col2, mcol);
619 displistmesh_free(dlm);
625 if (dmNeedsFree) dm->release(dm);
627 end_fastshade_for_ob(ob);
630 void shadeMeshMCol(Object *ob, Mesh *me)
632 Render *re= fastshade_get_render();
633 mesh_create_shadedColors(re, ob, 1, (unsigned int**)&me->mcol, NULL);
636 /* has base pointer, to check for layer */
637 /* called from drawobject.c */
638 void shadeDispList(Base *base)
640 Object *ob= base->object;
645 float imat[3][3], mat[4][4], vec[3];
646 float *fp, *nor, n1[3];
650 re= fastshade_get_render();
652 dl = find_displist(&ob->disp, DL_VERTCOL);
654 BLI_remlink(&ob->disp, dl);
658 if(ob->type==OB_MESH) {
659 dl= MEM_callocN(sizeof(DispList), "displistshade");
660 BLI_addtail(&ob->disp, dl);
661 dl->type= DL_VERTCOL;
663 mesh_create_shadedColors(re, ob, 0, &dl->col1, &dl->col2);
667 init_fastshade_for_ob(re, ob, &need_orco, mat, imat);
669 if ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT) {
671 /* now we need the normals */
676 dlob= MEM_callocN(sizeof(DispList), "displistshade");
677 BLI_addtail(&ob->disp, dlob);
678 dlob->type= DL_VERTCOL;
679 dlob->parts= dl->parts;
682 if(dl->type==DL_INDEX3) {
683 col1= dlob->col1= MEM_mallocN(sizeof(int)*dl->nr, "col1");
686 col1= dlob->col1= MEM_mallocN(sizeof(int)*dl->parts*dl->nr, "col1");
690 ma= give_current_material(ob, dl->col+1);
691 if(ma==NULL) ma= &defmaterial;
693 if(dl->type==DL_INDEX3) {
695 /* there's just one normal */
696 n1[0]= imat[0][0]*dl->nors[0]+imat[0][1]*dl->nors[1]+imat[0][2]*dl->nors[2];
697 n1[1]= imat[1][0]*dl->nors[0]+imat[1][1]*dl->nors[1]+imat[1][2]*dl->nors[2];
698 n1[2]= imat[2][0]*dl->nors[0]+imat[2][1]*dl->nors[1]+imat[2][2]*dl->nors[2];
706 Mat4MulVecfl(mat, vec);
708 fastshade(vec, n1, fp, ma, (char *)col1, 0, 0);
714 else if(dl->type==DL_SURF) {
722 Mat4MulVecfl(mat, vec);
724 n1[0]= imat[0][0]*nor[0]+imat[0][1]*nor[1]+imat[0][2]*nor[2];
725 n1[1]= imat[1][0]*nor[0]+imat[1][1]*nor[1]+imat[1][2]*nor[2];
726 n1[2]= imat[2][0]*nor[0]+imat[2][1]*nor[1]+imat[2][2]*nor[2];
729 fastshade(vec, n1, fp, ma, (char *)col1, 0, 0);
731 fp+= 3; nor+= 3; col1++;
738 else if(ob->type==OB_MBALL) {
739 /* there are normals already */
744 if(dl->type==DL_INDEX4) {
747 if(dl->col1) MEM_freeN(dl->col1);
748 col1= dl->col1= MEM_mallocN(sizeof(int)*dl->nr, "col1");
750 ma= give_current_material(ob, dl->col+1);
751 if(ma==NULL) ma= &defmaterial;
759 Mat4MulVecfl(mat, vec);
762 n1[0]= imat[0][0]*nor[0]+imat[0][1]*nor[1]+imat[0][2]*nor[2];
763 n1[1]= imat[1][0]*nor[0]+imat[1][1]*nor[1]+imat[1][2]*nor[2];
764 n1[2]= imat[2][0]*nor[0]+imat[2][1]*nor[1]+imat[2][2]*nor[2];
767 fastshade(vec, n1, fp, ma, (char *)col1, 0, 0);
769 fp+= 3; col1++; nor+= 3;
777 end_fastshade_for_ob(ob);
781 /* frees render and shade part of displists */
782 void reshadeall_displist(void)
787 fastshade_free_render();
789 for(base= G.scene->base.first; base; base= base->next) {
791 freedisplist(&ob->disp);
792 if(base->lay & G.scene->lay) {
793 /* Metaballs have standard displist at the Object */
794 if(ob->type==OB_MBALL) shadeDispList(base);
799 /* ****************** make displists ********************* */
801 static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase)
805 BezTriple *bezt, *prevbezt;
807 float *data, *v1, *v2;
814 if(G.rendering && cu->resolu_ren!=0)
815 resolu= cu->resolu_ren;
819 if((nu->type & 7)==CU_BEZIER) {
824 if(nu->flagu & CU_CYCLIC) a++;
829 if(a==0 && (nu->flagu & CU_CYCLIC)) bezt= nu->bezt;
831 if(prevbezt->h2==HD_VECT && bezt->h1==HD_VECT) len++;
834 if(a==0 && (nu->flagu & CU_CYCLIC)==0) len++;
840 dl= MEM_callocN(sizeof(DispList), "makeDispListbez");
841 /* len+1 because of 'forward_diff_bezier' function */
842 dl->verts= MEM_callocN( (len+1)*3*sizeof(float), "dlverts");
843 BLI_addtail(dispbase, dl);
847 dl->charidx= nu->charidx;
864 if(a==0 && dl->type== DL_POLY) bezt= nu->bezt;
866 if(prevbezt->h2==HD_VECT && bezt->h1==HD_VECT) {
867 VECCOPY(data, prevbezt->vec[1]);
871 v1= prevbezt->vec[1];
873 forward_diff_bezier(v1[0], v1[3], v2[0], v2[3], data, resolu, 3);
874 forward_diff_bezier(v1[1], v1[4], v2[1], v2[4], data+1, resolu, 3);
875 forward_diff_bezier(v1[2], v1[5], v2[2], v2[5], data+2, resolu, 3);
879 if(a==0 && dl->type==DL_SEGM) {
880 VECCOPY(data, bezt->vec[1]);
887 else if((nu->type & 7)==CU_NURBS) {
888 len= nu->pntsu*resolu;
889 dl= MEM_callocN(sizeof(DispList), "makeDispListsurf");
890 dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
891 BLI_addtail(dispbase, dl);
895 dl->charidx = nu->charidx;
898 if(nu->flagu & 1) dl->type= DL_POLY;
899 else dl->type= DL_SEGM;
900 makeNurbcurve(nu, data, resolu, 3);
902 else if((nu->type & 7)==CU_POLY) {
904 dl= MEM_callocN(sizeof(DispList), "makeDispListpoly");
905 dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
906 BLI_addtail(dispbase, dl);
910 dl->charidx = nu->charidx;
913 if(nu->flagu & 1) dl->type= DL_POLY;
914 else dl->type= DL_SEGM;
919 VECCOPY(data, bp->vec);
930 void filldisplist(ListBase *dispbase, ListBase *to)
932 EditVert *eve, *v1, *vlast;
934 DispList *dlnew=0, *dl;
936 int colnr=0, charidx=0, cont=1, tot, a, *index;
939 if(dispbase==0) return;
940 if(dispbase->first==0) return;
949 if(dl->type==DL_POLY) {
950 if(charidx<dl->charidx) cont= 1;
951 else if(charidx==dl->charidx) {
954 charidx= dl->charidx;
956 /* make editverts and edges */
964 eve= BLI_addfillvert(f1);
967 if(vlast==0) v1= eve;
969 BLI_addfilledge(vlast, eve);
974 if(eve!=0 && v1!=0) {
975 BLI_addfilledge(eve, v1);
982 if(totvert && BLI_edgefill(0, (G.obedit && G.obedit->actcol)?(G.obedit->actcol-1):0)) {
986 efa= fillfacebase.first;
993 dlnew= MEM_callocN(sizeof(DispList), "filldisplist");
994 dlnew->type= DL_INDEX3;
999 dlnew->index= MEM_mallocN(tot*3*sizeof(int), "dlindex");
1000 dlnew->verts= MEM_mallocN(totvert*3*sizeof(float), "dlverts");
1005 eve= fillvertbase.first;
1007 VECCOPY(f1, eve->co);
1011 eve->tmp.l = totvert;
1018 efa= fillfacebase.first;
1019 index= dlnew->index;
1021 index[0]= (long)efa->v1->tmp.l;
1022 index[1]= (long)efa->v2->tmp.l;
1023 index[2]= (long)efa->v3->tmp.l;
1030 BLI_addhead(to, dlnew);
1038 /* do not free polys, needed for wireframe display */
1042 static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase)
1044 ListBase front, back;
1045 DispList *dl, *dlnew;
1049 front.first= front.last= back.first= back.last= 0;
1051 dl= dispbase->first;
1053 if(dl->type==DL_SURF) {
1054 if( (dl->flag & DL_CYCL_V) && (dl->flag & DL_CYCL_U)==0 ) {
1055 if( (cu->flag & CU_BACK) && (dl->flag & DL_BACK_CURVE) ) {
1056 dlnew= MEM_callocN(sizeof(DispList), "filldisp");
1057 BLI_addtail(&front, dlnew);
1058 dlnew->verts= fp1= MEM_mallocN(sizeof(float)*3*dl->parts, "filldisp1");
1059 dlnew->nr= dl->parts;
1061 dlnew->type= DL_POLY;
1062 dlnew->col= dl->col;
1063 dlnew->charidx = dl->charidx;
1075 if( (cu->flag & CU_FRONT) && (dl->flag & DL_FRONT_CURVE) ) {
1076 dlnew= MEM_callocN(sizeof(DispList), "filldisp");
1077 BLI_addtail(&back, dlnew);
1078 dlnew->verts= fp1= MEM_mallocN(sizeof(float)*3*dl->parts, "filldisp1");
1079 dlnew->nr= dl->parts;
1081 dlnew->type= DL_POLY;
1082 dlnew->col= dl->col;
1083 dlnew->charidx= dl->charidx;
1085 fp= dl->verts+3*(dl->nr-1);
1100 filldisplist(&front, dispbase);
1101 filldisplist(&back, dispbase);
1103 freedisplist(&front);
1104 freedisplist(&back);
1106 filldisplist(dispbase, dispbase);
1110 void curve_to_filledpoly(Curve *cu, ListBase *nurb, ListBase *dispbase)
1112 if(cu->flag & CU_3D) return;
1114 if(dispbase->first && ((DispList*) dispbase->first)->type==DL_SURF) {
1115 bevels_to_filledpoly(cu, dispbase);
1118 filldisplist(dispbase, dispbase);
1122 /* calculates a bevel width (radius) for a particular subdivided curve part,
1123 * based on the radius value of the surrounding CVs */
1124 static float calc_manual_taper(Curve *cu, Nurb *nu, int cursubdiv)
1126 BezTriple *bezt, *beztfirst, *beztlast, *beztnext, *beztprev;
1127 BPoint *bp, *bpfirst, *bplast;
1129 float prevrad=0.0, nextrad=0.0, rad=0.0, ratio=0.0;
1130 int vectseg=0, subdivs=0;
1132 if((nu==NULL) || (nu->pntsu<=1)) return 1.0;
1136 if(G.rendering && cu->resolu_ren!=0) resolu= cu->resolu_ren;
1137 else resolu= nu->resolu;
1139 if(((nu->type & 7)==CU_BEZIER) && (bezt != NULL)) {
1140 beztfirst = nu->bezt;
1141 beztlast = nu->bezt + (nu->pntsu - 1);
1143 /* loop through the CVs to end up with a pointer to the CV before the subdiv in question, and a ratio
1144 * of how far that subdiv is between this CV and the next */
1145 while(bezt<=beztlast) {
1150 if (subdivs==cursubdiv) {
1155 /* check to see if we're looking at a vector segment (no subdivisions) */
1156 if (nu->flagu & CU_CYCLIC) {
1157 if (bezt == beztfirst) {
1158 if ((beztlast->h2==HD_VECT) && (bezt->h1==HD_VECT)) vectseg = 1;
1160 if ((beztprev->h2==HD_VECT) && (bezt->h1==HD_VECT)) vectseg = 1;
1162 } else if ((bezt->h2==HD_VECT) && (beztnext->h1==HD_VECT)) vectseg = 1;
1166 /* if it's NOT a vector segment, check to see if the subdiv falls within the segment */
1169 if (cursubdiv < subdivs) {
1170 ratio = 1.0 - ((subdivs - cursubdiv)/(float)resolu);
1174 /* must be a vector segment.. loop again! */
1181 /* Now we have a nice bezt pointer to the CV that we want. But cyclic messes it up, so must correct for that..
1182 * (cyclic goes last-> first -> first+1 -> first+2 -> ...) */
1183 if (nu->flagu & CU_CYCLIC) {
1184 if (bezt == beztfirst) bezt = beztlast;
1188 /* find the radii at the bounding CVs and interpolate between them based on ratio */
1189 rad = prevrad = bezt->radius;
1191 if ((bezt == beztlast) && (nu->flagu & CU_CYCLIC)) { /* loop around */
1193 } else if (bezt != beztlast) {
1196 nextrad = bezt->radius;
1199 else if( ( ((nu->type & 7)==CU_NURBS) || ((nu->type & 7)==CU_POLY)) && (bp != NULL)) {
1200 /* follows similar algo as for bezt above */
1202 bplast = nu->bp + (nu->pntsu - 1);
1204 if ((nu->type & 7)==CU_POLY) resolu=1;
1207 if (subdivs==cursubdiv) {
1214 if (cursubdiv < subdivs) {
1215 ratio = 1.0 - ((subdivs - cursubdiv)/(float)resolu);
1222 if ( ((nu->type & 7)==CU_NURBS) && (nu->flagu & CU_CYCLIC)) {
1223 if (bp == bplast) bp = bpfirst;
1227 rad = prevrad = bp->radius;
1229 if ((bp == bplast) && (nu->flagu & CU_CYCLIC)) { /* loop around */
1231 } else if (bp != bplast) {
1234 nextrad = bp->radius;
1239 if (nextrad != prevrad) {
1240 /* smooth interpolation */
1241 rad = prevrad + (nextrad-prevrad)*(3.0f*ratio*ratio - 2.0f*ratio*ratio*ratio);
1252 - first point left, last point right
1253 - based on subdivided points in original curve, not on points in taper curve (still)
1255 static float calc_taper(Object *taperobj, int cur, int tot)
1260 if(taperobj==NULL) return 1.0;
1265 makeDispListCurveTypes(taperobj, 0);
1269 float fac= ((float)cur)/(float)(tot-1);
1270 float minx, dx, *fp;
1273 /* horizontal size */
1275 dx= dl->verts[3*(dl->nr-1)] - minx;
1279 for(a=0; a<dl->nr; a++, fp+=3) {
1280 if( (fp[0]-minx)/dx >= fac) {
1281 /* interpolate with prev */
1283 float fac1= (fp[-3]-minx)/dx;
1284 float fac2= (fp[0]-minx)/dx;
1286 return fp[1]*(fac1-fac)/(fac1-fac2) + fp[-2]*(fac-fac2)/(fac1-fac2);
1291 return fp[-2]; // last y coord
1298 void makeDispListMBall(Object *ob)
1300 if(!ob || ob->type!=OB_MBALL) return;
1302 freedisplist(&(ob->disp));
1304 if(ob->type==OB_MBALL) {
1305 if(ob==find_basis_mball(ob)) {
1306 metaball_polygonize(ob);
1307 tex_space_mball(ob);
1309 object_deform_mball(ob);
1313 boundbox_displist(ob);
1316 static ModifierData *curve_get_tesselate_point(Object *ob, int forRender, int editmode)
1318 ModifierData *md = modifiers_getVirtualModifierList(ob);
1319 ModifierData *preTesselatePoint;
1321 preTesselatePoint = NULL;
1322 for (; md; md=md->next) {
1323 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1325 if (!(md->mode&(1<<forRender))) continue;
1326 if (editmode && !(md->mode&eModifierMode_Editmode)) continue;
1327 if (mti->isDisabled && mti->isDisabled(md)) continue;
1329 if (md->type==eModifierType_Hook || md->type==eModifierType_Softbody) {
1330 preTesselatePoint = md;
1334 return preTesselatePoint;
1337 void curve_calc_modifiers_pre(Object *ob, ListBase *nurb, int forRender, float (**originalVerts_r)[3], float (**deformedVerts_r)[3], int *numVerts_r)
1339 int editmode = (!forRender && ob==G.obedit);
1340 ModifierData *md = modifiers_getVirtualModifierList(ob);
1341 ModifierData *preTesselatePoint = curve_get_tesselate_point(ob, forRender, editmode);
1343 float (*originalVerts)[3] = NULL;
1344 float (*deformedVerts)[3] = NULL;
1346 if(ob!=G.obedit && do_ob_key(ob)) {
1347 deformedVerts = curve_getVertexCos(ob->data, nurb, &numVerts);
1348 originalVerts = MEM_dupallocN(deformedVerts);
1351 if (preTesselatePoint) {
1352 for (; md; md=md->next) {
1353 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1355 if (!(md->mode&(1<<forRender))) continue;
1356 if (editmode && !(md->mode&eModifierMode_Editmode)) continue;
1357 if (mti->isDisabled && mti->isDisabled(md)) continue;
1358 if (mti->type!=eModifierTypeType_OnlyDeform) continue;
1360 if (!deformedVerts) {
1361 deformedVerts = curve_getVertexCos(ob->data, nurb, &numVerts);
1362 originalVerts = MEM_dupallocN(deformedVerts);
1365 mti->deformVerts(md, ob, NULL, deformedVerts, numVerts);
1367 if (md==preTesselatePoint)
1372 if (deformedVerts) {
1373 curve_applyVertexCos(ob->data, nurb, deformedVerts);
1376 *originalVerts_r = originalVerts;
1377 *deformedVerts_r = deformedVerts;
1378 *numVerts_r = numVerts;
1381 void curve_calc_modifiers_post(Object *ob, ListBase *nurb, ListBase *dispbase, int forRender, float (*originalVerts)[3], float (*deformedVerts)[3])
1383 int editmode = (!forRender && ob==G.obedit);
1384 ModifierData *md = modifiers_getVirtualModifierList(ob);
1385 ModifierData *preTesselatePoint = curve_get_tesselate_point(ob, forRender, editmode);
1388 if (preTesselatePoint) {
1389 md = preTesselatePoint->next;
1392 for (; md; md=md->next) {
1393 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1395 if (!(md->mode&(1<<forRender))) continue;
1396 if (editmode && !(md->mode&eModifierMode_Editmode)) continue;
1397 if (mti->isDisabled && mti->isDisabled(md)) continue;
1398 if (mti->type!=eModifierTypeType_OnlyDeform) continue;
1400 for (dl=dispbase->first; dl; dl=dl->next) {
1401 mti->deformVerts(md, ob, NULL, (float(*)[3]) dl->verts, (dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr);
1405 if (deformedVerts) {
1406 curve_applyVertexCos(ob->data, nurb, originalVerts);
1407 MEM_freeN(originalVerts);
1408 MEM_freeN(deformedVerts);
1412 void makeDispListSurf(Object *ob, ListBase *dispbase, int forRender)
1416 Curve *cu = ob->data;
1421 float (*originalVerts)[3];
1422 float (*deformedVerts)[3];
1424 if(!forRender && ob==G.obedit) {
1431 curve_calc_modifiers_pre(ob, nubase, forRender, &originalVerts, &deformedVerts, &numVerts);
1433 for (nu=nubase->first; nu; nu=nu->next) {
1434 if(forRender || nu->hide==0) {
1436 len= nu->pntsu*nu->resolu;
1438 dl= MEM_callocN(sizeof(DispList), "makeDispListsurf");
1439 dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
1441 BLI_addtail(dispbase, dl);
1444 dl->col= nu->mat_nr;
1445 dl->charidx= nu->charidx;
1449 if(nu->flagu & 1) dl->type= DL_POLY;
1450 else dl->type= DL_SEGM;
1452 makeNurbcurve(nu, data, nu->resolu, 3);
1455 len= nu->resolu*nu->resolv;
1457 dl= MEM_callocN(sizeof(DispList), "makeDispListsurf");
1458 dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
1459 BLI_addtail(dispbase, dl);
1461 dl->col= nu->mat_nr;
1462 dl->charidx= nu->charidx;
1468 dl->parts= nu->resolu; /* in reverse, because makeNurbfaces works that way */
1470 if(nu->flagv & CU_CYCLIC) dl->flag|= DL_CYCL_U; /* reverse too! */
1471 if(nu->flagu & CU_CYCLIC) dl->flag|= DL_CYCL_V;
1473 makeNurbfaces(nu, data, 0);
1479 tex_space_curve(cu);
1482 curve_calc_modifiers_post(ob, nubase, dispbase, forRender, originalVerts, deformedVerts);
1485 void makeDispListCurveTypes(Object *ob, int forOrco)
1487 Curve *cu = ob->data;
1490 /* we do allow duplis... this is only displist on curve level */
1491 if(!ELEM3(ob->type, OB_SURF, OB_CURVE, OB_FONT)) return;
1493 freedisplist(&(ob->disp));
1494 dispbase= &(cu->disp);
1495 freedisplist(dispbase);
1497 if(ob->type==OB_SURF) {
1498 makeDispListSurf(ob, dispbase, 0);
1500 else if ELEM(ob->type, OB_CURVE, OB_FONT) {
1502 float (*originalVerts)[3];
1503 float (*deformedVerts)[3];
1504 int obedit= (G.obedit && G.obedit->data==ob->data && G.obedit->type==OB_CURVE);
1505 ListBase *nubase = obedit?&editNurb:&cu->nurb;
1508 BLI_freelistN(&(cu->bev));
1510 if(cu->path) free_path(cu->path);
1513 if(ob->type==OB_FONT) text_to_curve(ob, 0);
1515 if(!forOrco) curve_calc_modifiers_pre(ob, nubase, 0, &originalVerts, &deformedVerts, &numVerts);
1519 /* If curve has no bevel will return nothing */
1520 makebevelcurve(ob, &dlbev);
1522 /* no bevel or extrude, and no width correction? */
1523 if (!dlbev.first && cu->width==1.0f) {
1524 curve_to_displist(cu, nubase, dispbase);
1526 float widfac= cu->width-1.0;
1527 BevList *bl= cu->bev.first;
1528 Nurb *nu= nubase->first;
1530 for (; bl && nu; bl=bl->next,nu=nu->next) {
1536 /* exception handling; curve without bevel or extrude, with width correction */
1537 if(dlbev.first==NULL) {
1538 dl= MEM_callocN(sizeof(DispList), "makeDispListbev");
1539 dl->verts= MEM_callocN(3*sizeof(float)*bl->nr, "dlverts");
1540 BLI_addtail(dispbase, dl);
1542 if(bl->poly!= -1) dl->type= DL_POLY;
1543 else dl->type= DL_SEGM;
1545 if(dl->type==DL_SEGM) dl->flag = (DL_FRONT_CURVE|DL_BACK_CURVE);
1549 dl->col= nu->mat_nr;
1550 dl->charidx= nu->charidx;
1554 bevp= (BevPoint *)(bl+1);
1557 data[0]= bevp->x+widfac*bevp->sina;
1558 data[1]= bevp->y+widfac*bevp->cosa;
1567 for (dlb=dlbev.first; dlb; dlb=dlb->next) {
1569 /* for each part of the bevel use a separate displblock */
1570 dl= MEM_callocN(sizeof(DispList), "makeDispListbev1");
1571 dl->verts= data= MEM_callocN(3*sizeof(float)*dlb->nr*bl->nr, "dlverts");
1572 BLI_addtail(dispbase, dl);
1576 dl->flag= dlb->flag & (DL_FRONT_CURVE|DL_BACK_CURVE);
1577 if(dlb->type==DL_POLY) dl->flag |= DL_CYCL_U;
1578 if(bl->poly>=0) dl->flag |= DL_CYCL_V;
1582 dl->col= nu->mat_nr;
1583 dl->charidx= nu->charidx;
1585 dl->bevelSplitFlag= MEM_callocN(sizeof(*dl->col2)*((bl->nr+0x1F)>>5), "col2");
1586 bevp= (BevPoint *)(bl+1);
1588 /* for each point of poly make a bevel piece */
1589 bevp= (BevPoint *)(bl+1);
1590 for(a=0; a<bl->nr; a++,bevp++) {
1592 if (cu->taperobj==NULL) {
1593 fac = calc_manual_taper(cu, nu, a);
1595 fac = calc_taper(cu->taperobj, a, bl->nr);
1599 dl->bevelSplitFlag[a>>5] |= 1<<(a&0x1F);
1602 /* rotate bevel piece and write in data */
1604 for (b=0; b<dlb->nr; b++,fp1+=3,data+=3) {
1605 if(cu->flag & CU_3D) {
1608 vec[0]= fp1[1]+widfac;
1612 Mat3MulVecfl(bevp->mat, vec);
1614 data[0]= bevp->x+ fac*vec[0];
1615 data[1]= bevp->y+ fac*vec[1];
1616 data[2]= bevp->z+ fac*vec[2];
1619 data[0]= bevp->x+ fac*(widfac+fp1[1])*bevp->sina;
1620 data[1]= bevp->y+ fac*(widfac+fp1[1])*bevp->cosa;
1621 data[2]= bevp->z+ fac*fp1[2];
1629 freedisplist(&dlbev);
1632 curve_to_filledpoly(cu, nubase, dispbase);
1634 if(cu->flag & CU_PATH) calc_curvepath(ob);
1636 if(!forOrco) curve_calc_modifiers_post(ob, nubase, &cu->disp, 0, originalVerts, deformedVerts);
1637 tex_space_curve(cu);
1640 boundbox_displist(ob);
1643 void imagestodisplist(void)
1648 static void boundbox_displist(Object *ob)
1651 float min[3], max[3];
1656 INIT_MINMAX(min, max);
1658 if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
1659 Curve *cu= ob->data;
1661 if(cu->bb==0) cu->bb= MEM_callocN(sizeof(BoundBox), "boundbox");
1667 if(dl->type==DL_INDEX3) tot= dl->nr;
1668 else tot= dl->nr*dl->parts;
1671 for(a=0; a<tot; a++, vert+=3) {
1672 DO_MINMAX(vert, min, max);
1680 boundbox_set_from_min_max(bb, min, max);
1684 void displistmesh_add_edges(DispListMesh *dlm)
1686 EdgeHash *eh = BLI_edgehash_new();
1687 EdgeHashIterator *ehi;
1690 for (i=0; i<dlm->totface; i++) {
1691 MFace *mf = &dlm->mface[i];
1693 if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
1694 BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
1695 if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
1696 BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
1699 if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
1700 BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
1701 if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
1702 BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
1704 if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
1705 BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
1709 dlm->totedge = BLI_edgehash_size(eh);
1710 dlm->medge = MEM_callocN(dlm->totedge*sizeof(*dlm->medge), "medge");
1712 ehi = BLI_edgehashIterator_new(eh);
1713 for (i=0; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
1714 MEdge *med = &dlm->medge[i++];
1716 BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
1718 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
1720 BLI_edgehashIterator_free(ehi);
1722 BLI_edgehash_free(eh, NULL);