polyhedron.c
Go to the documentation of this file.
1 #include "polyhedron.h"
2 
3 #include "htransform.h"
4 #include "error.h"
5 #include "algebra.h"
6 #include "geom.h"
7 #include "boolean.h"
8 
9 #include <stdio.h>
10 #include <math.h>
11 #include <string.h>
12 #include <strings.h>
13 #include <xlocale.h>
14 #include <sys/stat.h>
15 
16 #if (_ASSIMP)
17  #include <assimp/cimport.h>
18  #include <assimp/scene.h>
19  #include <assimp/postprocess.h>
20 #endif
21 
40 boolean ReadGeneralMesh(char *fn,Tpolyhedron *p);
41 
53 void ReadSTL(char *fn,Tpolyhedron *p);
54 
65 void ReadOFF(FILE *f,Tpolyhedron *p);
66 
81 void GenerateCylinderOFF(unsigned int g,Tpolyhedron *p);
82 
93 void ReadLine(FILE *f,Tpolyhedron *p);
94 
105 void ReadSegments(FILE *f,Tpolyhedron *p);
106 
119 void ReadCylinder(FILE *f,unsigned int g,Tpolyhedron *p);
120 
135 void GenerateSphereOFF(unsigned int g,Tpolyhedron *p);
136 
149 void ReadSphere(FILE *f,unsigned int g,Tpolyhedron *p);
150 
151 #if (_ASSIMP)
152 
165 void ProcessSceneNode(unsigned int *oV,unsigned int *oF,
166  Tpolyhedron *p,const struct aiScene *sc,const struct aiNode *nd);
167 
168 void ProcessSceneNode(unsigned int *oV,unsigned int *oF,
169  Tpolyhedron *p,const struct aiScene *sc,const struct aiNode *nd)
170 {
171  unsigned int i,j,k;
172  THTransform tr;
173  const struct aiMesh *mesh;
174  unsigned int ndxV,ndxF;
175 
176  /* Get the transform for this node */
177  HTransformSetElement(0,0,nd->mTransformation.a1,&tr);
178  HTransformSetElement(0,1,nd->mTransformation.a2,&tr);
179  HTransformSetElement(0,2,nd->mTransformation.a3,&tr);
180  HTransformSetElement(0,3,nd->mTransformation.a4,&tr);
181 
182  HTransformSetElement(1,0,nd->mTransformation.b1,&tr);
183  HTransformSetElement(1,1,nd->mTransformation.b2,&tr);
184  HTransformSetElement(1,2,nd->mTransformation.b3,&tr);
185  HTransformSetElement(1,3,nd->mTransformation.b4,&tr);
186 
187  HTransformSetElement(2,0,nd->mTransformation.c1,&tr);
188  HTransformSetElement(2,1,nd->mTransformation.c2,&tr);
189  HTransformSetElement(2,2,nd->mTransformation.c3,&tr);
190  HTransformSetElement(2,3,nd->mTransformation.c4,&tr);
191 
192  HTransformSetElement(3,0,nd->mTransformation.d1,&tr);
193  HTransformSetElement(3,1,nd->mTransformation.d2,&tr);
194  HTransformSetElement(3,2,nd->mTransformation.d3,&tr);
195  HTransformSetElement(3,3,nd->mTransformation.d4,&tr);
196 
197  /* Add the meshes to the polyhedron structure */
198  for(k=0;k<nd->mNumMeshes;k++)
199  {
200  mesh=sc->mMeshes[nd->mMeshes[k]];
201 
202  for(i=0;i<mesh->mNumVertices;i++)
203  {
204  ndxV=(*oV)+i;
205  NEW(p->v[ndxV],3,double);
206  p->v[ndxV][0]=(double)mesh->mVertices[i].x;
207  p->v[ndxV][1]=(double)mesh->mVertices[i].y;
208  p->v[ndxV][2]=(double)mesh->mVertices[i].z;
209 
210  HTransformApply(p->v[ndxV],p->v[ndxV],&tr);
211  }
212 
213  for(i=0;i<mesh->mNumFaces;i++)
214  {
215  ndxF=(*oF)+i;
216  p->nvf[ndxF]=mesh->mFaces[i].mNumIndices;
217  NEW(p->fv[ndxF],p->nvf[i],unsigned int);
218  for(j=0;j<p->nvf[ndxF];j++)
219  p->fv[ndxF][j]=((*oV)+mesh->mFaces[i].mIndices[j]);
220  }
221  (*oV)+=mesh->mNumVertices;
222  (*oF)+=mesh->mNumFaces;
223  }
224 
225  /* Recursively process the child nodes */
226  for(i=0;i<nd->mNumChildren;i++)
227  ProcessSceneNode(oV,oF,p,sc,nd->mChildren[i]);
228 }
229 #endif
230 
231 boolean ReadGeneralMesh(char *fn,Tpolyhedron *p)
232 {
233  boolean ok=FALSE;
234 
235  #if (_ASSIMP)
236  const struct aiScene *sc;
237 
238  /* We triangulate (as required by some collision detection
239  engines). */
240  sc=aiImportFile(fn,aiProcess_Triangulate);
241 
242  if (sc)
243  {
244  const struct aiMesh *mesh;
245  unsigned int k,oV,oF;
246 
247  p->type=OFF;
248 
249  ok=TRUE;
250 
251  /* Count the total number of vertices and faces
252  in the scene. */
253  p->nv=0;
254  p->nf=0;
255  for(k=0;k<sc->mNumMeshes;k++)
256  {
257  mesh=sc->mMeshes[k];
258 
259  p->nv+=mesh->mNumVertices;
260  p->nf+=mesh->mNumFaces;
261 
262  }
263  p->ne=0;/* Number of edges not used */
264 
265  /* allocate enough space for all the vertices */
266  NEW(p->v,p->nv,double*);
267  /* allocate space for all the faces */
268  NEW(p->nvf,p->nf,unsigned int);
269  NEW(p->fv,p->nf,unsigned int*);
270 
271  /* Recursively process all the nodes in the scene */
272  oV=0;
273  oF=0;
274  ProcessSceneNode(&oV,&oF,p,sc,sc->mRootNode);
275 
276  aiReleaseImport(sc);
277  }
278  else
279  Error("Error reading the geometry file");
280  #else
281  Error("The assimp library is missing");
282  #endif
283 
284  return(ok);
285 }
286 
287 void ReadSTL(char *fn,Tpolyhedron *p)
288 {
289  char header[75];
290  short int u;
291  float v[3];
292  double vd[3];
293  unsigned int nt,i,j,k;
294  boolean found;
295  FILE *f;
296 
297  f=fopen(fn,"rb");
298  if (!f)
299  Error("Can not open STL file");
300 
301  p->type=OFF;
302 
303  fread(header,sizeof(char),5,f);
304  header[5]=0;
305  if (strcasecmp(header,"SOLID")==0)
306  Error("Can not read ASCII STL files yet");
307  /* skip the rest of the header */
308  fread(header,sizeof(char),75,f);
309 
310  /* read the number of triangles */
311  fread(&nt,sizeof(int),1,f);
312 
313  p->nv=0; /* this will be increased as needed */
314  p->nf=nt;
315  p->ne=0; /* not used */
316 
317  /* allocate enough space for all the vertices */
318  NEW(p->v,nt,double*);
319 
320  /* and for all the faces */
321  NEW(p->nvf,nt,unsigned int);
322  NEW(p->fv,nt,unsigned int*);
323 
324  for(i=0;i<nt;i++)
325  {
326  /* skip the normal */
327  fread(v,sizeof(float),3,f);
328 
329  p->nvf[i]=3; /* all faces have 3 vertices */
330  NEW(p->fv[i],p->nvf[i],unsigned int);
331 
332  for(j=0;j<3;j++)
333  {
334  /* read the vertex and convert it to double */
335  fread(v,sizeof(float),3,f);
336  vd[0]=(double)v[0];
337  vd[1]=(double)v[1];
338  vd[2]=(double)v[2];
339 
340  /* Check if we already have this vertex (with 1e-3 accuracy) */
341  found=FALSE;
342  k=0;
343  while((!found)&&(k<p->nv))
344  {
345  found=(Distance(3,vd,p->v[k])<1e-3);
346  if (!found) k++;
347  }
348  if (!found)
349  {
350  /* k==p->nv */
351  NEW(p->v[k],3,double);
352  p->v[k][0]=vd[0];
353  p->v[k][1]=vd[1];
354  p->v[k][2]=vd[2];
355  p->nv++;
356  }
357  p->fv[i][j]=k;
358  }
359 
360  /* skip the tail (supposed to be 0 always) */
361  fread(&u,sizeof(short),1,f);
362  }
363  fclose(f);
364 }
365 
366 void ReadOFF(FILE *f,Tpolyhedron *p)
367 {
368  unsigned int i,j;
369  double av;
370 
371  p->type=OFF;
372 
373  fscanf(f,"%u",&(p->nv));
374  fscanf(f,"%u",&(p->nf));
375  fscanf(f,"%u",&(p->ne));
376  if ((p->nv==0)||(p->nf==0))
377  Error("Empty OFF");
378 
379  NEW(p->v,p->nv,double*);
380  for(i=0;i<p->nv;i++)
381  {
382  NEW(p->v[i],3,double);
383  fscanf(f,"%lf",&(p->v[i][0]));
384  fscanf(f,"%lf",&(p->v[i][1]));
385  fscanf(f,"%lf",&(p->v[i][2]));
386  }
387 
388  NEW(p->nvf,p->nf,unsigned int);
389  NEW(p->fv,p->nf,unsigned int*);
390  for(i=0;i<p->nf;i++)
391  {
392  fscanf(f,"%u",&(p->nvf[i]));
393  if (p->nvf[i]==0)
394  Error("Empty face in OFF");
395  NEW(p->fv[i],p->nvf[i],unsigned int);
396 
397  for(j=0;j<p->nvf[i];j++)
398  fscanf(f,"%u",&(p->fv[i][j]));
399  }
400 
401  /* Cancel the sphere information */
402  p->rad=0;
403  p->center[0]=p->center[1]=p->center[2]=0.0;
404 
405  /* and the cylinder information too */
406  p->p1[0]=p->p1[1]=p->p1[2]=0.0;
407  p->p2[0]=p->p2[1]=p->p2[2]=0.0;
408 
409  /* Compute the bounding box */
410  p->maxCoord=0;
411  for(i=0;i<p->nv;i++)
412  {
413  for(j=0;j<3;j++)
414  {
415  av=fabs(p->v[i][j]);
416  if (av>p->maxCoord)
417  p->maxCoord=av;
418  }
419  }
420 }
421 
422 void GenerateCylinderOFF(unsigned int g,Tpolyhedron *p)
423 {
424  unsigned int i,j,k,n;
425  THTransform m;
426  double a,av;
427 
428  if ((p->type!=CYLINDER)&&(p->type!=LINE))
429  Error("Using GenerateCylinderOFF in a non cylindric/line convex polyhedron");
430 
431  /*The points are defined on the reference cylinder (aligned along axis X
432  and with length 1 and radii 1) that is later on scaled and enlarged */
433  n=4+g;
434  p->nv=2*n;
435  NEW(p->v,p->nv,double*);
436  for(i=0;i<n;i++)
437  {
438  NEW(p->v[i],3,double);
439  NEW(p->v[n+i],3,double);
440 
441  p->v[i][0]=0;
442  p->v[n+i][0]=1;
443 
444  a=((double)i/(double)n)*M_2PI;
445  p->v[i][1]=p->v[n+i][1]=cos(a);
446  p->v[i][2]=p->v[n+i][2]=sin(a);
447  }
448 
449  /*Now rotate the points according to the cylinder orientation defined by p1,p2*/
450  HTransformX2Vect(p->rad,p->rad,p->p1,p->p2,&m);
451 
452  for(i=0;i<p->nv;i++)
453  HTransformApply(p->v[i],p->v[i],&m);
454 
455  HTransformDelete(&m);
456 
457  /* face information */
458  p->nf=n+2*(n-2);
459  p->ne=0; /* not used */
460 
461  NEW(p->nvf,p->nf,unsigned int);
462  NEW(p->fv,p->nf,unsigned int*);
463  /* lateral faces */
464  for(i=0;i<n;i++)
465  {
466  j=(i+1)%n;
467 
468  p->nvf[i]=4;
469  NEW(p->fv[i],4,unsigned int);
470  p->fv[i][0]=i;
471  p->fv[i][1]=i+n;
472  p->fv[i][2]=j+n;
473  p->fv[i][3]=j;
474  }
475  /* up faces */
476  for(i=2;i<n;i++)
477  {
478  k=n+i-2;
479  p->nvf[k]=3;
480  NEW(p->fv[k],3,unsigned int);
481  p->fv[k][0]=n+0;
482  p->fv[k][1]=n+i;
483  p->fv[k][2]=n+i-1;
484  }
485  for(i=2;i<n;i++)
486  {
487  k=n+(n-2)+i-2;
488  p->nvf[k]=3;
489  NEW(p->fv[k],3,unsigned int);
490  p->fv[k][0]=i-1;
491  p->fv[k][1]=i;
492  p->fv[k][2]=0;
493  }
494 
495  /* Compute the bounding box using the points that approximate the cylinder */
496  p->maxCoord=0;
497  for(i=0;i<p->nv;i++)
498  {
499  for(j=0;j<3;j++)
500  {
501  av=fabs(p->v[i][j]);
502  if (av>p->maxCoord)
503  p->maxCoord=av;
504  }
505  }
506 }
507 
508 void ReadLine(FILE *f,Tpolyhedron *p)
509 {
510  p->type=LINE;
511 
512  p->rad=0.01;
513 
514  fscanf(f,"%lf",&(p->p1[0]));
515  fscanf(f,"%lf",&(p->p1[1]));
516  fscanf(f,"%lf",&(p->p1[2]));
517 
518  fscanf(f,"%lf",&(p->p2[0]));
519  fscanf(f,"%lf",&(p->p2[1]));
520  fscanf(f,"%lf",&(p->p2[2]));
521 
522  /*Cancel sphere information*/
523  p->center[0]=p->center[1]=p->center[2]=0.0;
524 
525  /*Generate the OFF information*/
526  GenerateCylinderOFF(0,p);
527 }
528 
529 void ReadSegments(FILE *f,Tpolyhedron *p)
530 {
531  unsigned int i,j;
532  double av;
533 
534  p->type=SEGMENTS;
535 
536  fscanf(f,"%u",&(p->nv));
537 
538  NEW(p->v,p->nv,double*);
539  for(i=0;i<p->nv;i++)
540  {
541  NEW(p->v[i],3,double);
542  fscanf(f,"%lf",&(p->v[i][0]));
543  fscanf(f,"%lf",&(p->v[i][1]));
544  fscanf(f,"%lf",&(p->v[i][2]));
545  }
546  /* Compute the bounding box */
547  p->maxCoord=0;
548  for(i=0;i<p->nv;i++)
549  {
550  for(j=0;j<3;j++)
551  {
552  av=fabs(p->v[i][j]);
553  if (av>p->maxCoord)
554  p->maxCoord=av;
555  }
556  }
557 
558  /*Cancel sphere information*/
559  p->center[0]=p->center[1]=p->center[2]=0.0;
560 
561  /* Cancel cylinder/line info */
562  p->rad=0;
563  p->p1[0]=p->p1[1]=p->p1[2]=0.0;
564  p->p2[0]=p->p2[1]=p->p2[2]=0.0;
565 
566  /*Cancel OFF information*/
567  p->nf=0;
568  p->nvf=0;
569  p->ne=0;
570 }
571 
572 void ReadCylinder(FILE *f,unsigned int g,Tpolyhedron *p)
573 {
574  p->type=CYLINDER;
575 
576  fscanf(f,"%lf",&(p->rad));
577 
578  fscanf(f,"%lf",&(p->p1[0]));
579  fscanf(f,"%lf",&(p->p1[1]));
580  fscanf(f,"%lf",&(p->p1[2]));
581 
582  fscanf(f,"%lf",&(p->p2[0]));
583  fscanf(f,"%lf",&(p->p2[1]));
584  fscanf(f,"%lf",&(p->p2[2]));
585 
586  /*Cancel sphere information*/
587  p->center[0]=p->center[1]=p->center[2]=0.0;
588 
589  /*Generate the OFF information*/
590  GenerateCylinderOFF(g,p);
591 }
592 
593 void GenerateSphereOFF(unsigned int g,Tpolyhedron *p)
594 {
595  unsigned int i,j,k,in,r1,r2,n,m;
596  double **meridian;
597  THTransform tr,t;
598  double a,offset,av;
599 
600  if (p->type!=SPHERE)
601  Error("Using GenerateSphereOFF in a non spheric convex polyhedron");
602 
603  /*Vertex information for collision avoidance (in the future refined according to 'g')*/
604  n=3+g;
605  m=4+g;
606 
607  offset=M_PI/((double)n-1);
608  a=-M_PI_2;
609 
610  NEW(meridian,n,double*);
611  for(i=0;i<n;i++)
612  {
613  NEW(meridian[i],3,double);
614  meridian[i][0]=p->rad*cos(a);
615  meridian[i][1]=0.0;
616  meridian[i][2]=p->rad*sin(a);
617 
618  a+=offset;
619  }
620 
621  p->nv=n*m;
622  NEW(p->v,p->nv,double*);
623  for(i=0;i<p->nv;i++)
624  NEW(p->v[i],3,double);
625 
626  a=0.0;
627  offset=M_2PI/(double)m;
628 
629  HTransformTxyz(p->center[0],p->center[1],p->center[2],&t);
630  for(j=0;j<m;j++)
631  {
632  HTransformRz(a,&tr);
633  HTransformProduct(&t,&tr,&tr);
634  for(i=0;i<n;i++)
635  HTransformApply(meridian[i],p->v[j*n+i],&tr);
636 
637  a+=offset;
638 
639  HTransformDelete(&tr);
640  }
641  HTransformDelete(&t);
642 
643  for(i=0;i<n;i++)
644  free(meridian[i]);
645  free(meridian);
646 
647  /* face information */
648  p->nf=m*(n-2)+m;
649  p->ne=0; /* not used */
650 
651  NEW(p->nvf,p->nf,unsigned int);
652  NEW(p->fv,p->nf,unsigned int*);
653  k=0;
654  for(j=0;j<m;j++) /* for each meridian */
655  {
656  r1=j*n; //first point in this meridian
657  r2=((j+1)%m)*n; //first point in next meridian
658 
659  for(i=0;i<n-1;i++) /* for each point in the meridian */
660  {
661  in=i+1; // Next point in meridian. Never goes to 0 (i<n-1)
662 
663  // Define a face
664  if (i==0)
665  {
666  p->nvf[k]=3;
667  NEW(p->fv[k],3,unsigned int);
668  p->fv[k][0]=r1+i; // == r2+i
669  p->fv[k][1]=r2+in;
670  p->fv[k][2]=r1+in;
671  }
672  else
673  {
674  if (i==(n-2))
675  {
676  p->nvf[k]=3;
677  NEW(p->fv[k],3,unsigned int);
678  p->fv[k][0]=r1+i;
679  p->fv[k][1]=r2+i;
680  p->fv[k][2]=r1+in; // == r2+in
681  }
682  else
683  {
684  p->nvf[k]=4;
685  NEW(p->fv[k],4,unsigned int);
686  p->fv[k][0]=r1+i;
687  p->fv[k][1]=r2+i;
688  p->fv[k][2]=r2+in;
689  p->fv[k][3]=r1+in;
690  }
691  }
692  k++;
693  }
694  }
695 
696  /* Compute the bounding box using the points that approximate the sphere */
697  p->maxCoord=0;
698  for(i=0;i<p->nv;i++)
699  {
700  for(j=0;j<3;j++)
701  {
702  av=fabs(p->v[i][j]);
703  if (av>p->maxCoord)
704  p->maxCoord=av;
705  }
706  }
707 }
708 
709 void ReadSphere(FILE *f,unsigned int g,Tpolyhedron *p)
710 {
711  p->type=SPHERE;
712 
713  fscanf(f,"%lf",&(p->rad));
714 
715  fscanf(f,"%lf",&(p->center[0]));
716  fscanf(f,"%lf",&(p->center[1]));
717  fscanf(f,"%lf",&(p->center[2]));
718 
719  /*Cancel cylinder information*/
720  p->p1[0]=p->p1[1]=p->p1[2]=0.0;
721  p->p2[0]=p->p2[1]=p->p2[2]=0.0;
722 
723  /*Generate the OFF information*/
724  GenerateSphereOFF(g,p);
725 }
726 
728  unsigned int gr,unsigned int bs,Tpolyhedron *p)
729 {
730  char *ext;
731 
732  p->status=bs; /* normal, hidden, decoration*/
733 
734  if (bs==HIDDEN_SHAPE)
735  NewColor(1.0,1.0,1.0,c); /* for hidden shapes we use a default color */
736  else
737  CopyColor(&(p->color),c);
738 
739  p->obj3d=NO_UINT;
740 
741  ext=GetFileExtension(fname);
742  if ((ext==NULL)||(strcasecmp(ext,"OFF")==0))
743  {
744  /* Note that the CuikSuite uses and extended OFF
745  files which can also include the definition of
746  cylinders, spheres, lines, or sets of segments.
747  */
748  FILE *f;
749  char *stmp;
750  boolean off, cylinder,sphere,line,segments;
751 
752  NEW(stmp,20,char); /* 20 is enough to read OFF/SPHERE/CYLINDER */
753 
754  f=fopen(GetFileFullName(fname),"r");
755  if (!f)
756  Error("Could not open Polyhedron file");
757 
758  fscanf(f,"%s",stmp); /* OFF -> skip it */
759 
760  off=(strcasecmp(stmp,"OFF")==0);
761  cylinder=(strcasecmp(stmp,"CYLINDER")==0);
762  sphere=(strcasecmp(stmp,"SPHERE")==0);
763  line=(strcasecmp(stmp,"LINE")==0);
764  segments=(strcasecmp(stmp,"SEGMENTS")==0);
765 
766  if ((!off)&&(!cylinder)&&(!sphere)&&(!line)&&(!segments))
767  Error("Unknow type of shape");
768 
769  if (off)
770  ReadOFF(f,p);
771 
772  if (cylinder)
773  ReadCylinder(f,gr,p);
774 
775  if (line)
776  ReadLine(f,p);
777 
778  if (segments)
779  ReadSegments(f,p);
780 
781  if (sphere)
782  ReadSphere(f,gr,p);
783 
784  free(stmp);
785  fclose(f);
786  }
787  else
788  {
789  #if (_ASSIMP)
790  if (!ReadGeneralMesh(GetFileFullName(fname),p))
791  Error("Error reading geometry from file in InitPolyhedronFromFile");
792  #else
793  if (strcasecmp(ext,"STL")==0)
794  ReadSTL(GetFileFullName(fname),p);
795  else
796  Error("Unknown file type in InitPolyhedronFromFile. Try compiling with the Assimp library");
797  #endif
798  }
799 }
800 
801 void InitPolyhedronFromTriangles(unsigned int nv,double **v,
802  unsigned int nt,unsigned int **t,
803  Tcolor *c,unsigned int bs,Tpolyhedron *p)
804 {
805  unsigned int i,j;
806  double av;
807 
808  p->type=OFF;
809 
810  p->status=bs; /* normal, hidden, decoration*/
811  CopyColor(&(p->color),c);
812  p->obj3d=NO_UINT;
813 
814  p->nv=nv;
815  p->nf=nt;
816  p->ne=3*nt; /* not used */
817 
818  NEW(p->v,p->nv,double*);
819  for(i=0;i<p->nv;i++)
820  {
821  NEW(p->v[i],3,double);
822  for(j=0;j<3;j++)
823  p->v[i][j]=v[i][j];
824  }
825 
826  NEW(p->nvf,p->nf,unsigned int);
827  NEW(p->fv,p->nf,unsigned int*);
828  for(i=0;i<p->nf;i++)
829  {
830  p->nvf[i]=3; /* three vertices per face */
831  NEW(p->fv[i],p->nvf[i],unsigned int);
832  for(j=0;j<3;j++)
833  p->fv[i][j]=t[i][j];
834  }
835 
836  /* Cancel the sphere information */
837  p->rad=0;
838  p->center[0]=p->center[1]=p->center[2]=0.0;
839 
840  /* and the cylinder information too */
841  p->p1[0]=p->p1[1]=p->p1[2]=0.0;
842  p->p2[0]=p->p2[1]=p->p2[2]=0.0;
843 
844  /* Compute the bounding box */
845  p->maxCoord=0;
846  for(i=0;i<p->nv;i++)
847  {
848  for(j=0;j<3;j++)
849  {
850  av=fabs(p->v[i][j]);
851  if (av>p->maxCoord)
852  p->maxCoord=av;
853  }
854  }
855 }
856 
857 void NewBox(double xl,double yl,double zl,
858  double xu,double yu,double zu,
859  Tcolor *c,unsigned int bs,Tpolyhedron *p)
860 {
861  unsigned int i,j;
862  double av;
863 
864  if ((xu<=xl)||(yu<=yl)||(zu<=zl))
865  Error("Incorrect ranges in the box definition");
866 
867  p->type=OFF;
868 
869  p->status=bs; /* normal, hidden, decoration*/
870  CopyColor(&(p->color),c);
871  p->obj3d=NO_UINT;
872 
873  p->nv=8;
874  p->nf=6;
875  p->ne=12; /* not used */
876 
877  NEW(p->v,p->nv,double*);
878  for(i=0;i<p->nv;i++)
879  NEW(p->v[i],3,double);
880 
881  p->v[0][0]=xl; p->v[0][1]=yl; p->v[0][2]=zl;
882  p->v[1][0]=xl; p->v[1][1]=yu; p->v[1][2]=zl;
883  p->v[2][0]=xu; p->v[2][1]=yu; p->v[2][2]=zl;
884  p->v[3][0]=xu; p->v[3][1]=yl; p->v[3][2]=zl;
885  p->v[4][0]=xl; p->v[4][1]=yl; p->v[4][2]=zu;
886  p->v[5][0]=xl; p->v[5][1]=yu; p->v[5][2]=zu;
887  p->v[6][0]=xu; p->v[6][1]=yu; p->v[6][2]=zu;
888  p->v[7][0]=xu; p->v[7][1]=yl; p->v[7][2]=zu;
889 
890  NEW(p->nvf,p->nf,unsigned int);
891  NEW(p->fv,p->nf,unsigned int*);
892  for(i=0;i<p->nf;i++)
893  {
894  p->nvf[i]=4; /* four vertices per face */
895  NEW(p->fv[i],p->nvf[i],unsigned int);
896  }
897 
898  p->fv[0][0]=0; p->fv[0][1]=1; p->fv[0][2]=2; p->fv[0][3]=3;
899  p->fv[1][0]=6; p->fv[1][1]=5; p->fv[1][2]=4; p->fv[1][3]=7;
900  p->fv[2][0]=3; p->fv[2][1]=2; p->fv[2][2]=6; p->fv[2][3]=7;
901  p->fv[3][0]=2; p->fv[3][1]=1; p->fv[3][2]=5; p->fv[3][3]=6;
902  p->fv[4][0]=4; p->fv[4][1]=5; p->fv[4][2]=1; p->fv[4][3]=0;
903  p->fv[5][0]=3; p->fv[5][1]=0; p->fv[5][2]=4; p->fv[5][3]=7;
904 
905  /* Cancel the sphere information */
906  p->rad=0;
907  p->center[0]=p->center[1]=p->center[2]=0.0;
908 
909  /* and the cylinder information too */
910  p->p1[0]=p->p1[1]=p->p1[2]=0.0;
911  p->p2[0]=p->p2[1]=p->p2[2]=0.0;
912 
913  /* Compute the bounding box */
914  p->maxCoord=0;
915  for(i=0;i<p->nv;i++)
916  {
917  for(j=0;j<3;j++)
918  {
919  av=fabs(p->v[i][j]);
920  if (av>p->maxCoord)
921  p->maxCoord=av;
922  }
923  }
924 }
925 
926 void NewSphere(double r,double *center,Tcolor *c,
927  unsigned int gr,unsigned int bs,Tpolyhedron *p)
928 {
929  p->type=SPHERE;
930  p->status=bs; /* normal, hidden, decoration*/
931 
932  CopyColor(&(p->color),c);
933  p->obj3d=NO_UINT;
934 
935  /*Set the sphere information*/
936  p->rad=r;
937 
938  p->center[0]=center[0];
939  p->center[1]=center[1];
940  p->center[2]=center[2];
941 
942  /*Cancel cylinder information*/
943  p->p1[0]=p->p1[1]=p->p1[2]=0.0;
944  p->p2[0]=p->p2[1]=p->p2[2]=0.0;
945 
946  /*Generate the OFF information*/
947  GenerateSphereOFF(gr,p);
948 }
949 
950 void NewCylinder(double r,double *p1,double *p2,Tcolor *c,
951  unsigned int gr,unsigned int bs,Tpolyhedron *p)
952 {
953  p->type=CYLINDER;
954  p->status=bs; /* normal, hidden, decoration*/
955 
956  CopyColor(&(p->color),c);
957  p->obj3d=NO_UINT;
958 
959  /*Set the cylinder information*/
960  p->rad=r;
961 
962  p->p1[0]=p1[0];
963  p->p1[1]=p1[1];
964  p->p1[2]=p1[2];
965 
966  p->p2[0]=p2[0];
967  p->p2[1]=p2[1];
968  p->p2[2]=p2[2];
969 
970  /*Cancel sphere information*/
971  p->center[0]=p->center[1]=p->center[2]=0.0;
972 
973  /*Generate the OFF information*/
974  GenerateCylinderOFF(gr,p);
975 }
976 
977 void NewLine(double *p1,double *p2,Tcolor *c,
978  unsigned int bs,Tpolyhedron *p)
979 {
980  p->type=LINE;
981  p->status=bs; /* normal, hidden, decoration*/
982 
983  CopyColor(&(p->color),c);
984  p->obj3d=NO_UINT;
985 
986  /*Set the line information*/
987  p->rad=0.01; /* small radius for collision detection */
988 
989  p->p1[0]=p1[0];
990  p->p1[1]=p1[1];
991  p->p1[2]=p1[2];
992 
993  p->p2[0]=p2[0];
994  p->p2[1]=p2[1];
995  p->p2[2]=p2[2];
996 
997  /*Cancel sphere information*/
998  p->center[0]=p->center[1]=p->center[2]=0.0;
999 
1000  /*Generate the OFF information*/
1001  GenerateCylinderOFF(0,p);
1002 }
1003 
1004 void NewSegments(unsigned int n,double *x,double *y,double *z,Tcolor *c,
1005  Tpolyhedron *p)
1006 {
1007  unsigned int i,j;
1008  double av;
1009 
1010  p->type=SEGMENTS;
1011  p->status=DECOR_SHAPE; /* never included in collision detection */
1012 
1013  CopyColor(&(p->color),c);
1014  p->obj3d=NO_UINT;
1015 
1016  /*Set the segments information*/
1017  p->nv=n;
1018  NEW(p->v,n,double*);
1019  for(i=0;i<n;i++)
1020  {
1021  NEW(p->v[i],3,double);
1022  p->v[i][0]=x[i];
1023  p->v[i][1]=y[i];
1024  p->v[i][2]=z[i];
1025  }
1026 
1027  /* Compute the bounding box */
1028  p->maxCoord=0;
1029  for(i=0;i<p->nv;i++)
1030  {
1031  for(j=0;j<3;j++)
1032  {
1033  av=fabs(p->v[i][j]);
1034  if (av>p->maxCoord)
1035  p->maxCoord=av;
1036  }
1037  }
1038 
1039  /*Cancel sphere/cylinder information*/
1040  p->center[0]=p->center[1]=p->center[2]=0.0;
1041  p->rad=0;
1042  p->p1[0]=p->p1[1]=p->p1[2]=0.0;
1043  p->p2[0]=p->p2[1]=p->p2[2]=0.0;
1044 
1045  /*Cancel the OFF information*/
1046  p->nf=0;
1047  p->ne=0;
1048  p->nvf=0;
1049 }
1050 
1052 {
1053  unsigned int i,j;
1054 
1055  p_dst->type=p_src->type;
1056  p_dst->status=p_src->status;
1057 
1058  /*plot3d information*/
1059  CopyColor(&(p_dst->color),&(p_src->color));
1060 
1061  p_dst->obj3d=p_src->obj3d;
1062 
1063  /* off information */
1064  p_dst->nv=p_src->nv;
1065  p_dst->nf=p_src->nf;
1066  p_dst->ne=p_src->ne;
1067 
1068  if (p_dst->nv>0)
1069  {
1070  NEW(p_dst->v,p_src->nv,double*);
1071  for(i=0;i<p_dst->nv;i++)
1072  {
1073  NEW(p_dst->v[i],3,double);
1074  p_dst->v[i][0]=p_src->v[i][0];
1075  p_dst->v[i][1]=p_src->v[i][1];
1076  p_dst->v[i][2]=p_src->v[i][2];
1077  }
1078  }
1079  else
1080  p_dst->v=NULL;
1081 
1082  if (p_dst->nf>0)
1083  {
1084  NEW(p_dst->nvf,p_dst->nf,unsigned int);
1085  NEW(p_dst->fv,p_dst->nf,unsigned int*);
1086  for(i=0;i<p_dst->nf;i++)
1087  {
1088  p_dst->nvf[i]=p_src->nvf[i];
1089  NEW(p_dst->fv[i],p_dst->nvf[i],unsigned int);
1090 
1091  for(j=0;j<p_dst->nvf[i];j++)
1092  p_dst->fv[i][j]=p_src->fv[i][j];
1093  }
1094  }
1095  else
1096  {
1097  p_dst->nvf=NULL;
1098  p_dst->fv=NULL;
1099  }
1100 
1101  /*Sphere - Cylinder - Line information (if any)*/
1102  p_dst->rad=p_src->rad;
1103  for(i=0;i<3;i++)
1104  {
1105  p_dst->center[i]=p_src->center[i];
1106  p_dst->p1[i]=p_src->p1[i];
1107  p_dst->p2[i]=p_src->p2[i];
1108  }
1109 
1110  p_dst->maxCoord=p_src->maxCoord;
1111 }
1112 
1114 {
1115  /* if the transform is the identity just do not apply it */
1116  if (!HTransformIsIdentity(t))
1117  {
1118  unsigned int i,j;
1119  double av;
1120 
1121  if (p->nv>0)
1122  {
1123  /*Off information*/
1124  p->maxCoord=0;
1125  for(i=0;i<p->nv;i++)
1126  {
1127  HTransformApply(p->v[i],p->v[i],t);
1128  for(j=0;j<3;j++)
1129  {
1130  av=fabs(p->v[i][j]);
1131  if (av>p->maxCoord)
1132  p->maxCoord=av;
1133  }
1134  }
1135  }
1136 
1137  /*Sphere - Cylinder - Line information*/
1138  /* recall that sphere,cylinder,line also have vertices */
1139  HTransformApply(p->center,p->center,t);
1140  HTransformApply(p->p1,p->p1,t);
1141  HTransformApply(p->p2,p->p2,t);
1142  }
1143 }
1144 
1146 {
1147  if (p->type!=SPHERE)
1148  Error("GetPolyhedronCenter is only defined for spheres");
1149 
1150  c[0]=p->center[0];
1151  c[1]=p->center[1];
1152  c[2]=p->center[2];
1153 }
1154 
1156 {
1157  return(p->type);
1158 }
1159 
1161 {
1162  CopyColor(&(p->color),c);
1163 }
1164 
1166 {
1167  CopyColor(c,&(p->color));
1168 }
1169 
1171 {
1172  return(p->status);
1173 }
1174 
1175 void GetOFFInfo(unsigned int *nv,double ***v,unsigned int *nf,
1176  unsigned int **nvf,unsigned int ***fv,Tpolyhedron *p)
1177 {
1178  *nv=p->nv;
1179  *v=p->v;
1180  *nf=p->nf;
1181  *nvf=p->nvf;
1182  *fv=p->fv;
1183 }
1184 
1186 {
1187  return(p->nv);
1188 }
1189 
1190 void GetPolyhedronDefiningPoint(unsigned int i,double *point,Tpolyhedron *p)
1191 {
1192  unsigned int j;
1193 
1194  switch(p->type)
1195  {
1196  case CYLINDER:
1197  case LINE:
1198  if (i>1)
1199  Error("Point counter out of range in GetPolyhedronDefiningPoint");
1200 
1201  if (i==0)
1202  {
1203  for(j=0;j<3;j++)
1204  point[j]=p->p1[j];
1205  }
1206  else
1207  {
1208  for(j=0;j<3;j++)
1209  point[j]=p->p2[j];
1210  }
1211  break;
1212 
1213  case SPHERE:
1214  if (i>0)
1215  Error("Point counter out of range in GetPolyhedronDefiningPoint");
1216 
1217  for(j=0;j<3;j++)
1218  point[j]=p->center[j];
1219  break;
1220 
1221  case OFF:
1222  case SEGMENTS:
1223  GetPolyhedronVertex(i,point,p);
1224  break;
1225 
1226  default:
1227  Error("Undefined Polyhedron type in GetPolyhedronDefiningPoint");
1228  break;
1229  }
1230 }
1231 
1233 {
1234  if ((p->type==OFF)||(p->type==LINE)||(p->type==SEGMENTS))
1235  Error("Radius is not defined for OFFs,LINEs, or SEGMENTS");
1236  return(p->rad);
1237 }
1238 
1239 void GetPolyhedronVertex(unsigned int i,double *point,Tpolyhedron *p)
1240 {
1241  unsigned int j;
1242 
1243  if (i>=p->nv)
1244  Error("Vertex counter out of range");
1245 
1246  for(j=0;j<3;j++)
1247  point[j]=p->v[i][j];
1248 }
1249 
1251 {
1252  return(p->maxCoord);
1253 }
1254 
1256 {
1257  if (p->status!=HIDDEN_SHAPE)
1258  {
1259  p->obj3d=StartNew3dObject(&(p->color),pt);
1260 
1261  switch(p->type)
1262  {
1263  case OFF:
1264  Plot3dObject(p->nv,p->nf,p->ne,p->v,p->nvf,p->fv,pt);
1265  break;
1266  case LINE:
1267  PlotLine(p->p1,p->p2,pt);
1268  break;
1269  case CYLINDER:
1270  //PlotCylinder(p->rad,p->p1,p->p2,pt);
1271  Plot3dObject(p->nv,p->nf,p->ne,p->v,p->nvf,p->fv,pt);
1272  break;
1273  case SPHERE:
1274  PlotSphere(p->rad,p->center[0],p->center[1],p->center[2],pt);
1275  break;
1276  case SEGMENTS:
1277  PlotSegments(p->nv,p->v,pt);
1278  break;
1279  }
1280 
1281  Close3dObject(pt);
1282  }
1283 }
1284 
1286 {
1287  if (p->type==SPHERE)
1288  {
1289  double v[3];
1290 
1291  HTransformApply(p->center,v,t);
1292 
1293  fprintf(f,"%.16f %.16f %.16f\n",v[0],v[1],v[2]);
1294  }
1295 }
1296 
1298 {
1299  if (p->type==SPHERE)
1300  {
1301  double v[3];
1302 
1303  HTransformApply(p->center,v,t);
1304 
1305  fprintf(f,"%.16f %.16f %.16f %.16f\n",v[0],v[1],v[2],p->rad);
1306  }
1307 }
1308 
1310 {
1311  if ((p->obj3d!=NO_UINT)&&(p->status!=HIDDEN_SHAPE))
1312  Move3dObject(p->obj3d,t,pt);
1313 }
1314 
1315 void SavePolyhedron(char *fileName,Tpolyhedron *p)
1316 {
1317  FILE *f;
1318  unsigned int i,j;
1319 
1320  f=fopen(fileName,"w");
1321  if (!f)
1322  Error("Could not open output file for a convex polyhedron");
1323 
1324  switch(p->type)
1325  {
1326  case OFF:
1327  fprintf(f,"OFF\n");
1328  fprintf(f,"%u %u 1\n",p->nv,p->nf);
1329  for(i=0;i<p->nv;i++)
1330  fprintf(f,"%f %f %f\n",p->v[i][0],p->v[i][1],p->v[i][2]);
1331  fprintf(f,"\n");
1332  for(i=0;i<p->nf;i++)
1333  {
1334  fprintf(f,"%u ",p->nvf[i]);
1335  for(j=0;j<p->nvf[i];j++)
1336  fprintf(f," %u",p->fv[i][j]);
1337  fprintf(f,"\n");
1338  }
1339  break;
1340  case LINE:
1341  fprintf(f,"LINE\n");
1342  fprintf(f,"%.16f %.16f %.16f\n",p->p1[0],p->p1[1],p->p1[2]);
1343  fprintf(f,"%.16f %.16f %.16f\n",p->p2[0],p->p2[1],p->p2[2]);
1344  break;
1345  case CYLINDER:
1346  fprintf(f,"CYLINDER\n");
1347  fprintf(f,"%.16f\n",p->rad);
1348  fprintf(f,"%.16f %.16f %.16f\n",p->p1[0],p->p1[1],p->p1[2]);
1349  fprintf(f,"%.16f %.16f %.16f\n",p->p2[0],p->p2[1],p->p2[2]);
1350  break;
1351  case SPHERE:
1352  fprintf(f,"SPHERE\n");
1353  fprintf(f,"%.16f\n",p->rad);
1354  fprintf(f,"%.16f %.16f %.16f\n",p->center[0],p->center[1],p->center[2]);
1355  break;
1356  case SEGMENTS:
1357  fprintf(f,"SEGMENTS\n");
1358  fprintf(f,"%u\n",p->nv);
1359  for(i=0;i<p->nv;i++)
1360  fprintf(f,"%f %f %f\n",p->v[i][0],p->v[i][1],p->v[i][2]);
1361  break;
1362  }
1363  fclose(f);
1364 }
1365 
1366 void PrintPolyhedron(FILE *f,char *path,char *label,unsigned int n,Tpolyhedron *p)
1367 {
1368  unsigned int i;
1369 
1370  if (n>0)
1371  fprintf(f," ");
1372 
1373  switch(p->type)
1374  {
1375  case OFF:
1376  {
1377  unsigned int l;
1378  char *pname;
1379  Tfilename fbody;
1380 
1381  /* ensure that folder "bodies" exists */
1382  CreateFileName(path,"bodies",NULL,NULL,&fbody);
1383  mkdir(GetFileFullName(&fbody),0777);
1384  DeleteFileName(&fbody);
1385 
1386  /* store the object in file */
1387  if (label!=NULL)
1388  {
1389  l=strlen(label);
1390  NEW(pname,l+30,char);
1391  sprintf(pname,"bodies/%s_%u",label,n);
1392  }
1393  else
1394  {
1395  NEW(pname,30,char);
1396  sprintf(pname,"bodies/_body_%u",n);
1397  }
1398 
1399  CreateFileName(path,pname,NULL,OFF_EXT,&fbody);
1400 
1401  SavePolyhedron(GetFileFullName(&fbody),p);
1402  fprintf(f,"body \"%s\"",GetFileFullName(&fbody));
1403 
1404  DeleteFileName(&fbody);
1405  free(pname);
1406  }
1407  break;
1408  case LINE:
1409  fprintf(f,"line (");
1410  Print3Reals(f,p->p1[0],p->p1[1],p->p1[2]);
1411  fprintf(f,") (");
1412  Print3Reals(f,p->p2[0],p->p2[1],p->p2[2]);
1413  fprintf(f,")");
1414  break;
1415  case CYLINDER:
1416  fprintf(f,"cylinder %g (",p->rad);
1417  Print3Reals(f,p->p1[0],p->p1[1],p->p1[2]);
1418  fprintf(f,") (");
1419  Print3Reals(f,p->p2[0],p->p2[1],p->p2[2]);
1420  fprintf(f,")");
1421  break;
1422  case SPHERE:
1423  fprintf(f,"sphere %g (",p->rad);
1424  Print3Reals(f,p->center[0],p->center[1],p->center[2]);
1425  fprintf(f,")");
1426  break;
1427  case SEGMENTS:
1428  {
1429  /* Print the segments in blocks to avoid memory overflow in the parser*/
1430  unsigned int s,e;
1431  boolean end;
1432 
1433  end=FALSE;
1434  s=0;
1435  while(!end)
1436  {
1437  e=s+1000; /* Adjust this if you have memory overflow in the parser */
1438  if (e>=p->nv)
1439  {
1440  e=p->nv;
1441  end=TRUE;
1442  }
1443  fprintf(f,"segments (");
1444  for(i=s;i<e;i++)
1445  {
1446  Print3Reals(f,p->v[i][0],p->v[i][1],p->v[i][2]);
1447  if (i<e-1)
1448  {
1449  fprintf(f,";");
1450  if (((i-s)%2)==1) fprintf(f,"\n ");
1451  }
1452  }
1453  fprintf(f,") color (%g,%g,%g)\n ",
1454  GetRed(&(p->color)),GetGreen(&(p->color)),GetBlue(&(p->color)));
1455  s=e;
1456  }
1457  }
1458  break;
1459  }
1460 
1461  if (p->type!=SEGMENTS)
1462  {
1463  if (p->status!=HIDDEN_SHAPE)
1464  fprintf(f," color (%g,%g,%g)",
1465  GetRed(&(p->color)),GetGreen(&(p->color)),GetBlue(&(p->color)));
1466 
1467  switch(p->status)
1468  {
1469  case NORMAL_SHAPE:
1470  break;
1471  case HIDDEN_SHAPE:
1472  fprintf(f," hidden");
1473  break;
1474  case DECOR_SHAPE:
1475  fprintf(f," decoration");
1476  break;
1477  default:
1478  Error("Unknown body disply status in PrintPolyhedron");
1479  }
1480  }
1481  fprintf(f,"\n");
1482 }
1483 
1485 {
1486  unsigned int i;
1487 
1488  if (p->nv>0)
1489  {
1490  for(i=0;i<p->nv;i++)
1491  free(p->v[i]);
1492  free(p->v);
1493  }
1494 
1495  if (p->nf>0)
1496  {
1497  for(i=0;i<p->nf;i++)
1498  free(p->fv[i]);
1499 
1500  free(p->fv);
1501  free(p->nvf);
1502  }
1503 
1504 }
1505 
1506 
Definition of the boolean type.
void GetPolyhedronDefiningPoint(unsigned int i, double *point, Tpolyhedron *p)
Gets a point defining a a object.
Definition: polyhedron.c:1190
unsigned int ** fv
Definition: polyhedron.h:140
void PolyhedronPrintCenterAndCenter(FILE *f, THTransform *t, Tpolyhedron *p)
Prints the center and the radius of a sphere to a file.
Definition: polyhedron.c:1297
double p1[3]
Definition: polyhedron.h:146
Definition of basic functions.
void PrintPolyhedron(FILE *f, char *path, char *label, unsigned int n, Tpolyhedron *p)
Stores the polyhedron information into a file.
Definition: polyhedron.c:1366
double maxCoord
Definition: polyhedron.h:149
#define FALSE
FALSE.
Definition: boolean.h:30
void GetOFFInfo(unsigned int *nv, double ***v, unsigned int *nf, unsigned int **nvf, unsigned int ***fv, Tpolyhedron *p)
Gets the OFF information.
Definition: polyhedron.c:1175
void HTransformApply(double *p_in, double *p_out, THTransform *t)
Multiply a homogeneous transform and a vector.
Definition: htransform.c:728
unsigned int obj3d
Definition: polyhedron.h:133
void HTransformTxyz(double tx, double ty, double tz, THTransform *t)
Constructor.
Definition: htransform.c:140
#define NEW(_var, _n, _type)
Allocates memory space.
Definition: defines.h:385
Data structure to hold the information about the name of a file.
Definition: filename.h:248
void PolyhedronPrintCenter(FILE *f, THTransform *t, Tpolyhedron *p)
Prints the center of a sphere to a file.
Definition: polyhedron.c:1285
void ReadSphere(FILE *f, unsigned int g, Tpolyhedron *p)
Constructor.
Definition: polyhedron.c:709
A homgeneous transform in R^3.
void GetPolyhedronColor(Tcolor *c, Tpolyhedron *p)
Gets the color of a polyhedron.
Definition: polyhedron.c:1165
void PlotSegments(unsigned int n, double **pt, Tplot3d *p)
Adds a collecion of segments to the current object.
Definition: plot3d.c:412
double p2[3]
Definition: polyhedron.h:147
double GetGreen(Tcolor *c)
Gets the green component of a color.
Definition: color.c:78
#define OFF_EXT
File extension for geomview OFF files.
Definition: filename.h:101
double center[3]
Definition: polyhedron.h:144
#define NORMAL_SHAPE
One of the possible type of shapes.
Definition: polyhedron.h:28
void GetPolyhedronCenter(double *c, Tpolyhedron *p)
Gets the center of the spheres.
Definition: polyhedron.c:1145
double GetPolyhedronRadius(Tpolyhedron *p)
Returns the radius used in the definition of the object.
Definition: polyhedron.c:1232
#define TRUE
TRUE.
Definition: boolean.h:21
#define CYLINDER
One of the possible type of polyhedrons.
Definition: polyhedron.h:80
void Error(const char *s)
General error function.
Definition: error.c:80
void CopyColor(Tcolor *c_dst, Tcolor *c_src)
Copy constructor.
Definition: color.c:21
A color.
Definition: color.h:23
void PlotLine(double x0, double y0, double x1, double y1, Tplot *p)
Plots a segment.
Definition: plot.c:215
#define OFF
One of the possible type of polyhedrons.
Definition: polyhedron.h:59
void PlotSphere(double r, double x, double y, double z, Tplot3d *p)
Adds a sphere to the current object.
Definition: plot3d.c:369
#define SEGMENTS
One of the possible type of polyhedrons.
Definition: polyhedron.h:100
void CopyPolyhedron(Tpolyhedron *p_dst, Tpolyhedron *p_src)
Copy constructor.
Definition: polyhedron.c:1051
CBLAS_INLINE void HTransformProduct(THTransform *t1, THTransform *t2, THTransform *t3)
Product of two homogeneous transforms.
Definition: htransform.c:404
unsigned int GetPolyhedronNVertex(Tpolyhedron *p)
Gets the number of vertexes of a polyhedron.
Definition: polyhedron.c:1185
void ReadLine(FILE *f, Tpolyhedron *p)
Constructor.
Definition: polyhedron.c:508
#define LINE
One of the possible type of polyhedrons.
Definition: polyhedron.h:90
void HTransformX2Vect(double sy, double sz, double *p1, double *p2, THTransform *t)
Transform a unitary vector along the X axis to a generic vector.
Definition: htransform.c:539
void Move3dObject(unsigned int nobj, THTransform *t, Tplot3d *p)
Moves a 3d object.
Definition: plot3d.c:217
A polyhedron.
Definition: polyhedron.h:124
Error and warning functions.
void DeleteFileName(Tfilename *fn)
Destructor.
Definition: filename.c:205
void ReadSTL(char *fn, Tpolyhedron *p)
Constructor.
Definition: polyhedron.c:287
A 3D plot.
Definition: plot3d.h:54
void ReadCylinder(FILE *f, unsigned int g, Tpolyhedron *p)
Constructor.
Definition: polyhedron.c:572
void PlotPolyhedron(Tplot3d *pt, Tpolyhedron *p)
Adds the polyhedron to a 3D geometry.
Definition: polyhedron.c:1255
double Distance(unsigned int s, double *v1, double *v2)
Computes the distance of two points.
unsigned int GetPolyhedronStatus(Tpolyhedron *p)
Gets the status of a polyhedron (NORMAL, HIDDEN, DECOR).
Definition: polyhedron.c:1170
boolean ReadGeneralMesh(char *fn, Tpolyhedron *p)
Constructor.
Definition: polyhedron.c:231
void HTransformRz(double rz, THTransform *t)
Constructor.
Definition: htransform.c:189
double ** v
Definition: polyhedron.h:138
unsigned int status
Definition: polyhedron.h:127
void NewSphere(double r, double *center, Tcolor *c, unsigned int gr, unsigned int bs, Tpolyhedron *p)
Constructor.
Definition: polyhedron.c:926
#define M_PI_2
Pi/2.
Definition: defines.h:92
void ReadOFF(FILE *f, Tpolyhedron *p)
Constructor.
Definition: polyhedron.c:366
void NewCylinder(double r, double *p1, double *p2, Tcolor *c, unsigned int gr, unsigned int bs, Tpolyhedron *p)
Constructor.
Definition: polyhedron.c:950
double rad
Definition: polyhedron.h:142
void GenerateCylinderOFF(unsigned int g, Tpolyhedron *p)
Generates an OFF that approximates a cylinder.
Definition: polyhedron.c:422
void MovePolyhedron(Tplot3d *pt, THTransform *t, Tpolyhedron *p)
Moves an object previously added to a 3D scene.
Definition: polyhedron.c:1309
void SavePolyhedron(char *fileName, Tpolyhedron *p)
Stores the geometic information of a polyhedron into a file.
Definition: polyhedron.c:1315
void CreateFileName(char *path, char *name, char *suffix, char *ext, Tfilename *fn)
Constructor.
Definition: filename.c:22
Definition of the THTransform type and the associated functions.
unsigned int * nvf
Definition: polyhedron.h:139
char * GetFileFullName(Tfilename *fn)
Gets the file full name (paht+name+extension).
Definition: filename.c:151
#define M_2PI
2*Pi.
Definition: defines.h:100
#define M_PI
Pi.
Definition: defines.h:83
#define SPHERE
One of the possible type of polyhedrons.
Definition: polyhedron.h:70
Tcolor color
Definition: polyhedron.h:131
double GetRed(Tcolor *c)
Gets the red component of a color.
Definition: color.c:73
Definition of the Tpolyhedron type and the associated functions.
#define NO_UINT
Used to denote an identifier that has not been initialized.
Definition: defines.h:435
double GetPolyhedronMaxCoordinate(Tpolyhedron *p)
Returns the maximum coordinate value used in a polyhedron.
Definition: polyhedron.c:1250
void InitPolyhedronFromFile(Tfilename *fname, Tcolor *c, unsigned int gr, unsigned int bs, Tpolyhedron *p)
Constructor.
Definition: polyhedron.c:727
unsigned int nf
Definition: polyhedron.h:136
void HTransformDelete(THTransform *t)
Destructor.
Definition: htransform.c:833
void GetPolyhedronVertex(unsigned int i, double *point, Tpolyhedron *p)
Gets a vertex of a polyhedron.
Definition: polyhedron.c:1239
void HTransformSetElement(unsigned int i, unsigned int j, double v, THTransform *t)
Sets an element in a homogeneous transform.
Definition: htransform.c:306
void DeletePolyhedron(Tpolyhedron *p)
Destructor.
Definition: polyhedron.c:1484
unsigned int GetPolyhedronType(Tpolyhedron *p)
Retrives the type of a polyhedron.
Definition: polyhedron.c:1155
unsigned int ne
Definition: polyhedron.h:137
void NewSegments(unsigned int n, double *x, double *y, double *z, Tcolor *c, Tpolyhedron *p)
Constructor.
Definition: polyhedron.c:1004
void NewColor(double r, double g, double b, Tcolor *c)
Constructor.
Definition: color.c:14
unsigned int nv
Definition: polyhedron.h:135
void Plot3dObject(unsigned int nv, unsigned int nf, unsigned int ne, double **v, unsigned int *nvf, unsigned int **fv, Tplot3d *p)
Adds a polytope to the current object.
Definition: plot3d.c:276
void NewLine(double *p1, double *p2, Tcolor *c, unsigned int bs, Tpolyhedron *p)
Constructor.
Definition: polyhedron.c:977
char * GetFileExtension(Tfilename *fn)
Gets the file extension.
Definition: filename.c:171
void GenerateSphereOFF(unsigned int g, Tpolyhedron *p)
Generates an OFF that approximates a sphere.
Definition: polyhedron.c:593
void SetPolyhedronColor(Tcolor *c, Tpolyhedron *p)
Changes the color of a polyhedron.
Definition: polyhedron.c:1160
void NewBox(double xl, double yl, double zl, double xu, double yu, double zu, Tcolor *c, unsigned int bs, Tpolyhedron *p)
Constructor.
Definition: polyhedron.c:857
double GetBlue(Tcolor *c)
Gets the blue component of a color.
Definition: color.c:83
unsigned int StartNew3dObject(Tcolor *c, Tplot3d *p)
Start a composed object.
Definition: plot3d.c:157
void Close3dObject(Tplot3d *p)
Closes a composed object.
Definition: plot3d.c:171
void InitPolyhedronFromTriangles(unsigned int nv, double **v, unsigned int nt, unsigned int **t, Tcolor *c, unsigned int bs, Tpolyhedron *p)
Constructor.
Definition: polyhedron.c:801
void Print3Reals(FILE *f, double r1, double r2, double r3)
Pretty print three real number.
Definition: geom.c:754
void ReadSegments(FILE *f, Tpolyhedron *p)
Constructor.
Definition: polyhedron.c:529
#define DECOR_SHAPE
One of the possible type of shapes.
Definition: polyhedron.h:46
void TransformPolyhedron(THTransform *t, Tpolyhedron *p)
Applies a homogenoeus transform to a polyhedron.
Definition: polyhedron.c:1113
unsigned int type
Definition: polyhedron.h:125
boolean HTransformIsIdentity(THTransform *t)
Identify the identity matrix.
Definition: htransform.c:91
#define HIDDEN_SHAPE
One of the possible type of shapes.
Definition: polyhedron.h:37