00001 #include "cpolyhedron.h"
00002
00003 #include "htransform.h"
00004 #include "error.h"
00005
00006 #include <string.h>
00007 #include <math.h>
00008
00009
00028 void ReadOFF(FILE *f,Tcpolyhedron *p);
00029
00044 void GenerateCylinderOFF(unsigned int g,Tcpolyhedron *p);
00045
00058 void ReadCylinder(FILE *f,unsigned int g,Tcpolyhedron *p);
00059
00074 void GenerateSphereOFF(unsigned int g,Tcpolyhedron *p);
00075
00088 void ReadSphere(FILE *f,unsigned int g,Tcpolyhedron *p);
00089
00090 void ReadOFF(FILE *f,Tcpolyhedron *p)
00091 {
00092 unsigned int i,j;
00093 double av;
00094
00095 p->type=OFF;
00096
00097 fscanf(f,"%u",&(p->nv));
00098 fscanf(f,"%u",&(p->nf));
00099 fscanf(f,"%u",&(p->ne));
00100 if ((p->nv==0)||(p->nf==0))
00101 Error("Empty OFF");
00102
00103 NEW(p->v,p->nv,double*);
00104 for(i=0;i<p->nv;i++)
00105 {
00106 NEW(p->v[i],3,double);
00107 fscanf(f,"%lf",&(p->v[i][0]));
00108 fscanf(f,"%lf",&(p->v[i][1]));
00109 fscanf(f,"%lf",&(p->v[i][2]));
00110 }
00111
00112 NEW(p->nvf,p->nf,unsigned int);
00113 NEW(p->fv,p->nf,unsigned int*);
00114 for(i=0;i<p->nf;i++)
00115 {
00116 fscanf(f,"%u",&(p->nvf[i]));
00117 if (p->nvf[i]==0)
00118 Error("Empty face in OFF");
00119 NEW(p->fv[i],p->nvf[i],unsigned int);
00120
00121 for(j=0;j<p->nvf[i];j++)
00122 fscanf(f,"%u",&(p->fv[i][j]));
00123 }
00124
00125
00126 p->rad=0;
00127 p->center[0]=p->center[1]=p->center[2]=0.0;
00128
00129
00130 p->p1[0]=p->p1[1]=p->p1[2]=0.0;
00131 p->p2[0]=p->p2[1]=p->p2[2]=0.0;
00132
00133
00134 p->maxCoord=0;
00135 for(i=0;i<p->nv;i++)
00136 {
00137 for(j=0;j<3;j++)
00138 {
00139 av=fabs(p->v[i][j]);
00140 if (av>p->maxCoord)
00141 p->maxCoord=av;
00142 }
00143 }
00144 }
00145
00146 void GenerateCylinderOFF(unsigned int g,Tcpolyhedron *p)
00147 {
00148 unsigned int i,j,n;
00149 THTransform m;
00150 double a,av;
00151
00152 if (p->type!=CYLINDER)
00153 Error("Using GenerateCylinderOFF in a non cylindric convex polyhedron");
00154
00155
00156
00157 n=4+g;
00158 p->nv=2*n;
00159 NEW(p->v,p->nv,double*);
00160 for(i=0;i<n;i++)
00161 {
00162 NEW(p->v[i],3,double);
00163 NEW(p->v[n+i],3,double);
00164
00165 p->v[i][0]=0;
00166 p->v[n+i][0]=1;
00167
00168 a=(double)i/(double)n*M_2PI;
00169 p->v[i][1]=p->v[n+i][1]=cos(a);
00170 p->v[i][2]=p->v[n+i][2]=sin(a);
00171 }
00172
00173
00174 HTransformX2Vect(p->rad,p->rad,p->p1,p->p2,&m);
00175
00176 for(i=0;i<p->nv;i++)
00177 HTransformApply(p->v[i],p->v[i],&m);
00178
00179
00180 p->nf=0;
00181 p->fv=NULL;
00182 p->nvf=NULL;
00183
00184 HTransformDelete(&m);
00185
00186
00187 p->maxCoord=0;
00188 for(i=0;i<p->nv;i++)
00189 {
00190 for(j=0;j<3;j++)
00191 {
00192 av=fabs(p->v[i][j]);
00193 if (av>p->maxCoord)
00194 p->maxCoord=av;
00195 }
00196 }
00197 }
00198
00199 void ReadCylinder(FILE *f,unsigned int g,Tcpolyhedron *p)
00200 {
00201 p->type=CYLINDER;
00202
00203 fscanf(f,"%lf",&(p->rad));
00204
00205 fscanf(f,"%lf",&(p->p1[0]));
00206 fscanf(f,"%lf",&(p->p1[1]));
00207 fscanf(f,"%lf",&(p->p1[2]));
00208
00209 fscanf(f,"%lf",&(p->p2[0]));
00210 fscanf(f,"%lf",&(p->p2[1]));
00211 fscanf(f,"%lf",&(p->p2[2]));
00212
00213
00214 p->center[0]=p->center[1]=p->center[2]=0.0;
00215
00216
00217 GenerateCylinderOFF(g,p);
00218 }
00219
00220 void GenerateSphereOFF(unsigned int g,Tcpolyhedron *p)
00221 {
00222 unsigned int i,j,n,m;
00223 double **meridian;
00224 THTransform rz,tr;
00225 double a,offset,av;
00226
00227 if (p->type!=SPHERE)
00228 Error("Using GenerateCylinderOFF in a non spheric convex polyhedron");
00229
00230
00231 n=1+g;
00232 m=4+g;
00233
00234 offset=M_PI_2/((double)(n+1));
00235 a=0.0;
00236
00237 NEW(meridian,2*n,double*);
00238 for(i=0;i<n;i++)
00239 {
00240 a+=offset;
00241 NEW(meridian[i],3,double);
00242 meridian[i][0]=p->rad*cos(a);
00243 meridian[i][1]=0.0;
00244 meridian[i][2]=p->rad*sin(a);
00245
00246 NEW(meridian[n+i],3,double);
00247 meridian[n+i][0]=meridian[i][0];
00248 meridian[n+i][1]=0.0;
00249 meridian[n+i][2]=-meridian[i][2];
00250 }
00251
00252 p->nv=2*n*m;
00253 NEW(p->v,p->nv,double*);
00254 for(i=0;i<p->nv;i++)
00255 NEW(p->v[i],3,double);
00256
00257 a=0.0;
00258 offset=M_2PI/(double)m;
00259
00260 for(j=0;j<m;j++)
00261 {
00262 HTransformTxyz(p->center[0],p->center[1],p->center[2],&tr);
00263 HTransformRz(a,&rz);
00264 HTransformProduct(&tr,&rz,&tr);
00265 for(i=0;i<2*n;i++)
00266 HTransformApply(meridian[i],p->v[j*(2*n)+i],&tr);
00267
00268 a+=offset;
00269
00270 HTransformDelete(&tr);
00271 HTransformDelete(&rz);
00272 }
00273
00274 for(i=0;i<2*n;i++)
00275 free(meridian[i]);
00276 free(meridian);
00277
00278
00279 p->nf=0;
00280 p->fv=NULL;
00281 p->nvf=NULL;
00282
00283
00284 p->maxCoord=0;
00285 for(i=0;i<p->nv;i++)
00286 {
00287 for(j=0;j<3;j++)
00288 {
00289 av=fabs(p->v[i][j]);
00290 if (av>p->maxCoord)
00291 p->maxCoord=av;
00292 }
00293 }
00294 }
00295
00296 void ReadSphere(FILE *f,unsigned int g,Tcpolyhedron *p)
00297 {
00298 p->type=SPHERE;
00299
00300 fscanf(f,"%lf",&(p->rad));
00301
00302 fscanf(f,"%lf",&(p->center[0]));
00303 fscanf(f,"%lf",&(p->center[1]));
00304 fscanf(f,"%lf",&(p->center[2]));
00305
00306
00307 p->p1[0]=p->p1[1]=p->p1[2]=0.0;
00308 p->p2[0]=p->p2[1]=p->p2[2]=0.0;
00309
00310
00311 GenerateSphereOFF(g,p);
00312 }
00313
00314 void InitCPolyhedronFromFile(char *fname,Tcolor *c,
00315 unsigned int gr,Tcpolyhedron *p)
00316 {
00317 FILE *f;
00318 char *stmp;
00319 boolean off, cylinder,sphere;
00320
00321 CopyColor(&(p->color),c);
00322
00323 p->obj3d=NO_UINT;
00324
00325 NEW(stmp,20,char);
00326
00327 f=fopen(fname,"r");
00328 if (!f)
00329 Error("Could not open CPolyhedron file");
00330
00331 fscanf(f,"%s",stmp);
00332
00333 off=(strcmp(stmp,"OFF")==0);
00334 cylinder=(strcmp(stmp,"CYLINDER")==0);
00335 sphere=(strcmp(stmp,"SPHERE")==0);
00336
00337 if ((!off)&&(!cylinder)&&(!sphere))
00338 Error("Unknow type of shape");
00339
00340 if (off)
00341 ReadOFF(f,p);
00342
00343 if (cylinder)
00344 ReadCylinder(f,gr,p);
00345
00346 if (sphere)
00347 ReadSphere(f,gr,p);
00348
00349 free(stmp);
00350 fclose(f);
00351 }
00352
00353 void NewSphere(double r,double *center,Tcolor *c,
00354 unsigned int gr,Tcpolyhedron *p)
00355 {
00356 p->type=SPHERE;
00357
00358 CopyColor(&(p->color),c);
00359 p->obj3d=NO_UINT;
00360
00361
00362 p->rad=r;
00363
00364 p->center[0]=center[0];
00365 p->center[1]=center[1];
00366 p->center[2]=center[2];
00367
00368
00369 p->p1[0]=p->p1[1]=p->p1[2]=0.0;
00370 p->p2[0]=p->p2[1]=p->p2[2]=0.0;
00371
00372
00373 GenerateSphereOFF(gr,p);
00374 }
00375
00376 void NewCylinder(double r,double *p1,double *p2,Tcolor *c,
00377 unsigned int gr,Tcpolyhedron *p)
00378 {
00379 p->type=CYLINDER;
00380
00381 CopyColor(&(p->color),c);
00382 p->obj3d=NO_UINT;
00383
00384
00385 p->rad=r;
00386
00387 p->p1[0]=p1[0];
00388 p->p1[1]=p1[1];
00389 p->p1[2]=p1[2];
00390
00391 p->p2[0]=p2[0];
00392 p->p2[1]=p2[1];
00393 p->p2[2]=p2[2];
00394
00395
00396 p->center[0]=p->center[1]=p->center[2]=0.0;
00397
00398
00399 GenerateCylinderOFF(gr,p);
00400 }
00401
00402
00403 void CopyCPolyhedron(Tcpolyhedron *p_dst,Tcpolyhedron *p_src)
00404 {
00405 unsigned int i,j;
00406
00407 p_dst->type=p_src->type;
00408
00409
00410 CopyColor(&(p_dst->color),&(p_src->color));
00411
00412 p_dst->obj3d=p_src->obj3d;
00413
00414
00415 p_dst->nv=p_src->nv;
00416 p_dst->nf=p_src->nf;
00417 p_dst->ne=p_src->ne;
00418
00419 NEW(p_dst->v,p_src->nv,double*);
00420 for(i=0;i<p_dst->nv;i++)
00421 {
00422 NEW(p_dst->v[i],3,double);
00423 p_dst->v[i][0]=p_src->v[i][0];
00424 p_dst->v[i][1]=p_src->v[i][1];
00425 p_dst->v[i][2]=p_src->v[i][2];
00426 }
00427
00428 NEW(p_dst->nvf,p_dst->nf,unsigned int);
00429 NEW(p_dst->fv,p_dst->nf,unsigned int*);
00430 for(i=0;i<p_dst->nf;i++)
00431 {
00432 p_dst->nvf[i]=p_src->nvf[i];
00433 NEW(p_dst->fv[i],p_dst->nvf[i],unsigned int);
00434
00435 for(j=0;j<p_dst->nvf[i];j++)
00436 p_dst->fv[i][j]=p_src->fv[i][j];
00437 }
00438
00439
00440 p_dst->rad=p_src->rad;
00441 for(i=0;i<3;i++)
00442 {
00443 p_dst->center[i]=p_src->center[i];
00444 p_dst->p1[i]=p_src->p1[i];
00445 p_dst->p2[i]=p_src->p2[i];
00446 }
00447
00448 p_dst->maxCoord=p_src->maxCoord;
00449 }
00450
00451 void TransformCPolyhedron(THTransform *t,Tcpolyhedron *p)
00452 {
00453 unsigned int i,j;
00454 double av;
00455
00456
00457 p->maxCoord=0;
00458 for(i=0;i<p->nv;i++)
00459 {
00460 HTransformApply(p->v[i],p->v[i],t);
00461 for(j=0;j<3;j++)
00462 {
00463 av=fabs(p->v[i][j]);
00464 if (av>p->maxCoord)
00465 p->maxCoord=av;
00466 }
00467 }
00468
00469
00470 HTransformApply(p->center,p->center,t);
00471 HTransformApply(p->p1,p->p1,t);
00472 HTransformApply(p->p2,p->p2,t);
00473 }
00474
00475 unsigned int GetCPolyhedronType(Tcpolyhedron *p)
00476 {
00477 return(p->type);
00478 }
00479
00480 void SetCPolyhedronColor(Tcolor *c,Tcpolyhedron *p)
00481 {
00482 CopyColor(&(p->color),c);
00483 }
00484
00485 void GetCPolyhedronColor(Tcolor *c,Tcpolyhedron *p)
00486 {
00487 CopyColor(c,&(p->color));
00488 }
00489
00490 unsigned int GetCPolyhedronNVertex(Tcpolyhedron *p)
00491 {
00492 return(p->nv);
00493 }
00494
00495 void GetCPolyhedronDefiningPoint(unsigned int i,double *point,Tcpolyhedron *p)
00496 {
00497 unsigned int j;
00498
00499 switch(p->type)
00500 {
00501 case CYLINDER:
00502 if (i>1)
00503 Error("Vertex counter out of range in GetCPolyhedronInterestPoint");
00504
00505 if (i==0)
00506 {
00507 for(j=0;j<3;j++)
00508 point[j]=p->p1[j];
00509 }
00510 else
00511 {
00512 for(j=0;j<3;j++)
00513 point[j]=p->p2[j];
00514 }
00515 break;
00516
00517 case SPHERE:
00518 if (i>0)
00519 Error("Vertex counter out of range in GetCPolyhedronInterestPoint");
00520
00521 for(j=0;j<3;j++)
00522 point[j]=p->center[j];
00523 break;
00524
00525 case OFF:
00526 GetCPolyhedronVertex(i,point,p);
00527 break;
00528
00529 default:
00530 Error("Undefined CPolyhedron type in GetCPolyhedronInterestPoint");
00531 break;
00532 }
00533 }
00534
00535 double GetCpolyhedronRadius(Tcpolyhedron *p)
00536 {
00537 if (p->type==OFF)
00538 Error("Radius is not defined for OFFs");
00539 return(p->rad);
00540 }
00541
00542 void GetCPolyhedronVertex(unsigned int i,double *point,Tcpolyhedron *p)
00543 {
00544 unsigned int j;
00545
00546 if (i>=p->nv)
00547 Error("Vertex counter out of range");
00548
00549 for(j=0;j<3;j++)
00550 point[j]=p->v[i][j];
00551 }
00552
00553 double GetCPolyhedronMaxCoordinate(Tcpolyhedron *p)
00554 {
00555 return(p->maxCoord);
00556 }
00557
00558 void PlotCPolyhedron(Tplot3d *pt,Tcpolyhedron *p)
00559 {
00560 p->obj3d=StartNew3dObject(&(p->color),pt);
00561
00562 switch(p->type)
00563 {
00564 case OFF:
00565 Plot3dObject(p->nv,p->nf,p->ne,p->v,p->nvf,p->fv,pt);
00566 break;
00567 case CYLINDER:
00568 PlotCylinder(p->rad,p->p1,p->p2,pt);
00569
00570
00571
00572
00573
00574
00575
00576
00577 break;
00578 case SPHERE:
00579 PlotSphere(p->rad,p->center[0],p->center[1],p->center[2],pt);
00580
00581
00582
00583
00584
00585
00586
00587
00588 break;
00589 }
00590
00591 Close3dObject(pt);
00592 }
00593
00594 void MoveCPolyhedron(Tplot3d *pt,THTransform *t,Tcpolyhedron *p)
00595 {
00596 if (p->obj3d!=NO_UINT)
00597 Move3dObject(p->obj3d,t,pt);
00598 }
00599
00600 void SaveCPolyhedron(char *fileName,Tcpolyhedron *p)
00601 {
00602 FILE *f;
00603 unsigned int i,j;
00604
00605 f=fopen(fileName,"w");
00606 if (!f)
00607 Error("Could not open output file for a convex polyhedron");
00608
00609 switch(p->type)
00610 {
00611 case OFF:
00612 fprintf(f,"OFF\n");
00613 fprintf(f,"%u %u 1\n\n",p->nv,p->nf);
00614 for(i=0;i<p->nv;i++)
00615 fprintf(f,"%f %f %f\n",p->v[i][0],p->v[i][1],p->v[i][2]);
00616 fprintf(f,"\n");
00617 for(i=0;i<p->nf;i++)
00618 {
00619 fprintf(f,"%u ",p->nvf[i]);
00620 for(j=0;j<p->nvf[i];j++)
00621 fprintf(f," %u",p->fv[i][j]);
00622 fprintf(f,"\n");
00623 }
00624 break;
00625 case CYLINDER:
00626 fprintf(f,"CYLINDER\n");
00627 fprintf(f,"%f\n",p->rad);
00628 fprintf(f,"%f %f %f\n",p->p1[0],p->p1[1],p->p1[2]);
00629 fprintf(f,"%f %f %f\n",p->p2[0],p->p2[1],p->p2[2]);
00630 break;
00631 case SPHERE:
00632 fprintf(f,"SPHERE\n");
00633 fprintf(f,"%f\n",p->rad);
00634 fprintf(f,"%f %f %f\n",p->center[0],p->center[1],p->center[2]);
00635 break;
00636 }
00637
00638 fclose(f);
00639 }
00640
00641 void DeleteCPolyhedron(Tcpolyhedron *p)
00642 {
00643 unsigned int i;
00644
00645 for(i=0;i<p->nv;i++)
00646 free(p->v[i]);
00647 free(p->v);
00648
00649 if (p->nf>0)
00650 {
00651 for(i=0;i<p->nf;i++)
00652 free(p->fv[i]);
00653
00654 free(p->fv);
00655 free(p->nvf);
00656 }
00657 }
00658
00659