Files Classes Functions Hierarchy
00001 00002 #include <vector> 00003 using namespace std; 00004 00005 #include <d3clipping.h> 00006 00007 typedef point3<double> pt3; 00008 typedef point3<double> const pt3c; 00009 00010 void d3clipping::reprocessStack 00011 ( 00012 uintc nstacksz, 00013 uintc s, 00014 uintc neib0, 00015 uintc neib1 00016 ) 00017 { 00018 processSimplex(s); 00019 00020 if (neib0!=0) 00021 processSimplex(neib0); 00022 if (neib1!=0) 00023 processSimplex(neib1); 00024 00025 uintc nstack1 = vi.size(); 00026 for (uint i=nstacksz; i<nstack1; ++i) 00027 processSimplex(i); 00028 00029 } 00030 00031 00032 void d3clipping::addintersectionpoint( pt3c & A, pt3c & B ) 00033 { 00034 assert(bv.size()==pt.size()); 00035 // Any point added is assumed to be black. 00036 00037 static pt3 p; 00038 H.intersection(p,A,B); 00039 00040 pt.push_back(p); 00041 bv.push_back(true); 00042 } 00043 00044 00045 d3clipping::d3clipping 00046 ( 00047 d3tess & tess_, 00048 partitionspace< pt3, double > const & H_ 00049 ) 00050 : tess(tess_), vi(tess.vi), pt(tess.pt), H(H_) 00051 { 00052 } 00053 00054 00055 void d3clipping::processB1W2 00056 ( 00057 uintc s, 00058 uintc b0, 00059 uintc w0, 00060 uintc w1 00061 ) 00062 { 00063 assert(s>0); 00064 uintc nstack=vi.size(); 00065 assert(s<nstack); 00066 assert(b0<pt.size()); 00067 assert(w0<pt.size()); 00068 assert(w1<pt.size()); 00069 assert(b0>0); 00070 assert(w0>0); 00071 assert(w1>0); 00072 00073 pt3c & B0(pt[b0]); 00074 pt3c & W0(pt[w0]); 00075 pt3c & W1(pt[w1]); 00076 00077 if ( H.isOnBoundary(B0,zero) ) 00078 { 00079 tess.simplexdelete(s); 00080 return; 00081 } 00082 00083 // Neighboring simplexes are reprocessed. 00084 00085 uintc neib0 = vi[s].nifrom(w0); 00086 uintc neib1 = vi[s].nifrom(w1); 00087 00088 // The simplex is cut in two. 00089 00090 uintc z0 = pt.size(); 00091 uintc z1 = z0 + 1; 00092 addintersectionpoint(B0,W0); 00093 addintersectionpoint(B0,W1); 00094 00095 tess.splitwithline(s,w1,z0,w0,z1); 00096 00097 reprocessStack(nstack,s,neib0,neib1); 00098 } 00099 00100 00101 void d3clipping::processW1B2 00102 ( 00103 uintc s, 00104 uintc w0, 00105 uintc b0, 00106 uintc b1 00107 ) 00108 { 00109 assert(s>0); 00110 uintc nstack = vi.size(); 00111 assert(s<nstack); 00112 assert(w0<pt.size()); 00113 assert(b0<pt.size()); 00114 assert(b1<pt.size()); 00115 assert(w0>0); 00116 assert(b0>0); 00117 assert(b1>0); 00118 00119 pt3c & W0(pt[w0]); 00120 pt3c & B0(pt[b0]); 00121 pt3c & B1(pt[b1]); 00122 00123 if ( H.isOnBoundary(B0,zero) ) 00124 { 00125 if ( H.isOnBoundary(B1,zero) ) 00126 { 00127 tess.simplexdelete(s); 00128 return; 00129 } 00130 00131 uintc neib0 = vi[s].nifrom(b0); 00132 00133 addintersectionpoint(B1,W0); 00134 00135 tess.split1D(s,b0,pt.size()-1); 00136 00137 reprocessStack(nstack,s,neib0); 00138 00139 return; 00140 } 00141 00142 if ( H.isOnBoundary(B1,zero) ) 00143 { 00144 uintc neib1 = vi[s].nifrom(b1); 00145 00146 addintersectionpoint(B0,W0); 00147 00148 tess.split1D(s,b1,pt.size()-1); 00149 00150 reprocessStack(nstack,s,neib1); 00151 00152 return; 00153 } 00154 00155 // Line split 00156 00157 // Neighboring simplexes are reprocessed. 00158 00159 uintc neib0 = vi[s].nifrom(b0); 00160 uintc neib1 = vi[s].nifrom(b1); 00161 00162 // The simplex is cut in two. 00163 00164 uintc z0 = pt.size(); 00165 addintersectionpoint(B0,W0); 00166 addintersectionpoint(B1,W0); 00167 uintc z1 = z0 + 1; 00168 00169 tess.splitwithline(s,b0,z1,b1,z0); 00170 00171 reprocessStack(nstack,s,neib0,neib1); 00172 } 00173 00174 void d3clipping::processSimplex(uintc s) 00175 { 00176 assert(s>0); 00177 assert(s<vi.size()); 00178 00179 // Initilly classify the point without considering 00180 // if the point is on the boundary. 00181 00182 d3tri const * t = & vi[s]; 00183 if (t->isnull()) 00184 return; 00185 00186 uintc p0 = t->pi[0]; 00187 uintc p1 = t->pi[1]; 00188 uintc p2 = t->pi[2]; 00189 00190 uint k=0; 00191 if (bv[p0]) 00192 k += 1; 00193 if (bv[p1]) 00194 k += 2; 00195 if (bv[p2]) 00196 k += 4; 00197 00198 switch (k) 00199 { 00200 // All black points, accept the triangle. 00201 case 7: 00202 break; 00203 00204 // All white points, delete the triangle. 00205 case 0: 00206 tess.simplexdelete(s); 00207 break; 00208 00209 // One black two white 00210 case 1: 00211 processB1W2(s,p0,p1,p2); 00212 break; 00213 00214 case 2: 00215 processB1W2(s,p1,p0,p2); 00216 break; 00217 00218 case 4: 00219 processB1W2(s,p2,p0,p1); 00220 break; 00221 00222 // Two black on white 00223 case 3: 00224 processW1B2(s,p2,p0,p1); 00225 break; 00226 00227 case 5: 00228 processW1B2(s,p1,p0,p2); 00229 break; 00230 00231 case 6: 00232 processW1B2(s,p0,p1,p2); 00233 break; 00234 } 00235 } 00236 00237 00238 // Note: I could merge processSimplex(uintc s) into 00239 // eval() however I will wait for a while to see how 00240 // the algorithm evolves. The merge I believe would 00241 // produce faster code as memory does not have to be 00242 // thrashed around. 00243 void d3clipping::eval() 00244 { 00245 uint ptsz = pt.size(); 00246 bv.resize(ptsz); 00247 // Ignore the first element as point 0 is defined as no point. 00248 bv[0]=true; 00249 // Because the partition H is subtracting from the mesh its 00250 // balls are white. So the H.isInside function has to be 00251 // inverted. If the point is on H's boundary there is a possibiliby 00252 // that it could be classified wrongly. In this case I believe 00253 // the algorithm is robust enough to handle it by re interpreting any 00254 // 2 black 1 white cases to 3 black again because such cases are 00255 // re processed anyway. 00256 for (uint i=1; i<ptsz; ++i) 00257 bv[i] = ! H.isInside( pt[i] ); 00258 00259 for (uint i=1; i<vi.size(); ++i ) 00260 processSimplex(i); 00261 } 00262 00263 00264 00265 00266
1.5.8