cgma
PST_Data.hpp
Go to the documentation of this file.
00001 //-------------------------------------------------------------------------
00002 // Filename      : PST_Data.hpp
00003 //
00004 // Purpose       : Classes for representing geometry facets.  Used by 
00005 //                 PartSurfTess to find the graphis faceting for 
00006 //                 PartitionSurfaces.
00007 //
00008 // Special Notes : 
00009 //
00010 // Creator       : Jason Kraftcheck
00011 //
00012 // Creation Date : 05/17/01
00013 //-------------------------------------------------------------------------
00014 #ifndef PST_DATA_HPP
00015 #define PST_DATA_HPP
00016 #include <vector>
00017 
00018 #include "CubitVector.hpp"
00019 #include "CubitDefines.h"
00020 #include "DLIList.hpp"
00021 #include "CubitPlane.hpp"
00022 
00023 #define PST_OTHER(A,B,C) (((A)==(B))?(C):(((A)==(C))?(B):0))
00024 
00025 class PST_CoEdge;
00026 class PST_Edge;
00027 class PST_Point;
00028 class PST_Face;
00029 class GMem;
00030 
00031 class PST_Entity;
00032 
00033 class PST_EntityOwner {
00034   public:
00035   virtual void 
00036   notify_split( PST_Entity* old_entity, PST_Entity* new_entity ) = 0;
00037 };
00038 
00039 class PST_Entity
00040 {
00041   public:
00042   
00043   inline PST_EntityOwner* owner() const;
00044   
00045   inline void owner( PST_EntityOwner* );
00046   
00047   protected:
00048   
00049   inline PST_Entity();
00050   
00051   virtual ~PST_Entity() = 0;
00052   
00053   private:
00054   
00055   PST_EntityOwner* myOwner;
00056 };
00057 
00058 
00059 //-------------------------------------------------------------------------
00060 // Purpose       : Class representing a vertex in facet data structure
00061 //
00062 // Special Notes : 
00063 //
00064 // Creator       : Jason Kraftcheck
00065 //
00066 // Creation Date : 05/16/01
00067 //-------------------------------------------------------------------------
00068 class PST_Point : public CubitVector, public PST_Entity
00069 {
00070   friend class PST_Edge;
00071 
00072   public:
00073   
00074     PST_Point( const CubitVector& position )
00075       : CubitVector( position ),
00076         mark(0), private_mark_(false), edge_(0)
00077       { }
00078 
00079     ~PST_Point() ;
00080       //- Destroys this point, and all edges and faces that
00081       //- the point exists in.
00082     
00083     PST_Edge* edge() 
00084       { return edge_; }
00085     
00086     inline PST_Edge* next( PST_Edge* prev );
00087     
00088     PST_Edge* common( PST_Point* pt );
00089     
00090     int faces( DLIList<PST_Face*>* list = 0 );
00091     
00092     //PST_Face* boundary_face();
00093     
00094     void debug_draw( int color = 1, bool flush = true );
00095     static void debug_draw_points( DLIList<PST_Point*>& list, 
00096                              int color, bool flush = true );
00097   
00098     int validate( CubitBoolean print = CUBIT_FALSE );
00099     
00100     void print();
00101 
00102     int mark;
00103   
00104     int sequence;
00105     
00106   private:
00107     cBit private_mark_ : 1;
00108   
00109     PST_Edge* edge_;
00110 };
00111 
00112 //-------------------------------------------------------------------------
00113 // Purpose       : Association between a PST_Edge and a PST_Face
00114 //
00115 // Special Notes : Allocated inline in PST_Edge -- Do NOT memory manage!
00116 //
00117 // Creator       : Jason Kraftcheck
00118 //
00119 // Creation Date : 05/16/01
00120 //-------------------------------------------------------------------------
00121 class PST_CoEdge
00122 {
00123   friend class PST_Edge;
00124   
00125   public:
00126   
00127     PST_CoEdge* next()
00128       { return next_; }
00129       
00130     PST_Edge* edge()
00131       { return edge_; }
00132     
00133     PST_Face* face()
00134       { return face_; }
00135     
00136     inline CubitSense sense();
00137     
00138     inline PST_Point* start_point();
00139     inline PST_Point* end_point();
00140     inline PST_Point* common( PST_CoEdge* coedge );
00141     inline PST_Point* other( PST_Point* point );
00142     
00143     inline const CubitVector& start_coord();
00144     inline const CubitVector& end_coord();
00145     inline CubitVector direction();
00146     
00147     inline PST_CoEdge* other();
00148     
00149     PST_CoEdge* previous();
00150       
00151     int validate( CubitBoolean print = CUBIT_FALSE );
00152       
00153   private:
00154 
00155     PST_CoEdge()
00156       : next_(0), edge_(0), face_(0)
00157       { }
00158   
00159     PST_CoEdge( PST_Edge* owner )
00160       : next_(0), edge_(owner), face_(0)
00161       { }
00162     
00163     ~PST_CoEdge() 
00164       { assert( !face_ ); } 
00165     
00166     PST_CoEdge* next_;
00167     PST_Edge*   edge_;
00168     PST_Face*   face_;
00169 };
00170     
00171 
00172 //-------------------------------------------------------------------------
00173 // Purpose       : Edge in facet data structure
00174 //
00175 // Special Notes : 
00176 //
00177 // Creator       : Jason Kraftcheck
00178 //
00179 // Creation Date : 05/16/01
00180 //-------------------------------------------------------------------------
00181 class PST_Edge : public PST_Entity
00182 {
00183   public:
00184     
00185     static void make_gmem( GMem& gmem, DLIList<PST_Face*>& facets );
00186     static void make_gmem( GMem& gmem, DLIList<PST_Edge*>& edges );
00187     static void make_facets( GMem& gmem, double tolerance,
00188                              DLIList<PST_Edge*>& edges );
00189     static void make_facets(
00190                      const std::vector<double>& coordinates, 
00191                const std::vector<int>& connections,
00192                      double tolerance, 
00193                DLIList<PST_Edge*>& edge_list );
00194 
00195     PST_Edge( PST_Point* start_pt, PST_Point* end_pt )
00196       : mark(0), private_mark_(false),
00197         start_(0), end_(0)
00198       { 
00199         assert( start_pt != end_pt );
00200         set_start_point( start_pt );
00201         set_end_point( end_pt );
00202         forward_ = PST_CoEdge(this);
00203         reverse_ = PST_CoEdge(this);
00204       }
00205     
00206     
00207     static PST_Face* create_face( PST_Point* p1,
00208                                   PST_Point* p2,
00209                                   PST_Point* p3 );
00210 
00211     static PST_Edge* split_face( PST_Point* start,
00212                                  PST_Point* end,
00213                                  PST_Face* hint = 0 );
00214       //- This method splits a face by creating an edge
00215       //- between two existing points on that face.   
00216       //- If the face to split is not specified, both
00217       //- points must have exactly one face in common.
00218       //- If the points do not have a common face, have
00219       //- more than one common face and no face is 
00220       //- specified, do not exist in the passed face, 
00221       //- or already have a common edge, NULL is returned.
00222                                  
00223     static PST_Edge* split_face( PST_CoEdge* after_coedge_1,
00224                                  PST_CoEdge* after_coedge_2 );
00225       //- Split a face with an edge from the end of the first
00226       //- coedge to the end of the second coedge.  NULL is
00227       //- returned if the coedges do not have a common face,
00228       //- or the desired edge already exists.
00229                                  
00230     static PST_Edge* insert_in_face( PST_Point* end,
00231                                      PST_CoEdge* after_this );
00232       //- Create a non-manifold edge in a face.  The edge is
00233       //- inserted starting at the end of the passed coedge,
00234       //- and terminating at the passed point.  If the 
00235       //- passed point already exists in a face, null is
00236       //- returned.
00237                                      
00238     PST_Edge* split( PST_Point* point );
00239       //- Split an existing edge.  Creates a new edge in the 
00240       //- same face(s) as the existing edge.  Returns null
00241       //- if the passed already exists in any face.
00242 
00243     ~PST_Edge();
00244       //- Destroy this edge, splitting or merging faces as
00245       //- necessary.  Does NOT destroy unused points.
00246     
00247     PST_Point* start_point()
00248       { return start_; }
00249     
00250     PST_Point* end_point()
00251       { return end_; }
00252     
00253     const CubitVector& start_coord()
00254       { return *start_; }
00255       
00256     const CubitVector& end_coord()
00257       { return *end_; }
00258     
00259     CubitVector direction()
00260       { return end_coord() - start_coord(); }
00261       
00262     
00263     CubitVector position( double t )
00264       { return start_coord() + t * direction(); }
00265   
00266     double closest_on_line( const CubitVector& pos );
00267     double closest_on_edge( const CubitVector& pos );
00268       // Parameter of the closest position on 
00269       // a) the line containing this edge or 
00270       // b) this bounded edge.
00271       
00272     double closest_on_line( const CubitVector& base, 
00273                             const CubitVector& direction );
00274       // The parameter of the closest position on
00275       // the line containing this edge to the passed line.
00276       // Use position(..) function above to get coordinates.
00277       
00278     PST_Point* other( PST_Point* pt )
00279       { return PST_OTHER(pt,start_,end_); }
00280     
00281     inline PST_Point* common_point( PST_Edge* edge );
00282     
00283     PST_CoEdge* forward() 
00284       { return &forward_; }
00285     
00286     PST_CoEdge* reverse()
00287       { return &reverse_; }
00288       
00289     PST_CoEdge* other( PST_CoEdge* coedge )
00290       { return PST_OTHER(coedge,&forward_,&reverse_); }
00291     
00292     inline PST_CoEdge* coedge( PST_Face* face );
00293     
00294     
00295     PST_Face* other( PST_Face* face )
00296       { return PST_OTHER(face,forward_.face(),reverse_.face()); }
00297    
00298     
00299     inline PST_Face* common_face( PST_Edge* edge );
00300     
00301     inline CubitSense sense( PST_Face* face );
00302     
00303     CubitSense sense( PST_CoEdge* coedge )
00304       { return coedge == forward() ? CUBIT_FORWARD  :
00305                coedge == reverse() ? CUBIT_REVERSED : CUBIT_UNKNOWN; }
00306 
00307     PST_Edge* other( PST_Point* point, PST_Face* face );
00308       // Find the other edge in the passed face that
00309       // shares the passed point.  Returns NULL if multiple
00310       // matches in a non-manifold face.
00311 
00312     PST_Edge* next( PST_Point* pt )
00313       { return pt == start_ ? start_next_ : 
00314                pt == end_   ? end_next_ : 0; }
00315                
00316     //inline bool boundary();
00317     
00318     static void faces( DLIList<PST_Edge*>& edges, DLIList<PST_Face*>& faces );
00319     static void edges( DLIList<PST_Face*>& faces, DLIList<PST_Edge*>& edges );
00320     static void edges( DLIList<PST_Point*>& pts,  DLIList<PST_Edge*>& edges );
00321     static void points( DLIList<PST_Edge*>& edges, DLIList<PST_Point*>& pts );
00322     
00323     void debug_draw( int color = 1, bool flush = true );
00324     static void debug_draw_points( DLIList<PST_Edge*>& list, 
00325                              int color, int bcolor = 0, bool flush = true );
00326     static void debug_draw_edges ( DLIList<PST_Edge*>& list, 
00327                              int color, int bcolor = 0, bool flush = true );
00328     static void debug_draw_faces ( DLIList<PST_Edge*>& list, 
00329                              int color, bool flush = true );
00330     
00331     static int validate( DLIList<PST_Edge*>& edges, CubitBoolean print = CUBIT_FALSE );
00332     int validate( CubitBoolean print = CUBIT_FALSE );
00333     
00334     void print();
00335 
00336     int mark;
00337 
00338   private:
00339     cBit private_mark_ : 1;
00340     
00341     void remove_point( PST_Point*& ptr, PST_Edge*& next );
00342     void remove_start_point() { remove_point( start_, start_next_ ); }
00343     void remove_end_point()   { remove_point( end_, end_next_); }
00344     
00345     void set_point( PST_Point* pt, PST_Point*& ptr, PST_Edge*& next );
00346     void set_start_point( PST_Point* pt )
00347       { set_point( pt, start_, start_next_ ); }
00348     void set_end_point( PST_Point* pt )
00349       { set_point( pt, end_, end_next_ ); }
00350       
00351     PST_Point* start_;
00352     PST_Point* end_;
00353     PST_Edge* start_next_;
00354     PST_Edge* end_next_;
00355     
00356     PST_CoEdge forward_;
00357     PST_CoEdge reverse_;
00358 };
00359 
00360 //-------------------------------------------------------------------------
00361 // Purpose       : Face in facet data structure
00362 //
00363 // Special Notes : 
00364 //
00365 // Creator       : Jason Kraftcheck
00366 //
00367 // Creation Date : 05/16/01
00368 //-------------------------------------------------------------------------
00369 class PST_Face : public PST_Entity
00370 {
00371   friend class PST_Edge;
00372   friend class PST_Point;
00373 
00374   public:
00375       
00376     const CubitPlane& plane()
00377       {
00378         if( update_plane_ )
00379           calculate_plane();
00380         return plane_;
00381       }
00382   
00383     CubitVector normal()
00384       { return plane().normal(); }
00385       
00386       
00387     double bounding_length();
00388     
00389     PST_CoEdge* first_coedge()
00390       { return coedge_; }
00391       
00392     void append_points( DLIList<PST_Point*>& result_list );
00393     
00394     PST_Point* opposite( PST_Edge* edge );
00395     PST_Edge* opposite( PST_Point* point );
00396       // for triangles
00397       
00398     bool two_edges( PST_Point* point, PST_Edge*& edge1, PST_Edge*& edge2 );
00399   
00400     bool modified()
00401       { return modified_; }
00402     
00403     void modified( bool b )
00404       { 
00405         modified_ = b;
00406         if( b ) update_plane_ = 1;
00407       }
00408       
00409     void debug_draw( int color = 1, bool flush = true );
00410     static void debug_draw_faces( DLIList<PST_Face*>& list, 
00411                             int color, bool flush = true );
00412   
00413     int validate( CubitBoolean print = CUBIT_FALSE );
00414     
00415     void print();
00416     
00417     int mark;
00418     
00419     int sequence;
00420     
00421     int parent;
00422     
00423   private:
00424   
00425     PST_Face( PST_CoEdge* coedge )
00426       : mark(0), sequence(0), parent(0),
00427         coedge_(coedge), 
00428         //boundary_(0),
00429         modified_(0),
00430         update_plane_(1),
00431         private_mark_(false)
00432         
00433       { }
00434       
00435     PST_Face( PST_CoEdge* coedge, PST_Face* split_from )
00436       : mark(0), sequence(0), parent(0),
00437         coedge_(coedge),
00438         //boundary_(split_from->boundary()),
00439         modified_(0),
00440         update_plane_(1),
00441         private_mark_(false)
00442       { split_from->modified(true); }
00443   
00444     ~PST_Face()
00445       { assert( !coedge_ ); }
00446   
00447     bool calculate_plane();
00448     
00449     PST_CoEdge* coedge_;
00450     CubitPlane  plane_;
00451     
00452     //cBit boundary_     : 1;
00453     cBit modified_     : 1;
00454     cBit update_plane_ : 1;
00455     cBit private_mark_ : 1;
00456 };
00457 
00458 /*************************************************************************
00459  *                               PST_Point
00460  ************************************************************************/
00461 
00462 inline PST_Edge* PST_Point::next( PST_Edge* prev )
00463 { 
00464   return prev->next(this);
00465 }
00466 
00467 /*************************************************************************
00468  *                               PST_CoEdge
00469  ************************************************************************/
00470 
00471 inline CubitSense PST_CoEdge::sense()
00472 {
00473   return edge_->sense(this);
00474 }
00475 
00476 inline PST_Point* PST_CoEdge::start_point()
00477 {
00478   return sense() == CUBIT_FORWARD ? edge_->start_point() : edge_->end_point();
00479 }
00480 
00481 inline PST_Point* PST_CoEdge::end_point()
00482 {
00483   return sense() == CUBIT_FORWARD ? edge_->end_point() : edge_->start_point();
00484 }
00485 
00486 inline PST_Point* PST_CoEdge::other( PST_Point* point )
00487 {
00488   return edge_->other( point );
00489 }
00490 
00491 inline const CubitVector& PST_CoEdge::start_coord()
00492 {
00493   return sense() == CUBIT_FORWARD ? edge_->start_coord() : edge_->end_coord();
00494 }
00495 
00496 inline const CubitVector& PST_CoEdge::end_coord()
00497 {
00498   return sense() == CUBIT_FORWARD ? edge_->end_coord() : edge_->start_coord();
00499 }
00500 
00501 inline CubitVector PST_CoEdge::direction()
00502 {
00503   return sense() == CUBIT_FORWARD                  ? 
00504          edge_->end_coord() - edge_->start_coord() :
00505          edge_->start_coord() - edge_->end_coord() ;
00506 }
00507 
00508 inline PST_CoEdge* PST_CoEdge::other()
00509 {
00510   return edge_->other(this);
00511 }
00512 
00513 
00514 
00515 /*************************************************************************
00516  *                               PST_Edge
00517  ************************************************************************/
00518 
00519 inline PST_Point* PST_Edge::common_point( PST_Edge* edge )
00520 {
00521   PST_Point* result = 0;
00522   
00523   if( (edge->start_ == start_) || 
00524       (edge->end_   == start_)  )
00525     result = start_;
00526   
00527   if( (edge->start_ == end_) || 
00528       (edge->end_   == end_)  )
00529     result = result ? 0 : end_;
00530   
00531   return result;
00532 }
00533 
00534 inline PST_CoEdge* PST_Edge::coedge( PST_Face* face )
00535 {
00536   PST_CoEdge* result = 0;
00537   
00538   if( forward_.face_ == face )
00539     result = &forward_;
00540   
00541   if( reverse_.face_ == face )
00542     result = result ? 0 : &reverse_;
00543   
00544   return result;
00545 }
00546 
00547 inline CubitSense PST_Edge::sense( PST_Face* face )
00548 {
00549   CubitSense result = CUBIT_UNKNOWN;
00550   
00551   if( forward_.face_ == face )
00552     result = CUBIT_FORWARD;
00553   
00554   if( reverse_.face_ == face )
00555     result = (result != CUBIT_UNKNOWN) ? CUBIT_UNKNOWN : CUBIT_REVERSED;
00556   
00557   return result;
00558 }
00559 
00560 inline PST_Entity::PST_Entity() : myOwner(0) { ; }
00561 
00562 inline PST_EntityOwner* PST_Entity::owner() const
00563   { return myOwner; }
00564 
00565 inline void PST_Entity::owner( PST_EntityOwner* ent )
00566   { myOwner = ent; }
00567 
00568 
00569 /*************************************************************************
00570  *                               PST_Face
00571  ************************************************************************/
00572  
00573  // find the minimum edge length and use this for the bounding length
00574 inline double PST_Face::bounding_length()
00575 {
00576   // The coedges appear to be stored in a circular list so 
00577   // get the length of the first edge and then iterate
00578   PST_CoEdge* coe = this->first_coedge();
00579   CubitVector pos1 = coe->start_coord();
00580   CubitVector pos2 = coe->end_coord();
00581   CubitVector dist = pos1 - pos2;
00582   double length = dist.length_squared();
00583 
00584   // start the chain at the next coedge
00585   coe = coe->next();
00586 
00587   // walk through the coedges till we get back to the first 
00588   // and find the minimum length edge
00589   double l;
00590   for ( ; coe != this->first_coedge(); coe = coe->next() )
00591   {
00592     pos1 = coe->start_coord();
00593     pos2 = coe->end_coord();
00594     dist = pos1 - pos2;
00595     l = dist.length_squared();
00596     if ( l < length)
00597       length = l;
00598   }
00599 
00600   return sqrt(length);
00601 }
00602 
00603 #endif
00604 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines