Commit eb22bf42 authored by jean-pierre charras's avatar jean-pierre charras
Browse files

Pcbnew: very minor fixes and update: update clipper version. uncrustify...

Pcbnew: very minor fixes and update:  update clipper version. uncrustify polytri/* and fix some warning compil.
parent 6e56aa2f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@
#ifndef DRW_BASE_H
#define DRW_BASE_H

#define DRW_VERSION "0.5.10"
#define DRW_VERSION "0.5.11"

#include <string>
#include <cmath>
+4 −4
Original line number Diff line number Diff line
@@ -88,8 +88,8 @@ CPolyLine::~CPolyLine()
#include "clipper.hpp"
int CPolyLine::NormalizeAreaOutlines( std::vector<CPolyLine*>* aNewPolygonList )
{
    ClipperLib::Polygon raw_polygon;
    ClipperLib::Polygons normalized_polygons;
    ClipperLib::Path raw_polygon;
    ClipperLib::Paths normalized_polygons;

    unsigned corners_count = m_CornersList.GetCornersCount();

@@ -115,7 +115,7 @@ int CPolyLine::NormalizeAreaOutlines( std::vector<CPolyLine*>* aNewPolygonList )
    // enter main outline
    for( unsigned ii = 0; ii < normalized_polygons.size(); ii++ )
    {
        ClipperLib::Polygon& polygon = normalized_polygons[ii];
        ClipperLib::Path& polygon = normalized_polygons[ii];
        cornerslist.clear();
        for( unsigned jj = 0; jj < polygon.size(); jj++ )
            cornerslist.push_back( KI_POLY_POINT( KiROUND( polygon[jj].X ),
@@ -142,7 +142,7 @@ int CPolyLine::NormalizeAreaOutlines( std::vector<CPolyLine*>* aNewPolygonList )
                ClipperLib::SimplifyPolygon( raw_polygon, normalized_polygons );
                for( unsigned ii = 0; ii < normalized_polygons.size(); ii++ )
                {
                    ClipperLib::Polygon& polygon = normalized_polygons[ii];
                    ClipperLib::Path& polygon = normalized_polygons[ii];
                    cornerslist.clear();
                    for( unsigned jj = 0; jj < polygon.size(); jj++ )
                        cornerslist.push_back( KI_POLY_POINT( KiROUND( polygon[jj].X ),
+2788 −1757

File changed.

Preview size limit exceeded, changes collapsed.

+202 −147
Original line number Diff line number Diff line
/*******************************************************************************
*                                                                              *
* Author    :  Angus Johnson                                                   *
* Version   :  5.1.4                                                           *
* Date      :  24 March 2013                                                   *
* Version   :  6.1.2                                                           *
* Date      :  15 December 2013                                                *
* Website   :  http://www.angusj.com                                           *
* Copyright :  Angus Johnson 2010-2013                                         *
*                                                                              *
@@ -34,11 +34,29 @@
#ifndef clipper_hpp
#define clipper_hpp

#define CLIPPER_VERSION "6.1.2"

//use_int32: When enabled 32bit ints are used instead of 64bit ints. This
//improve performance but coordinate values are limited to the range +/- 46340
//#define use_int32

//use_xyz: adds a Z member to IntPoint. Adds a minor cost to perfomance.
//#define use_xyz

//use_lines: Enables line clipping. Adds a very minor cost to performance.
//#define use_lines
  
//use_deprecated: Enables support for the obsolete OffsetPaths() function
//which has been replace with the ClipperOffset class.
#define use_deprecated  

#include <vector>
#include <set>
#include <stdexcept>
#include <cstring>
#include <cstdlib>
#include <ostream>
#include <functional>

namespace ClipperLib {

@@ -50,23 +68,64 @@ enum PolyType { ptSubject, ptClip };
//see http://glprogramming.com/red/chapter11.html
enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative };

typedef signed long long long64;
typedef unsigned long long ulong64;
#ifdef use_int32
typedef int cInt;
typedef unsigned int cUInt;
#else
typedef signed long long cInt;
typedef unsigned long long cUInt;
#endif

struct IntPoint {
public:
  long64 X;
  long64 Y;
  IntPoint(long64 x = 0, long64 y = 0): X(x), Y(y) {};
  friend std::ostream& operator <<(std::ostream &s, IntPoint &p);
  cInt X;
  cInt Y;
#ifdef use_xyz
  cInt Z;
  IntPoint(cInt x = 0, cInt y = 0, cInt z = 0): X(x), Y(y), Z(z) {};
#else
  IntPoint(cInt x = 0, cInt y = 0): X(x), Y(y) {};
#endif

  friend inline bool operator== (const IntPoint& a, const IntPoint& b)
  {
    return a.X == b.X && a.Y == b.Y;
  }
  friend inline bool operator!= (const IntPoint& a, const IntPoint& b)
  {
    return a.X != b.X  || a.Y != b.Y; 
  }
};
//------------------------------------------------------------------------------

typedef std::vector< IntPoint > Path;
typedef std::vector< Path > Paths;

inline Path& operator <<(Path& poly, const IntPoint& p) {poly.push_back(p); return poly;}
inline Paths& operator <<(Paths& polys, const Path& p) {polys.push_back(p); return polys;}

std::ostream& operator <<(std::ostream &s, const IntPoint &p);
std::ostream& operator <<(std::ostream &s, const Path &p);
std::ostream& operator <<(std::ostream &s, const Paths &p);

typedef std::vector< IntPoint > Polygon;
typedef std::vector< Polygon > Polygons;
struct DoublePoint
{
  double X;
  double Y;
  DoublePoint(double x = 0, double y = 0) : X(x), Y(y) {}
  DoublePoint(IntPoint ip) : X((double)ip.X), Y((double)ip.Y) {}
};
//------------------------------------------------------------------------------

#ifdef use_xyz
typedef void (*TZFillCallback)(IntPoint& z1, IntPoint& z2, IntPoint& pt);
#endif

std::ostream& operator <<(std::ostream &s, Polygon &p);
std::ostream& operator <<(std::ostream &s, Polygons &p);
enum InitOptions {ioReverseSolution = 1, ioStrictlySimple = 2, ioPreserveCollinear = 4};
enum JoinType {jtSquare, jtRound, jtMiter};
enum EndType {etClosedPolygon, etClosedLine, etOpenButt, etOpenSquare, etOpenRound};
#ifdef use_deprecated
  enum EndType_ {etClosed, etButt = 2, etSquare, etRound};
#endif

class PolyNode;
typedef std::vector< PolyNode* > PolyNodes;
@@ -75,17 +134,22 @@ class PolyNode
{ 
public:
    PolyNode();
    Polygon Contour;
    Path Contour;
    PolyNodes Childs;
    PolyNode* Parent;
    PolyNode* GetNext() const;
    bool IsHole() const;
    bool IsOpen() const;
    int ChildCount() const;
private:
    PolyNode* GetNextSiblingUp() const;
    unsigned Index; //node index in Parent.Childs
    bool m_IsOpen;
    JoinType m_jointype;
    EndType m_endtype;
    PolyNode* GetNextSiblingUp() const;
    void AddChild(PolyNode& child);
    friend class Clipper; //to access Index
    friend class ClipperOffset; 
};

class PolyTree: public PolyNode
@@ -100,112 +164,54 @@ private:
    friend class Clipper; //to access AllNodes
};

enum JoinType { jtSquare, jtRound, jtMiter };

bool Orientation(const Polygon &poly);
double Area(const Polygon &poly);
bool Orientation(const Path &poly);
double Area(const Path &poly);

void OffsetPolygons(const Polygons &in_polys, Polygons &out_polys,
  double delta, JoinType jointype = jtSquare, double limit = 0, bool autoFix = true);
#ifdef use_deprecated
  void OffsetPaths(const Paths &in_polys, Paths &out_polys,
    double delta, JoinType jointype, EndType_ endtype, double limit = 0);
#endif

void SimplifyPolygon(const Polygon &in_poly, Polygons &out_polys, PolyFillType fillType = pftEvenOdd);
void SimplifyPolygons(const Polygons &in_polys, Polygons &out_polys, PolyFillType fillType = pftEvenOdd);
void SimplifyPolygons(Polygons &polys, PolyFillType fillType = pftEvenOdd);
void SimplifyPolygon(const Path &in_poly, Paths &out_polys, PolyFillType fillType = pftEvenOdd);
void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType fillType = pftEvenOdd);
void SimplifyPolygons(Paths &polys, PolyFillType fillType = pftEvenOdd);

void CleanPolygon(Polygon& in_poly, Polygon& out_poly, double distance = 1.415);
void CleanPolygons(Polygons& in_polys, Polygons& out_polys, double distance = 1.415);
void CleanPolygon(const Path& in_poly, Path& out_poly, double distance = 1.415);
void CleanPolygon(Path& poly, double distance = 1.415);
void CleanPolygons(const Paths& in_polys, Paths& out_polys, double distance = 1.415);
void CleanPolygons(Paths& polys, double distance = 1.415);

void PolyTreeToPolygons(PolyTree& polytree, Polygons& polygons);
void MinkowskiSum(const Path& poly, const Path& path, Paths& solution, bool isClosed);
void MinkowskiDiff(const Path& poly, const Path& path, Paths& solution, bool isClosed);

void ReversePolygon(Polygon& p);
void ReversePolygons(Polygons& p);
void PolyTreeToPaths(const PolyTree& polytree, Paths& paths);
void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths);
void OpenPathsFromPolyTree(PolyTree& polytree, Paths& paths);

//used internally ...
enum EdgeSide { esLeft = 1, esRight = 2};
enum IntersectProtects { ipNone = 0, ipLeft = 1, ipRight = 2, ipBoth = 3 };

struct TEdge {
  long64 xbot;
  long64 ybot;
  long64 xcurr;
  long64 ycurr;
  long64 xtop;
  long64 ytop;
  double dx;
  long64 deltaX;
  long64 deltaY;
  PolyType polyType;
  EdgeSide side;
  int windDelta; //1 or -1 depending on winding direction
  int windCnt;
  int windCnt2; //winding count of the opposite polytype
  int outIdx;
  TEdge *next;
  TEdge *prev;
  TEdge *nextInLML;
  TEdge *nextInAEL;
  TEdge *prevInAEL;
  TEdge *nextInSEL;
  TEdge *prevInSEL;
};
void ReversePath(Path& p);
void ReversePaths(Paths& p);

struct IntersectNode {
  TEdge          *edge1;
  TEdge          *edge2;
  IntPoint        pt;
  IntersectNode  *next;
};
struct IntRect { cInt left; cInt top; cInt right; cInt bottom; };

struct LocalMinima {
  long64        Y;
  TEdge        *leftBound;
  TEdge        *rightBound;
  LocalMinima  *next;
};

struct Scanbeam {
  long64    Y;
  Scanbeam *next;
};

struct OutPt; //forward declaration

struct OutRec {
  int     idx;
  bool    isHole;
  OutRec *FirstLeft;  //see comments in clipper.pas
  PolyNode *polyNode;
  OutPt  *pts;
  OutPt  *bottomPt;
};

struct OutPt {
  int     idx;
  IntPoint pt;
  OutPt   *next;
  OutPt   *prev;
};

struct JoinRec {
  IntPoint  pt1a;
  IntPoint  pt1b;
  int       poly1Idx;
  IntPoint  pt2a;
  IntPoint  pt2b;
  int       poly2Idx;
};

struct HorzJoinRec {
  TEdge    *edge;
  int       savedIdx;
};
//enums that are used internally ...
enum EdgeSide { esLeft = 1, esRight = 2};

struct IntRect { long64 left; long64 top; long64 right; long64 bottom; };
//forward declarations (for stuff used internally) ...
struct TEdge;
struct IntersectNode;
struct LocalMinima;
struct Scanbeam;
struct OutPt;
struct OutRec;
struct Join;

typedef std::vector < OutRec* > PolyOutList;
typedef std::vector < TEdge* > EdgeList;
typedef std::vector < JoinRec* > JoinList;
typedef std::vector < HorzJoinRec* > HorzJoinList;
typedef std::vector < Join* > JoinList;
typedef std::vector < IntersectNode* > IntersectList;


//------------------------------------------------------------------------------

//ClipperBase is the ancestor to the Clipper class. It should not be
//instantiated directly. This class simply abstracts the conversion of sets of
@@ -215,29 +221,38 @@ class ClipperBase
public:
  ClipperBase();
  virtual ~ClipperBase();
  bool AddPolygon(const Polygon &pg, PolyType polyType);
  bool AddPolygons( const Polygons &ppg, PolyType polyType);
  bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed);
  bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed);
  virtual void Clear();
  IntRect GetBounds();
  bool PreserveCollinear() {return m_PreserveCollinear;};
  void PreserveCollinear(bool value) {m_PreserveCollinear = value;};
protected:
  void DisposeLocalMinimaList();
  TEdge* AddBoundsToLML(TEdge *e);
  TEdge* AddBoundsToLML(TEdge *e, bool IsClosed);
  void PopLocalMinima();
  virtual void Reset();
  TEdge* ProcessBound(TEdge* E, bool IsClockwise);
  void InsertLocalMinima(LocalMinima *newLm);
  void DoMinimaLML(TEdge* E1, TEdge* E2, bool IsClosed);
  TEdge* DescendToMin(TEdge *&E);
  void AscendToMax(TEdge *&E, bool Appending, bool IsClosed);
  LocalMinima      *m_CurrentLM;
  LocalMinima      *m_MinimaList;
  bool              m_UseFullRange;
  EdgeList          m_edges;
  bool             m_PreserveCollinear;
  bool             m_HasOpenPaths;
};
//------------------------------------------------------------------------------

class Clipper : public virtual ClipperBase
{
public:
  Clipper();
  Clipper(int initOptions = 0);
  ~Clipper();
  bool Execute(ClipType clipType,
    Polygons &solution,
    Paths &solution,
    PolyFillType subjFillType = pftEvenOdd,
    PolyFillType clipFillType = pftEvenOdd);
  bool Execute(ClipType clipType,
@@ -247,31 +262,40 @@ public:
  void Clear();
  bool ReverseSolution() {return m_ReverseOutput;};
  void ReverseSolution(bool value) {m_ReverseOutput = value;};
  bool StrictlySimple() {return m_StrictSimple;};
  void StrictlySimple(bool value) {m_StrictSimple = value;};
  //set the callback function for z value filling on intersections (otherwise Z is 0)
#ifdef use_xyz
  void ZFillFunction(TZFillCallback zFillFunc);
#endif
protected:
  void Reset();
  virtual bool ExecuteInternal();
private:
  PolyOutList       m_PolyOuts;
  JoinList          m_Joins;
  HorzJoinList      m_HorizJoins;
  JoinList          m_GhostJoins;
  IntersectList     m_IntersectList;
  ClipType          m_ClipType;
  Scanbeam         *m_Scanbeam;
  std::set< cInt, std::greater<cInt> > m_Scanbeam;
  TEdge           *m_ActiveEdges;
  TEdge           *m_SortedEdges;
  IntersectNode   *m_IntersectNodes;
  bool             m_ExecuteLocked;
  PolyFillType     m_ClipFillType;
  PolyFillType     m_SubjFillType;
  bool             m_ReverseOutput;
  bool             m_UsingPolyTree; 
  void DisposeScanbeamList();
  bool             m_StrictSimple;
#ifdef use_xyz
  TZFillCallback   m_ZFill; //custom callback 
#endif
  void SetWindingCount(TEdge& edge);
  bool IsEvenOddFillType(const TEdge& edge) const;
  bool IsEvenOddAltFillType(const TEdge& edge) const;
  void InsertScanbeam(const long64 Y);
  long64 PopScanbeam();
  void InsertLocalMinimaIntoAEL(const long64 botY);
  void InsertEdgeIntoAEL(TEdge *edge);
  void InsertScanbeam(const cInt Y);
  cInt PopScanbeam();
  void InsertLocalMinimaIntoAEL(const cInt botY);
  void InsertEdgeIntoAEL(TEdge *edge, TEdge* startEdge);
  void AddEdgeToSEL(TEdge *edge);
  void CopyAELToSEL();
  void DeleteFromSEL(TEdge *e);
@@ -279,48 +303,79 @@ private:
  void UpdateEdgeIntoAEL(TEdge *&e);
  void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2);
  bool IsContributing(const TEdge& edge) const;
  bool IsTopHorz(const long64 XPos);
  bool IsTopHorz(const cInt XPos);
  void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2);
  void DoMaxima(TEdge *e, long64 topY);
  void ProcessHorizontals();
  void ProcessHorizontal(TEdge *horzEdge);
  void DoMaxima(TEdge *e);
  void PrepareHorzJoins(TEdge* horzEdge, bool isTopOfScanbeam);
  void ProcessHorizontals(bool IsTopOfScanbeam);
  void ProcessHorizontal(TEdge *horzEdge, bool isTopOfScanbeam);
  void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
  void AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
  OutPt* AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
  OutRec* GetOutRec(int idx);
  void AppendPolygon(TEdge *e1, TEdge *e2);
  void DoEdge1(TEdge *edge1, TEdge *edge2, const IntPoint &pt);
  void DoEdge2(TEdge *edge1, TEdge *edge2, const IntPoint &pt);
  void DoBothEdges(TEdge *edge1, TEdge *edge2, const IntPoint &pt);
  void IntersectEdges(TEdge *e1, TEdge *e2,
    const IntPoint &pt, const IntersectProtects protects);
    const IntPoint &pt, bool protect = false);
  OutRec* CreateOutRec();
  void AddOutPt(TEdge *e, const IntPoint &pt);
  void DisposeAllPolyPts();
  OutPt* AddOutPt(TEdge *e, const IntPoint &pt);
  void DisposeAllOutRecs();
  void DisposeOutRec(PolyOutList::size_type index);
  bool ProcessIntersections(const long64 botY, const long64 topY);
  void AddIntersectNode(TEdge *e1, TEdge *e2, const IntPoint &pt);
  void BuildIntersectList(const long64 botY, const long64 topY);
  bool ProcessIntersections(const cInt botY, const cInt topY);
  void BuildIntersectList(const cInt botY, const cInt topY);
  void ProcessIntersectList();
  void ProcessEdgesAtTopOfScanbeam(const long64 topY);
  void BuildResult(Polygons& polys);
  void ProcessEdgesAtTopOfScanbeam(const cInt topY);
  void BuildResult(Paths& polys);
  void BuildResult2(PolyTree& polytree);
  void SetHoleState(TEdge *e, OutRec *OutRec);
  void SetHoleState(TEdge *e, OutRec *outrec);
  void DisposeIntersectNodes();
  bool FixupIntersectionOrder();
  void FixupOutPolygon(OutRec &outRec);
  void FixupOutPolygon(OutRec &outrec);
  bool IsHole(TEdge *e);
  void FixHoleLinkage(OutRec &outRec);
  void AddJoin(TEdge *e1, TEdge *e2, int e1OutIdx = -1, int e2OutIdx = -1);
  bool FindOwnerFromSplitRecs(OutRec &outRec, OutRec *&currOrfl);
  void FixHoleLinkage(OutRec &outrec);
  void AddJoin(OutPt *op1, OutPt *op2, const IntPoint offPt);
  void ClearJoins();
  void AddHorzJoin(TEdge *e, int idx);
  void ClearHorzJoins();
  bool JoinPoints(const JoinRec *j, OutPt *&p1, OutPt *&p2);
  void FixupJoinRecs(JoinRec *j, OutPt *pt, unsigned startIdx);
  void ClearGhostJoins();
  void AddGhostJoin(OutPt *op, const IntPoint offPt);
  bool JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2);
  void JoinCommonEdges();
  void DoSimplePolygons();
  void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec);
  void FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec);
#ifdef use_xyz
  void SetZ(IntPoint& pt, TEdge& e);
#endif
};

//------------------------------------------------------------------------------

class ClipperOffset 
{
public:
  ClipperOffset(double miterLimit = 2.0, double roundPrecision = 0.25);
  ~ClipperOffset();
  void AddPath(const Path& path, JoinType joinType, EndType endType);
  void AddPaths(const Paths& paths, JoinType joinType, EndType endType);
  void Execute(Paths& solution, double delta);
  void Execute(PolyTree& solution, double delta);
  void Clear();
  double MiterLimit;
  double ArcTolerance;
private:
  Paths m_destPolys;
  Path m_srcPoly;
  Path m_destPoly;
  std::vector<DoublePoint> m_normals;
  double m_delta, m_sinA, m_sin, m_cos;
  double m_miterLim, m_StepsPerRad;
  IntPoint m_lowest;
  PolyNode m_polyNodes;

  void FixOrientations();
  void DoOffset(double delta);
  void OffsetPoint(int j, int& k, JoinType jointype);
  void DoSquare(int j, int k);
  void DoMiter(int j, int k, double r);
  void DoRound(int j, int k);
};
//------------------------------------------------------------------------------

class clipperException : public std::exception
+335 −208
Original line number Diff line number Diff line
@@ -32,7 +32,6 @@
#include <iostream>

namespace p2t {

Triangle::Triangle( Point& a, Point& b, Point& c )
{
    points_[0]      = &a; points_[1] = &b; points_[2] = &c;
@@ -42,6 +41,7 @@ Triangle::Triangle(Point& a, Point& b, Point& c)
    interior_ = false;
}


// Update neighbor pointers
void Triangle::MarkNeighbor( Point* p1, Point* p2, Triangle* t )
{
@@ -55,39 +55,50 @@ void Triangle::MarkNeighbor(Point* p1, Point* p2, Triangle* t)
        assert( 0 );
}


// Exhaustive search to update neighbor pointers
void Triangle::MarkNeighbor( Triangle& t )
{
  if (t.Contains(points_[1], points_[2])) {
    if( t.Contains( points_[1], points_[2] ) )
    {
        neighbors_[0] = &t;
        t.MarkNeighbor( points_[1], points_[2], this );
  } else if (t.Contains(points_[0], points_[2])) {
    }
    else if( t.Contains( points_[0], points_[2] ) )
    {
        neighbors_[1] = &t;
        t.MarkNeighbor( points_[0], points_[2], this );
  } else if (t.Contains(points_[0], points_[1])) {
    }
    else if( t.Contains( points_[0], points_[1] ) )
    {
        neighbors_[2] = &t;
        t.MarkNeighbor( points_[0], points_[1], this );
    }
}


/**
 * Clears all references to all other triangles and points
 */
void Triangle::Clear()
{
    Triangle* t;

    for( int i = 0; i<3; i++ )
    {
        t = neighbors_[i];

        if( t != NULL )
        {
            t->ClearNeighbor( this );
        }
    }

    ClearNeighbors();
    points_[0] = points_[1] = points_[2] = NULL;
}


void Triangle::ClearNeighbor( Triangle* triangle )
{
    if( neighbors_[0] == triangle )
@@ -104,6 +115,7 @@ void Triangle::ClearNeighbor(Triangle *triangle )
    }
}


void Triangle::ClearNeighbors()
{
    neighbors_[0]   = NULL;
@@ -111,21 +123,25 @@ void Triangle::ClearNeighbors()
    neighbors_[2]   = NULL;
}


void Triangle::ClearDelunayEdges()
{
    delaunay_edge[0] = delaunay_edge[1] = delaunay_edge[2] = false;
}


Point* Triangle::OppositePoint( Triangle& t, Point& p )
{
    Point*  cw  = t.PointCW( p );
    double  x   = cw->x;
    double  y   = cw->y;

    x   = p.x;
    y   = p.y;
    return PointCW( *cw );
}


// Legalized triangle by rotating clockwise around point(0)
void Triangle::Legalize( Point& point )
{
@@ -134,233 +150,344 @@ void Triangle::Legalize(Point& point)
    points_[2]  = &point;
}


// Legalize triagnle by rotating clockwise around oPoint
void Triangle::Legalize( Point& opoint, Point& npoint )
{
  if (&opoint == points_[0]) {
    if( &opoint == points_[0] )
    {
        points_[1]  = points_[0];
        points_[0]  = points_[2];
        points_[2]  = &npoint;
  } else if (&opoint == points_[1]) {
    }
    else if( &opoint == points_[1] )
    {
        points_[2]  = points_[1];
        points_[1]  = points_[0];
        points_[0]  = &npoint;
  } else if (&opoint == points_[2]) {
    }
    else if( &opoint == points_[2] )
    {
        points_[0]  = points_[2];
        points_[2]  = points_[1];
        points_[1]  = &npoint;
  } else {
    }
    else
    {
        assert( 0 );
    }
}


int Triangle::Index( const Point* p )
{
  if (p == points_[0]) {
    if( p == points_[0] )
    {
        return 0;
  } else if (p == points_[1]) {
    }
    else if( p == points_[1] )
    {
        return 1;
  } else if (p == points_[2]) {
    }
    else if( p == points_[2] )
    {
        return 2;
    }

    assert( 0 );
}


int Triangle::EdgeIndex( const Point* p1, const Point* p2 )
{
  if (points_[0] == p1) {
    if (points_[1] == p2) {
    if( points_[0] == p1 )
    {
        if( points_[1] == p2 )
        {
            return 2;
    } else if (points_[2] == p2) {
        }
        else if( points_[2] == p2 )
        {
            return 1;
        }
  } else if (points_[1] == p1) {
    if (points_[2] == p2) {
    }
    else if( points_[1] == p1 )
    {
        if( points_[2] == p2 )
        {
            return 0;
    } else if (points_[0] == p2) {
        }
        else if( points_[0] == p2 )
        {
            return 2;
        }
  } else if (points_[2] == p1) {
    if (points_[0] == p2) {
    }
    else if( points_[2] == p1 )
    {
        if( points_[0] == p2 )
        {
            return 1;
    } else if (points_[1] == p2) {
        }
        else if( points_[1] == p2 )
        {
            return 0;
        }
    }

    return -1;
}


void Triangle::MarkConstrainedEdge( const int index )
{
    constrained_edge[index] = true;
}


void Triangle::MarkConstrainedEdge( Edge& edge )
{
    MarkConstrainedEdge( edge.p, edge.q );
}


// Mark edge as constrained
void Triangle::MarkConstrainedEdge( Point* p, Point* q )
{
  if ((q == points_[0] && p == points_[1]) || (q == points_[1] && p == points_[0])) {
    if( (q == points_[0] && p == points_[1]) || (q == points_[1] && p == points_[0]) )
    {
        constrained_edge[2] = true;
  } else if ((q == points_[0] && p == points_[2]) || (q == points_[2] && p == points_[0])) {
    }
    else if( (q == points_[0] && p == points_[2]) || (q == points_[2] && p == points_[0]) )
    {
        constrained_edge[1] = true;
  } else if ((q == points_[1] && p == points_[2]) || (q == points_[2] && p == points_[1])) {
    }
    else if( (q == points_[1] && p == points_[2]) || (q == points_[2] && p == points_[1]) )
    {
        constrained_edge[0] = true;
    }
}


// The point counter-clockwise to given point
Point* Triangle::PointCW( Point& point )
{
  if (&point == points_[0]) {
    if( &point == points_[0] )
    {
        return points_[2];
  } else if (&point == points_[1]) {
    }
    else if( &point == points_[1] )
    {
        return points_[0];
  } else if (&point == points_[2]) {
    }
    else if( &point == points_[2] )
    {
        return points_[1];
    }

    assert( 0 );
}


// The point counter-clockwise to given point
Point* Triangle::PointCCW( Point& point )
{
  if (&point == points_[0]) {
    if( &point == points_[0] )
    {
        return points_[1];
  } else if (&point == points_[1]) {
    }
    else if( &point == points_[1] )
    {
        return points_[2];
  } else if (&point == points_[2]) {
    }
    else if( &point == points_[2] )
    {
        return points_[0];
    }

    assert( 0 );
}


// The neighbor clockwise to given point
Triangle* Triangle::NeighborCW( Point& point )
{
  if (&point == points_[0]) {
    if( &point == points_[0] )
    {
        return neighbors_[1];
  } else if (&point == points_[1]) {
    }
    else if( &point == points_[1] )
    {
        return neighbors_[2];
    }

    return neighbors_[0];
}


// The neighbor counter-clockwise to given point
Triangle* Triangle::NeighborCCW( Point& point )
{
  if (&point == points_[0]) {
    if( &point == points_[0] )
    {
        return neighbors_[2];
  } else if (&point == points_[1]) {
    }
    else if( &point == points_[1] )
    {
        return neighbors_[0];
    }

    return neighbors_[1];
}


bool Triangle::GetConstrainedEdgeCCW( Point& p )
{
  if (&p == points_[0]) {
    if( &p == points_[0] )
    {
        return constrained_edge[2];
  } else if (&p == points_[1]) {
    }
    else if( &p == points_[1] )
    {
        return constrained_edge[0];
    }

    return constrained_edge[1];
}


bool Triangle::GetConstrainedEdgeCW( Point& p )
{
  if (&p == points_[0]) {
    if( &p == points_[0] )
    {
        return constrained_edge[1];
  } else if (&p == points_[1]) {
    }
    else if( &p == points_[1] )
    {
        return constrained_edge[2];
    }

    return constrained_edge[0];
}


void Triangle::SetConstrainedEdgeCCW( Point& p, bool ce )
{
  if (&p == points_[0]) {
    if( &p == points_[0] )
    {
        constrained_edge[2] = ce;
  } else if (&p == points_[1]) {
    }
    else if( &p == points_[1] )
    {
        constrained_edge[0] = ce;
  } else {
    }
    else
    {
        constrained_edge[1] = ce;
    }
}


void Triangle::SetConstrainedEdgeCW( Point& p, bool ce )
{
  if (&p == points_[0]) {
    if( &p == points_[0] )
    {
        constrained_edge[1] = ce;
  } else if (&p == points_[1]) {
    }
    else if( &p == points_[1] )
    {
        constrained_edge[2] = ce;
  } else {
    }
    else
    {
        constrained_edge[0] = ce;
    }
}


bool Triangle::GetDelunayEdgeCCW( Point& p )
{
  if (&p == points_[0]) {
    if( &p == points_[0] )
    {
        return delaunay_edge[2];
  } else if (&p == points_[1]) {
    }
    else if( &p == points_[1] )
    {
        return delaunay_edge[0];
    }

    return delaunay_edge[1];
}


bool Triangle::GetDelunayEdgeCW( Point& p )
{
  if (&p == points_[0]) {
    if( &p == points_[0] )
    {
        return delaunay_edge[1];
  } else if (&p == points_[1]) {
    }
    else if( &p == points_[1] )
    {
        return delaunay_edge[2];
    }

    return delaunay_edge[0];
}


void Triangle::SetDelunayEdgeCCW( Point& p, bool e )
{
  if (&p == points_[0]) {
    if( &p == points_[0] )
    {
        delaunay_edge[2] = e;
  } else if (&p == points_[1]) {
    }
    else if( &p == points_[1] )
    {
        delaunay_edge[0] = e;
  } else {
    }
    else
    {
        delaunay_edge[1] = e;
    }
}


void Triangle::SetDelunayEdgeCW( Point& p, bool e )
{
  if (&p == points_[0]) {
    if( &p == points_[0] )
    {
        delaunay_edge[1] = e;
  } else if (&p == points_[1]) {
    }
    else if( &p == points_[1] )
    {
        delaunay_edge[2] = e;
  } else {
    }
    else
    {
        delaunay_edge[0] = e;
    }
}


// The neighbor across to given point
Triangle& Triangle::NeighborAcross( Point& opoint )
{
  if (&opoint == points_[0]) {
    if( &opoint == points_[0] )
    {
        return *neighbors_[0];
  } else if (&opoint == points_[1]) {
    }
    else if( &opoint == points_[1] )
    {
        return *neighbors_[1];
    }

    return *neighbors_[2];
}


void Triangle::DebugPrint()
{
    std::cout << points_[0]->x << "," << points_[0]->y << " ";
    std::cout << points_[1]->x << "," << points_[1]->y << " ";
    std::cout << points_[2]->x << "," << points_[2]->y << "\n";
}

}
Loading