proj home

Files   Classes   Functions   Hierarchy  

d3clipping.cpp

Go to the documentation of this file.
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 

Generated on Fri Mar 4 00:49:26 2011 for Chelton Evans Source by  doxygen 1.5.8