BOOLEAN.H

Go to the documentation of this file.
00001 /* --
00002 OpenFX version 2.3 - Modelling, Animation and Rendering Package
00003 -- */
00004 
00005 /* boolean.h  */
00006 
00012 typedef struct Boolean_WORKEDGE {
00013   long e;
00014   long ea[2]; 
00015   short  t;   
00016   short  b;   
00017 } workedge;
00018 
00024 typedef struct Boolean_WORKFACE {
00025   long f;
00026   long ea[3]; 
00027   long fa[3]; 
00028   int  id;    
00029   vector n;
00030 } workface;
00031 
00037 typedef struct Boolean_TOOLEDGE {
00038   long e;
00039   vector p0,p1;
00040 } tooledge;
00041 
00047 typedef struct Boolean_TOOLFACE {
00048   long f;
00049   point  p0,p1,p2;
00050   vector n;
00051 } toolface;
00052 
00058 typedef struct Boolean_VTXADJ {
00059   long nf,ne;
00060   long *flist;
00061   long *elist;
00062 } vtxadj;
00063 
00064 #ifndef min
00065 #define min(a,b)  ( ((a) < (b)) ? (a) : (b) )
00066 #endif
00067 #ifndef max
00068 #define max(a,b)  ( ((a) > (b)) ? (a) : (b) )
00069 #endif
00070 #define VECCOPY(a,b)    { b[0] = a[0]; b[1] = a[1]; b[2] = a[2]; }
00071 #define VECSUB(a,b,c)   { c[0]=a[0]-b[0]; c[1]=a[1]-b[1]; c[2]=a[2]-b[2];}
00072 #define VECSUM(a,b,c)   { c[0]=a[0]+b[0]; c[1]=a[1]+b[1]; c[2]=a[2]+b[2];}
00073 #define VECSCALE(a,b,c) { c[0]=(a)*b[0]; c[1]=(a)*b[1]; c[2]=(a)*b[2];}
00074 #define DOT(a,b)        ( (a[0]*b[0]) + (a[1]*b[1]) + (a[2]*b[2]) )
00075 #define CROSS(v1,v2,r)  { \
00076                           r[0] = (v1[1]*v2[2]) - (v2[1]*v1[2]);  \
00077                           r[1] = (v1[2]*v2[0]) - (v1[0]*v2[2]);  \
00078                           r[2] = (v1[0]*v2[1]) - (v2[0]*v1[1]);  \
00079                          }
00080 #define POINT2VECTOR(p,v) v[0]=(double)p[0]; v[1]=(double)p[1]; \
00081                           v[2]=(double)p[2];
00082 #define VECTOR2POINT(v,p) p[0]=(long)v[0]; p[1]=(long)v[1]; \
00083                           p[2]=(long)v[2];
00084 
00085 #define NO               0
00086 #define YES              1
00087 #define FAIL            -1
00088 #define OK               1
00089 
00090 static workface *add_small_face(long a, long b, long c,
00091                                 long f, long i, workface *w,
00092                                 long *nface);
00093 static long BoolAddVertex(vector v, short status);
00094 static short EdgePierceFace(vector vi,
00095                             vector p0, vector p1, vector p2,
00096                             short *code, short *id);
00097 static short EdgeThroughFace(vector pa, vector pb, vector pc, vector n,
00098                              vector p0, vector p1, vector p2, short full);
00099 static workface *AddDelaunayTriangulation(vector p2, workface *bf1, long id,
00100                                      long nns,long *nf, workface *w,
00101                                      long *nwe,workedge **we);
00102 static short Del_Swap(vector p, long v1l, long v2l, long v3l);
00103 static long Del_Edgeid(long v1, long v2, workface *w, long k,
00104                        long *fa1, long *fa2, long *e1, long *e2);
00105 static workface *split_edge(vector p2, long  edgeID,
00106                             workface *w, workedge **e,
00107                             long *nface, long *nedge, long *LastVtxID);
00108 static void switch_adjacent_faces(long edgeID, workface *w, long n,
00109                                    workedge *we, long ne);
00110 static int FindAdjFaces(workface *wf, long nf, workedge *we, long ne);
00111 static void SetConnectingID(long);
00112 static void FindBitsAndPieces(workface *, long, workedge *, long, long);
00113 static int can_switch_faces(long , workface *, workedge *);
00114 static void IntersectObject(int, int);
00115 
00116 #define TOL  200000.0  // very important DO not TAMPER
00117 #define TOL1    0.0005 //0.001 // 0.01 changed 4/6/95 for problem with missed point
00118 #define TOL2    0.9995 //0.999 // 0.99 in phase one too near an edge and disregarded
00119 #define TOL3   -1.00000
00120 #define TOL8    1.00000
00121 #define TOL5   -0.001
00122 #define TOL6    1.001
00123 #define TOL9  100.0
00124 #define TOLA  100.0
00125 #define TOLB  10.0
00126 #define TOLC  100.0
00127 
00128 static short EdgePierceFace(vector vi,
00129                             vector p0, vector p1, vector p2,
00130                             short *code, short *id){
00131 /* code  = 0 point vi is in plane and inside face                */
00132 /*       = 1   "      "      "        on edge id id's the edge   */
00133 /*       = 2   "      "      "        at vertex id id's the edge */
00134  double ve1,ve2,ve3,vp1,vp2,vp3,q1,q2,q3,det,a,b,ab,
00135         det1,det2,det3,detmax,dm;
00136  short k;
00137   q1=vi[0]-p0[0];  q2=vi[1]-p0[1];  q3=vi[2]-p0[2];
00138  ve1=p2[0]-p0[0]; ve2=p2[1]-p0[1]; ve3=p2[2]-p0[2];
00139  vp1=p1[0]-p0[0]; vp2=p1[1]-p0[1]; vp3=p1[2]-p0[2];
00140  det1=ve1*vp2-vp1*ve2;    /* new way to ensure optimum numerics */
00141  det2=ve2*vp3-vp2*ve3;
00142  det3=ve1*vp3-vp1*ve3;
00143  k=0; detmax=TOL;
00144  if((dm=fabs(det1)) > detmax){k=1; detmax=dm;}
00145  if((dm=fabs(det2)) > detmax){k=2; detmax=dm;}
00146  if((dm=fabs(det3)) > detmax){k=3; detmax=dm;}
00147  if(k == 0)return 0;
00148  else if(k == 1){
00149    a=( vp2*q1-vp1*q2)/det1;
00150    b=(-ve2*q1+ve1*q2)/det1;
00151  }
00152  else if(k == 2){
00153    a=( vp3*q2-vp2*q3)/det2;
00154    b=(-ve3*q2+ve2*q3)/det2;
00155  }
00156  else if(k == 3){
00157    a=( vp3*q1-vp1*q3)/det3;
00158    b=(-ve3*q1+ve1*q3)/det3;
00159  }
00160  else return 0;
00161 /* a=1 at p2      b=1 at p1  */
00162  ab=a+b;
00163  if(a < TOL5 || a > TOL6 || b < TOL5 || b > TOL6 || ab > TOL6)return 0;
00164  if(a >= TOL1 && a <= TOL2 && b >= TOL1 && b <= TOL2 && ab <= TOL2){
00165    *code=0;  /* inside face */
00166    return 1;
00167  }
00168  else if(a < TOL1){ /* along edge 0-1 */
00169    if(b < TOL1){ /* p0 */
00170      *code=2; *id=0;
00171      return 1;
00172    }
00173    else if(b > TOL2){ /* p1 */
00174      *code=2; *id=1;
00175      return 1;
00176    }
00177    else{  /* on edge 0-1 */
00178      *code=1; *id=0;
00179      return 1;
00180    }
00181  }
00182  else if(b < TOL1){ /* along edge 0-2 */
00183    if(a < TOL1){ /* p0 */
00184      *code=2; *id=0;
00185      return 1;
00186    }
00187    else if(a > TOL2){ /* p2 */
00188      *code=2; *id=2;
00189      return 1;
00190    }
00191    else{ /* on edge 0-2 */
00192      *code=1; *id=2;
00193      return 1;
00194    }
00195  }
00196  else if(ab > TOL2){/* on edge 1-2 */
00197    *code=1; *id=1;
00198    return 1;
00199  }
00200  return 0;
00201 }
00202 
00203 static short EdgeThroughFace(vector pa, vector pb, vector pc,vector n,
00204                              vector p0, vector p1, vector p2, short full){
00205 /* full = 0 implies that the edge intersects the tool face internally.
00206             At least one vertex of the edge does not lie in the plane
00207             of the tool face face.
00208    full = 1 implies that the edge crosses the tool face but it may cross
00209             the face at one of it's edges, however neither of the vertices
00210             of the edge lie in/near the plane of the tool face.
00211    full = 2 implies that if both points lie in plane of tool face then
00212             it is checked to see if it is a bounding edge.
00213    pa, pb and pc are the vertices of the face
00214    p0 and p1 are points at end of edge
00215    returns p2 point of intersection
00216    tool edge 0-1 intersects work face
00217 */
00218  short code,id;
00219  vector da,db,dba;
00220  double d,d0,d1,d01,mu,mu1;
00221  VECSUB(pa,p0,da)
00222  VECSUB(pa,p1,db)
00223  d0=DOT(da,n); d1=DOT(db,n);
00224  d01 =d0*d1;
00225  if(fabs(d0) > TOLA || fabs(d1) > TOLA){         /* TOLA => not in plane */
00226    /* at least one vertex lies out of the tool plane */
00227    if(d01 <= TOL8){          /* TOL8 => edge crosses the tool face cross */
00228      VECSUB(p1,p0,dba)
00229      mu1=DOT(dba,n);
00230      if(fabs(mu1) > TOL9){
00231        mu=d0/mu1;
00232        if(full > 0){   /* not near either end of edge */
00233          if(fabs(d0) < TOLA || fabs(d1) < TOLA)return 0;
00234        }
00235        VECSCALE(mu,dba,dba)
00236        VECSUM(p0,dba,p2)   /* p2 is the intersection point */
00237        if(EdgePierceFace(p2,pa,pb,pc,&code,&id)){
00238          if(code == 0 || full > 0)return 1; /* allow Xn even on face edges */
00239        }
00240      }
00241    }
00242  }
00243  else if(full == 2){ /* both points lie in plane of tool face */
00244    /* check to see if this edge is a boundary edge   */
00245    VECSUM(p0,p1,dba)
00246    VECSCALE(0.5,dba,dba)        /* midpoint of edge  */
00247    VECSUB(pa,dba,da)
00248    if(fabs(DOT(da,n)) < TOLC){  /*    "  is in plane */
00249      if(EdgePierceFace(dba,pa,pb,pc,&code,&id))return 2; /* inside toolface */
00250    }
00251  }
00252  return 0;
00253 }
00254 
00255 static int O_normalize(vector v){
00256  double n,nn;
00257  n= (double)((v[0]*v[0]) + (v[1]*v[1]) + (v[2]*v[2]));
00258  if(n < 1.e-10)return FAIL;
00259  nn=sqrt(n);
00260  n = 1.0 / nn;
00261  VECSCALE(n,v,v)
00262  return OK;
00263 }
00264 
00265 #if 0
00266 static int PrintAdjFaces(workface *wf, long nf, workedge *we, long ne){
00267  face *f;
00268  edge *e;
00269  vertex *vp;
00270  long i,nvl=0;
00271  fprintf(debug,"nwf=%ld nwe=%ld\nVertices\n",nf,ne);
00272  vp=MainVp; for(i=0;i<Nvert;i++){
00273    if(vp->status == DESELECTED){ /* work vertex */
00274      fprintf(debug,"%4ld  [%4ld  %4ld  %4ld]\n",nvl,
00275      vp->xyz[0]/1024,vp->xyz[1]/1024,vp->xyz[2]/1024);
00276      nvl++;
00277    }
00278    vp++;
00279  }
00280  fprintf(debug,"Faces\n");
00281  for(i=0;i<nf;i++){
00282   f=(MainFp+wf[i].f);
00283   fprintf(debug,"f[%4ld] =[%4ld %4ld %4ld]  af=[%4ld  %4ld  %4ld]  ae=[%4ld  %4ld  %4ld]\n",i,
00284        (MainVp+f->V[0])->id,(MainVp+f->V[1])->id,(MainVp+f->V[2])->id,
00285        wf[i].fa[0],wf[i].fa[1],wf[i].fa[2],
00286        wf[i].ea[0],wf[i].ea[1],wf[i].ea[2]);
00287  }
00288  fprintf(debug,"Edges\n");
00289  for(i=0;i<ne;i++){
00290    e=(MainEp+we[i].e);
00291    fprintf(debug,"e[%4ld] = [%4ld  %4ld]  af=[%4ld  %4ld]  boundary=[%1ld]\n",i,
00292       (MainVp+e->V[0])->id,(MainVp+e->V[1])->id,
00293       we[i].ea[0],we[i].ea[1],we[i].b);
00294  }
00295 }
00296 #endif

Generated on Sun Apr 27 14:20:10 2014 for OpenFX by  doxygen 1.5.6