|
Blender
V2.59
|
00001 /* displist.c 00002 * 00003 * 00004 * $Id: displist.c 37504 2011-06-15 10:17:06Z blendix $ 00005 * 00006 * ***** BEGIN GPL LICENSE BLOCK ***** 00007 * 00008 * This program is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU General Public License 00010 * as published by the Free Software Foundation; either version 2 00011 * of the License, or (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with this program; if not, write to the Free Software Foundation, 00020 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00021 * 00022 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00023 * All rights reserved. 00024 * 00025 * The Original Code is: all of this file. 00026 * 00027 * Contributor(s): none yet. 00028 * 00029 * ***** END GPL LICENSE BLOCK ***** 00030 */ 00031 00037 #include <math.h> 00038 #include <stdio.h> 00039 #include <string.h> 00040 00041 #include "MEM_guardedalloc.h" 00042 00043 #include "DNA_curve_types.h" 00044 #include "DNA_meshdata_types.h" 00045 #include "DNA_scene_types.h" 00046 #include "DNA_object_types.h" 00047 #include "DNA_material_types.h" 00048 00049 #include "BLI_blenlib.h" 00050 #include "BLI_math.h" 00051 #include "BLI_editVert.h" 00052 #include "BLI_scanfill.h" 00053 #include "BLI_utildefines.h" 00054 00055 #include "BKE_global.h" 00056 #include "BKE_displist.h" 00057 #include "BKE_cdderivedmesh.h" 00058 #include "BKE_object.h" 00059 #include "BKE_mball.h" 00060 #include "BKE_material.h" 00061 #include "BKE_curve.h" 00062 #include "BKE_key.h" 00063 #include "BKE_anim.h" 00064 #include "BKE_font.h" 00065 #include "BKE_lattice.h" 00066 #include "BKE_modifier.h" 00067 00068 #include "BLO_sys_types.h" // for intptr_t support 00069 00070 #include "ED_curve.h" /* for BKE_curve_nurbs */ 00071 00072 extern Material defmaterial; /* material.c */ 00073 00074 static void boundbox_displist(Object *ob); 00075 00076 void free_disp_elem(DispList *dl) 00077 { 00078 if(dl) { 00079 if(dl->verts) MEM_freeN(dl->verts); 00080 if(dl->nors) MEM_freeN(dl->nors); 00081 if(dl->index) MEM_freeN(dl->index); 00082 if(dl->col1) MEM_freeN(dl->col1); 00083 if(dl->col2) MEM_freeN(dl->col2); 00084 if(dl->bevelSplitFlag) MEM_freeN(dl->bevelSplitFlag); 00085 MEM_freeN(dl); 00086 } 00087 } 00088 00089 void freedisplist(ListBase *lb) 00090 { 00091 DispList *dl; 00092 00093 dl= lb->first; 00094 while(dl) { 00095 BLI_remlink(lb, dl); 00096 free_disp_elem(dl); 00097 dl= lb->first; 00098 } 00099 } 00100 00101 DispList *find_displist_create(ListBase *lb, int type) 00102 { 00103 DispList *dl; 00104 00105 dl= lb->first; 00106 while(dl) { 00107 if(dl->type==type) return dl; 00108 dl= dl->next; 00109 } 00110 00111 dl= MEM_callocN(sizeof(DispList), "find_disp"); 00112 dl->type= type; 00113 BLI_addtail(lb, dl); 00114 00115 return dl; 00116 } 00117 00118 DispList *find_displist(ListBase *lb, int type) 00119 { 00120 DispList *dl; 00121 00122 dl= lb->first; 00123 while(dl) { 00124 if(dl->type==type) return dl; 00125 dl= dl->next; 00126 } 00127 00128 return NULL; 00129 } 00130 00131 int displist_has_faces(ListBase *lb) 00132 { 00133 DispList *dl; 00134 for(dl= lb->first; dl; dl= dl->next) { 00135 if ELEM3(dl->type, DL_INDEX3, DL_INDEX4, DL_SURF) 00136 return 1; 00137 } 00138 return 0; 00139 } 00140 00141 void copy_displist(ListBase *lbn, ListBase *lb) 00142 { 00143 DispList *dln, *dl; 00144 00145 freedisplist(lbn); 00146 00147 dl= lb->first; 00148 while(dl) { 00149 00150 dln= MEM_dupallocN(dl); 00151 BLI_addtail(lbn, dln); 00152 dln->verts= MEM_dupallocN(dl->verts); 00153 dln->nors= MEM_dupallocN(dl->nors); 00154 dln->index= MEM_dupallocN(dl->index); 00155 dln->col1= MEM_dupallocN(dl->col1); 00156 dln->col2= MEM_dupallocN(dl->col2); 00157 00158 if(dl->bevelSplitFlag) 00159 dln->bevelSplitFlag= MEM_dupallocN(dl->bevelSplitFlag); 00160 00161 dl= dl->next; 00162 } 00163 } 00164 00165 void addnormalsDispList(ListBase *lb) 00166 { 00167 DispList *dl = NULL; 00168 float *vdata, *ndata, nor[3]; 00169 float *v1, *v2, *v3, *v4; 00170 float *n1, *n2, *n3, *n4; 00171 int a, b, p1, p2, p3, p4; 00172 00173 00174 dl= lb->first; 00175 00176 while(dl) { 00177 if(dl->type==DL_INDEX3) { 00178 if(dl->nors==NULL) { 00179 dl->nors= MEM_callocN(sizeof(float)*3, "dlnors"); 00180 if(dl->verts[2] < 0.0f) dl->nors[2]= -1.0f; 00181 else dl->nors[2]= 1.0f; 00182 } 00183 } 00184 else if(dl->type==DL_SURF) { 00185 if(dl->nors==NULL) { 00186 dl->nors= MEM_callocN(sizeof(float)*3*dl->nr*dl->parts, "dlnors"); 00187 00188 vdata= dl->verts; 00189 ndata= dl->nors; 00190 00191 for(a=0; a<dl->parts; a++) { 00192 00193 if (surfindex_displist(dl, a, &b, &p1, &p2, &p3, &p4)==0) 00194 break; 00195 00196 v1= vdata+ 3*p1; 00197 n1= ndata+ 3*p1; 00198 v2= vdata+ 3*p2; 00199 n2= ndata+ 3*p2; 00200 v3= vdata+ 3*p3; 00201 n3= ndata+ 3*p3; 00202 v4= vdata+ 3*p4; 00203 n4= ndata+ 3*p4; 00204 00205 for(; b<dl->nr; b++) { 00206 00207 normal_quad_v3( nor,v1, v3, v4, v2); 00208 00209 add_v3_v3(n1, nor); 00210 add_v3_v3(n2, nor); 00211 add_v3_v3(n3, nor); 00212 add_v3_v3(n4, nor); 00213 00214 v2= v1; v1+= 3; 00215 v4= v3; v3+= 3; 00216 n2= n1; n1+= 3; 00217 n4= n3; n3+= 3; 00218 } 00219 } 00220 a= dl->parts*dl->nr; 00221 v1= ndata; 00222 while(a--) { 00223 normalize_v3(v1); 00224 v1+= 3; 00225 } 00226 } 00227 } 00228 dl= dl->next; 00229 } 00230 } 00231 00232 void count_displist(ListBase *lb, int *totvert, int *totface) 00233 { 00234 DispList *dl; 00235 00236 dl= lb->first; 00237 while(dl) { 00238 00239 switch(dl->type) { 00240 case DL_SURF: 00241 *totvert+= dl->nr*dl->parts; 00242 *totface+= (dl->nr-1)*(dl->parts-1); 00243 break; 00244 case DL_INDEX3: 00245 case DL_INDEX4: 00246 *totvert+= dl->nr; 00247 *totface+= dl->parts; 00248 break; 00249 case DL_POLY: 00250 case DL_SEGM: 00251 *totvert+= dl->nr*dl->parts; 00252 } 00253 00254 dl= dl->next; 00255 } 00256 } 00257 00258 int surfindex_displist(DispList *dl, int a, int *b, int *p1, int *p2, int *p3, int *p4) 00259 { 00260 if((dl->flag & DL_CYCL_V)==0 && a==(dl->parts)-1) { 00261 return 0; 00262 } 00263 00264 if(dl->flag & DL_CYCL_U) { 00265 (*p1)= dl->nr*a; 00266 (*p2)= (*p1)+ dl->nr-1; 00267 (*p3)= (*p1)+ dl->nr; 00268 (*p4)= (*p2)+ dl->nr; 00269 (*b)= 0; 00270 } else { 00271 (*p2)= dl->nr*a; 00272 (*p1)= (*p2)+1; 00273 (*p4)= (*p2)+ dl->nr; 00274 (*p3)= (*p1)+ dl->nr; 00275 (*b)= 1; 00276 } 00277 00278 if( (dl->flag & DL_CYCL_V) && a==dl->parts-1) { \ 00279 (*p3)-= dl->nr*dl->parts; \ 00280 (*p4)-= dl->nr*dl->parts; \ 00281 } 00282 00283 return 1; 00284 } 00285 00286 /* ****************** make displists ********************* */ 00287 00288 static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase, int forRender) 00289 { 00290 Nurb *nu; 00291 DispList *dl; 00292 BezTriple *bezt, *prevbezt; 00293 BPoint *bp; 00294 float *data; 00295 int a, len, resolu; 00296 00297 nu= nubase->first; 00298 while(nu) { 00299 if(nu->hide==0) { 00300 00301 if(forRender && cu->resolu_ren!=0) 00302 resolu= cu->resolu_ren; 00303 else 00304 resolu= nu->resolu; 00305 00306 if(!check_valid_nurb_u(nu)); 00307 else if(nu->type == CU_BEZIER) { 00308 00309 /* count */ 00310 len= 0; 00311 a= nu->pntsu-1; 00312 if(nu->flagu & CU_NURB_CYCLIC) a++; 00313 00314 prevbezt= nu->bezt; 00315 bezt= prevbezt+1; 00316 while(a--) { 00317 if(a==0 && (nu->flagu & CU_NURB_CYCLIC)) bezt= nu->bezt; 00318 00319 if(prevbezt->h2==HD_VECT && bezt->h1==HD_VECT) len++; 00320 else len+= resolu; 00321 00322 if(a==0 && (nu->flagu & CU_NURB_CYCLIC)==0) len++; 00323 00324 prevbezt= bezt; 00325 bezt++; 00326 } 00327 00328 dl= MEM_callocN(sizeof(DispList), "makeDispListbez"); 00329 /* len+1 because of 'forward_diff_bezier' function */ 00330 dl->verts= MEM_callocN( (len+1)*3*sizeof(float), "dlverts"); 00331 BLI_addtail(dispbase, dl); 00332 dl->parts= 1; 00333 dl->nr= len; 00334 dl->col= nu->mat_nr; 00335 dl->charidx= nu->charidx; 00336 00337 data= dl->verts; 00338 00339 if(nu->flagu & CU_NURB_CYCLIC) { 00340 dl->type= DL_POLY; 00341 a= nu->pntsu; 00342 } 00343 else { 00344 dl->type= DL_SEGM; 00345 a= nu->pntsu-1; 00346 } 00347 00348 prevbezt= nu->bezt; 00349 bezt= prevbezt+1; 00350 00351 while(a--) { 00352 if(a==0 && dl->type== DL_POLY) bezt= nu->bezt; 00353 00354 if(prevbezt->h2==HD_VECT && bezt->h1==HD_VECT) { 00355 VECCOPY(data, prevbezt->vec[1]); 00356 data+= 3; 00357 } 00358 else { 00359 int j; 00360 for(j=0; j<3; j++) { 00361 forward_diff_bezier( prevbezt->vec[1][j], 00362 prevbezt->vec[2][j], 00363 bezt->vec[0][j], 00364 bezt->vec[1][j], 00365 data+j, resolu, 3*sizeof(float)); 00366 } 00367 00368 data+= 3*resolu; 00369 } 00370 00371 if(a==0 && dl->type==DL_SEGM) { 00372 VECCOPY(data, bezt->vec[1]); 00373 } 00374 00375 prevbezt= bezt; 00376 bezt++; 00377 } 00378 } 00379 else if(nu->type == CU_NURBS) { 00380 len= (resolu*SEGMENTSU(nu)); 00381 00382 dl= MEM_callocN(sizeof(DispList), "makeDispListsurf"); 00383 dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts"); 00384 BLI_addtail(dispbase, dl); 00385 dl->parts= 1; 00386 00387 dl->nr= len; 00388 dl->col= nu->mat_nr; 00389 dl->charidx = nu->charidx; 00390 00391 data= dl->verts; 00392 if(nu->flagu & CU_NURB_CYCLIC) dl->type= DL_POLY; 00393 else dl->type= DL_SEGM; 00394 makeNurbcurve(nu, data, NULL, NULL, NULL, resolu, 3*sizeof(float)); 00395 } 00396 else if(nu->type == CU_POLY) { 00397 len= nu->pntsu; 00398 dl= MEM_callocN(sizeof(DispList), "makeDispListpoly"); 00399 dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts"); 00400 BLI_addtail(dispbase, dl); 00401 dl->parts= 1; 00402 dl->nr= len; 00403 dl->col= nu->mat_nr; 00404 dl->charidx = nu->charidx; 00405 00406 data= dl->verts; 00407 if(nu->flagu & CU_NURB_CYCLIC) dl->type= DL_POLY; 00408 else dl->type= DL_SEGM; 00409 00410 a= len; 00411 bp= nu->bp; 00412 while(a--) { 00413 VECCOPY(data, bp->vec); 00414 bp++; 00415 data+= 3; 00416 } 00417 } 00418 } 00419 nu= nu->next; 00420 } 00421 } 00422 00423 00424 void filldisplist(ListBase *dispbase, ListBase *to, int flipnormal) 00425 { 00426 EditVert *eve, *v1, *vlast; 00427 EditFace *efa; 00428 DispList *dlnew=NULL, *dl; 00429 float *f1; 00430 int colnr=0, charidx=0, cont=1, tot, a, *index, nextcol= 0; 00431 intptr_t totvert; 00432 00433 if(dispbase==NULL) return; 00434 if(dispbase->first==NULL) return; 00435 00436 while(cont) { 00437 cont= 0; 00438 totvert= 0; 00439 nextcol= 0; 00440 00441 dl= dispbase->first; 00442 while(dl) { 00443 00444 if(dl->type==DL_POLY) { 00445 if(charidx<dl->charidx) cont= 1; 00446 else if(charidx==dl->charidx) { /* character with needed index */ 00447 if(colnr==dl->col) { 00448 /* make editverts and edges */ 00449 f1= dl->verts; 00450 a= dl->nr; 00451 eve= v1= NULL; 00452 00453 while(a--) { 00454 vlast= eve; 00455 00456 eve= BLI_addfillvert(f1); 00457 totvert++; 00458 00459 if(vlast==NULL) v1= eve; 00460 else { 00461 BLI_addfilledge(vlast, eve); 00462 } 00463 f1+=3; 00464 } 00465 00466 if(eve!=NULL && v1!=NULL) { 00467 BLI_addfilledge(eve, v1); 00468 } 00469 } else if (colnr<dl->col) { 00470 /* got poly with next material at current char */ 00471 cont= 1; 00472 nextcol= 1; 00473 } 00474 } 00475 } 00476 dl= dl->next; 00477 } 00478 00479 if(totvert && (tot= BLI_edgefill(0))) { // XXX (obedit && obedit->actcol)?(obedit->actcol-1):0)) { 00480 if(tot) { 00481 dlnew= MEM_callocN(sizeof(DispList), "filldisplist"); 00482 dlnew->type= DL_INDEX3; 00483 dlnew->col= colnr; 00484 dlnew->nr= totvert; 00485 dlnew->parts= tot; 00486 00487 dlnew->index= MEM_mallocN(tot*3*sizeof(int), "dlindex"); 00488 dlnew->verts= MEM_mallocN(totvert*3*sizeof(float), "dlverts"); 00489 00490 /* vert data */ 00491 f1= dlnew->verts; 00492 totvert= 0; 00493 eve= fillvertbase.first; 00494 while(eve) { 00495 VECCOPY(f1, eve->co); 00496 f1+= 3; 00497 00498 /* index number */ 00499 eve->tmp.l = totvert; 00500 totvert++; 00501 00502 eve= eve->next; 00503 } 00504 00505 /* index data */ 00506 efa= fillfacebase.first; 00507 index= dlnew->index; 00508 while(efa) { 00509 index[0]= (intptr_t)efa->v1->tmp.l; 00510 index[1]= (intptr_t)efa->v2->tmp.l; 00511 index[2]= (intptr_t)efa->v3->tmp.l; 00512 00513 if(flipnormal) 00514 SWAP(int, index[0], index[2]); 00515 00516 index+= 3; 00517 efa= efa->next; 00518 } 00519 } 00520 00521 BLI_addhead(to, dlnew); 00522 00523 } 00524 BLI_end_edgefill(); 00525 00526 if(nextcol) { 00527 /* stay at current char but fill polys with next material */ 00528 colnr++; 00529 } else { 00530 /* switch to next char and start filling from first material */ 00531 charidx++; 00532 colnr= 0; 00533 } 00534 } 00535 00536 /* do not free polys, needed for wireframe display */ 00537 00538 } 00539 00540 static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase) 00541 { 00542 ListBase front, back; 00543 DispList *dl, *dlnew; 00544 float *fp, *fp1; 00545 int a, dpoly; 00546 00547 front.first= front.last= back.first= back.last= NULL; 00548 00549 dl= dispbase->first; 00550 while(dl) { 00551 if(dl->type==DL_SURF) { 00552 if( (dl->flag & DL_CYCL_V) && (dl->flag & DL_CYCL_U)==0 ) { 00553 if( (cu->flag & CU_BACK) && (dl->flag & DL_BACK_CURVE) ) { 00554 dlnew= MEM_callocN(sizeof(DispList), "filldisp"); 00555 BLI_addtail(&front, dlnew); 00556 dlnew->verts= fp1= MEM_mallocN(sizeof(float)*3*dl->parts, "filldisp1"); 00557 dlnew->nr= dl->parts; 00558 dlnew->parts= 1; 00559 dlnew->type= DL_POLY; 00560 dlnew->col= dl->col; 00561 dlnew->charidx = dl->charidx; 00562 00563 fp= dl->verts; 00564 dpoly= 3*dl->nr; 00565 00566 a= dl->parts; 00567 while(a--) { 00568 VECCOPY(fp1, fp); 00569 fp1+= 3; 00570 fp+= dpoly; 00571 } 00572 } 00573 if( (cu->flag & CU_FRONT) && (dl->flag & DL_FRONT_CURVE) ) { 00574 dlnew= MEM_callocN(sizeof(DispList), "filldisp"); 00575 BLI_addtail(&back, dlnew); 00576 dlnew->verts= fp1= MEM_mallocN(sizeof(float)*3*dl->parts, "filldisp1"); 00577 dlnew->nr= dl->parts; 00578 dlnew->parts= 1; 00579 dlnew->type= DL_POLY; 00580 dlnew->col= dl->col; 00581 dlnew->charidx= dl->charidx; 00582 00583 fp= dl->verts+3*(dl->nr-1); 00584 dpoly= 3*dl->nr; 00585 00586 a= dl->parts; 00587 while(a--) { 00588 VECCOPY(fp1, fp); 00589 fp1+= 3; 00590 fp+= dpoly; 00591 } 00592 } 00593 } 00594 } 00595 dl= dl->next; 00596 } 00597 00598 filldisplist(&front, dispbase, 1); 00599 filldisplist(&back, dispbase, 0); 00600 00601 freedisplist(&front); 00602 freedisplist(&back); 00603 00604 filldisplist(dispbase, dispbase, 0); 00605 00606 } 00607 00608 static void curve_to_filledpoly(Curve *cu, ListBase *UNUSED(nurb), ListBase *dispbase) 00609 { 00610 if(cu->flag & CU_3D) return; 00611 00612 if(dispbase->first && ((DispList*) dispbase->first)->type==DL_SURF) { 00613 bevels_to_filledpoly(cu, dispbase); 00614 } 00615 else { 00616 filldisplist(dispbase, dispbase, 0); 00617 } 00618 } 00619 00620 /* taper rules: 00621 - only 1 curve 00622 - first point left, last point right 00623 - based on subdivided points in original curve, not on points in taper curve (still) 00624 */ 00625 float calc_taper(Scene *scene, Object *taperobj, int cur, int tot) 00626 { 00627 DispList *dl; 00628 00629 if(taperobj==NULL || taperobj->type!=OB_CURVE) return 1.0; 00630 00631 dl= taperobj->disp.first; 00632 if(dl==NULL) { 00633 makeDispListCurveTypes(scene, taperobj, 0); 00634 dl= taperobj->disp.first; 00635 } 00636 if(dl) { 00637 float fac= ((float)cur)/(float)(tot-1); 00638 float minx, dx, *fp; 00639 int a; 00640 00641 /* horizontal size */ 00642 minx= dl->verts[0]; 00643 dx= dl->verts[3*(dl->nr-1)] - minx; 00644 if(dx > 0.0f) { 00645 00646 fp= dl->verts; 00647 for(a=0; a<dl->nr; a++, fp+=3) { 00648 if( (fp[0]-minx)/dx >= fac) { 00649 /* interpolate with prev */ 00650 if(a>0) { 00651 float fac1= (fp[-3]-minx)/dx; 00652 float fac2= (fp[0]-minx)/dx; 00653 if(fac1!=fac2) 00654 return fp[1]*(fac1-fac)/(fac1-fac2) + fp[-2]*(fac-fac2)/(fac1-fac2); 00655 } 00656 return fp[1]; 00657 } 00658 } 00659 return fp[-2]; // last y coord 00660 } 00661 } 00662 00663 return 1.0; 00664 } 00665 00666 void makeDispListMBall(Scene *scene, Object *ob) 00667 { 00668 if(!ob || ob->type!=OB_MBALL) return; 00669 00670 // XXX: mball stuff uses plenty of global variables 00671 // while this is unchanged updating during render is unsafe 00672 if(G.rendering) return; 00673 00674 freedisplist(&(ob->disp)); 00675 00676 if(ob->type==OB_MBALL) { 00677 if(ob==find_basis_mball(scene, ob)) { 00678 metaball_polygonize(scene, ob, &ob->disp); 00679 tex_space_mball(ob); 00680 00681 object_deform_mball(ob, &ob->disp); 00682 } 00683 } 00684 00685 boundbox_displist(ob); 00686 } 00687 00688 void makeDispListMBall_forRender(Scene *scene, Object *ob, ListBase *dispbase) 00689 { 00690 metaball_polygonize(scene, ob, dispbase); 00691 tex_space_mball(ob); 00692 00693 object_deform_mball(ob, dispbase); 00694 } 00695 00696 static ModifierData *curve_get_tesselate_point(Scene *scene, Object *ob, int forRender, int editmode) 00697 { 00698 ModifierData *md = modifiers_getVirtualModifierList(ob); 00699 ModifierData *preTesselatePoint; 00700 int required_mode; 00701 00702 if(forRender) required_mode = eModifierMode_Render; 00703 else required_mode = eModifierMode_Realtime; 00704 00705 if(editmode) required_mode |= eModifierMode_Editmode; 00706 00707 preTesselatePoint = NULL; 00708 for (; md; md=md->next) { 00709 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 00710 00711 if (!modifier_isEnabled(scene, md, required_mode)) continue; 00712 if (mti->type == eModifierTypeType_Constructive) return preTesselatePoint; 00713 00714 if (ELEM3(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_MeshDeform)) { 00715 preTesselatePoint = md; 00716 00717 /* this modifiers are moving point of tesselation automatically 00718 (some of them even can't be applied on tesselated curve), set flag 00719 for incformation button in modifier's header */ 00720 md->mode |= eModifierMode_ApplyOnSpline; 00721 } else if(md->mode&eModifierMode_ApplyOnSpline) { 00722 preTesselatePoint = md; 00723 } 00724 } 00725 00726 return preTesselatePoint; 00727 } 00728 00729 static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, float (**originalVerts_r)[3], float (**deformedVerts_r)[3], int *numVerts_r) 00730 { 00731 ModifierData *md = modifiers_getVirtualModifierList(ob); 00732 ModifierData *preTesselatePoint; 00733 Curve *cu= ob->data; 00734 ListBase *nurb= BKE_curve_nurbs(cu); 00735 int numVerts = 0; 00736 int editmode = (!forRender && cu->editnurb); 00737 float (*originalVerts)[3] = NULL; 00738 float (*deformedVerts)[3] = NULL; 00739 float *keyVerts= NULL; 00740 int required_mode; 00741 00742 if(forRender) required_mode = eModifierMode_Render; 00743 else required_mode = eModifierMode_Realtime; 00744 00745 preTesselatePoint = curve_get_tesselate_point(scene, ob, forRender, editmode); 00746 00747 if(editmode) required_mode |= eModifierMode_Editmode; 00748 00749 if(cu->editnurb==NULL) { 00750 keyVerts= do_ob_key(scene, ob); 00751 00752 if(keyVerts) { 00753 /* split coords from key data, the latter also includes 00754 tilts, which is passed through in the modifier stack. 00755 this is also the reason curves do not use a virtual 00756 shape key modifier yet. */ 00757 deformedVerts= curve_getKeyVertexCos(cu, nurb, keyVerts); 00758 originalVerts= MEM_dupallocN(deformedVerts); 00759 } 00760 } 00761 00762 if (preTesselatePoint) { 00763 for (; md; md=md->next) { 00764 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 00765 00766 md->scene= scene; 00767 00768 if ((md->mode & required_mode) != required_mode) continue; 00769 if (mti->isDisabled && mti->isDisabled(md, forRender)) continue; 00770 if (mti->type!=eModifierTypeType_OnlyDeform) continue; 00771 00772 if (!deformedVerts) { 00773 deformedVerts = curve_getVertexCos(cu, nurb, &numVerts); 00774 originalVerts = MEM_dupallocN(deformedVerts); 00775 } 00776 00777 mti->deformVerts(md, ob, NULL, deformedVerts, numVerts, forRender, editmode); 00778 00779 if (md==preTesselatePoint) 00780 break; 00781 } 00782 } 00783 00784 if (deformedVerts) 00785 curve_applyVertexCos(cu, nurb, deformedVerts); 00786 if (keyVerts) /* these are not passed through modifier stack */ 00787 curve_applyKeyVertexTilts(cu, nurb, keyVerts); 00788 00789 if(keyVerts) 00790 MEM_freeN(keyVerts); 00791 00792 *originalVerts_r = originalVerts; 00793 *deformedVerts_r = deformedVerts; 00794 *numVerts_r = numVerts; 00795 } 00796 00797 static float (*displist_get_allverts (ListBase *dispbase, int *totvert))[3] 00798 { 00799 DispList *dl; 00800 float (*allverts)[3], *fp; 00801 00802 *totvert= 0; 00803 00804 for (dl=dispbase->first; dl; dl=dl->next) 00805 *totvert+= (dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr; 00806 00807 allverts= MEM_mallocN((*totvert)*sizeof(float)*3, "displist_get_allverts allverts"); 00808 fp= (float*)allverts; 00809 for (dl=dispbase->first; dl; dl=dl->next) { 00810 int offs= 3 * ((dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr); 00811 memcpy(fp, dl->verts, sizeof(float) * offs); 00812 fp+= offs; 00813 } 00814 00815 return allverts; 00816 } 00817 00818 static void displist_apply_allverts(ListBase *dispbase, float (*allverts)[3]) 00819 { 00820 DispList *dl; 00821 float *fp; 00822 00823 fp= (float*)allverts; 00824 for (dl=dispbase->first; dl; dl=dl->next) { 00825 int offs= 3 * ((dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr); 00826 memcpy(dl->verts, fp, sizeof(float) * offs); 00827 fp+= offs; 00828 } 00829 } 00830 00831 static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispbase, 00832 DerivedMesh **derivedFinal, int forRender, float (*originalVerts)[3], float (*deformedVerts)[3]) 00833 { 00834 ModifierData *md = modifiers_getVirtualModifierList(ob); 00835 ModifierData *preTesselatePoint; 00836 Curve *cu= ob->data; 00837 ListBase *nurb= BKE_curve_nurbs(cu); 00838 int required_mode = 0, totvert = 0; 00839 int editmode = (!forRender && cu->editnurb); 00840 DerivedMesh *dm= NULL, *ndm; 00841 float (*vertCos)[3] = NULL; 00842 00843 if(forRender) required_mode = eModifierMode_Render; 00844 else required_mode = eModifierMode_Realtime; 00845 00846 preTesselatePoint = curve_get_tesselate_point(scene, ob, forRender, editmode); 00847 00848 if(editmode) required_mode |= eModifierMode_Editmode; 00849 00850 if (preTesselatePoint) { 00851 md = preTesselatePoint->next; 00852 } 00853 00854 if (derivedFinal && *derivedFinal) { 00855 (*derivedFinal)->release (*derivedFinal); 00856 } 00857 00858 for (; md; md=md->next) { 00859 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 00860 00861 md->scene= scene; 00862 00863 if ((md->mode & required_mode) != required_mode) continue; 00864 if (mti->isDisabled && mti->isDisabled(md, forRender)) continue; 00865 00866 if (mti->type == eModifierTypeType_OnlyDeform || 00867 (mti->type == eModifierTypeType_DeformOrConstruct && !dm)) { 00868 if (dm) { 00869 if (!vertCos) { 00870 totvert = dm->getNumVerts(dm); 00871 vertCos = MEM_mallocN(sizeof(*vertCos) * totvert, "dfmv"); 00872 dm->getVertCos(dm, vertCos); 00873 } 00874 00875 mti->deformVerts(md, ob, dm, vertCos, totvert, forRender, editmode); 00876 } else { 00877 if (!vertCos) { 00878 vertCos= displist_get_allverts(dispbase, &totvert); 00879 } 00880 00881 mti->deformVerts(md, ob, NULL, vertCos, totvert, forRender, editmode); 00882 } 00883 } else { 00884 if (!derivedFinal) { 00885 /* makeDisplistCurveTypes could be used for beveling, where derived mesh */ 00886 /* is totally unnecessary, so we could stop modifiers applying */ 00887 /* when we found constructive modifier but derived mesh is unwanted result */ 00888 break; 00889 } 00890 00891 if (dm) { 00892 if (vertCos) { 00893 DerivedMesh *tdm = CDDM_copy(dm); 00894 dm->release(dm); 00895 dm = tdm; 00896 00897 CDDM_apply_vert_coords(dm, vertCos); 00898 CDDM_calc_normals(dm); 00899 } 00900 } else { 00901 if (vertCos) { 00902 displist_apply_allverts(dispbase, vertCos); 00903 } 00904 00905 if (ELEM(ob->type, OB_CURVE, OB_FONT) && (cu->flag & CU_DEFORM_FILL)) { 00906 curve_to_filledpoly(cu, nurb, dispbase); 00907 } 00908 00909 dm= CDDM_from_curve_customDB(ob, dispbase); 00910 00911 CDDM_calc_normals(dm); 00912 } 00913 00914 if (vertCos) { 00915 /* Vertex coordinates were applied to necessary data, could free it */ 00916 MEM_freeN(vertCos); 00917 vertCos= NULL; 00918 } 00919 00920 ndm = mti->applyModifier(md, ob, dm, forRender, editmode); 00921 00922 if (ndm) { 00923 /* Modifier returned a new derived mesh */ 00924 00925 if (dm && dm != ndm) /* Modifier */ 00926 dm->release (dm); 00927 dm = ndm; 00928 } 00929 } 00930 } 00931 00932 if (vertCos) { 00933 if (dm) { 00934 DerivedMesh *tdm = CDDM_copy(dm); 00935 dm->release(dm); 00936 dm = tdm; 00937 00938 CDDM_apply_vert_coords(dm, vertCos); 00939 CDDM_calc_normals(dm); 00940 MEM_freeN(vertCos); 00941 } else { 00942 displist_apply_allverts(dispbase, vertCos); 00943 MEM_freeN(vertCos); 00944 vertCos= NULL; 00945 } 00946 } 00947 00948 if (derivedFinal) { 00949 (*derivedFinal) = dm; 00950 } 00951 00952 if (deformedVerts) { 00953 curve_applyVertexCos(ob->data, nurb, originalVerts); 00954 MEM_freeN(originalVerts); 00955 MEM_freeN(deformedVerts); 00956 } 00957 } 00958 00959 static void displist_surf_indices(DispList *dl) 00960 { 00961 int a, b, p1, p2, p3, p4; 00962 int *index; 00963 00964 dl->totindex= 0; 00965 00966 index=dl->index= MEM_mallocN( 4*sizeof(int)*(dl->parts+1)*(dl->nr+1), "index array nurbs"); 00967 00968 for(a=0; a<dl->parts; a++) { 00969 00970 if (surfindex_displist(dl, a, &b, &p1, &p2, &p3, &p4)==0) 00971 break; 00972 00973 for(; b<dl->nr; b++, index+=4) { 00974 index[0]= p1; 00975 index[1]= p2; 00976 index[2]= p4; 00977 index[3]= p3; 00978 00979 dl->totindex++; 00980 00981 p2= p1; p1++; 00982 p4= p3; p3++; 00983 00984 } 00985 } 00986 00987 } 00988 00989 static DerivedMesh *create_orco_dm(Scene *scene, Object *ob) 00990 { 00991 DerivedMesh *dm; 00992 ListBase disp= {NULL, NULL}; 00993 00994 /* OrcoDM should be created from underformed disp lists */ 00995 makeDispListCurveTypes_forOrco(scene, ob, &disp); 00996 dm= CDDM_from_curve_customDB(ob, &disp); 00997 00998 freedisplist(&disp); 00999 01000 return dm; 01001 } 01002 01003 static void add_orco_dm(Scene *scene, Object *ob, DerivedMesh *dm, DerivedMesh *orcodm) 01004 { 01005 float (*orco)[3], (*layerorco)[3]; 01006 int totvert, a; 01007 Curve *cu= ob->data; 01008 01009 totvert= dm->getNumVerts(dm); 01010 01011 if(orcodm) { 01012 orco= MEM_callocN(sizeof(float)*3*totvert, "dm orco"); 01013 01014 if(orcodm->getNumVerts(orcodm) == totvert) 01015 orcodm->getVertCos(orcodm, orco); 01016 else 01017 dm->getVertCos(dm, orco); 01018 } 01019 else { 01020 orco= (float(*)[3])make_orco_curve(scene, ob); 01021 } 01022 01023 for(a=0; a<totvert; a++) { 01024 float *co = orco[a]; 01025 co[0] = (co[0]-cu->loc[0])/cu->size[0]; 01026 co[1] = (co[1]-cu->loc[1])/cu->size[1]; 01027 co[2] = (co[2]-cu->loc[2])/cu->size[2]; 01028 } 01029 01030 if((layerorco = DM_get_vert_data_layer(dm, CD_ORCO))) { 01031 memcpy(layerorco, orco, sizeof(float)*totvert); 01032 MEM_freeN(orco); 01033 } 01034 else 01035 DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, orco); 01036 } 01037 01038 static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *derivedFinal, int forRender) 01039 { 01040 /* this function represents logic of mesh's orcodm calculation */ 01041 /* for displist-based objects */ 01042 01043 ModifierData *md = modifiers_getVirtualModifierList(ob); 01044 ModifierData *preTesselatePoint; 01045 Curve *cu= ob->data; 01046 int required_mode; 01047 int editmode = (!forRender && cu->editnurb); 01048 DerivedMesh *ndm, *orcodm= NULL; 01049 01050 if(forRender) required_mode = eModifierMode_Render; 01051 else required_mode = eModifierMode_Realtime; 01052 01053 preTesselatePoint = curve_get_tesselate_point(scene, ob, forRender, editmode); 01054 01055 if(editmode) required_mode |= eModifierMode_Editmode; 01056 01057 if (preTesselatePoint) { 01058 md = preTesselatePoint->next; 01059 } 01060 01061 for (; md; md=md->next) { 01062 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 01063 01064 md->scene= scene; 01065 01066 if ((md->mode & required_mode) != required_mode) continue; 01067 if (mti->isDisabled && mti->isDisabled(md, forRender)) continue; 01068 if (mti->type!=eModifierTypeType_Constructive) continue; 01069 01070 if(!orcodm) 01071 orcodm= create_orco_dm(scene, ob); 01072 01073 ndm = mti->applyModifier(md, ob, orcodm, forRender, 0); 01074 01075 if(ndm) { 01076 /* if the modifier returned a new dm, release the old one */ 01077 if(orcodm && orcodm != ndm) { 01078 orcodm->release(orcodm); 01079 } 01080 orcodm = ndm; 01081 } 01082 } 01083 01084 /* add an orco layer if needed */ 01085 add_orco_dm(scene, ob, derivedFinal, orcodm); 01086 01087 if(orcodm) 01088 orcodm->release(orcodm); 01089 } 01090 01091 void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase, 01092 DerivedMesh **derivedFinal, int forRender, int forOrco) 01093 { 01094 ListBase *nubase; 01095 Nurb *nu; 01096 Curve *cu = ob->data; 01097 DispList *dl; 01098 float *data; 01099 int len; 01100 int numVerts; 01101 float (*originalVerts)[3]; 01102 float (*deformedVerts)[3]; 01103 01104 if(!forRender && cu->editnurb) 01105 nubase= ED_curve_editnurbs(cu); 01106 else 01107 nubase= &cu->nurb; 01108 01109 if(!forOrco) 01110 curve_calc_modifiers_pre(scene, ob, forRender, &originalVerts, &deformedVerts, &numVerts); 01111 01112 for (nu=nubase->first; nu; nu=nu->next) { 01113 if(forRender || nu->hide==0) { 01114 int resolu= nu->resolu, resolv= nu->resolv; 01115 01116 if(forRender){ 01117 if(cu->resolu_ren) resolu= cu->resolu_ren; 01118 if(cu->resolv_ren) resolv= cu->resolv_ren; 01119 } 01120 01121 if(nu->pntsv==1) { 01122 len= SEGMENTSU(nu)*resolu; 01123 01124 dl= MEM_callocN(sizeof(DispList), "makeDispListsurf"); 01125 dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts"); 01126 01127 BLI_addtail(dispbase, dl); 01128 dl->parts= 1; 01129 dl->nr= len; 01130 dl->col= nu->mat_nr; 01131 dl->charidx= nu->charidx; 01132 01133 /* dl->rt will be used as flag for render face and */ 01134 /* CU_2D conflicts with R_NOPUNOFLIP */ 01135 dl->rt= nu->flag & ~CU_2D; 01136 01137 data= dl->verts; 01138 if(nu->flagu & CU_NURB_CYCLIC) dl->type= DL_POLY; 01139 else dl->type= DL_SEGM; 01140 01141 makeNurbcurve(nu, data, NULL, NULL, NULL, resolu, 3*sizeof(float)); 01142 } 01143 else { 01144 len= (nu->pntsu*resolu) * (nu->pntsv*resolv); 01145 01146 dl= MEM_callocN(sizeof(DispList), "makeDispListsurf"); 01147 dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts"); 01148 BLI_addtail(dispbase, dl); 01149 01150 dl->col= nu->mat_nr; 01151 dl->charidx= nu->charidx; 01152 01153 /* dl->rt will be used as flag for render face and */ 01154 /* CU_2D conflicts with R_NOPUNOFLIP */ 01155 dl->rt= nu->flag & ~CU_2D; 01156 01157 data= dl->verts; 01158 dl->type= DL_SURF; 01159 01160 dl->parts= (nu->pntsu*resolu); /* in reverse, because makeNurbfaces works that way */ 01161 dl->nr= (nu->pntsv*resolv); 01162 if(nu->flagv & CU_NURB_CYCLIC) dl->flag|= DL_CYCL_U; /* reverse too! */ 01163 if(nu->flagu & CU_NURB_CYCLIC) dl->flag|= DL_CYCL_V; 01164 01165 makeNurbfaces(nu, data, 0, resolu, resolv); 01166 01167 /* gl array drawing: using indices */ 01168 displist_surf_indices(dl); 01169 } 01170 } 01171 } 01172 01173 /* make copy of 'undeformed" displist for texture space calculation 01174 actually, it's not totally undeformed -- pre-tesselation modifiers are 01175 already applied, thats how it worked for years, so keep for compatibility (sergey) */ 01176 copy_displist(&cu->disp, dispbase); 01177 01178 if (!forRender) { 01179 tex_space_curve(cu); 01180 } 01181 01182 if(!forOrco) 01183 curve_calc_modifiers_post(scene, ob, dispbase, derivedFinal, 01184 forRender, originalVerts, deformedVerts); 01185 } 01186 01187 static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispbase, 01188 DerivedMesh **derivedFinal, int forRender, int forOrco) 01189 { 01190 Curve *cu = ob->data; 01191 01192 /* we do allow duplis... this is only displist on curve level */ 01193 if(!ELEM3(ob->type, OB_SURF, OB_CURVE, OB_FONT)) return; 01194 01195 if(ob->type==OB_SURF) { 01196 makeDispListSurf(scene, ob, dispbase, derivedFinal, forRender, forOrco); 01197 } 01198 else if (ELEM(ob->type, OB_CURVE, OB_FONT)) { 01199 ListBase dlbev; 01200 ListBase *nubase; 01201 float (*originalVerts)[3]; 01202 float (*deformedVerts)[3]; 01203 int numVerts; 01204 01205 nubase= BKE_curve_nurbs(cu); 01206 01207 BLI_freelistN(&(cu->bev)); 01208 01209 if(cu->path) free_path(cu->path); 01210 cu->path= NULL; 01211 01212 if(ob->type==OB_FONT) BKE_text_to_curve(scene, ob, 0); 01213 01214 if(!forOrco) curve_calc_modifiers_pre(scene, ob, forRender, &originalVerts, &deformedVerts, &numVerts); 01215 01216 makeBevelList(ob); 01217 01218 /* If curve has no bevel will return nothing */ 01219 makebevelcurve(scene, ob, &dlbev, forRender); 01220 01221 /* no bevel or extrude, and no width correction? */ 01222 if (!dlbev.first && cu->width==1.0f) { 01223 curve_to_displist(cu, nubase, dispbase, forRender); 01224 } else { 01225 float widfac= cu->width - 1.0f; 01226 BevList *bl= cu->bev.first; 01227 Nurb *nu= nubase->first; 01228 01229 for (; bl && nu; bl=bl->next,nu=nu->next) { 01230 DispList *dl; 01231 float *fp1, *data; 01232 BevPoint *bevp; 01233 int a,b; 01234 01235 if (bl->nr) { /* blank bevel lists can happen */ 01236 01237 /* exception handling; curve without bevel or extrude, with width correction */ 01238 if(dlbev.first==NULL) { 01239 dl= MEM_callocN(sizeof(DispList), "makeDispListbev"); 01240 dl->verts= MEM_callocN(3*sizeof(float)*bl->nr, "dlverts"); 01241 BLI_addtail(dispbase, dl); 01242 01243 if(bl->poly!= -1) dl->type= DL_POLY; 01244 else dl->type= DL_SEGM; 01245 01246 if(dl->type==DL_SEGM) dl->flag = (DL_FRONT_CURVE|DL_BACK_CURVE); 01247 01248 dl->parts= 1; 01249 dl->nr= bl->nr; 01250 dl->col= nu->mat_nr; 01251 dl->charidx= nu->charidx; 01252 01253 /* dl->rt will be used as flag for render face and */ 01254 /* CU_2D conflicts with R_NOPUNOFLIP */ 01255 dl->rt= nu->flag & ~CU_2D; 01256 01257 a= dl->nr; 01258 bevp= (BevPoint *)(bl+1); 01259 data= dl->verts; 01260 while(a--) { 01261 data[0]= bevp->vec[0]+widfac*bevp->sina; 01262 data[1]= bevp->vec[1]+widfac*bevp->cosa; 01263 data[2]= bevp->vec[2]; 01264 bevp++; 01265 data+=3; 01266 } 01267 } 01268 else { 01269 DispList *dlb; 01270 01271 for (dlb=dlbev.first; dlb; dlb=dlb->next) { 01272 01273 /* for each part of the bevel use a separate displblock */ 01274 dl= MEM_callocN(sizeof(DispList), "makeDispListbev1"); 01275 dl->verts= data= MEM_callocN(3*sizeof(float)*dlb->nr*bl->nr, "dlverts"); 01276 BLI_addtail(dispbase, dl); 01277 01278 dl->type= DL_SURF; 01279 01280 dl->flag= dlb->flag & (DL_FRONT_CURVE|DL_BACK_CURVE); 01281 if(dlb->type==DL_POLY) dl->flag |= DL_CYCL_U; 01282 if(bl->poly>=0) dl->flag |= DL_CYCL_V; 01283 01284 dl->parts= bl->nr; 01285 dl->nr= dlb->nr; 01286 dl->col= nu->mat_nr; 01287 dl->charidx= nu->charidx; 01288 01289 /* dl->rt will be used as flag for render face and */ 01290 /* CU_2D conflicts with R_NOPUNOFLIP */ 01291 dl->rt= nu->flag & ~CU_2D; 01292 01293 dl->bevelSplitFlag= MEM_callocN(sizeof(*dl->col2)*((bl->nr+0x1F)>>5), "bevelSplitFlag"); 01294 01295 /* for each point of poly make a bevel piece */ 01296 bevp= (BevPoint *)(bl+1); 01297 for(a=0; a<bl->nr; a++,bevp++) { 01298 float fac=1.0; 01299 if (cu->taperobj==NULL) { 01300 if ( (cu->bevobj!=NULL) || !((cu->flag & CU_FRONT) || (cu->flag & CU_BACK)) ) 01301 fac = bevp->radius; 01302 } else { 01303 fac = calc_taper(scene, cu->taperobj, a, bl->nr); 01304 } 01305 01306 if (bevp->split_tag) { 01307 dl->bevelSplitFlag[a>>5] |= 1<<(a&0x1F); 01308 } 01309 01310 /* rotate bevel piece and write in data */ 01311 fp1= dlb->verts; 01312 for (b=0; b<dlb->nr; b++,fp1+=3,data+=3) { 01313 if(cu->flag & CU_3D) { 01314 float vec[3]; 01315 01316 vec[0]= fp1[1]+widfac; 01317 vec[1]= fp1[2]; 01318 vec[2]= 0.0; 01319 01320 mul_qt_v3(bevp->quat, vec); 01321 01322 data[0]= bevp->vec[0] + fac*vec[0]; 01323 data[1]= bevp->vec[1] + fac*vec[1]; 01324 data[2]= bevp->vec[2] + fac*vec[2]; 01325 } 01326 else { 01327 data[0]= bevp->vec[0] + fac*(widfac+fp1[1])*bevp->sina; 01328 data[1]= bevp->vec[1] + fac*(widfac+fp1[1])*bevp->cosa; 01329 data[2]= bevp->vec[2] + fac*fp1[2]; 01330 } 01331 } 01332 } 01333 01334 /* gl array drawing: using indices */ 01335 displist_surf_indices(dl); 01336 } 01337 } 01338 } 01339 01340 } 01341 freedisplist(&dlbev); 01342 } 01343 01344 if (!(cu->flag & CU_DEFORM_FILL)) { 01345 curve_to_filledpoly(cu, nubase, dispbase); 01346 } 01347 01348 if(cu->flag & CU_PATH) calc_curvepath(ob); 01349 01350 /* make copy of 'undeformed" displist for texture space calculation 01351 actually, it's not totally undeformed -- pre-tesselation modifiers are 01352 already applied, thats how it worked for years, so keep for compatibility (sergey) */ 01353 copy_displist(&cu->disp, dispbase); 01354 01355 if (!forRender) { 01356 tex_space_curve(cu); 01357 } 01358 01359 if(!forOrco) curve_calc_modifiers_post(scene, ob, dispbase, derivedFinal, forRender, originalVerts, deformedVerts); 01360 01361 if (cu->flag & CU_DEFORM_FILL && !ob->derivedFinal) { 01362 curve_to_filledpoly(cu, nubase, dispbase); 01363 } 01364 } 01365 } 01366 01367 void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco) 01368 { 01369 Curve *cu= ob->data; 01370 ListBase *dispbase; 01371 01372 freedisplist(&(ob->disp)); 01373 dispbase= &(ob->disp); 01374 freedisplist(dispbase); 01375 01376 /* free displist used for textspace */ 01377 freedisplist(&cu->disp); 01378 01379 do_makeDispListCurveTypes(scene, ob, dispbase, &ob->derivedFinal, 0, forOrco); 01380 01381 if (ob->derivedFinal) { 01382 DM_set_object_boundbox (ob, ob->derivedFinal); 01383 } else { 01384 boundbox_displist (ob); 01385 01386 /* if there is no derivedMesh, object's boundbox is unneeded */ 01387 if (ob->bb) { 01388 MEM_freeN(ob->bb); 01389 ob->bb= NULL; 01390 } 01391 } 01392 } 01393 01394 void makeDispListCurveTypes_forRender(Scene *scene, Object *ob, ListBase *dispbase, 01395 DerivedMesh **derivedFinal, int forOrco) 01396 { 01397 do_makeDispListCurveTypes(scene, ob, dispbase, derivedFinal, 1, forOrco); 01398 } 01399 01400 void makeDispListCurveTypes_forOrco(struct Scene *scene, struct Object *ob, struct ListBase *dispbase) 01401 { 01402 do_makeDispListCurveTypes(scene, ob, dispbase, NULL, 1, 1); 01403 } 01404 01405 /* add Orco layer to the displist object which has got derived mesh and return orco */ 01406 float *makeOrcoDispList(Scene *scene, Object *ob, DerivedMesh *derivedFinal, int forRender) { 01407 float *orco; 01408 01409 if (derivedFinal == NULL) 01410 derivedFinal= ob->derivedFinal; 01411 01412 if (!derivedFinal->getVertDataArray(derivedFinal, CD_ORCO)) { 01413 curve_calc_orcodm(scene, ob, derivedFinal, forRender); 01414 } 01415 01416 orco= derivedFinal->getVertDataArray(derivedFinal, CD_ORCO); 01417 01418 if(orco) { 01419 orco= MEM_dupallocN(orco); 01420 } 01421 01422 return orco; 01423 } 01424 01425 /* this is confusing, there's also min_max_object, appplying the obmat... */ 01426 static void boundbox_displist(Object *ob) 01427 { 01428 BoundBox *bb=NULL; 01429 float min[3], max[3]; 01430 DispList *dl; 01431 float *vert; 01432 int a, tot=0; 01433 01434 INIT_MINMAX(min, max); 01435 01436 if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) { 01437 Curve *cu= ob->data; 01438 int doit= 0; 01439 01440 if(cu->bb==NULL) cu->bb= MEM_callocN(sizeof(BoundBox), "boundbox"); 01441 bb= cu->bb; 01442 01443 dl= ob->disp.first; 01444 01445 while (dl) { 01446 if(dl->type==DL_INDEX3) tot= dl->nr; 01447 else tot= dl->nr*dl->parts; 01448 01449 vert= dl->verts; 01450 for(a=0; a<tot; a++, vert+=3) { 01451 doit= 1; 01452 DO_MINMAX(vert, min, max); 01453 } 01454 01455 dl= dl->next; 01456 } 01457 01458 if(!doit) { 01459 /* there's no geometry in displist, use zero-sized boundbox */ 01460 zero_v3(min); 01461 zero_v3(max); 01462 } 01463 01464 } 01465 01466 if(bb) { 01467 boundbox_set_from_min_max(bb, min, max); 01468 } 01469 } 01470