#ifndef TMeshPoint_hxx_seen #define TMeshPoint_hxx_seen #include #include #include "IMeshEdge.hxx" namespace COMET { class IMesh; class IMeshEdge; class IMeshPoint; class IMeshXYPoint; }; /// An abstract representation of a point that will be connected into a mesh. /// The user must inherit from this to create a real point which provides the /// X, and Y coordinates of the point (in whatever abstract space the /// triangulation is being done). class COMET::IMeshPoint { friend class IMesh; friend class IMeshEdge; public: class Walker; typedef TMeshEdgeSet::iterator EdgeIterator; typedef std::vector PointVector; typedef std::vector PathVector; IMeshPoint(); virtual ~IMeshPoint(); /// The abstract X coordinate for the point. virtual double X(void) const = 0; /// The abstract Y coordinate for the point. virtual double Y(void) const = 0; /// Return the number of edges attached to this point. int GetEdgeCount(void) const {return fEdges.size();} /// Return the beginning of the edge. Note that the edge order is /// undefined. EdgeIterator BeginEdges(void) const {return fEdges.begin();} /// Return the end of the edges. EdgeIterator EndEdges(void) const {return fEdges.end();} /// Return an iterator that will "walk" over the set of points that are /// connected to this point by edges. Walker BeginPoints(void); /// Return an iterator that marks the end of the set of points that are /// simply connected. Walker& EndPoints(void); /// Return paths that connect to points. This takes a beginning and /// ending point, and will return a vector of paths that go between the /// points. It can take two optional arguments. The first is the maximum /// number of paths to return (the default is two paths). In this case, /// it will return the first too complete paths that are found. The /// second is the maximum number of steps that can be in any single path. /// The first point in a path will always be the requested beginning /// point. The last point in a path will always be the requested ending /// point /// /// The return paths are ordered by path length from the shortest to the /// longest. This means that if you are using a this method to check if /// the ends an edge are part of a closed loop, the first path will be /// just the beginning and the ending points (one step) and the second /// path will be the rest of the loop. PathVector GetPaths(const IMeshPoint* end, int maxPaths=2, int maxSteps=10); // bool operator == (const IMeshPoint& rhs) const; bool operator < (const IMeshPoint& rhs) const; private: /// The set of edges for this IMeshPoint. TMeshEdgeSet fEdges; /// This is used by IMesh to add edges to the IMeshPoint. void AddEdge(IMeshEdge* a); /// This is used by IMeshEdge objects to remove themselves from the /// IMeshPoint. void RemoveEdge(IMeshEdge* a); public: class IPathPoint { public: IPathPoint(const IMeshPoint* point, const IPathPoint* path) : fPoint(point), fPath(path) {} IPathPoint(const IPathPoint& pp) : fPoint(pp.fPoint), fPath(pp.fPath) {} const IMeshPoint* GetPoint() const {return fPoint;} const IPathPoint* GetPath() const {return fPath;} int GetLength() const {return (!fPath) ? (1): (1+fPath->GetLength());} private: const IMeshPoint* fPoint; const IPathPoint* fPath; }; class Walker : public std::iterator { public: Walker(); Walker(const Walker&); Walker(IMeshPoint*); ~Walker(); IMeshPoint* operator *() const; Walker& operator ++(); bool operator == (Walker& rhs); bool operator != (Walker& rhs); private: void PackQueue(void); std::queue fQueue; std::set fSeen; }; private: static Walker fEnd; }; namespace COMET { struct TMeshPointPointerLessThan { bool operator () (const IMeshPoint* a, const IMeshPoint* b) const { return *a < *b; } }; typedef std::set TMeshPointSet; }; /// A simple concrete representation of a point that will be connected into a /// mesh. class COMET::IMeshXYPoint : public COMET::IMeshPoint { public : /// Create a new point. IMeshXYPoint(double x, double y) : fX(x), fY(y) { } virtual ~IMeshXYPoint(); /// Return the X value of the point. double X(void) const {return fX;} /// Return the X value of the point. double Y(void) const {return fY;} private : // The X Coordinate of the point. double fX; // The Y Coordinate of the point. double fY; }; std::ostream& operator << (std::ostream& s, COMET::IMeshPoint& p); #endif