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