text: // This file is part of RAVL, Recognition And Vision Library 
  // Copyright (C) 2002, University of Surrey
  // This code may be redistributed under the terms of the GNU Lesser
  // General Public License (LGPL). See the lgpl.licence file for details or
  // see http://www.gnu.org/copyleft/lesser.html
  // file-header-ends-here
  #ifndef RAVL_THEMESHFACE_HEADER
  #define RAVL_THEMESHFACE_HEADER 1
  //! rcsid="$Id: THEMeshFace.hh 5240 2005-12-06 17:16:50Z plugger $"
  //! lib=RavlCore
  //! docentry="Ravl.API.Core.Graphs.Half Edge Mesh"
  //! date="24/4/2002"
  //! author="Charles Galambos"
  //! file="Ravl/Core/Container/Graph/THEMeshFace.hh"
  
  #include "Ravl/DLink.hh"
  #include "Ravl/HEMeshBaseFace.hh"
  #include "Ravl/THEMeshEdge.hh"
  
  namespace RavlN {
    
    template<class VertexDataT,class FaceDataT,class EdgeDataT> class THEMeshVertexC;
    template<class VertexDataT,class FaceDataT,class EdgeDataT> class THEMeshFaceC;
    template<class VertexDataT,class FaceDataT,class EdgeDataT> class THEMeshFaceBodyC;
    template<class VertexDataT,class FaceDataT,class EdgeDataT> class THEMeshC;
    template<class VertexDataT,class FaceDataT,class EdgeDataT> class THEMeshFaceEdgeIterC;
    template<class VertexDataT,class FaceDataT,class EdgeDataT> class THEMeshEdgeC;
    template<class VertexDataT,class FaceDataT,class EdgeDataT> class THEMeshEdgeBodyC;
    template<class VertexDataT,class FaceDataT,class EdgeDataT> class THEMeshBodyC;  
    template<class VertexDataT,class FaceDataT,class EdgeDataT> class THEMeshFaceIterC;
    
    //! userlevel=Develop
    //: Face in mesh.
    
    template<class VertexDataT,class FaceDataT = EmptyC,class EdgeDataT = EmptyC>
    class THEMeshFaceBodyC 
      : public HEMeshBaseFaceBodyC
    {
    public:
      THEMeshFaceBodyC(UIntT nid = 0)
        : HEMeshBaseFaceBodyC(nid)
      {}
      //: Default constructor.
  
      THEMeshFaceBodyC(const FaceDataT &faceData,UIntT nid = 0)
        : HEMeshBaseFaceBodyC(nid),
  	data(faceData)
      {}
      //: Constructor.
      
      THEMeshFaceBodyC(THEMeshEdgeBodyC<VertexDataT,FaceDataT,EdgeDataT> &nedge)
        : HEMeshBaseFaceBodyC(&nedge)
      {}
      //: Default constructor.
      
    protected:
      THEMeshEdgeBodyC<VertexDataT,FaceDataT,EdgeDataT> *FirstEdge()
      { return static_cast<THEMeshEdgeBodyC<VertexDataT,FaceDataT,EdgeDataT> *>(edge); }
      //: Access first edge.
      
    public:        
      THEMeshEdgeC<VertexDataT,FaceDataT,EdgeDataT> Edge() 
      { return THEMeshEdgeC<VertexDataT,FaceDataT,EdgeDataT>(*edge); }
      //: Get an edge leading to the face.
      
      THEMeshEdgeC<VertexDataT,FaceDataT,EdgeDataT> FindEdge(THEMeshVertexC<VertexDataT,FaceDataT,EdgeDataT> a);
      //: Find the edge linking to vertex a.
      // If edge is not found an invalid handle is returned.
      
      FaceDataT &Data()
      { return data; }
      //: Access data.
      
      const FaceDataT &Data() const
      { return data; }
      //: Access data.
      
    private:
      FaceDataT data;
      
      friend class THEMeshFaceEdgeIterC<VertexDataT,FaceDataT,EdgeDataT>;
      friend class THEMeshFaceC<VertexDataT,FaceDataT,EdgeDataT>;
      friend class THEMeshEdgeBodyC<VertexDataT,FaceDataT,EdgeDataT>;
      friend class THEMeshBodyC<VertexDataT,FaceDataT,EdgeDataT>;
    };
    
    //! userlevel=Normal
    //: Face in mesh.
    
    template<class VertexDataT,class FaceDataT = EmptyC,class EdgeDataT = EmptyC>
    class THEMeshFaceC 
      : public HEMeshBaseFaceC
    {
    public:
      THEMeshFaceC()
      {}
      //: Default constructor
      // Creates an invalid handle.
      
      THEMeshFaceC(const HEMeshBaseFaceC &base)
        : HEMeshBaseFaceC(dynamic_cast<const THEMeshFaceBodyC<VertexDataT,FaceDataT,EdgeDataT> *>(BodyPtr(base)))
      {}
      //: Base constructor.
      
    protected:
      THEMeshFaceBodyC<VertexDataT,FaceDataT,EdgeDataT> &Body()
      { return static_cast<THEMeshFaceBodyC<VertexDataT,FaceDataT,EdgeDataT> &>(HEMeshBaseFaceC::Body()); }
      //: Body access.
      
      const THEMeshFaceBodyC<VertexDataT,FaceDataT,EdgeDataT> &Body() const
      { return static_cast<const THEMeshFaceBodyC<VertexDataT,FaceDataT,EdgeDataT> &>(HEMeshBaseFaceC::Body()); }
      //: Body access.
      
    public:
      FaceDataT &Data()
      { return Body().Data(); }
      //: Access data.
      
      const FaceDataT &Data() const
      { return Body().Data(); }
      //: Access data.
  
    protected:
      THEMeshFaceC(THEMeshFaceBodyC<VertexDataT,FaceDataT,EdgeDataT> &bod)
        : HEMeshBaseFaceC(bod)
      {}
      //: Body constructor.
      
      THEMeshFaceC(const FaceDataT &faceData,UIntT nid = 0)
        : HEMeshBaseFaceC(new THEMeshFaceBodyC<VertexDataT,FaceDataT,EdgeDataT>(faceData,nid))
      {}
      //: Construct a new face.
      
      THEMeshFaceC(THEMeshEdgeC<VertexDataT,FaceDataT,EdgeDataT> edge)
        : HEMeshBaseFaceC(new THEMeshFaceBodyC<VertexDataT,FaceDataT,EdgeDataT>(edge.Body()))
      {}
      //: Construct a new face.
      
      
  #if 0
      THEMeshEdgeBodyC<VertexDataT,FaceDataT,EdgeDataT> *FirstEdge()
      { return Body().FirstEdge(); }
      //: Access first edge.
  #endif
    public:    
      THEMeshEdgeC<VertexDataT,FaceDataT,EdgeDataT> Edge() 
      { return THEMeshEdgeC<VertexDataT,FaceDataT,EdgeDataT>(Body().Edge()); }
      //: Get an edge leading to the face.
  
  #if 0    
      THEMeshEdgeC<VertexDataT,FaceDataT,EdgeDataT> FindEdge(THEMeshVertexC<VertexDataT,FaceDataT,EdgeDataT> a)
      { return Body().FindEdge(a); }
      //: Find the edge linking to vertex a.
      // If edge is not found an invalid handle is returned.
  #endif    
      
    private:
      friend class THEMeshFaceEdgeIterC<VertexDataT,FaceDataT,EdgeDataT>;
      friend class THEMeshBodyC<VertexDataT,FaceDataT,EdgeDataT>;
      friend class THEMeshEdgeC<VertexDataT,FaceDataT,EdgeDataT>;
      friend class THEMeshVertexBodyC<VertexDataT,FaceDataT,EdgeDataT>;
      friend class THEMeshFaceIterC<VertexDataT,FaceDataT,EdgeDataT>;
      friend class THEMeshC<VertexDataT,FaceDataT,EdgeDataT>;
    };
    
    //! userlevel=Normal
    //: Iterate through edges around a face.
    
    template<class VertexDataT,class FaceDataT = EmptyC,class EdgeDataT = EmptyC>
    class THEMeshFaceEdgeIterC 
      : public HEMeshBaseFaceEdgeIterC
    {
    public:
      THEMeshFaceEdgeIterC()
      {}
      //: Default constructor.
      
      THEMeshFaceEdgeIterC(const THEMeshFaceC<VertexDataT,FaceDataT,EdgeDataT> &face)
        : HEMeshBaseFaceEdgeIterC(face)
      {}
      //: Construct from a face
      
      THEMeshFaceEdgeIterC(THEMeshFaceBodyC<VertexDataT,FaceDataT,EdgeDataT> &face)
        : HEMeshBaseFaceEdgeIterC(face)
      {}
      //: Construct from a face
  
    protected:
      THEMeshEdgeBodyC<VertexDataT,FaceDataT,EdgeDataT> &At()
      { return static_cast<THEMeshEdgeBodyC<VertexDataT,FaceDataT,EdgeDataT> &>(*at); }
      //: Access destination.
  
      const THEMeshEdgeBodyC<VertexDataT,FaceDataT,EdgeDataT> &At() const
      { return static_cast<THEMeshEdgeBodyC<VertexDataT,FaceDataT,EdgeDataT> &>(*at); }
      //: Access destination.
      
    public:
      THEMeshEdgeC<VertexDataT,FaceDataT,EdgeDataT> Data()
      { return THEMeshEdgeC<VertexDataT,FaceDataT,EdgeDataT>(At()); }
      //: Access edge.
      // Iterator must be at a valid element
      // before calling this method.
      
      const THEMeshEdgeC<VertexDataT,FaceDataT,EdgeDataT> Data() const
      { return THEMeshEdgeC<VertexDataT,FaceDataT,EdgeDataT>(At()); }
      //: Access edge.
      // Iterator must be at a valid element
      // before calling this method.
      
      const THEMeshEdgeC<VertexDataT,FaceDataT,EdgeDataT> operator *() const
      { return THEMeshEdgeC<VertexDataT,FaceDataT,EdgeDataT>(At()); }
      //: Access edge.
      // Iterator must be at a valid element
      // before calling this method.
      
      THEMeshEdgeC<VertexDataT,FaceDataT,EdgeDataT> operator *()
      { return THEMeshEdgeC<VertexDataT,FaceDataT,EdgeDataT>(At()); }
      //: Access edge.
      // Iterator must be at a valid element
      // before calling this method.
      
      const THEMeshEdgeBodyC<VertexDataT,FaceDataT,EdgeDataT> *operator->() const
      { return &At(); }
      //: Access edge.
      // Iterator must be at a valid element
      // before calling this method.
      
      THEMeshEdgeBodyC<VertexDataT,FaceDataT,EdgeDataT> *operator->()
      { return &At(); }
      //: Access edge.
      // Iterator must be at a valid element
      // before calling this method.
  
    };
  
    template<class VertexDataT,class FaceDataT,class EdgeDataT>
    inline THEMeshFaceC<VertexDataT,FaceDataT,EdgeDataT> THEMeshEdgeC<VertexDataT,FaceDataT,EdgeDataT>::Face() 
    { return THEMeshFaceC<VertexDataT,FaceDataT,EdgeDataT>(HEMeshBaseEdgeC::Face()); }
    
  }
  
  #endif
  