00001
00002
00003
00004
00005
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
00132
00133
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;
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
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;
00166 return 1;
00167 }
00168 else if(a < TOL1){
00169 if(b < TOL1){
00170 *code=2; *id=0;
00171 return 1;
00172 }
00173 else if(b > TOL2){
00174 *code=2; *id=1;
00175 return 1;
00176 }
00177 else{
00178 *code=1; *id=0;
00179 return 1;
00180 }
00181 }
00182 else if(b < TOL1){
00183 if(a < TOL1){
00184 *code=2; *id=0;
00185 return 1;
00186 }
00187 else if(a > TOL2){
00188 *code=2; *id=2;
00189 return 1;
00190 }
00191 else{
00192 *code=1; *id=2;
00193 return 1;
00194 }
00195 }
00196 else if(ab > TOL2){
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
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
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){
00226
00227 if(d01 <= TOL8){
00228 VECSUB(p1,p0,dba)
00229 mu1=DOT(dba,n);
00230 if(fabs(mu1) > TOL9){
00231 mu=d0/mu1;
00232 if(full > 0){
00233 if(fabs(d0) < TOLA || fabs(d1) < TOLA)return 0;
00234 }
00235 VECSCALE(mu,dba,dba)
00236 VECSUM(p0,dba,p2)
00237 if(EdgePierceFace(p2,pa,pb,pc,&code,&id)){
00238 if(code == 0 || full > 0)return 1;
00239 }
00240 }
00241 }
00242 }
00243 else if(full == 2){
00244
00245 VECSUM(p0,p1,dba)
00246 VECSCALE(0.5,dba,dba)
00247 VECSUB(pa,dba,da)
00248 if(fabs(DOT(da,n)) < TOLC){
00249 if(EdgePierceFace(dba,pa,pb,pc,&code,&id))return 2;
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){
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