cgma
PST_Data.cpp
Go to the documentation of this file.
00001 #include "PST_Data.hpp"
00002 #include "GMem.hpp"
00003 #include "GfxDebug.hpp"
00004 #include "GeometryDefines.h"
00005 #include "CubitMessage.hpp"
00006 
00007 #define PST_MAX_LIST_LEN 1000
00008 // Used only for debugging.  Has no effect
00009 // if compiled -DNDEBUG.
00010 
00011 const double RESABS_SQR = GEOMETRY_RESABS * GEOMETRY_RESABS;
00012 
00013 
00014 /*************************************************************************
00015  *                               PST_Point
00016  ************************************************************************/
00017 
00018 PST_Point::~PST_Point()
00019 {
00020   while( edge_ )
00021     delete edge_;
00022 }
00023 
00024 PST_Edge* PST_Point::common( PST_Point* pt )
00025 {
00026   if( edge_ )
00027   {
00028 #ifndef NDEBUG
00029     int debug = 0;
00030 #endif
00031     
00032     PST_Edge* e = edge_;
00033     do
00034     {
00035       if( e->other(pt) == this )
00036         return e;
00037       e = next( e );  
00038     
00039 #ifndef NDEBUG
00040       assert( ++debug < PST_MAX_LIST_LEN );
00041 #endif
00042     } while( e && e != edge_ );
00043   }
00044   return 0;
00045 }
00046 
00047 
00048 int PST_Point::faces( DLIList<PST_Face*>* list )
00049 {
00050   int count = 0;
00051   if( edge() )
00052   {
00053     PST_Edge* e = edge();
00054     do
00055     {
00056       if (e->forward()->face())
00057         e->forward()->face()->private_mark_ = true;
00058       if (e->reverse()->face())
00059         e->reverse()->face()->private_mark_ = true;
00060       e = e->next(this);
00061     } while( e != edge() );
00062     
00063     do
00064     {
00065       if( e->forward()->face() && e->forward()->face()->private_mark_ )
00066       {
00067         count++;
00068         e->forward()->face()->private_mark_ = false;
00069         if( list ) list->append(e->forward()->face());
00070       }
00071       if( e->reverse()->face() && e->reverse()->face()->private_mark_ )
00072       {
00073         count++;
00074         e->reverse()->face()->private_mark_ = false;
00075         if( list ) list->append(e->reverse()->face());
00076       }
00077       e = e->next(this);
00078     } while( e != edge() );
00079   }      
00080   
00081   return count;
00082 }
00083 
00084 /*************************************************************************
00085  *                               PST_Face
00086  ************************************************************************/
00087 
00088 void PST_Face::append_points( DLIList<PST_Point*>& result_list )
00089 {
00090   PST_CoEdge* ce = coedge_;
00091 #ifndef NDEBUG
00092   int debug = 0;
00093 #endif
00094   do
00095   {
00096     result_list.append( ce->end_point() );
00097     ce = ce->next();
00098     
00099 #ifndef NDEBUG
00100     assert( ++debug < PST_MAX_LIST_LEN );
00101 #endif
00102   } while( ce != coedge_ );
00103 }
00104 
00105 PST_Point* PST_Face::opposite( PST_Edge* edge )
00106 {
00107   PST_CoEdge* ce = coedge_;
00108 #ifndef NDEBUG
00109   int debug = 0;
00110 #endif
00111   do
00112   {
00113     if( ce->edge() == edge )
00114       return ce->next()->end_point();
00115     ce = ce->next();
00116     
00117 #ifndef NDEBUG
00118     assert( ++debug < PST_MAX_LIST_LEN );
00119 #endif
00120   } while( ce != coedge_ );
00121   
00122   return 0;
00123 }
00124 
00125 PST_Edge* PST_Face::opposite( PST_Point* point )
00126 {
00127   PST_CoEdge* ce = coedge_;
00128 #ifndef NDEBUG
00129   int debug = 0;
00130 #endif
00131   do
00132   {
00133     if( ce->start_point() == point )
00134       return ce->next()->edge();
00135     ce = ce->next();
00136     
00137 #ifndef NDEBUG
00138     assert( ++debug < PST_MAX_LIST_LEN );
00139 #endif
00140   } while( ce != coedge_ );
00141   
00142   return 0;
00143 }
00144 
00145 bool PST_Face::two_edges( PST_Point* point, PST_Edge*& e1, PST_Edge*& e2 )
00146 {
00147   e1 = e2 = 0;
00148   PST_CoEdge* ce = coedge_;
00149 #ifndef NDEBUG
00150   int debug = 0;
00151 #endif
00152   do
00153   {
00154     if( ce->end_point() == point )
00155     {
00156       if( e1 || e2 )
00157         return false;
00158       e1 = ce->edge();
00159       e2 = ce->next()->edge();
00160     }
00161     ce = ce->next();
00162     
00163 #ifndef NDEBUG
00164     assert( ++debug < PST_MAX_LIST_LEN );
00165 #endif
00166   } while( ce != coedge_ );
00167   
00168   return e1 && e2;
00169 }
00170 
00171 
00172 bool PST_Face::calculate_plane()
00173 {
00174   update_plane_ = 0;
00175 
00176   // Use Newell's method
00177   
00178   CubitVector dif, sum, ref(0.,0.,0.);
00179   CubitVector norm(0.,0.,0.);
00180   
00181   // For each coedge...
00182   
00183   PST_CoEdge* ce = coedge_;
00184   int count = 0;
00185   do
00186   {
00187     count++;
00188     const CubitVector& pt1 = ce->start_coord();
00189     const CubitVector& pt2 = ce->end_coord();
00190     dif   = pt2 - pt1;
00191     sum   = pt2 + pt1;
00192     ref  += pt1;
00193     norm += CubitVector( dif.y()*sum.z(), dif.z()*sum.x(), dif.x()*sum.y() );
00194     ce = ce->next();
00195     
00196     assert( count < PST_MAX_LIST_LEN );
00197   } while( ce != coedge_ );
00198   
00199   // Degenerate?
00200   
00201   double len = norm.length();
00202   if( len > CUBIT_RESABS )
00203   {
00204     double d = (ref % norm) / (count * len);
00205     norm /= -len; //reverse and normalize
00206 
00207     plane_.normal( norm );
00208     plane_.coefficient( d );
00209 
00210     return true;
00211   }
00212   else
00213   {
00214     plane_.normal( CubitVector(0.,0.,0.) );
00215     plane_.coefficient( 0. );
00216 
00217     return false;
00218   }
00219 }      
00220     
00221 
00222 
00223 /*************************************************************************
00224  *                              PST_CoEdge
00225  ************************************************************************/
00226 PST_CoEdge* PST_CoEdge::previous()
00227 {
00228   if( !next_ )
00229     return 0;
00230     
00231   PST_CoEdge* coedge = this;
00232 #ifndef NDEBUG
00233   int debug = 0;
00234 #endif
00235   while( coedge->next_ != this )
00236   {
00237     coedge = coedge->next_;
00238 #ifndef NDEBUG
00239     assert( ++debug < PST_MAX_LIST_LEN );
00240 #endif
00241   }
00242   return coedge;
00243 }
00244 
00245 /*************************************************************************
00246  *                               PST_Edge
00247  ************************************************************************/
00248 
00249 PST_Edge::~PST_Edge()
00250 {
00251     // Update list "head" pointers on points, if necessary.
00252   if( start_point() )
00253     remove_start_point();
00254   if( end_point() )
00255     remove_end_point();
00256 
00257     // Destroy parent facets
00258   for ( int i = 0; i < 2; i++ )
00259   {
00260     PST_CoEdge* coedge = i ? reverse() : forward();
00261     if ( coedge->face() )
00262     {
00263       PST_Face* face = coedge->face();
00264       face->coedge_ = 0;
00265       
00266       PST_CoEdge* first = coedge;
00267       do {
00268         assert(coedge->face() == face);
00269         coedge->face_ = 0;
00270         PST_CoEdge* next = coedge->next();
00271         coedge->next_ = 0;
00272         coedge = next;
00273       } while( first != coedge );
00274       delete face ;
00275     }
00276   }
00277 }
00278     
00279 double PST_Edge::closest_on_line( const CubitVector& P )
00280 {
00281   CubitVector B = start_coord();
00282   CubitVector M   = end_coord() - B;
00283   if( M.length_squared() < RESABS_SQR )
00284     return 0.0;
00285   return ( M % ( P - B ) ) / ( M % M );
00286 }
00287 
00288 double PST_Edge::closest_on_edge( const CubitVector& p )
00289 {
00290   double t = closest_on_line( p );
00291   if( t < 0.0 )
00292     t = 0.0;
00293   else if( t > 1.0 )
00294     t = 1.0;
00295   return t;
00296 }
00297 
00298 double PST_Edge::closest_on_line( const CubitVector& B2, 
00299                                   const CubitVector& M2 )
00300 {
00301   CubitVector B1 = start_coord();
00302   CubitVector M1 = direction();
00303   
00304   if( M1.length_squared() < RESABS_SQR )
00305     return 0.0;
00306   
00307   if( M2.length_squared() < RESABS_SQR )
00308     return closest_on_line( B2 );
00309   
00310   CubitVector cross = M2 * M1;
00311   if( cross.length_squared() < CUBIT_RESABS ) //parallel
00312     return 0.0;
00313   
00314   CubitVector N = M2 * cross;
00315   double      D = -( N % B2 );
00316   return -( N % B1 + D ) / ( N % M1 );
00317 }
00318 
00319 
00320 PST_Edge* PST_Edge::other( PST_Point* point, PST_Face* face )
00321 {
00322   PST_Edge *result = 0;
00323   for( PST_Edge* e = point->next(this); e != this; e = point->next(e) )
00324   {
00325     if( e->forward()->face() == face || e->reverse()->face() == face )
00326     {
00327       if( result && result != e )
00328         return 0;
00329       result = e;
00330     }
00331   }
00332   return result;
00333 }
00334 
00335 /*************************************************************************
00336  *                         Construction Methods
00337  ************************************************************************/
00338 
00339 PST_Face* PST_Edge::create_face( PST_Point* pt1, PST_Point* pt2, PST_Point* pt3 )
00340 {
00341     // It is trivial to generalize this function for creating
00342     // faces with an arbitrary number of sides, but I just
00343     // want triangles.
00344   const int size = 3;
00345   PST_Point* p[size] = { pt1, pt2, pt3 };
00346 
00347   int i;
00348   PST_Edge* e[size];
00349   PST_CoEdge* c[size];
00350   
00351     // Initialize edge and coedge arrays, creating
00352     // edges if necessary.
00353   for( i = 0; i < size; i++ )
00354   {
00355     e[i] = p[i]->common( p[(i+1)%size] );
00356     if( !e[i] )
00357     {
00358       e[i] = new PST_Edge( p[i], p[(i+1)%size] );
00359       c[i] = e[i]->forward();
00360     }
00361     else
00362     {
00363       c[i] = e[i]->start_point() == p[i] ? e[i]->forward() : e[i]->reverse();
00364       
00365         // If the co-edge in the appropriate direction is already
00366         // part of a face (other than the boundary face), then we
00367         // can't proceed.
00368 //      if( !c[i]->face()->boundary() )
00369       if( c[i]->face() )
00370       {
00371         while( --i >= 0 )
00372           if( ! c[i]->face() )
00373             delete e[i];
00374         return 0;
00375       }
00376     }
00377   }
00378   
00379   PST_Face* result = new PST_Face( c[0] );
00380   for ( i = 0; i < size; i++ )
00381   {
00382     int next = (i + 1) % size;
00383     c[i]->face_ = result;
00384     c[i]->next_ = c[next];
00385   }
00386   return result;
00387 
00388 }
00389 
00390 
00391 PST_Edge* PST_Edge::split_face( PST_Point* start, PST_Point* end, PST_Face* face )
00392 {
00393   if( !start->edge_ || !end->edge_ )
00394     return 0;
00395   
00396   if( ! face )
00397   {
00398     PST_Edge* start_edge = start->edge();
00399     do
00400     {
00401       PST_Face* curr_face = start_edge->forward()->face();
00402       PST_Face* rev_face = start_edge->reverse()->face();
00403       while( true )
00404       {
00405         PST_CoEdge* coe = curr_face->coedge_;
00406         do
00407         {
00408           if( coe->other( end ) )
00409           {
00410             if( face ) return 0;
00411             
00412             face = curr_face;
00413             curr_face = rev_face;
00414             break;
00415           }
00416           coe = coe->next();
00417         } while( coe != curr_face->coedge_ );
00418         
00419         if( curr_face == rev_face )
00420           break;
00421         else
00422           curr_face = rev_face;
00423       }
00424 
00425       start_edge = start_edge->next(start);
00426     } while( start_edge != start->edge() );
00427     
00428     if( !face ) return 0;
00429   }
00430   
00431   PST_CoEdge* start_coedge = 0;
00432   PST_CoEdge*   end_coedge = 0;
00433   
00434   PST_CoEdge* coedge = face->coedge_;
00435   do
00436   {
00437     if( coedge->end_point() == start )
00438     {
00439       start_coedge = coedge;
00440       break;
00441     }
00442     coedge = coedge->next();
00443   } while( coedge != face->coedge_ );
00444   
00445   if( ! start_coedge ) 
00446     return 0;
00447   
00448   coedge = start_coedge->next();
00449   PST_CoEdge* stop = start_coedge;
00450   do
00451   {
00452     if( coedge->end_point() == start )
00453     {
00454       start_coedge = coedge;
00455     }
00456    
00457     if( coedge->end_point() == end )
00458     {
00459       end_coedge = coedge;
00460       break;
00461     }
00462     
00463     coedge = coedge->next();
00464   } while( coedge != stop );
00465   
00466   if( ! end_coedge )
00467     return 0;
00468   
00469   
00470   return split_face( start_coedge, end_coedge );
00471 }
00472 
00473 PST_Edge* PST_Edge::split_face( PST_CoEdge* coedge1, PST_CoEdge* coedge2 )
00474 {
00475   PST_Point* point1 = coedge1->end_point();
00476   PST_Point* point2 = coedge2->end_point();
00477   
00478   if( (coedge1->edge()      == coedge2->edge() ) ||
00479       (coedge1->face()      != coedge2->face() ) ||
00480       (point1               == point2          ) ||
00481       ( point1->common( point2 )               ) )
00482     return 0;
00483   
00484   PST_Edge* new_edge = new PST_Edge( point1, point2 );
00485   new_edge->forward_.next_ = coedge2->next_;
00486   new_edge->reverse_.next_ = coedge1->next_;
00487   coedge1->next_ = new_edge->forward();
00488   coedge2->next_ = new_edge->reverse();
00489   
00490   PST_Face* old_face = coedge1->face();
00491   PST_Face* new_face = new PST_Face( new_edge->forward(), old_face );
00492   //new_face->boundary(0);
00493   old_face->coedge_ = new_edge->reverse();
00494   new_edge->reverse_.face_ = old_face;
00495   
00496   coedge1 = new_edge->forward();
00497   do
00498   {
00499     coedge1->face_ = new_face;
00500     coedge1 = coedge1->next();
00501   } while( coedge1 != new_edge->forward() );
00502 
00503   return new_edge;
00504 }
00505 
00506 
00507 PST_Edge* PST_Edge::insert_in_face( PST_Point* end, 
00508                                     PST_CoEdge* after_this )
00509 {
00510   if( end->edge_ )
00511     return 0;
00512   
00513   PST_Point* start = after_this->end_point();
00514   PST_Edge* new_edge = new PST_Edge( start, end );
00515   new_edge->forward_.next_ = new_edge->reverse();
00516   new_edge->reverse_.next_ = after_this->next_;
00517   new_edge->forward_.face_ = new_edge->reverse_.face_ = after_this->face_;
00518   after_this->next_ = new_edge->forward();
00519   after_this->face_->modified(true);
00520   return new_edge;
00521 }
00522 
00523 
00524 PST_Edge* PST_Edge::split( PST_Point* point )
00525 {
00526   if( point->edge_ )
00527     return 0; 
00528   
00529   PST_Edge* new_edge = new PST_Edge( point, end_ );
00530 
00531   if (forward()->face()) {
00532     new_edge->forward_.face_ = forward_.face_;
00533     new_edge->forward_.next_ = forward_.next_;
00534     forward_.next_ = new_edge->forward();
00535     forward_.face_->modified(true);
00536   }
00537   if (reverse()->face()) {
00538     new_edge->reverse_.face_ = reverse_.face_;
00539     new_edge->reverse_.next_ = reverse();
00540     reverse_.previous()->next_ = new_edge->reverse();
00541     reverse_.face_->modified(true);
00542   }  
00543 
00544   set_end_point(point);
00545   
00546   return new_edge;
00547 }
00548 
00549 
00550 void PST_Edge::set_point( PST_Point* pt, 
00551                           PST_Point*& ptr,
00552                           PST_Edge*& next )
00553 {
00554   if( ptr )
00555     remove_point( ptr, next );
00556   
00557   
00558   if( pt->edge_ )
00559   {
00560     if( pt->edge()->start_point() == pt )
00561     {
00562       next = pt->edge()->start_next_;
00563       pt->edge()->start_next_ = this;
00564     }
00565     else
00566     {
00567       assert( pt->edge()->end_point() == pt );
00568       next = pt->edge()->end_next_;
00569       pt->edge()->end_next_ = this;
00570     }
00571   }
00572   else
00573   {
00574     next = this;
00575     pt->edge_ = this;
00576   }
00577     
00578   ptr = pt;
00579 }
00580 
00581 void PST_Edge::remove_point( PST_Point*& ptr, PST_Edge*& next )
00582 {
00583   if( next == this )
00584   {
00585     ptr->edge_ = 0;
00586     next= 0;
00587     ptr = 0;
00588     return;
00589   }
00590   
00591   PST_Edge* prev = next;
00592   while( prev->next(ptr) != this )
00593   {
00594     prev = prev->next(ptr);
00595     assert( prev != next );
00596   }
00597   
00598   if( prev->start_next_ == this )
00599   {
00600     prev->start_next_ = next;
00601   }
00602   else
00603   {
00604     assert(prev->end_next_ == this);
00605     prev->end_next_ = next;
00606   }
00607   
00608   if( ptr->edge_ == this )
00609     ptr->edge_ = next;
00610 }
00611 
00612 
00613 void PST_Point::debug_draw( int color, bool flush )
00614 {
00615   GfxDebug::draw_point( float(x()), float(y()), float(z()), color );
00616   if( flush ) 
00617     GfxDebug::flush();
00618 }
00619   
00620 void PST_Edge::debug_draw( int color, bool flush )
00621 {
00622   GfxDebug::draw_line( 
00623     float(start_coord().x()), float(start_coord().y()), float(start_coord().z()),
00624     float(  end_coord().x()), float(  end_coord().y()), float(  end_coord().z()),
00625     color );
00626   if( flush ) GfxDebug::flush();
00627 }
00628 
00629 void PST_Face::debug_draw( int color, bool flush )
00630 {
00631   PST_CoEdge* coedge = first_coedge();
00632   do
00633   {
00634     coedge->edge()->debug_draw( color, false );
00635     coedge = coedge->next();
00636   } while( coedge != first_coedge() );
00637   if( flush ) GfxDebug::flush();
00638 }
00639 
00640 void PST_Edge::make_gmem( GMem& gmem, DLIList<PST_Face*>& facets )
00641 {
00642   DLIList<PST_Point*> point_list, temp_list;
00643   int i, j, pcount, fcount;
00644   
00645   for( i = facets.size(); i--; )
00646   {
00647     PST_Face* facet = facets.get_and_step();
00648 //    if( facet->boundary() )
00649 //      continue;
00650 
00651     temp_list.clean_out();
00652     facet->append_points( temp_list );
00653     for( j = temp_list.size(); j--; )
00654     {
00655       temp_list.get_and_step()->mark = -1;
00656     }
00657   }
00658   
00659   pcount = 0;
00660   fcount = 0;
00661   for( i = facets.size(); i--; )
00662   {
00663     PST_Face* facet = facets.get_and_step();
00664 //    if( facet->boundary() )
00665 //      continue;
00666     
00667     temp_list.clean_out();
00668     facet->append_points( temp_list );
00669     fcount += temp_list.size() + 1;
00670     for( j = temp_list.size(); j--; )
00671     {
00672       PST_Point* pt_ptr = temp_list.get_and_step();
00673       if( pt_ptr->mark == -1 )
00674       {
00675         pt_ptr->mark = pcount++;
00676         point_list.append( pt_ptr );
00677       }
00678     }
00679   }
00680   
00681   gmem.allocate_tri( facets.size() );
00682   gmem.pointListCount = point_list.size();
00683   GPoint* pt_array = gmem.point_list();
00684   
00685   point_list.reset();
00686   for( i = 0; i < point_list.size(); i++ )
00687   {
00688     PST_Point* pt_ptr = point_list.get_and_step();
00689     pt_array[i].x = float(pt_ptr->x());
00690     pt_array[i].y = float(pt_ptr->y());
00691     pt_array[i].z = float(pt_ptr->z());
00692   }
00693   
00694   gmem.fListCount = facets.size() * 4;
00695   int* offset = gmem.facet_list();
00696   for( i = facets.size(); i--; )
00697   {
00698 //    if( facets.get()->boundary() )
00699 //      continue;
00700       
00701     temp_list.clean_out();
00702     facets.get_and_step()->append_points( temp_list );
00703     *(offset++) = temp_list.size();
00704     for( j = temp_list.size(); j--; )
00705     {
00706       *(offset++) = temp_list.get_and_step()->mark;
00707     }
00708   }
00709 }
00710 
00711 void PST_Edge::make_gmem( GMem& gmem, DLIList<PST_Edge*>& edges )
00712 {
00713   DLIList<PST_Face*> face_list;
00714   PST_Edge::faces( edges, face_list );
00715   make_gmem( gmem, face_list );
00716 }
00717 
00718 void PST_Point::debug_draw_points( DLIList<PST_Point*>& point_list, int color, bool flush )
00719 {
00720   for( int p = point_list.size(); p--; )
00721     point_list.get_and_step()->debug_draw(color, false);
00722   if( flush ) GfxDebug::flush();
00723 }
00724 
00725 void PST_Edge::debug_draw_points( DLIList<PST_Edge*>& edge_list, 
00726                             int color, int boundary_color, bool flush )
00727 {
00728   if( ! boundary_color ) boundary_color = color;
00729   
00730   DLIList<PST_Point*> point_list;
00731   DLIList<PST_Point*> boundary_list;
00732   PST_Edge::points( edge_list, point_list );
00733   for( int i = point_list.size(); i--; )
00734   {
00735      PST_Point* pt = point_list.step_and_get();
00736      PST_Edge* e = pt->edge();
00737      do
00738      {
00739        if( !e->forward()->face() || !e->reverse()->face() )
00740          break;
00741        e = e->next(pt);
00742      } while( e != pt->edge() );
00743      if( !e->forward()->face() || !e->reverse()->face() )
00744      {
00745        point_list.change_to( 0 );
00746        boundary_list.append( pt );
00747      }
00748   }
00749   point_list.remove_all_with_value(0);
00750   
00751   PST_Point::debug_draw_points( point_list, color, false );
00752   PST_Point::debug_draw_points( boundary_list, boundary_color, flush );
00753 }
00754 
00755 void PST_Edge::debug_draw_edges(  DLIList<PST_Edge*>& edge_list,
00756                             int color, int boundary_color,
00757                             bool flush )
00758 {
00759   if( !boundary_color ) boundary_color = color;
00760   
00761   for( int e = edge_list.size(); e--; )
00762   {
00763     PST_Edge* edge_ptr = edge_list.get_and_step();
00764     int c = !edge_ptr->forward()->face() || !edge_ptr->reverse()->face()
00765        ? boundary_color : color;
00766     edge_ptr->debug_draw( c, false );
00767   }
00768   if( flush ) GfxDebug::flush();
00769 }
00770 
00771 void PST_Edge::debug_draw_faces( DLIList<PST_Edge*>& edge_list, int color, bool flush )
00772 {
00773   DLIList<PST_Face*> face_list;
00774   PST_Edge::faces( edge_list, face_list );
00775   PST_Face::debug_draw_faces( face_list, color, flush );
00776 }
00777 
00778 void PST_Edge::faces( DLIList<PST_Edge*>& edges, DLIList<PST_Face*>& faces )
00779 {
00780   int e;
00781   for( e = edges.size(); e--; )
00782   {
00783     PST_Edge* edge_ptr = edges.get_and_step();
00784     if( edge_ptr->forward()->face() )
00785       edge_ptr->forward()->face()->private_mark_ = 1;
00786     if( edge_ptr->reverse()->face() )
00787       edge_ptr->reverse()->face()->private_mark_ = 1;
00788   }
00789   for( e = edges.size(); e--; )
00790   {
00791     PST_Edge* edge_ptr = edges.get_and_step();
00792     PST_Face* fface_ptr = edge_ptr->forward()->face();
00793     PST_Face* rface_ptr = edge_ptr->reverse()->face();
00794     if( fface_ptr && fface_ptr->private_mark_ )
00795     {
00796       fface_ptr->private_mark_ = 0;
00797       faces.append( fface_ptr );
00798     }
00799     if( rface_ptr && rface_ptr->private_mark_ )
00800     {
00801       rface_ptr->private_mark_ = 0;
00802       faces.append( rface_ptr );
00803     }
00804   }
00805 }
00806 
00807 void PST_Edge::edges( DLIList<PST_Face*>& faces, DLIList<PST_Edge*>& edges )
00808 {
00809   int f;
00810   for( f = faces.size(); f--; )
00811   {
00812     PST_CoEdge* first = faces.get_and_step()->first_coedge();
00813     PST_CoEdge* coedge = first;
00814     do
00815     {
00816       coedge->edge()->private_mark_ = 1;
00817       coedge = coedge->next();
00818     } while( coedge != first );
00819   }
00820   
00821   for( f = faces.size(); f--; )
00822   {
00823     PST_CoEdge* first = faces.get_and_step()->first_coedge();
00824     PST_CoEdge* coedge = first;
00825     do
00826     {
00827       if( coedge->edge()->private_mark_ )
00828       {
00829         coedge->edge()->private_mark_ = 0;
00830         edges.append( coedge->edge() );
00831       }
00832       coedge = coedge->next();
00833     } while( coedge != first );
00834   }
00835 }  
00836 
00837 void PST_Edge::edges( DLIList<PST_Point*>& pts, DLIList<PST_Edge*>& edges )
00838 {
00839   int p;
00840   for( p = pts.size(); p--; )
00841   {
00842     PST_Point* pt = pts.get_and_step();
00843     PST_Edge* edge = pt->edge();
00844     if( edge ) do
00845     {
00846       edge->private_mark_ = 1;
00847       edge = edge->next( pt );
00848     } while( edge != pt->edge() );
00849   }
00850   
00851   for( p = pts.size(); p--; )
00852   {
00853     PST_Point* pt = pts.get_and_step();
00854     PST_Edge* edge = pt->edge();
00855     if( edge ) do
00856     {
00857       if( edge->private_mark_ )
00858       {
00859         edge->private_mark_ = 0;
00860         edges.append( edge );
00861       }
00862       edge = edge->next( pt );
00863     } while( edge != pt->edge() );
00864   }
00865 }
00866 
00867 
00868 void PST_Edge::points( DLIList<PST_Edge*>& edges, DLIList<PST_Point*>& points )
00869 {
00870   int e;
00871   for( e = edges.size(); e--; )
00872   {
00873     PST_Edge* edge_ptr = edges.get_and_step();
00874     edge_ptr->start_point()->private_mark_ = 1;
00875     edge_ptr->end_point()->private_mark_ = 1;
00876   }
00877   for( e = edges.size(); e--; )
00878   {
00879     PST_Edge* edge_ptr = edges.get_and_step();
00880     PST_Point* sp = edge_ptr->start_point();
00881     PST_Point* ep = edge_ptr->end_point();
00882     if( sp->private_mark_ )
00883     {
00884       sp->private_mark_ = 0;
00885       points.append( sp );
00886     }
00887     if( ep->private_mark_ )
00888     {
00889       ep->private_mark_ = 0;
00890       points.append( ep );
00891     }
00892   }
00893 }
00894 
00895 void PST_Face::debug_draw_faces( DLIList<PST_Face*>& face_list, int color, bool flush )
00896 {
00897   for( int f = face_list.size(); f--; )
00898     face_list.get_and_step()->debug_draw( color, false );
00899   if( flush ) GfxDebug::flush();
00900 }
00901 
00902 void PST_Edge::make_facets( GMem& gmem, double tolerance, 
00903                             DLIList<PST_Edge*>& edge_list )
00904 {
00905   assert(gmem.fListCount % 4 == 0);
00906   std::vector<double> points(gmem.pointListCount*3);
00907   std::vector<int> facets(gmem.fListCount*3/4);
00908   int i;
00909   GPoint* pitor = gmem.point_list();
00910   std::vector<double>::iterator ditor = points.begin();
00911   for ( i = gmem.pointListCount; i--; )
00912   {
00913     *ditor++ = pitor->x;
00914     *ditor++ = pitor->y;
00915     *ditor++ = pitor->z;
00916     pitor++;
00917   }
00918   
00919   int* fitor = gmem.facet_list();
00920   std::vector<int>::iterator iitor = facets.begin();
00921   for ( i = 0; i < gmem.fListCount; i += 4 )
00922   {
00923     assert( *fitor++ == 3 );
00924     *iitor++ = *fitor++;
00925     *iitor++ = *fitor++;
00926     *iitor++ = *fitor++;
00927   }
00928    
00929   make_facets( points, facets, tolerance, edge_list ); 
00930 }
00931 
00932 void PST_Edge::make_facets( 
00933     const std::vector<double>& coordinates,
00934     const std::vector<int>& connections,
00935     double tolerance, 
00936     DLIList<PST_Edge*>& edge_list )
00937 {
00938   DLIList<PST_Face*> face_list;
00939   double tol_sqr = tolerance * tolerance;
00940   int i, j, k, numcoords, numtriangles;
00941   
00942   numcoords = coordinates.size()/3;
00943   numtriangles = connections.size()/3;
00944   //The list of points created.
00945   PST_Point** ptlist = new PST_Point*[numcoords];
00946   
00947   //The list of indices into ptlist, where the index into this
00948   //list is the same as the index into the point list, and
00949   //the value in this list is the index of the corresponding 
00950   //point in ptlist.  This is used because some points will
00951   //be merged due to the tolerance.  
00952   int* ptindex_list = new int[numcoords];
00953    
00954   //Create the points
00955   k = 0;
00956   for( i = 0; i < numcoords; i++ )
00957   {
00958     CubitVector pos( coordinates[3*i], coordinates[3*i+1], coordinates[3*i+2] );
00959  
00960     //Check if we need to merge this point with a different point
00961     for( j = 0; j < k; j++ )
00962     {
00963       if( (*(ptlist[j]) - pos).length_squared() <= tol_sqr )
00964         break;
00965     }
00966     if( j == k )
00967     {
00968       ptlist[k] = new PST_Point( pos );
00969       ptlist[k++]->sequence = i;
00970     }
00971     ptindex_list[i] = j;
00972   } 
00973   
00974   int fail_count = 0;
00975   for ( i = 0; i < numtriangles; i++ )
00976   {
00977     int i1 = ptindex_list[connections[3*i  ]];
00978     int i2 = ptindex_list[connections[3*i+1]];
00979     int i3 = ptindex_list[connections[3*i+2]];
00980     if ( i1 == i2 || i2 == i3 || i3 == i1 )
00981     {
00982       PRINT_ERROR("Degenerate facet encountered in PST_Edge::make_facets()\n");
00983       fail_count++;
00984     }
00985     else
00986     {
00987       PST_Face* new_face 
00988         = PST_Edge::create_face( ptlist[i1], ptlist[i2], ptlist[i3] );
00989       if( new_face ){
00990         face_list.append(new_face);
00991         new_face->sequence = i;
00992       }
00993       else{
00994         fail_count++;
00995       }
00996     }
00997   }
00998    
00999   if( fail_count > 0 )
01000     PRINT_ERROR("Failed to construct %d facets in PST_Data::make_facets(..)\n",
01001       fail_count);
01002    
01003   delete [] ptindex_list;
01004   delete [] ptlist;
01005   
01006   if(fail_count == 0)
01007   {
01008     PST_Edge::edges( face_list, edge_list );
01009     validate( edge_list, true );
01010     bool debug1 = false;
01011     if (debug1)
01012       debug_draw_edges( edge_list, CUBIT_BLUE_INDEX, CUBIT_RED_INDEX, true );
01013   }
01014 }
01015 
01016 int PST_Point::validate(CubitBoolean print)
01017 {
01018   if( edge_ && !edge_->other(this) )
01019   {
01020     if( print )
01021     {
01022       PRINT_INFO("Bad point->edge link.  Point %p, Edge %p.\n", (void*)this, (void*)edge_);
01023     }
01024     return 1;
01025   }
01026   return 0;
01027 }
01028 
01029 int PST_Edge::validate(CubitBoolean print)
01030 {
01031   int result = 0;
01032   int count = 0;
01033   PST_Edge* edge = 0;
01034 
01035   if( !start_ )
01036   {
01037     if( print ) PRINT_ERROR("Edge %p has null start point.\n", (void*)this);
01038     result++;
01039   }
01040   else 
01041   {
01042     result += start_->validate(print);
01043   
01044     edge = this;
01045     count = 0;
01046     do
01047     {
01048       if( count++ > PST_MAX_LIST_LEN )
01049       {
01050         if( print )
01051         {
01052           PRINT_ERROR("Bad edge list around Point %p.\n", (void*)start_);
01053         }
01054         result++;
01055         break;
01056       }
01057       edge = edge->next( start_ );
01058     } while( edge != this );
01059   }  
01060 
01061   
01062   if( !end_ )
01063   {
01064     if( print ) PRINT_ERROR("Edge %p has null end point.\n", (void*)this);
01065     result++;
01066   }
01067   else 
01068   {
01069     result += end_->validate(print);
01070 
01071     count = 0;
01072     edge = this;
01073     do
01074     {
01075       if( count++ > PST_MAX_LIST_LEN )
01076       {
01077         if( print )
01078         {
01079           PRINT_ERROR("Bad edge list around Point %p.\n", (void*)end_);
01080         }
01081         result++;
01082         break;
01083       }
01084       edge = edge->next( end_ );
01085     } while( edge != this );
01086   }
01087   
01088   if (forward_.face_ && !forward_.next_)
01089   {
01090     if( print )
01091       PRINT_ERROR("Forward CoEdge on Edge %p as Face %p but no next().\n",
01092         (void*)this, (void*)forward_.face_);
01093     count++;
01094   }
01095   
01096   if (reverse_.face_ && !reverse_.next_)
01097   {
01098     if( print )
01099       PRINT_ERROR("Reverse CoEdge on Edge %p as Face %p but no next().\n",
01100         (void*)this, (void*)reverse_.face_);
01101     count++;
01102   }
01103   
01104   if (!forward_.face_ && forward_.next_)
01105   {
01106     if( print )
01107       PRINT_ERROR("Forward CoEdge on Edge %p as %p as next CoEdge but no Face.\n",
01108         (void*)this, (void*)forward_.next_);
01109     count++;
01110   }
01111   
01112   if (!reverse_.face_ && reverse_.next_)
01113   {
01114     if( print )
01115       PRINT_ERROR("Reverse CoEdge on Edge %p as %p as next CoEdge but no Face.\n",
01116         (void*)this, (void*)reverse_.next_);
01117     count++;
01118   }
01119     
01120   return result;
01121 }
01122 
01123 int PST_CoEdge::validate( CubitBoolean print )
01124 {
01125   int result = 0;
01126   if( ! edge_ )
01127   {
01128     if( print ) PRINT_ERROR("Coedge %p has null edge.\n", (void*)this);
01129     result++;
01130   }
01131   else 
01132   {
01133     if( ! edge_->other( this ) )
01134     {
01135       if( print ) 
01136         PRINT_ERROR( "Inconsistent coedge->edge link.  CoEdge: %p  Edge: %p\n",
01137           (void*)edge_, (void*)this );
01138       result++;
01139     }
01140     result += edge_->validate(print);
01141   }
01142   return result;
01143 }
01144       
01145 int PST_Face::validate( CubitBoolean print )
01146 {
01147   PST_CoEdge* coe = coedge_;
01148   
01149   if( !coedge_ )
01150   {
01151     if(print) PRINT_ERROR("Face %p has null loop.\n", (void*)this);
01152     return 1;
01153   }
01154   
01155   int count = 0;
01156   int result = 0;
01157   do
01158   {
01159     if( count++ > PST_MAX_LIST_LEN )
01160     {
01161       if( print ) PRINT_ERROR("Face %p loop is infinite.\n", (void*)this);
01162       result++;
01163       break;
01164     }
01165     
01166     if( coe->face() != this )
01167     {
01168       if( print ) 
01169         PRINT_ERROR("Loop for face %p contains face %p on edge %p.\n",
01170           (void*)this, (void*)coe->face(), (void*)coe->edge() );
01171       result++;
01172     }
01173     
01174     if( coe->edge() )
01175     {
01176       result += coe->edge()->validate( print );
01177     }
01178     else
01179     {
01180       if( print )
01181         PRINT_ERROR("Coedge %p in face %p has null edge.\n", (void*)coe, (void*)this);
01182       result++;
01183     }
01184     
01185     if( ! coe->next() )
01186     {
01187       if( print ) 
01188         PRINT_ERROR("Null coedge after coedge %p in face %p.\n", (void*)coe, (void*)this );
01189       result++;
01190       break;
01191     }
01192 
01193     coe = coe->next();
01194     
01195   } while( coe != coedge_ );
01196   
01197   return result;
01198 }
01199 
01200 int PST_Edge::validate( DLIList<PST_Edge*>& edges, CubitBoolean print )
01201 {
01202   DLIList<PST_Face*> faces;
01203   PST_Edge::faces( edges, faces );
01204   
01205   int result = 0;
01206   for( int f = faces.size(); f--; )
01207     result += faces.get_and_step()->validate(print);
01208   return result;
01209 }
01210 
01211 void PST_Face::print()
01212 {
01213   if( ! coedge_ )
01214   {
01215     PRINT_ERROR("Face %p has null coedge.\n", (void*)this);
01216     return;
01217   }
01218   
01219   PRINT_INFO("Face        CoEdge       Edge         Start Pt     End Pt\n"
01220              "----------  -----------  -----------  -----------  -----------\n" );
01221   PST_CoEdge* coe = coedge_;
01222     PRINT_INFO("%10p %10p  %10p  %10p  %10p\n",
01223       (void*)this, (void*)coe, (void*)coe->edge(), (void*)coe->start_point(), (void*)coe->end_point() );
01224   coe = coe->next();
01225   while( coe && coe != coedge_ )
01226   {
01227     PRINT_INFO("            %10p  %10p  %10p  %10p\n",
01228       (void*)coe, (void*)coe->edge(), (void*)coe->start_point(), (void*)coe->end_point() );
01229     coe = coe->next();
01230   }
01231 }
01232 
01233 void PST_Edge::print()
01234 {
01235   PRINT_INFO("Edge %p:  Points:  Start: %p  End: %p   Faces:  Forward: %p  Reverse: %p\n",
01236     (void*)this, (void*)start_, (void*)end_, (void*)forward_.face_, (void*)reverse_.face_ );
01237 }
01238 
01239 void PST_Point::print()
01240 {
01241   PRINT_INFO("Point %p : ( %f, %f, %f )", (void*)this , x(), y(), z() );
01242   
01243   if( edge_ )
01244   {
01245     PRINT_INFO("  Edges:");
01246     int count = 0;
01247     PST_Edge* edge = edge_;
01248     do 
01249     {
01250       if( count )
01251       {
01252         PRINT_INFO("\t%8p", (void*)edge);
01253       }
01254       else
01255       {
01256         PRINT_INFO("\n\t%8p", (void*)edge);
01257       }
01258       
01259       count = (count + 1) % 4;
01260       edge = edge->next(this);
01261     
01262     } while( edge && edge != edge_ );
01263     
01264   }
01265   PRINT_INFO("\n");
01266 }
01267 
01268     
01269 PST_Entity::~PST_Entity()
01270  { }
01271 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines