#include <Shape.h>

Collaboration diagram for Shape:

List of all members.

Classes

struct  back_data
struct  dg_arete
struct  dg_point
struct  edge_data
struct  edge_list
struct  incidenceData
struct  point_data
struct  quick_raster_data
struct  raster_data
struct  sTreeChange
struct  sweep_dest_data
struct  sweep_src_data
struct  voronoi_edge
struct  voronoi_point

Public Types

enum  sTreeChangeType { EDGE_INSERTED = 0, EDGE_REMOVED = 1, INTERSECTION = 2 }

Public Member Functions

 Shape ()
virtual ~Shape ()
void MakeBackData (bool nVal)
void MakeVoronoiData (bool nVal)
void Affiche ()
void Copy (Shape *a)
 Copy point and edge data from `who' into this object, discarding any cached data that we have.
void Reset (int n=0, int m=0)
 Clear points and edges and prepare internal data using new size.
int AddPoint (const Geom::Point x)
void SubPoint (int p)
void SwapPoints (int a, int b)
void SwapPoints (int a, int b, int c)
void SortPoints ()
int AddEdge (int st, int en)
int AddEdge (int st, int en, int leF, int riF)
void SubEdge (int e)
void SwapEdges (int a, int b)
void SwapEdges (int a, int b, int c)
void SortEdges ()
int Other (int p, int b) const
int NextAt (int p, int b) const
int PrevAt (int p, int b) const
int CycleNextAt (int p, int b) const
int CyclePrevAt (int p, int b) const
void ConnectStart (int p, int b)
void ConnectEnd (int p, int b)
void DisconnectStart (int b)
void DisconnectEnd (int b)
void Inverse (int b)
void CalcBBox (bool strict_degree=false)
void Plot (double ix, double iy, double ir, double mx, double my, bool doPoint, bool edgesNo, bool pointNo, bool doDir, char *fileName)
void ConvertToForme (Path *dest)
void ConvertToForme (Path *dest, int nbP, Path **orig, bool splitWhenForced=false)
void ConvertToFormeNested (Path *dest, int nbP, Path **orig, int wildPath, int &nbNest, int *&nesting, int *&contStart, bool splitWhenForced=false)
int ConvertToShape (Shape *a, FillRule directed=fill_nonZero, bool invert=false)
int Reoriente (Shape *a)
void ForceToPolygon ()
int Booleen (Shape *a, Shape *b, BooleanOp mod, int cutPathID=-1)
int MakeOffset (Shape *of, double dec, JoinType join, double miter, bool do_profile=false, double cx=0, double cy=0, double radius=0, Geom::Matrix *i2doc=NULL)
int MakeTweak (int mode, Shape *a, double dec, JoinType join, double miter, bool do_profile, Geom::Point c, Geom::Point vector, double radius, Geom::Matrix *i2doc)
int PtWinding (const Geom::Point px) const
int Winding (const Geom::Point px) const
void BeginRaster (float &pos, int &curPt)
void EndRaster ()
void BeginQuickRaster (float &pos, int &curPt)
void EndQuickRaster ()
void Scan (float &pos, int &curP, float to, float step)
void QuickScan (float &pos, int &curP, float to, bool doSort, float step)
void DirectScan (float &pos, int &curP, float to, float step)
void DirectQuickScan (float &pos, int &curP, float to, bool doSort, float step)
void Scan (float &pos, int &curP, float to, FloatLigne *line, bool exact, float step)
void Scan (float &pos, int &curP, float to, FillRule directed, BitLigne *line, bool exact, float step)
void Scan (float &pos, int &curP, float to, AlphaLigne *line, bool exact, float step)
void QuickScan (float &pos, int &curP, float to, FloatLigne *line, float step)
void QuickScan (float &pos, int &curP, float to, FillRule directed, BitLigne *line, float step)
void QuickScan (float &pos, int &curP, float to, AlphaLigne *line, float step)
void Transform (Geom::Matrix const &tr)
int numberOfPoints () const
bool hasPoints () const
int numberOfEdges () const
bool hasEdges () const
void needPointsSorting ()
void needEdgesSorting ()
bool hasBackData () const
dg_point const & getPoint (int n) const
dg_arete const & getEdge (int n) const

Static Public Member Functions

static double Round (double x)
static double HalfRound (double x)
static double IHalfRound (double x)

Public Attributes

std::vector< back_dataebData
std::vector< voronoi_pointvorpData
std::vector< voronoi_edgevoreData
int nbQRas
int firstQRas
int lastQRas
quick_raster_dataqrsData
std::vector< sTreeChangechgts
int nbInc
int maxInc
incidenceDataiData
SweepTreeListsTree
SweepEventQueuesEvts
double leftX
double topY
double rightX
double bottomY
int maxPt
int maxAr
int type

Private Member Functions

void initialisePointData ()
void initialiseEdgeData ()
void clearIncidenceData ()
void _countUpDown (int P, int *numberUp, int *numberDown, int *upEdge, int *downEdge) const
void _countUpDownTotalDegree2 (int P, int *numberUp, int *numberDown, int *upEdge, int *downEdge) const
 Version of Shape::_countUpDown optimised for the case when getPoint(P).totalDegree() == 2.
void _updateIntersection (int e, int p)
void MakePointData (bool nVal)
 Allocates space for point cache or clears the cache.
void MakeEdgeData (bool nVal)
void MakeSweepSrcData (bool nVal)
void MakeSweepDestData (bool nVal)
void MakeRasterData (bool nVal)
void MakeQuickRasterData (bool nVal)
void SortPoints (int s, int e)
void SortPointsByOldInd (int s, int e)
void ResetSweep ()
void CleanupSweep ()
void SortEdgesList (edge_list *edges, int s, int e)
void TesteIntersection (SweepTree *t, Side s, bool onlyDiff)
bool TesteIntersection (SweepTree *iL, SweepTree *iR, Geom::Point &atx, double &atL, double &atR, bool onlyDiff)
bool TesteIntersection (Shape *iL, Shape *iR, int ilb, int irb, Geom::Point &atx, double &atL, double &atR, bool onlyDiff)
bool TesteAdjacency (Shape *iL, int ilb, const Geom::Point atx, int nPt, bool push)
int PushIncidence (Shape *a, int cb, int pt, double theta)
int CreateIncidence (Shape *a, int cb, int pt)
void AssemblePoints (Shape *a)
int AssemblePoints (int st, int en)
void AssembleAretes (FillRule directed=fill_nonZero)
void AddChgt (int lastPointNo, int lastChgtPt, Shape *&shapeHead, int &edgeHead, sTreeChangeType type, Shape *lS, int lB, Shape *rS, int rB)
void CheckAdjacencies (int lastPointNo, int lastChgtPt, Shape *shapeHead, int edgeHead)
void CheckEdges (int lastPointNo, int lastChgtPt, Shape *a, Shape *b, BooleanOp mod)
void Avance (int lastPointNo, int lastChgtPt, Shape *iS, int iB, Shape *a, Shape *b, BooleanOp mod)
void DoEdgeTo (Shape *iS, int iB, int iTo, bool direct, bool sens)
void GetWindings (Shape *a, Shape *b=NULL, BooleanOp mod=bool_op_union, bool brutal=false)
void Validate ()
int Winding (int nPt) const
void SortPointsRounded ()
void SortPointsRounded (int s, int e)
void CreateEdge (int no, float to, float step)
void AvanceEdge (int no, float to, bool exact, float step)
void DestroyEdge (int no, float to, FloatLigne *line)
void AvanceEdge (int no, float to, FloatLigne *line, bool exact, float step)
void DestroyEdge (int no, BitLigne *line)
void AvanceEdge (int no, float to, BitLigne *line, bool exact, float step)
void DestroyEdge (int no, AlphaLigne *line)
void AvanceEdge (int no, float to, AlphaLigne *line, bool exact, float step)
void AddContour (Path *dest, int nbP, Path **orig, int startBord, int curBord, bool splitWhenForced)
int ReFormeLineTo (int bord, int curBord, Path *dest, Path *orig)
int ReFormeArcTo (int bord, int curBord, Path *dest, Path *orig)
int ReFormeCubicTo (int bord, int curBord, Path *dest, Path *orig)
int ReFormeBezierTo (int bord, int curBord, Path *dest, Path *orig)
void ReFormeBezierChunk (const Geom::Point px, const Geom::Point nx, Path *dest, int inBezier, int nbInterm, Path *from, int p, double ts, double te)
int QuickRasterChgEdge (int oBord, int nbord, double x)
int QuickRasterAddEdge (int bord, double x, int guess)
void QuickRasterSubEdge (int bord)
void QuickRasterSwapEdge (int a, int b)
void QuickRasterSort ()

Static Private Member Functions

static int CmpQRs (const quick_raster_data &p1, const quick_raster_data &p2)
static int CmpToVert (const Geom::Point ax, const Geom::Point bx, bool as, bool bs)

Private Attributes

bool _need_points_sorting
 points have been added or removed: we need to sort the points again
bool _need_edges_sorting
 edges have been added: maybe they are not ordered clockwise
bool _has_points_data
 the pData array is allocated
bool _point_data_initialised
 the pData array is up to date
bool _has_edges_data
 the eData array is allocated
bool _has_sweep_src_data
 the swsData array is allocated
bool _has_sweep_dest_data
 the swdData array is allocated
bool _has_raster_data
 the swrData array is allocated
bool _has_quick_raster_data
 the swrData array is allocated
bool _has_back_data
bool _has_voronoi_data
bool _bbox_up_to_date
 the leftX/rightX/topY/bottomY are up to date
std::vector< dg_point_pts
std::vector< dg_arete_aretes
std::vector< edge_dataeData
std::vector< sweep_src_dataswsData
std::vector< sweep_dest_dataswdData
std::vector< raster_dataswrData
std::vector< point_datapData

Friends

class SweepTree
class SweepEvent
class SweepEventQueue

Detailed Description

Definition at line 53 of file Shape.h.


Member Enumeration Documentation

Enumerator:
EDGE_INSERTED 
EDGE_REMOVED 
INTERSECTION 

Definition at line 85 of file Shape.h.


Constructor & Destructor Documentation

Shape::Shape (  ) 

Definition at line 23 of file Shape.cpp.

References bottomY, leftX, maxAr, maxPt, rightX, topY, and type.

Shape::~Shape ( void   )  [virtual]

Definition at line 47 of file Shape.cpp.

References maxAr, maxPt, and qrsData.

{
  maxPt = 0;
  maxAr = 0;
  free(qrsData);
}


Member Function Documentation

void Shape::_countUpDown ( int  P,
int *  numberUp,
int *  numberDown,
int *  upEdge,
int *  downEdge 
) const [private]
Parameters:
P point index.
numberUp Filled in with the number of edges coming into P from above.
numberDown Filled in with the number of edges coming exiting P to go below.
upEdge One of the numberUp edges, or -1.
downEdge One of the numberDown edges, or -1.

Definition at line 1937 of file ShapeRaster.cpp.

References addnodes::e, Shape::dg_arete::en, getEdge(), getPoint(), Barcode::Code39Ext::i, Shape::dg_point::incidentEdge, max, min, NextAt(), numberOfEdges(), and Shape::dg_arete::st.

Referenced by QuickScan(), and Scan().

{
    *numberUp = 0;
    *numberDown = 0;
    *upEdge = -1;
    *downEdge = -1;
    
    int i = getPoint(P).incidentEdge[FIRST];
    
    while ( i >= 0 && i < numberOfEdges() ) {
        Shape::dg_arete const &e = getEdge(i);
        if ( P == std::max(e.st, e.en) ) {
            *upEdge = i;
            (*numberUp)++;
        }
        if ( P == std::min(e.st, e.en) ) {
            *downEdge = i;
            (*numberDown)++;
        }
        i = NextAt(P, i);
    }
    
}

void Shape::_countUpDownTotalDegree2 ( int  P,
int *  numberUp,
int *  numberDown,
int *  upEdge,
int *  downEdge 
) const [private]

Version of Shape::_countUpDown optimised for the case when getPoint(P).totalDegree() == 2.

Definition at line 1967 of file ShapeRaster.cpp.

References addnodes::e, Shape::dg_arete::en, getEdge(), getPoint(), Barcode::Code39Ext::i, Shape::dg_point::incidentEdge, max, min, and Shape::dg_arete::st.

Referenced by QuickScan(), and Scan().

{
    *numberUp = 0;
    *numberDown = 0;
    *upEdge = -1;
    *downEdge = -1;
    
    for (int i = 0; i < 2; i++) {
        int const j = getPoint(P).incidentEdge[i];
        Shape::dg_arete const &e = getEdge(j);
        if ( P == std::max(e.st, e.en) ) {
            *upEdge = j;
            (*numberUp)++;
        }
        if ( P == std::min(e.st, e.en) ) {
            *downEdge = j;
            (*numberDown)++;
        }
    }
}

void Shape::_updateIntersection ( int  e,
int  p 
) [private]

Definition at line 1990 of file ShapeRaster.cpp.

References getPoint(), swrData, and Shape::dg_point::x.

Referenced by QuickScan(), and Scan().

{
    swrData[e].lastX = swrData[e].curX;
    swrData[e].lastY = swrData[e].curY;
    swrData[e].curX = getPoint(p).x[0];
    swrData[e].curY = getPoint(p).x[1];
    swrData[e].misc = NULL;
}

void Shape::AddChgt ( int  lastPointNo,
int  lastChgtPt,
Shape *&  shapeHead,
int &  edgeHead,
sTreeChangeType  type,
Shape lS,
int  lB,
Shape rS,
int  rB 
) [private]

Definition at line 2922 of file ShapeSweep.cpp.

References SweepTree::bord, Shape::sTreeChange::bord, c, chgts, AVLTree::elem, getPoint(), LEFT, Shape::sTreeChange::obord, Shape::sTreeChange::osrc, Shape::sTreeChange::ptNo, RIGHT, SweepTree::src, Shape::sTreeChange::src, swsData, Shape::sTreeChange::type, and Shape::dg_point::x.

Referenced by Booleen(), and ConvertToShape().

{
    sTreeChange c;
    c.ptNo = lastPointNo;
    c.type = type;
    c.src = lS;
    c.bord = lB;
    c.osrc = rS;
    c.obord = rB;
    chgts.push_back(c);
    const int nCh = chgts.size() - 1;

    /* FIXME: this looks like a cut and paste job */

    if (lS) {
    SweepTree *lE = static_cast < SweepTree * >(lS->swsData[lB].misc);
    if (lE && lE->elem[LEFT]) {
        SweepTree *llE = static_cast < SweepTree * >(lE->elem[LEFT]);
        chgts[nCh].lSrc = llE->src;
        chgts[nCh].lBrd = llE->bord;
    } else {
        chgts[nCh].lSrc = NULL;
        chgts[nCh].lBrd = -1;
    }

    if (lS->swsData[lB].leftRnd < lastChgtPt) {
        lS->swsData[lB].leftRnd = lastPointNo;
        lS->swsData[lB].nextSh = shapeHead;
        lS->swsData[lB].nextBo = edgeHead;
        edgeHead = lB;
        shapeHead = lS;
    } else {
        int old = lS->swsData[lB].leftRnd;
        if (getPoint(old).x[0] > getPoint(lastPointNo).x[0]) {
        lS->swsData[lB].leftRnd = lastPointNo;
        }
    }
    if (lS->swsData[lB].rightRnd < lastChgtPt) {
        lS->swsData[lB].rightRnd = lastPointNo;
    } else {
        int old = lS->swsData[lB].rightRnd;
        if (getPoint(old).x[0] < getPoint(lastPointNo).x[0])
        lS->swsData[lB].rightRnd = lastPointNo;
    }
    }

    if (rS) {
    SweepTree *rE = static_cast < SweepTree * >(rS->swsData[rB].misc);
    if (rE->elem[RIGHT]) {
        SweepTree *rrE = static_cast < SweepTree * >(rE->elem[RIGHT]);
        chgts[nCh].rSrc = rrE->src;
        chgts[nCh].rBrd = rrE->bord;
    } else {
        chgts[nCh].rSrc = NULL;
        chgts[nCh].rBrd = -1;
    }
    
    if (rS->swsData[rB].leftRnd < lastChgtPt) {
        rS->swsData[rB].leftRnd = lastPointNo;
        rS->swsData[rB].nextSh = shapeHead;
        rS->swsData[rB].nextBo = edgeHead;
        edgeHead = rB;
        shapeHead = rS;
    } else {
        int old = rS->swsData[rB].leftRnd;
        if (getPoint(old).x[0] > getPoint(lastPointNo).x[0]) {
        rS->swsData[rB].leftRnd = lastPointNo;
        }
    }
    if (rS->swsData[rB].rightRnd < lastChgtPt) {
        rS->swsData[rB].rightRnd = lastPointNo;
    } else {
        int old = rS->swsData[rB].rightRnd;
        if (getPoint(old).x[0] < getPoint(lastPointNo).x[0])
        rS->swsData[rB].rightRnd = lastPointNo;
    }
    } else {
    SweepTree *lE = static_cast < SweepTree * >(lS->swsData[lB].misc);
    if (lE && lE->elem[RIGHT]) {
        SweepTree *rlE = static_cast < SweepTree * >(lE->elem[RIGHT]);
        chgts[nCh].rSrc = rlE->src;
        chgts[nCh].rBrd = rlE->bord;
    } else {
        chgts[nCh].rSrc = NULL;
        chgts[nCh].rBrd = -1;
    }
    }
}

void Shape::AddContour ( Path dest,
int  nbP,
Path **  orig,
int  startBord,
int  curBord,
bool  splitWhenForced 
) [private]

Definition at line 878 of file ShapeMisc.cpp.

References _has_back_data, Path::Close(), descr_arcto, descr_bezierto, descr_close, Path::descr_cmd, descr_cubicto, descr_forced, descr_interm_bezier, descr_lineto, descr_moveto, ebData, Path::ForcePoint(), getEdge(), getPoint(), Shape::dg_point::incidentEdge, Path::LineTo(), Path::MoveTo(), PathDescrBezierTo::nb, NULL, ReFormeArcTo(), ReFormeBezierTo(), ReFormeCubicTo(), ReFormeLineTo(), swdData, and voronoi::x.

Referenced by ConvertToForme(), and ConvertToFormeNested().

{
  int bord = startBord;
  
  {
    dest->MoveTo (getPoint(getEdge(bord).st).x);
  }
  
  while (bord >= 0)
  {
    int nPiece = ebData[bord].pieceID;
    int nPath = ebData[bord].pathID;
    
    if (nPath < 0 || nPath >= nbP || orig[nPath] == NULL)
    {
      // segment batard
      dest->LineTo (getPoint(getEdge(bord).en).x);
      bord = swdData[bord].suivParc;
    }
    else
    {
      Path *from = orig[nPath];
      if (nPiece < 0 || nPiece >= int(from->descr_cmd.size()))
        {
          // segment batard
          dest->LineTo (getPoint(getEdge(bord).en).x);
          bord = swdData[bord].suivParc;
        }
      else
        {
          int nType = from->descr_cmd[nPiece]->getType();
          if (nType == descr_close || nType == descr_moveto
            || nType == descr_forced)
        {
          // devrait pas arriver
          dest->LineTo (getPoint(getEdge(bord).en).x);
          bord = swdData[bord].suivParc;
        }
          else if (nType == descr_lineto)
        {
          bord = ReFormeLineTo (bord, curBord, dest, from);
        }
          else if (nType == descr_arcto)
        {
          bord = ReFormeArcTo (bord, curBord, dest, from);
        }
          else if (nType == descr_cubicto)
        {
          bord = ReFormeCubicTo (bord, curBord, dest, from);
        }
          else if (nType == descr_bezierto)
        {
          PathDescrBezierTo* nBData =
        dynamic_cast<PathDescrBezierTo *>(from->descr_cmd[nPiece]);
      
          if (nBData->nb == 0)
          {
            bord = ReFormeLineTo (bord, curBord, dest, from);
          }
          else
          {
            bord = ReFormeBezierTo (bord, curBord, dest, from);
          }
        }
          else if (nType == descr_interm_bezier)
        {
          bord = ReFormeBezierTo (bord, curBord, dest, from);
        }
          else
        {
          // devrait pas arriver non plus
          dest->LineTo (getPoint(getEdge(bord).en).x);
          bord = swdData[bord].suivParc;
        }
          if (bord >= 0 && getPoint(getEdge(bord).st).totalDegree() > 2 ) {
          dest->ForcePoint ();
        } else if ( bord >= 0 && getPoint(getEdge(bord).st).oldDegree > 2 && getPoint(getEdge(bord).st).totalDegree() == 2)  {
          if ( splitWhenForced ) {
            // pour les coupures
            dest->ForcePoint ();
         } else {
            if ( _has_back_data ) {
              int   prevEdge=getPoint(getEdge(bord).st).incidentEdge[FIRST];
              int   nextEdge=getPoint(getEdge(bord).st).incidentEdge[LAST];
              if ( getEdge(prevEdge).en != getEdge(bord).st ) {
                int  swai=prevEdge;prevEdge=nextEdge;nextEdge=swai;
              }
              if ( ebData[prevEdge].pieceID == ebData[nextEdge].pieceID  && ebData[prevEdge].pathID == ebData[nextEdge].pathID ) {
                if ( fabs(ebData[prevEdge].tEn-ebData[nextEdge].tSt) < 0.05 ) {
                } else {
                  dest->ForcePoint ();
                }
              } else {
                dest->ForcePoint ();
              }
            } else {
              dest->ForcePoint ();
            }    
          }
        }
      }
    }
  }
  dest->Close ();
}

int Shape::AddEdge ( int  st,
int  en 
)

Definition at line 1112 of file Shape.cpp.

References _aretes, _has_back_data, _has_edges_data, _has_raster_data, _has_sweep_dest_data, _has_sweep_src_data, _has_voronoi_data, _need_edges_sorting, org::w3c::dom::svg::a, ConnectEnd(), ConnectStart(), Shape::dg_arete::dx, ebData, eData, Shape::dg_arete::en, getEdge(), getPoint(), maxAr, n, Shape::dg_arete::nextE, Shape::dg_arete::nextS, numberOfEdges(), Point, Shape::dg_arete::prevE, Shape::dg_arete::prevS, Shape::dg_arete::st, swdData, swrData, swsData, type, voreData, and Shape::dg_point::x.

Referenced by Booleen(), Path::DoButt(), DoEdgeTo(), Path::DoJoin(), Path::DoLeftJoin(), Path::DoRightJoin(), Path::DoStroke(), Path::Fill(), MakeOffset(), MakeTweak(), nr_arena_shape_update_fill(), nr_arena_shape_update_stroke(), Path::RecRound(), and Path::Stroke().

{
  if (st == en)
    return -1;
  if (st < 0 || en < 0)
    return -1;
  type = shape_graph;
  if (numberOfEdges() >= maxAr)
    {
      maxAr = 2 * numberOfEdges() + 1;
      if (_has_edges_data)
        eData.resize(maxAr);
      if (_has_sweep_src_data)
        swsData.resize(maxAr);
      if (_has_sweep_dest_data)
        swdData.resize(maxAr);
      if (_has_raster_data)
        swrData.resize(maxAr);
      if (_has_back_data)
        ebData.resize(maxAr);
      if (_has_voronoi_data)
        voreData.resize(maxAr);
    }

  dg_arete a;
  a.dx = Geom::Point(0, 0);
  a.st = a.en = -1;
  a.prevS = a.nextS = -1;
  a.prevE = a.nextE = -1;
  if (st >= 0 && en >= 0) {
    a.dx = getPoint(en).x - getPoint(st).x;
  }

  _aretes.push_back(a);
  int const n = numberOfEdges() - 1;
  
  ConnectStart (st, n);
  ConnectEnd (en, n);
  if (_has_edges_data)
    {
      eData[n].weight = 1;
      eData[n].rdx = getEdge(n).dx;
    }
  if (_has_sweep_src_data)
    {
      swsData[n].misc = NULL;
      swsData[n].firstLinkedPoint = -1;
    }
  if (_has_back_data)
    {
      ebData[n].pathID = -1;
      ebData[n].pieceID = -1;
      ebData[n].tSt = ebData[n].tEn = 0;
    }
  if (_has_voronoi_data)
    {
      voreData[n].leF = -1;
      voreData[n].riF = -1;
    }
  _need_edges_sorting = true;
  return n;
}

int Shape::AddEdge ( int  st,
int  en,
int  leF,
int  riF 
)

Definition at line 1176 of file Shape.cpp.

References _aretes, _has_back_data, _has_edges_data, _has_raster_data, _has_sweep_dest_data, _has_sweep_src_data, _has_voronoi_data, _need_edges_sorting, org::w3c::dom::svg::a, ConnectEnd(), ConnectStart(), Shape::dg_arete::dx, ebData, eData, Shape::dg_arete::en, getEdge(), getPoint(), Shape::dg_point::incidentEdge, maxAr, n, NextAt(), Shape::dg_arete::nextE, Shape::dg_arete::nextS, numberOfEdges(), Point, Shape::dg_arete::prevE, Shape::dg_arete::prevS, Shape::dg_arete::st, swdData, swrData, swsData, type, voreData, and Shape::dg_point::x.

{
  if (st == en)
    return -1;
  if (st < 0 || en < 0)
    return -1;
  {
    int cb = getPoint(st).incidentEdge[FIRST];
    while (cb >= 0)
      {
        if (getEdge(cb).st == st && getEdge(cb).en == en)
          return -1;        // doublon
        if (getEdge(cb).st == en && getEdge(cb).en == st)
          return -1;        // doublon
        cb = NextAt (st, cb);
      }
  }
  type = shape_graph;
  if (numberOfEdges() >= maxAr)
    {
      maxAr = 2 * numberOfEdges() + 1;
      if (_has_edges_data)
        eData.resize(maxAr);
      if (_has_sweep_src_data)
        swsData.resize(maxAr);
      if (_has_sweep_dest_data)
        swdData.resize(maxAr);
      if (_has_raster_data)
        swrData.resize(maxAr);
      if (_has_back_data)
        ebData.resize(maxAr);
      if (_has_voronoi_data)
        voreData.resize(maxAr);
    }

  dg_arete a;
  a.dx = Geom::Point(0, 0);
  a.st = a.en = -1;
  a.prevS = a.nextS = -1;
  a.prevE = a.nextE = -1;
  if (st >= 0 && en >= 0) {
    a.dx = getPoint(en).x - getPoint(st).x;
  }
  
  _aretes.push_back(a);
  int const n = numberOfEdges() - 1;

  ConnectStart (st, n);
  ConnectEnd (en, n);
  if (_has_edges_data)
    {
      eData[n].weight = 1;
      eData[n].rdx = getEdge(n).dx;
    }
  if (_has_sweep_src_data)
    {
      swsData[n].misc = NULL;
      swsData[n].firstLinkedPoint = -1;
    }
  if (_has_back_data)
    {
      ebData[n].pathID = -1;
      ebData[n].pieceID = -1;
      ebData[n].tSt = ebData[n].tEn = 0;
    }
  if (_has_voronoi_data)
    {
      voreData[n].leF = leF;
      voreData[n].riF = riF;
    }
  _need_edges_sorting = true;
  return n;
}

int Shape::AddPoint ( const Geom::Point  x  ) 

Definition at line 312 of file Shape.cpp.

References _has_points_data, _has_voronoi_data, _need_points_sorting, _pts, Shape::dg_point::dI, Shape::dg_point::dO, Shape::dg_point::incidentEdge, maxPt, n, numberOfPoints(), Shape::dg_point::oldDegree, uniconv-ext::p, pData, Round(), vorpData, and Shape::dg_point::x.

Referenced by Booleen(), ConvertToShape(), Path::DoButt(), Path::DoJoin(), Path::DoLeftJoin(), Path::DoRightJoin(), Path::Fill(), nr_arena_shape_update_fill(), nr_arena_shape_update_stroke(), and Path::RecRound().

{
  if (numberOfPoints() >= maxPt)
    {
      maxPt = 2 * numberOfPoints() + 1;
      if (_has_points_data)
        pData.resize(maxPt);
      if (_has_voronoi_data)
        vorpData.resize(maxPt);
    }

  dg_point p;
  p.x = x;
  p.dI = p.dO = 0;
  p.incidentEdge[FIRST] = p.incidentEdge[LAST] = -1;
  p.oldDegree = -1;
  _pts.push_back(p);
  int const n = _pts.size() - 1;

  if (_has_points_data)
    {
      pData[n].pending = 0;
      pData[n].edgeOnLeft = -1;
      pData[n].nextLinkedPoint = -1;
      pData[n].askForWindingS = NULL;
      pData[n].askForWindingB = -1;
      pData[n].rx[0] = Round(p.x[0]);
      pData[n].rx[1] = Round(p.x[1]);
    }
  if (_has_voronoi_data)
    {
      vorpData[n].value = 0.0;
      vorpData[n].winding = -2;
    }
  _need_points_sorting = true;

  return n;
}

void Shape::Affiche ( void   ) 

Definition at line 54 of file Shape.cpp.

References _aretes, _pts, Barcode::Code39Ext::i, and voronoi::x.

{
  printf("sh=%p nbPt=%i nbAr=%i\n", this, static_cast<int>(_pts.size()), static_cast<int>(_aretes.size())); // localizing ok
  for (unsigned int i=0; i<_pts.size(); i++) {
    printf("pt %i : x=(%f %f) dI=%i dO=%i\n",i, _pts[i].x[0], _pts[i].x[1], _pts[i].dI, _pts[i].dO); // localizing ok
  }
  for (unsigned int i=0; i<_aretes.size(); i++) {
    printf("ar %i : dx=(%f %f) st=%i en=%i\n",i, _aretes[i].dx[0], _aretes[i].dx[1], _aretes[i].st, _aretes[i].en); // localizing ok
  }
}

void Shape::AssembleAretes ( FillRule  directed = fill_nonZero  )  [private]

Definition at line 2180 of file ShapeSweep.cpp.

References _aretes, _has_back_data, DisconnectEnd(), DisconnectStart(), ebData, eData, fill_justDont, getEdge(), getPoint(), Barcode::Code39Ext::i, Shape::dg_point::incidentEdge, Inverse(), NextAt(), numberOfEdges(), numberOfPoints(), Other(), pData, SwapEdges(), swsData, and Shape::dg_point::totalDegree().

Referenced by Booleen(), and ConvertToShape().

{
  if ( directed == fill_justDont && _has_back_data == false ) {
    directed=fill_nonZero;
  }
  
  for (int i = 0; i < numberOfPoints(); i++) {
    if (getPoint(i).totalDegree() == 2) {
      int cb, cc;
      cb = getPoint(i).incidentEdge[FIRST];
      cc = getPoint(i).incidentEdge[LAST];
      bool  doublon=false;
      if ((getEdge(cb).st == getEdge(cc).st && getEdge(cb).en == getEdge(cc).en)
          || (getEdge(cb).st == getEdge(cc).en && getEdge(cb).en == getEdge(cc).en)) doublon=true;
      if ( directed == fill_justDont ) {
        if ( doublon ) {
          if ( ebData[cb].pathID > ebData[cc].pathID ) {
            cc = getPoint(i).incidentEdge[FIRST]; // on swappe pour enlever cc
            cb = getPoint(i).incidentEdge[LAST];
          } else if ( ebData[cb].pathID == ebData[cc].pathID ) {
            if ( ebData[cb].pieceID > ebData[cc].pieceID ) {
              cc = getPoint(i).incidentEdge[FIRST]; // on swappe pour enlever cc
              cb = getPoint(i).incidentEdge[LAST];
            } else if ( ebData[cb].pieceID == ebData[cc].pieceID ) { 
              if ( ebData[cb].tSt > ebData[cc].tSt ) {
                cc = getPoint(i).incidentEdge[FIRST]; // on swappe pour enlever cc
                cb = getPoint(i).incidentEdge[LAST];
              }
            }
          }
        }
        if ( doublon ) eData[cc].weight = 0;
      } else {
      }
      if ( doublon ) {
        if (getEdge(cb).st == getEdge(cc).st) {
          eData[cb].weight += eData[cc].weight;
        } else {
          eData[cb].weight -= eData[cc].weight;
        }
          eData[cc].weight = 0;
        
          if (swsData[cc].firstLinkedPoint >= 0) {
          int cp = swsData[cc].firstLinkedPoint;
          while (cp >= 0) {
            pData[cp].askForWindingB = cb;
            cp = pData[cp].nextLinkedPoint;
          }
          if (swsData[cb].firstLinkedPoint < 0) {
            swsData[cb].firstLinkedPoint = swsData[cc].firstLinkedPoint;
          } else {
            int ncp = swsData[cb].firstLinkedPoint;
            while (pData[ncp].nextLinkedPoint >= 0) {
              ncp = pData[ncp].nextLinkedPoint;
            }
            pData[ncp].nextLinkedPoint = swsData[cc].firstLinkedPoint;
          }
        }
        
          DisconnectStart (cc);
          DisconnectEnd (cc);
          if (numberOfEdges() > 1) {
          int cp = swsData[numberOfEdges() - 1].firstLinkedPoint;
          while (cp >= 0) {
            pData[cp].askForWindingB = cc;
            cp = pData[cp].nextLinkedPoint;
          }
        }
          SwapEdges (cc, numberOfEdges() - 1);
          if (cb == numberOfEdges() - 1) {
          cb = cc;
        }
          _aretes.pop_back();
        }
    } else {
      int cb;
      cb = getPoint(i).incidentEdge[FIRST];
      while (cb >= 0 && cb < numberOfEdges()) {
          int other = Other (i, cb);
          int cc;
          cc = getPoint(i).incidentEdge[FIRST];
          while (cc >= 0 && cc < numberOfEdges()) {
          int ncc = NextAt (i, cc);
          bool  doublon=false;
          if (cc != cb && Other (i, cc) == other ) doublon=true;
          if ( directed == fill_justDont ) {
            if ( doublon ) {
              if ( ebData[cb].pathID > ebData[cc].pathID ) {
                doublon=false;
              } else if ( ebData[cb].pathID == ebData[cc].pathID ) {
                if ( ebData[cb].pieceID > ebData[cc].pieceID ) {
                  doublon=false;
                } else if ( ebData[cb].pieceID == ebData[cc].pieceID ) { 
                  if ( ebData[cb].tSt > ebData[cc].tSt ) {
                    doublon=false;
                  }
                }
              }
            }
            if ( doublon ) eData[cc].weight = 0;
          } else {
          }
          if ( doublon ) {
//            if (cc != cb && Other (i, cc) == other) {
            // doublon
            if (getEdge(cb).st == getEdge(cc).st) {
              eData[cb].weight += eData[cc].weight;
            } else {
              eData[cb].weight -= eData[cc].weight;
            }
            eData[cc].weight = 0;
            
            if (swsData[cc].firstLinkedPoint >= 0) {
              int cp = swsData[cc].firstLinkedPoint;
              while (cp >= 0) {
                pData[cp].askForWindingB = cb;
                cp = pData[cp].nextLinkedPoint;
              }
              if (swsData[cb].firstLinkedPoint < 0) {
                swsData[cb].firstLinkedPoint = swsData[cc].firstLinkedPoint;
              } else {
                int ncp = swsData[cb].firstLinkedPoint;
                while (pData[ncp].nextLinkedPoint >= 0) {
                  ncp = pData[ncp].nextLinkedPoint;
                }
                pData[ncp].nextLinkedPoint = swsData[cc].firstLinkedPoint;
              }
            }
            
            DisconnectStart (cc);
            DisconnectEnd (cc);
            if (numberOfEdges() > 1) {
              int cp = swsData[numberOfEdges() - 1].firstLinkedPoint;
              while (cp >= 0) {
                pData[cp].askForWindingB = cc;
                cp = pData[cp].nextLinkedPoint;
              }
            }
            SwapEdges (cc, numberOfEdges() - 1);
            if (cb == numberOfEdges() - 1) {
              cb = cc;
            }
            if (ncc == numberOfEdges() - 1) {
              ncc = cc;
            }
        _aretes.pop_back();
          }
          cc = ncc;
        }
          cb = NextAt (i, cb);
        }
    }
  }
  
  if ( directed == fill_justDont ) {
    for (int i = 0; i < numberOfEdges(); i++)  {
      if (eData[i].weight == 0) {
//        SubEdge(i);
 //       i--;
      } else {
        if (eData[i].weight < 0) Inverse (i);
      }
    }
  } else {
    for (int i = 0; i < numberOfEdges(); i++)  {
      if (eData[i].weight == 0) {
        //                      SubEdge(i);
        //                      i--;
      } else {
        if (eData[i].weight < 0) Inverse (i);
      }
    }
  }
}

void Shape::AssemblePoints ( Shape a  )  [private]

Definition at line 2162 of file ShapeSweep.cpp.

References _pts, hasPoints(), Barcode::Code39Ext::i, iData, nbInc, numberOfEdges(), numberOfPoints(), pData, and swsData.

Referenced by Booleen(), and ConvertToShape().

{
  if (hasPoints())
    {
      int lastI = AssemblePoints (0, numberOfPoints());

      for (int i = 0; i < a->numberOfEdges(); i++)
    {
      a->swsData[i].stPt = pData[a->swsData[i].stPt].newInd;
      a->swsData[i].enPt = pData[a->swsData[i].enPt].newInd;
    }
      for (int i = 0; i < nbInc; i++)
    iData[i].pt = pData[iData[i].pt].newInd;

      _pts.resize(lastI);
    }
}

int Shape::AssemblePoints ( int  st,
int  en 
) [private]

Definition at line 2114 of file ShapeSweep.cpp.

References _pts, getPoint(), Barcode::Code39Ext::i, NULL, pData, SortPointsByOldInd(), Shape::dg_point::x, and voronoi::x.

{
  if (en > st) {
   for (int i = st; i < en; i++) pData[i].oldInd = i;
//              SortPoints(st,en-1);
    SortPointsByOldInd (st, en - 1); // SortPointsByOldInd() is required here, because of the edges we have
                                       // associated with the point for later computation of winding numbers.
                                       // specifically, we need the first point we treated, it's the only one with a valid
                                       // associated edge (man, that was a nice bug).
     for (int i = st; i < en; i++) pData[pData[i].oldInd].newInd = i;

     int lastI = st;
     for (int i = st; i < en; i++) {
          pData[i].pending = lastI++;
          if (i > st && getPoint(i - 1).x[0] == getPoint(i).x[0] && getPoint(i - 1).x[1] == getPoint(i).x[1]) {
            pData[i].pending = pData[i - 1].pending;
            if (pData[pData[i].pending].askForWindingS == NULL) {
                pData[pData[i].pending].askForWindingS = pData[i].askForWindingS;
                pData[pData[i].pending].askForWindingB = pData[i].askForWindingB;
              } else {
                if (pData[pData[i].pending].askForWindingS == pData[i].askForWindingS
              && pData[pData[i].pending].askForWindingB == pData[i].askForWindingB) {
              // meme bord, c bon
                } else {
              // meme point, mais pas le meme bord: ouille!
              // il faut prendre le bord le plus a gauche
              // en pratique, n'arrive que si 2 maxima sont dans la meme case -> le mauvais choix prend une arete incidente 
              // au bon choix
//                                              printf("doh");
                }
              }
            lastI--;
          } else {
            if (i > pData[i].pending) {
                _pts[pData[i].pending].x = getPoint(i).x;
                pData[pData[i].pending].rx = getPoint(i).x;
                pData[pData[i].pending].askForWindingS = pData[i].askForWindingS;
                pData[pData[i].pending].askForWindingB = pData[i].askForWindingB;
              }
          }
        }
      for (int i = st; i < en; i++) pData[i].newInd = pData[pData[i].newInd].pending;
      return lastI;
  }
  return en;
}

void Shape::Avance ( int  lastPointNo,
int  lastChgtPt,
Shape iS,
int  iB,
Shape a,
Shape b,
BooleanOp  mod 
) [private]

Definition at line 3114 of file ShapeSweep.cpp.

References bool_op_diff, bool_op_symdiff, DoEdgeTo(), eData, getPoint(), HalfRound(), numberOfPoints(), uniconv-ext::p, swsData, and voronoi::x.

Referenced by CheckEdges().

{
  double dd = HalfRound (1);
  bool avoidDiag = false;
//      if ( lastChgtPt > 0 && pts[lastChgtPt-1].y+dd == pts[lastChgtPt].y ) avoidDiag=true;

  bool direct = true;
  if (lS == b && (mod == bool_op_diff || mod == bool_op_symdiff))
    direct = false;
  int lftN = lS->swsData[lB].leftRnd;
  int rgtN = lS->swsData[lB].rightRnd;
  if (lS->swsData[lB].doneTo < lastChgtPt)
    {
      int lp = lS->swsData[lB].curPoint;
      if (lp >= 0 && getPoint(lp).x[1] + dd == getPoint(lastChgtPt).x[1])
    avoidDiag = true;
      if (lS->eData[lB].rdx[1] == 0)
    {
      // tjs de gauche a droite et pas de diagonale
      if (lS->eData[lB].rdx[0] >= 0)
        {
          for (int p = lftN; p <= rgtN; p++)
        {
          DoEdgeTo (lS, lB, p, direct, true);
          lp = p;
        }
        }
      else
        {
          for (int p = lftN; p <= rgtN; p++)
        {
          DoEdgeTo (lS, lB, p, direct, false);
          lp = p;
        }
        }
    }
      else if (lS->eData[lB].rdx[1] > 0)
    {
      if (lS->eData[lB].rdx[0] >= 0)
        {

          for (int p = lftN; p <= rgtN; p++)
        {
          if (avoidDiag && p == lftN && getPoint(lftN).x[0] == getPoint(lp).x[0] + dd)
            {
              if (lftN > 0 && lftN - 1 >= lastChgtPt
              && getPoint(lftN - 1).x[0] == getPoint(lp).x[0])
            {
              DoEdgeTo (lS, lB, lftN - 1, direct, true);
              DoEdgeTo (lS, lB, lftN, direct, true);
            }
              else
            {
              DoEdgeTo (lS, lB, lftN, direct, true);
            }
            }
          else
            {
              DoEdgeTo (lS, lB, p, direct, true);
            }
          lp = p;
        }
        }
      else
        {

          for (int p = rgtN; p >= lftN; p--)
        {
          if (avoidDiag && p == rgtN && getPoint(rgtN).x[0] == getPoint(lp).x[0] - dd)
            {
              if (rgtN < numberOfPoints() && rgtN + 1 < lastPointNo
              && getPoint(rgtN + 1).x[0] == getPoint(lp).x[0])
            {
              DoEdgeTo (lS, lB, rgtN + 1, direct, true);
              DoEdgeTo (lS, lB, rgtN, direct, true);
            }
              else
            {
              DoEdgeTo (lS, lB, rgtN, direct, true);
            }
            }
          else
            {
              DoEdgeTo (lS, lB, p, direct, true);
            }
          lp = p;
        }
        }
    }
      else
    {
      if (lS->eData[lB].rdx[0] >= 0)
        {

          for (int p = rgtN; p >= lftN; p--)
        {
          if (avoidDiag && p == rgtN && getPoint(rgtN).x[0] == getPoint(lp).x[0] - dd)
            {
              if (rgtN < numberOfPoints() && rgtN + 1 < lastPointNo
              && getPoint(rgtN + 1).x[0] == getPoint(lp).x[0])
            {
              DoEdgeTo (lS, lB, rgtN + 1, direct, false);
              DoEdgeTo (lS, lB, rgtN, direct, false);
            }
              else
            {
              DoEdgeTo (lS, lB, rgtN, direct, false);
            }
            }
          else
            {
              DoEdgeTo (lS, lB, p, direct, false);
            }
          lp = p;
        }
        }
      else
        {

          for (int p = lftN; p <= rgtN; p++)
        {
          if (avoidDiag && p == lftN && getPoint(lftN).x[0] == getPoint(lp).x[0] + dd)
            {
              if (lftN > 0 && lftN - 1 >= lastChgtPt
              && getPoint(lftN - 1).x[0] == getPoint(lp).x[0])
            {
              DoEdgeTo (lS, lB, lftN - 1, direct, false);
              DoEdgeTo (lS, lB, lftN, direct, false);
            }
              else
            {
              DoEdgeTo (lS, lB, lftN, direct, false);
            }
            }
          else
            {
              DoEdgeTo (lS, lB, p, direct, false);
            }
          lp = p;
        }
        }
    }
      lS->swsData[lB].curPoint = lp;
    }
  lS->swsData[lB].doneTo = lastPointNo - 1;
}

void Shape::AvanceEdge ( int  no,
float  to,
FloatLigne line,
bool  exact,
float  step 
) [private]

Definition at line 1736 of file ShapeRaster.cpp.

References FloatLigne::AddBord(), FloatLigne::AddBordR(), AvanceEdge(), and swrData.

{
    AvanceEdge(no,to,exact,step);

    if ( swrData[no].sens ) {
        
        if ( swrData[no].curX < swrData[no].lastX ) {
            
            swrData[no].guess = line->AddBordR(swrData[no].curX,
                                               to - swrData[no].curY,
                                               swrData[no].lastX,
                                               to - swrData[no].lastY,
                                               -swrData[no].dydx,
                                               swrData[no].guess);
            
        } else if ( swrData[no].curX > swrData[no].lastX ) {
            
            swrData[no].guess = line->AddBord(swrData[no].lastX,
                                              -(to - swrData[no].lastY),
                                              swrData[no].curX,
                                              -(to - swrData[no].curY),
                                              swrData[no].dydx,
                                              swrData[no].guess);
        }
        
    } else {

        if ( swrData[no].curX < swrData[no].lastX ) {

            swrData[no].guess = line->AddBordR(swrData[no].curX,
                                               -(to - swrData[no].curY),
                                               swrData[no].lastX,
                                               -(to - swrData[no].lastY),
                                               swrData[no].dydx,
                                               swrData[no].guess);
            
        } else if ( swrData[no].curX > swrData[no].lastX ) {
            
            swrData[no].guess = line->AddBord(swrData[no].lastX,
                                              to - swrData[no].lastY,
                                              swrData[no].curX,
                                              to - swrData[no].curY,
                                              -swrData[no].dydx,
                                              swrData[no].guess);
        }
    }
}

void Shape::AvanceEdge ( int  no,
float  to,
bool  exact,
float  step 
) [private]

Definition at line 1656 of file ShapeRaster.cpp.

References Shape::dg_arete::dx, getEdge(), getPoint(), swrData, and Shape::dg_point::x.

Referenced by AvanceEdge(), DirectQuickScan(), DirectScan(), QuickScan(), and Scan().

{
    if ( exact ) {
        Geom::Point dir;
        Geom::Point stp;
        if ( swrData[no].sens ) {
            stp = getPoint(getEdge(no).st).x;
            dir = getEdge(no).dx;
        } else {
            stp = getPoint(getEdge(no).en).x;
            dir = -getEdge(no).dx;
        }
        
        if ( fabs(dir[1]) < 0.000001 ) {
            swrData[no].calcX = stp[0] + dir[0];
        } else {
            swrData[no].calcX = stp[0] + ((to - stp[1]) * dir[0]) / dir[1];
        }
    } else {
        swrData[no].calcX += step * swrData[no].dxdy;
    }
    
    swrData[no].lastX = swrData[no].curX;
    swrData[no].lastY = swrData[no].curY;
    swrData[no].curX = swrData[no].calcX;
    swrData[no].curY = to;
}

void Shape::AvanceEdge ( int  no,
float  to,
BitLigne line,
bool  exact,
float  step 
) [private]

Definition at line 1813 of file ShapeRaster.cpp.

References BitLigne::AddBord(), AvanceEdge(), and swrData.

{
    AvanceEdge(no, to, exact, step);

    if ( swrData[no].sens ) {
        
        if ( swrData[no].curX < swrData[no].lastX ) {
            
            line->AddBord(swrData[no].curX, swrData[no].lastX, false);
            
        } else if ( swrData[no].curX > swrData[no].lastX ) {
            
            line->AddBord(swrData[no].lastX, swrData[no].curX, false);
        }

    } else {
        
        if ( swrData[no].curX < swrData[no].lastX ) {
            
            line->AddBord(swrData[no].curX, swrData[no].lastX, false);
            
        } else if ( swrData[no].curX > swrData[no].lastX ) {
            
            line->AddBord(swrData[no].lastX, swrData[no].curX, false);
        }
    }
}

void Shape::AvanceEdge ( int  no,
float  to,
AlphaLigne line,
bool  exact,
float  step 
) [private]

Definition at line 1885 of file ShapeRaster.cpp.

References AlphaLigne::AddBord(), AvanceEdge(), and swrData.

{
    AvanceEdge(no,to,exact,step);

    if ( swrData[no].sens ) {
        
        if ( swrData[no].curX <= swrData[no].lastX ) {
            
            line->AddBord(swrData[no].curX,
                          0,
                          swrData[no].lastX,
                          swrData[no].curY - swrData[no].lastY,
                          -swrData[no].dydx);
            
        } else if ( swrData[no].curX > swrData[no].lastX ) {
            
            line->AddBord(swrData[no].lastX,
                          0,
                          swrData[no].curX,
                          swrData[no].curY - swrData[no].lastY,
                          swrData[no].dydx);
        }
        
    } else {
        
        if ( swrData[no].curX <= swrData[no].lastX ) {
            
            line->AddBord(swrData[no].curX,
                          0,
                          swrData[no].lastX,
                          swrData[no].lastY - swrData[no].curY,
                          swrData[no].dydx);
            
        } else if ( swrData[no].curX > swrData[no].lastX ) {
            
            line->AddBord(swrData[no].lastX,
                          0,
                          swrData[no].curX,
                          swrData[no].lastY - swrData[no].curY,
                          -swrData[no].dydx);
        }
    }
}

void Shape::BeginQuickRaster ( float &  pos,
int &  curPt 
)
void Shape::BeginRaster ( float &  pos,
int &  curPt 
)

Definition at line 26 of file ShapeRaster.cpp.

References eData, Shape::dg_arete::en, getEdge(), getPoint(), Barcode::Code39Ext::i, MakeEdgeData(), MakePointData(), MakeRasterData(), NULL, numberOfEdges(), numberOfPoints(), pData, sEvts, SortPoints(), Shape::dg_arete::st, sTree, SweepEventQueue, swrData, and Shape::dg_point::x.

Referenced by Inkscape::Text::Layout::ShapeScanlineMaker::ShapeScanlineMaker().

{
    if ( numberOfPoints() <= 1 || numberOfEdges() <= 1 ) {
        curPt = 0;
        pos = 0;
        return;
    }
    
    MakeRasterData(true);
    MakePointData(true);
    MakeEdgeData(true);

    if (sTree == NULL) {
        sTree = new SweepTreeList(numberOfEdges());
    }
    if (sEvts == NULL) {
        sEvts = new SweepEventQueue(numberOfEdges());
    }

    SortPoints();

    curPt = 0;
    pos = getPoint(0).x[1] - 1.0;

    for (int i = 0; i < numberOfPoints(); i++) {
        pData[i].pending = 0;
        pData[i].edgeOnLeft = -1;
        pData[i].nextLinkedPoint = -1;
        pData[i].rx[0] = /*Round(*/getPoint(i).x[0]/*)*/;
        pData[i].rx[1] = /*Round(*/getPoint(i).x[1]/*)*/;
    }

    for (int i = 0;i < numberOfEdges(); i++) {
        swrData[i].misc = NULL;
        eData[i].rdx=pData[getEdge(i).en].rx - pData[getEdge(i).st].rx;
    }
}

int Shape::Booleen ( Shape a,
Shape b,
BooleanOp  mod,
int  cutPathID = -1 
)

Definition at line 840 of file ShapeSweep.cpp.

References _aretes, _need_edges_sorting, _pts, SweepTreeList::add(), AddChgt(), AddEdge(), AddPoint(), AssembleAretes(), AssemblePoints(), bool_op_cut, bool_op_diff, bool_op_inters, bool_op_slice, bool_op_symdiff, bool_op_union, SweepTree::bord, CheckAdjacencies(), CheckEdges(), chgts, CleanupSweep(), clearIncidenceData(), SweepTree::ConvertTo(), Shape::dg_point::dI, directedEulerian(), Shape::dg_point::dO, ebData, eData, EDGE_INSERTED, EDGE_REMOVED, AVLTree::elem, Shape::dg_arete::en, SweepEventQueue::extract(), fill_justDont, getEdge(), getPoint(), GetWindings(), hasBackData(), Barcode::Code39Ext::i, Shape::dg_point::incidentEdge, initialiseEdgeData(), initialisePointData(), SweepTree::Insert(), SweepTree::InsertAt(), INTERSECTION, Inverse(), LEFT, MakeBackData(), MakeEdgeData(), MakePointData(), MakeSweepDestData(), MakeSweepSrcData(), NextAt(), NULL, numberOfEdges(), numberOfPoints(), pData, SweepEventQueue::peek(), SweepTree::Remove(), SweepTree::RemoveEvent(), SweepTree::RemoveEvents(), Reset(), ResetSweep(), RIGHT, Round(), sEvts, shape_polygon, SweepEventQueue::size(), SortPointsRounded(), SweepTree::src, Shape::dg_arete::st, sTree, SubEdge(), SwapEdges(), SweepTree::SwapWithRight(), swdData, SweepEventQueue, swsData, TesteIntersection(), Shape::dg_point::totalDegree(), and type.

Referenced by SPFlowtext::_buildExclusionShape(), sp_selected_path_boolop(), and UnionShape().

{
  if (a == b || a == NULL || b == NULL)
    return shape_input_err;
  Reset (0, 0);
  if (a->numberOfPoints() <= 1 || a->numberOfEdges() <= 1)
    return 0;
  if (b->numberOfPoints() <= 1 || b->numberOfEdges() <= 1)
    return 0;
  if ( mod == bool_op_cut ) {
  } else if ( mod == bool_op_slice ) {
  } else {
    if (a->type != shape_polygon)
      return shape_input_err;
    if (b->type != shape_polygon)
      return shape_input_err;
  }

  a->ResetSweep ();
  b->ResetSweep ();

  if (sTree == NULL) {
      sTree = new SweepTreeList(a->numberOfEdges() + b->numberOfEdges());
  }
  if (sEvts == NULL) {
      sEvts = new SweepEventQueue(a->numberOfEdges() + b->numberOfEdges());
  }
  
  MakePointData (true);
  MakeEdgeData (true);
  MakeSweepSrcData (true);
  MakeSweepDestData (true);
  if (a->hasBackData () && b->hasBackData ())
    {
      MakeBackData (true);
    }
  else
    {
      MakeBackData (false);
    }

  a->initialisePointData();
  b->initialisePointData();

  a->initialiseEdgeData();
  b->initialiseEdgeData();

  a->SortPointsRounded ();
  b->SortPointsRounded ();

  chgts.clear();

  double lastChange =
    (a->pData[0].rx[1] <
     b->pData[0].rx[1]) ? a->pData[0].rx[1] - 1.0 : b->pData[0].rx[1] - 1.0;
  int lastChgtPt = 0;
  int edgeHead = -1;
  Shape *shapeHead = NULL;

  clearIncidenceData();

  int curAPt = 0;
  int curBPt = 0;

  while (curAPt < a->numberOfPoints() || curBPt < b->numberOfPoints() || sEvts->size() > 0)
    {
/*      for (int i=0;i<sEvts.nbEvt;i++) {
            printf("%f %f %i %i\n",sEvts.events[i].posx,sEvts.events[i].posy,sEvts.events[i].leftSweep->bord,sEvts.events[i].rightSweep->bord); // localizing ok
        }
        //      cout << endl;
        if ( sTree.racine ) {
            SweepTree*  ct=static_cast <SweepTree*> (sTree.racine->Leftmost());
            while ( ct ) {
                printf("%i %i [%i\n",ct->bord,ct->startPoint,(ct->src==a)?1:0);
                ct=static_cast <SweepTree*> (ct->elem[RIGHT]);
            }
        }
        printf("\n");*/

    Geom::Point ptX;
      double ptL, ptR;
      SweepTree *intersL = NULL;
      SweepTree *intersR = NULL;
      int nPt = -1;
      Shape *ptSh = NULL;
      bool isIntersection = false;

      if (sEvts->peek(intersL, intersR, ptX, ptL, ptR))
    {
      if (curAPt < a->numberOfPoints())
        {
          if (curBPt < b->numberOfPoints())
        {
          if (a->pData[curAPt].rx[1] < b->pData[curBPt].rx[1]
              || (a->pData[curAPt].rx[1] == b->pData[curBPt].rx[1]
              && a->pData[curAPt].rx[0] < b->pData[curBPt].rx[0]))
            {
              if (a->pData[curAPt].pending > 0
              || (a->pData[curAPt].rx[1] > ptX[1]
                  || (a->pData[curAPt].rx[1] == ptX[1]
                  && a->pData[curAPt].rx[0] > ptX[0])))
            {
              /* FIXME: could be pop? */
              sEvts->extract(intersL, intersR, ptX, ptL, ptR);
              isIntersection = true;
            }
              else
            {
              nPt = curAPt++;
              ptSh = a;
              ptX = ptSh->pData[nPt].rx;
              isIntersection = false;
            }
            }
          else
            {
              if (b->pData[curBPt].pending > 0
              || (b->pData[curBPt].rx[1] > ptX[1]
                  || (b->pData[curBPt].rx[1] == ptX[1]
                  && b->pData[curBPt].rx[0] > ptX[0])))
            {
              /* FIXME: could be pop? */
              sEvts->extract(intersL, intersR, ptX, ptL, ptR);
              isIntersection = true;
            }
              else
            {
              nPt = curBPt++;
              ptSh = b;
              ptX = ptSh->pData[nPt].rx;
              isIntersection = false;
            }
            }
        }
          else
        {
          if (a->pData[curAPt].pending > 0
              || (a->pData[curAPt].rx[1] > ptX[1]
              || (a->pData[curAPt].rx[1] == ptX[1]
                  && a->pData[curAPt].rx[0] > ptX[0])))
            {
              /* FIXME: could be pop? */
              sEvts->extract(intersL, intersR, ptX, ptL, ptR);
              isIntersection = true;
            }
          else
            {
              nPt = curAPt++;
              ptSh = a;
              ptX = ptSh->pData[nPt].rx;
              isIntersection = false;
            }
        }
        }
      else
        {
          if (b->pData[curBPt].pending > 0
          || (b->pData[curBPt].rx[1] > ptX[1]
              || (b->pData[curBPt].rx[1] == ptX[1]
              && b->pData[curBPt].rx[0] > ptX[0])))
        {
          /* FIXME: could be pop? */
          sEvts->extract(intersL, intersR, ptX,  ptL, ptR);
          isIntersection = true;
        }
          else
        {
          nPt = curBPt++;
          ptSh = b;
          ptX = ptSh->pData[nPt].rx;
          isIntersection = false;
        }
        }
    }
      else
    {
      if (curAPt < a->numberOfPoints())
        {
          if (curBPt < b->numberOfPoints())
        {
          if (a->pData[curAPt].rx[1] < b->pData[curBPt].rx[1]
              || (a->pData[curAPt].rx[1] == b->pData[curBPt].rx[1]
              && a->pData[curAPt].rx[0] < b->pData[curBPt].rx[0]))
            {
              nPt = curAPt++;
              ptSh = a;
            }
          else
            {
              nPt = curBPt++;
              ptSh = b;
            }
        }
          else
        {
          nPt = curAPt++;
          ptSh = a;
        }
        }
      else
        {
          nPt = curBPt++;
          ptSh = b;
        }
      ptX = ptSh->pData[nPt].rx;
      isIntersection = false;
    }

      if (isIntersection == false)
    {
      if (ptSh->getPoint(nPt).dI == 0 && ptSh->getPoint(nPt).dO == 0)
        continue;
    }

      Geom::Point rPtX;
      rPtX[0]= Round (ptX[0]);
      rPtX[1]= Round (ptX[1]);
      int lastPointNo = -1;
      lastPointNo = AddPoint (rPtX);
      pData[lastPointNo].rx = rPtX;

      if (rPtX[1] > lastChange)
    {
      int lastI = AssemblePoints (lastChgtPt, lastPointNo);


      Shape *curSh = shapeHead;
      int curBo = edgeHead;
      while (curSh)
        {
          curSh->swsData[curBo].leftRnd =
        pData[curSh->swsData[curBo].leftRnd].newInd;
          curSh->swsData[curBo].rightRnd =
        pData[curSh->swsData[curBo].rightRnd].newInd;

          Shape *neSh = curSh->swsData[curBo].nextSh;
          curBo = curSh->swsData[curBo].nextBo;
          curSh = neSh;
        }

      for (unsigned int i = 0; i < chgts.size(); i++)
        {
          chgts[i].ptNo = pData[chgts[i].ptNo].newInd;
          if (chgts[i].type == 0)
        {
          if (chgts[i].src->getEdge(chgts[i].bord).st <
              chgts[i].src->getEdge(chgts[i].bord).en)
            {
              chgts[i].src->swsData[chgts[i].bord].stPt =
            chgts[i].ptNo;
            }
          else
            {
              chgts[i].src->swsData[chgts[i].bord].enPt =
            chgts[i].ptNo;
            }
        }
          else if (chgts[i].type == 1)
        {
          if (chgts[i].src->getEdge(chgts[i].bord).st >
              chgts[i].src->getEdge(chgts[i].bord).en)
            {
              chgts[i].src->swsData[chgts[i].bord].stPt =
            chgts[i].ptNo;
            }
          else
            {
              chgts[i].src->swsData[chgts[i].bord].enPt =
            chgts[i].ptNo;
            }
        }
        }

      CheckAdjacencies (lastI, lastChgtPt, shapeHead, edgeHead);

      CheckEdges (lastI, lastChgtPt, a, b, mod);

      for (int i = lastChgtPt; i < lastI; i++)
        {
          if (pData[i].askForWindingS)
        {
          Shape *windS = pData[i].askForWindingS;
          int windB = pData[i].askForWindingB;
          pData[i].nextLinkedPoint =
            windS->swsData[windB].firstLinkedPoint;
          windS->swsData[windB].firstLinkedPoint = i;
        }
        }

    if (lastI < lastPointNo)
        {
          _pts[lastI] = getPoint(lastPointNo);
          pData[lastI] = pData[lastPointNo];
        }
      lastPointNo = lastI;
      _pts.resize(lastI + 1);

      lastChgtPt = lastPointNo;
      lastChange = rPtX[1];
      chgts.clear();
      edgeHead = -1;
      shapeHead = NULL;
    }


      if (isIntersection)
    {
      // les 2 events de part et d'autre de l'intersection
      // (celui de l'intersection a deja ete depile)
      intersL->RemoveEvent (*sEvts, LEFT);
      intersR->RemoveEvent (*sEvts, RIGHT);

      AddChgt (lastPointNo, lastChgtPt, shapeHead, edgeHead, INTERSECTION,
           intersL->src, intersL->bord, intersR->src, intersR->bord);

      intersL->SwapWithRight (*sTree, *sEvts);

      TesteIntersection (intersL, LEFT, true);
      TesteIntersection (intersR, RIGHT, true);
    }
      else
    {
      int cb;

      int nbUp = 0, nbDn = 0;
      int upNo = -1, dnNo = -1;
      cb = ptSh->getPoint(nPt).incidentEdge[FIRST];
      while (cb >= 0 && cb < ptSh->numberOfEdges())
        {
          if ((ptSh->getEdge(cb).st < ptSh->getEdge(cb).en
           && nPt == ptSh->getEdge(cb).en)
          || (ptSh->getEdge(cb).st > ptSh->getEdge(cb).en
              && nPt == ptSh->getEdge(cb).st))
        {
          upNo = cb;
          nbUp++;
        }
          if ((ptSh->getEdge(cb).st > ptSh->getEdge(cb).en
           && nPt == ptSh->getEdge(cb).en)
          || (ptSh->getEdge(cb).st < ptSh->getEdge(cb).en
              && nPt == ptSh->getEdge(cb).st))
        {
          dnNo = cb;
          nbDn++;
        }
          cb = ptSh->NextAt (nPt, cb);
        }

      if (nbDn <= 0)
        {
          upNo = -1;
        }
      if (upNo >= 0 && (SweepTree *) ptSh->swsData[upNo].misc == NULL)
        {
          upNo = -1;
        }

//                      upNo=-1;

      bool doWinding = true;

      if (nbUp > 0)
        {
          cb = ptSh->getPoint(nPt).incidentEdge[FIRST];
          while (cb >= 0 && cb < ptSh->numberOfEdges())
        {
          if ((ptSh->getEdge(cb).st < ptSh->getEdge(cb).en
               && nPt == ptSh->getEdge(cb).en)
              || (ptSh->getEdge(cb).st > ptSh->getEdge(cb).en
              && nPt == ptSh->getEdge(cb).st))
            {
              if (cb != upNo)
            {
              SweepTree *node =
                (SweepTree *) ptSh->swsData[cb].misc;
              if (node == NULL)
                {
                }
              else
                {
                  AddChgt (lastPointNo, lastChgtPt, shapeHead,
                       edgeHead, EDGE_REMOVED, node->src, node->bord,
                       NULL, -1);
                  ptSh->swsData[cb].misc = NULL;

                  int onLeftB = -1, onRightB = -1;
                  Shape *onLeftS = NULL;
                  Shape *onRightS = NULL;
                  if (node->elem[LEFT])
                {
                  onLeftB =
                    (static_cast <
                     SweepTree * >(node->elem[LEFT]))->bord;
                  onLeftS =
                    (static_cast <
                     SweepTree * >(node->elem[LEFT]))->src;
                }
                  if (node->elem[RIGHT])
                {
                  onRightB =
                    (static_cast <
                     SweepTree * >(node->elem[RIGHT]))->bord;
                  onRightS =
                    (static_cast <
                     SweepTree * >(node->elem[RIGHT]))->src;
                }

                  node->Remove (*sTree, *sEvts, true);
                  if (onLeftS && onRightS)
                {
                  SweepTree *onLeft =
                    (SweepTree *) onLeftS->swsData[onLeftB].
                    misc;
//                                                                      SweepTree* onRight=(SweepTree*)onRightS->swsData[onRightB].misc;
                  if (onLeftS == ptSh
                      && (onLeftS->getEdge(onLeftB).en == nPt
                      || onLeftS->getEdge(onLeftB).st ==
                      nPt))
                    {
                    }
                  else
                    {
                      if (onRightS == ptSh
                      && (onRightS->getEdge(onRightB).en ==
                          nPt
                          || onRightS->getEdge(onRightB).
                          st == nPt))
                    {
                    }
                      else
                    {
                      TesteIntersection (onLeft, RIGHT, true);
                    }
                    }
                }
                }
            }
            }
          cb = ptSh->NextAt (nPt, cb);
        }
        }

      // traitement du "upNo devient dnNo"
      SweepTree *insertionNode = NULL;
      if (dnNo >= 0)
        {
          if (upNo >= 0)
        {
          SweepTree *node = (SweepTree *) ptSh->swsData[upNo].misc;

          AddChgt (lastPointNo, lastChgtPt, shapeHead, edgeHead, EDGE_REMOVED,
               node->src, node->bord, NULL, -1);

          ptSh->swsData[upNo].misc = NULL;

          node->RemoveEvents (*sEvts);
          node->ConvertTo (ptSh, dnNo, 1, lastPointNo);
          ptSh->swsData[dnNo].misc = node;
          TesteIntersection (node, RIGHT, true);
          TesteIntersection (node, LEFT, true);
          insertionNode = node;

          ptSh->swsData[dnNo].curPoint = lastPointNo;

          AddChgt (lastPointNo, lastChgtPt, shapeHead, edgeHead, EDGE_INSERTED,
               node->src, node->bord, NULL, -1);
        }
          else
        {
          SweepTree *node = sTree->add(ptSh, dnNo, 1, lastPointNo, this);
          ptSh->swsData[dnNo].misc = node;
          node->Insert (*sTree, *sEvts, this, lastPointNo, true);

          if (doWinding)
            {
              SweepTree *myLeft =
            static_cast < SweepTree * >(node->elem[LEFT]);
              if (myLeft)
            {
              pData[lastPointNo].askForWindingS = myLeft->src;
              pData[lastPointNo].askForWindingB = myLeft->bord;
            }
              else
            {
              pData[lastPointNo].askForWindingB = -1;
            }
              doWinding = false;
            }

          TesteIntersection (node, RIGHT, true);
          TesteIntersection (node, LEFT, true);
          insertionNode = node;

          ptSh->swsData[dnNo].curPoint = lastPointNo;

          AddChgt (lastPointNo, lastChgtPt, shapeHead, edgeHead, EDGE_INSERTED,
               node->src, node->bord, NULL, -1);
        }
        }

      if (nbDn > 1)
        {           // si nbDn == 1 , alors dnNo a deja ete traite
          cb = ptSh->getPoint(nPt).incidentEdge[FIRST];
          while (cb >= 0 && cb < ptSh->numberOfEdges())
        {
          if ((ptSh->getEdge(cb).st > ptSh->getEdge(cb).en
               && nPt == ptSh->getEdge(cb).en)
              || (ptSh->getEdge(cb).st < ptSh->getEdge(cb).en
              && nPt == ptSh->getEdge(cb).st))
            {
              if (cb != dnNo)
            {
              SweepTree *node = sTree->add(ptSh, cb, 1, lastPointNo, this);
              ptSh->swsData[cb].misc = node;
//                                                      node->Insert(sTree,*sEvts,this,lastPointNo,true);
              node->InsertAt (*sTree, *sEvts, this, insertionNode,
                      nPt, true);

              if (doWinding)
                {
                  SweepTree *myLeft =
                static_cast < SweepTree * >(node->elem[LEFT]);
                  if (myLeft)
                {
                  pData[lastPointNo].askForWindingS =
                    myLeft->src;
                  pData[lastPointNo].askForWindingB =
                    myLeft->bord;
                }
                  else
                {
                  pData[lastPointNo].askForWindingB = -1;
                }
                  doWinding = false;
                }

              TesteIntersection (node, RIGHT, true);
              TesteIntersection (node, LEFT, true);

              ptSh->swsData[cb].curPoint = lastPointNo;

              AddChgt (lastPointNo, lastChgtPt, shapeHead,
                   edgeHead, EDGE_INSERTED, node->src, node->bord, NULL,
                   -1);
            }
            }
          cb = ptSh->NextAt (nPt, cb);
        }
        }
    }
    }
  {
    int lastI = AssemblePoints (lastChgtPt, numberOfPoints());


    Shape *curSh = shapeHead;
    int curBo = edgeHead;
    while (curSh)
      {
    curSh->swsData[curBo].leftRnd =
      pData[curSh->swsData[curBo].leftRnd].newInd;
    curSh->swsData[curBo].rightRnd =
      pData[curSh->swsData[curBo].rightRnd].newInd;

    Shape *neSh = curSh->swsData[curBo].nextSh;
    curBo = curSh->swsData[curBo].nextBo;
    curSh = neSh;
      }

    /* FIXME: this kind of code seems to appear frequently */
    for (unsigned int i = 0; i < chgts.size(); i++)
      {
    chgts[i].ptNo = pData[chgts[i].ptNo].newInd;
    if (chgts[i].type == 0)
      {
        if (chgts[i].src->getEdge(chgts[i].bord).st <
        chgts[i].src->getEdge(chgts[i].bord).en)
          {
        chgts[i].src->swsData[chgts[i].bord].stPt = chgts[i].ptNo;
          }
        else
          {
        chgts[i].src->swsData[chgts[i].bord].enPt = chgts[i].ptNo;
          }
      }
    else if (chgts[i].type == 1)
      {
        if (chgts[i].src->getEdge(chgts[i].bord).st >
        chgts[i].src->getEdge(chgts[i].bord).en)
          {
        chgts[i].src->swsData[chgts[i].bord].stPt = chgts[i].ptNo;
          }
        else
          {
        chgts[i].src->swsData[chgts[i].bord].enPt = chgts[i].ptNo;
          }
      }
      }

    CheckAdjacencies (lastI, lastChgtPt, shapeHead, edgeHead);

    CheckEdges (lastI, lastChgtPt, a, b, mod);

    for (int i = lastChgtPt; i < lastI; i++)
      {
    if (pData[i].askForWindingS)
      {
        Shape *windS = pData[i].askForWindingS;
        int windB = pData[i].askForWindingB;
        pData[i].nextLinkedPoint = windS->swsData[windB].firstLinkedPoint;
        windS->swsData[windB].firstLinkedPoint = i;
      }
      }

    _pts.resize(lastI);

    edgeHead = -1;
    shapeHead = NULL;
  }

  chgts.clear();
  clearIncidenceData();

//      Plot(190,70,6,400,400,true,false,true,true);

  if ( mod == bool_op_cut ) {
    AssembleAretes (fill_justDont);
    // dupliquer les aretes de la coupure
    int i=numberOfEdges()-1;
    for (;i>=0;i--) {
      if ( ebData[i].pathID == cutPathID ) {
        // on duplique
        int nEd=AddEdge(getEdge(i).en,getEdge(i).st);
        ebData[nEd].pathID=cutPathID;
        ebData[nEd].pieceID=ebData[i].pieceID;
        ebData[nEd].tSt=ebData[i].tEn;
        ebData[nEd].tEn=ebData[i].tSt;
        eData[nEd].weight=eData[i].weight;
        // lui donner les firstlinkedpoitn si besoin
        if ( getEdge(i).en >= getEdge(i).st ) {
          int cp = swsData[i].firstLinkedPoint;
          while (cp >= 0) {
            pData[cp].askForWindingB = nEd;
            cp = pData[cp].nextLinkedPoint;
          }
          swsData[nEd].firstLinkedPoint = swsData[i].firstLinkedPoint;
          swsData[i].firstLinkedPoint=-1;
        }
      }
    }
  } else if ( mod == bool_op_slice ) {
  } else {
    AssembleAretes ();
  }
  
  for (int i = 0; i < numberOfPoints(); i++)
    {
      _pts[i].oldDegree = getPoint(i).totalDegree();
    }

  _need_edges_sorting = true;
  if ( mod == bool_op_slice ) {
  } else {
    GetWindings (a, b, mod, false);
  }
//      Plot(190,70,6,400,400,true,true,true,true);

  if (mod == bool_op_symdiff)
  {
    for (int i = 0; i < numberOfEdges(); i++)
    {
      swdData[i].leW = swdData[i].leW % 2;
      if (swdData[i].leW < 0)
        swdData[i].leW = -swdData[i].leW;
      swdData[i].riW = swdData[i].riW;
      if (swdData[i].riW < 0)
        swdData[i].riW = -swdData[i].riW;
      
      if (swdData[i].leW > 0 && swdData[i].riW <= 0)
        {
          eData[i].weight = 1;
        }
      else if (swdData[i].leW <= 0 && swdData[i].riW > 0)
        {
          Inverse (i);
          eData[i].weight = 1;
        }
      else
        {
          eData[i].weight = 0;
          SubEdge (i);
          i--;
        }
    }
  }
  else if (mod == bool_op_union || mod == bool_op_diff)
  {
    for (int i = 0; i < numberOfEdges(); i++)
    {
      if (swdData[i].leW > 0 && swdData[i].riW <= 0)
        {
          eData[i].weight = 1;
        }
      else if (swdData[i].leW <= 0 && swdData[i].riW > 0)
        {
          Inverse (i);
          eData[i].weight = 1;
        }
      else
        {
          eData[i].weight = 0;
          SubEdge (i);
          i--;
        }
    }
  }
  else if (mod == bool_op_inters)
  {
    for (int i = 0; i < numberOfEdges(); i++)
    {
      if (swdData[i].leW > 1 && swdData[i].riW <= 1)
        {
          eData[i].weight = 1;
        }
      else if (swdData[i].leW <= 1 && swdData[i].riW > 1)
        {
          Inverse (i);
          eData[i].weight = 1;
        }
      else
        {
          eData[i].weight = 0;
          SubEdge (i);
          i--;
        }
    }
  } else if ( mod == bool_op_cut ) {
    // inverser les aretes de la coupe au besoin
    for (int i=0;i<numberOfEdges();i++) {
      if ( getEdge(i).st < 0 || getEdge(i).en < 0 ) {
        if ( i < numberOfEdges()-1 ) {
          // decaler les askForWinding
          int cp = swsData[numberOfEdges()-1].firstLinkedPoint;
          while (cp >= 0) {
            pData[cp].askForWindingB = i;
            cp = pData[cp].nextLinkedPoint;
          }
        }
        SwapEdges(i,numberOfEdges()-1);
        SubEdge(numberOfEdges()-1);
//        SubEdge(i);
        i--;
      } else if ( ebData[i].pathID == cutPathID ) {
        swdData[i].leW=swdData[i].leW%2;
        swdData[i].riW=swdData[i].riW%2;
        if ( swdData[i].leW < swdData[i].riW ) {
          Inverse(i);
        }
      }
    }
  } else if ( mod == bool_op_slice ) {
    // supprimer les aretes de la coupe
    int i=numberOfEdges()-1;
    for (;i>=0;i--) {
      if ( ebData[i].pathID == cutPathID || getEdge(i).st < 0 || getEdge(i).en < 0 ) {
        SubEdge(i);
      }
    }
  }
  else
  {
    for (int i = 0; i < numberOfEdges(); i++)
    {
      if (swdData[i].leW > 0 && swdData[i].riW <= 0)
        {
          eData[i].weight = 1;
        }
      else if (swdData[i].leW <= 0 && swdData[i].riW > 0)
        {
          Inverse (i);
          eData[i].weight = 1;
        }
      else
        {
          eData[i].weight = 0;
          SubEdge (i);
          i--;
        }
    }
  }
  
  delete sTree;
  sTree = NULL;
  delete sEvts;
  sEvts = NULL;
  
  if ( mod == bool_op_cut ) {
    // on garde le askForWinding
  } else {
    MakePointData (false);
  }
  MakeEdgeData (false);
  MakeSweepSrcData (false);
  MakeSweepDestData (false);
  a->CleanupSweep ();
  b->CleanupSweep ();

  if (directedEulerian(this) == false)
    {
//              printf( "pas euclidian2");
      _pts.clear();
      _aretes.clear();
      return shape_euler_err;
    }
  type = shape_polygon;
  return 0;
}

void Shape::CalcBBox ( bool  strict_degree = false  ) 

Definition at line 2019 of file Shape.cpp.

References _bbox_up_to_date, bottomY, Shape::dg_point::dI, Shape::dg_point::dO, getPoint(), hasPoints(), Barcode::Code39Ext::i, leftX, numberOfPoints(), rightX, topY, voronoi::x, and Shape::dg_point::x.

Referenced by raster_glyph::LoadSubPixelPosition(), nr_arena_shape_add_bboxes(), nr_pixblock_render_shape_mask_or(), Inkscape::Text::Layout::ShapeScanlineMaker::ShapeScanlineMaker(), and sp_offset_set_shape().

{
  if (_bbox_up_to_date)
    return;
  if (hasPoints() == false)
  {
    leftX = rightX = topY = bottomY = 0;
    _bbox_up_to_date = true;
    return;
  }
  leftX = rightX = getPoint(0).x[0];
  topY = bottomY = getPoint(0).x[1];
  bool not_set=true;
  for (int i = 0; i < numberOfPoints(); i++)
  {
    if ( strict_degree == false || getPoint(i).dI > 0 || getPoint(i).dO > 0 ) {
      if ( not_set ) {
        leftX = rightX = getPoint(i).x[0];
        topY = bottomY = getPoint(i).x[1];
        not_set=false;
      } else {
        if (  getPoint(i).x[0] < leftX) leftX = getPoint(i).x[0];
        if (  getPoint(i).x[0] > rightX) rightX = getPoint(i).x[0];
        if (  getPoint(i).x[1] < topY) topY = getPoint(i).x[1];
        if (  getPoint(i).x[1] > bottomY) bottomY = getPoint(i).x[1];
      }
    }
  }

  _bbox_up_to_date = true;
}

void Shape::CheckAdjacencies ( int  lastPointNo,
int  lastChgtPt,
Shape shapeHead,
int  edgeHead 
) [private]

Definition at line 2723 of file ShapeSweep.cpp.

References SweepTree::bord, chgts, AVLTree::elem, getPoint(), n, NULL, SweepTree::src, swsData, TesteAdjacency(), Shape::dg_point::x, and voronoi::x.

Referenced by Booleen(), and ConvertToShape().

{
  for (unsigned int cCh = 0; cCh < chgts.size(); cCh++)
    {
      int chLeN = chgts[cCh].ptNo;
      int chRiN = chgts[cCh].ptNo;
      if (chgts[cCh].src)
    {
      Shape *lS = chgts[cCh].src;
      int lB = chgts[cCh].bord;
      int lftN = lS->swsData[lB].leftRnd;
      int rgtN = lS->swsData[lB].rightRnd;
      if (lftN < chLeN)
        chLeN = lftN;
      if (rgtN > chRiN)
        chRiN = rgtN;
//                      for (int n=lftN;n<=rgtN;n++) CreateIncidence(lS,lB,n);
      for (int n = lftN - 1; n >= lastChgtPt; n--)
        {
          if (TesteAdjacency (lS, lB, getPoint(n).x, n, false) ==
          false)
        break;
          lS->swsData[lB].leftRnd = n;
        }
      for (int n = rgtN + 1; n < lastPointNo; n++)
        {
          if (TesteAdjacency (lS, lB, getPoint(n).x, n, false) ==
          false)
        break;
          lS->swsData[lB].rightRnd = n;
        }
    }
      if (chgts[cCh].osrc)
    {
      Shape *rS = chgts[cCh].osrc;
      int rB = chgts[cCh].obord;
      int lftN = rS->swsData[rB].leftRnd;
      int rgtN = rS->swsData[rB].rightRnd;
      if (lftN < chLeN)
        chLeN = lftN;
      if (rgtN > chRiN)
        chRiN = rgtN;
//                      for (int n=lftN;n<=rgtN;n++) CreateIncidence(rS,rB,n);
      for (int n = lftN - 1; n >= lastChgtPt; n--)
        {
          if (TesteAdjacency (rS, rB, getPoint(n).x, n, false) ==
          false)
        break;
          rS->swsData[rB].leftRnd = n;
        }
      for (int n = rgtN + 1; n < lastPointNo; n++)
        {
          if (TesteAdjacency (rS, rB, getPoint(n).x, n, false) ==
          false)
        break;
          rS->swsData[rB].rightRnd = n;
        }
    }
      if (chgts[cCh].lSrc)
    {
      if (chgts[cCh].lSrc->swsData[chgts[cCh].lBrd].leftRnd < lastChgtPt)
        {
          Shape *nSrc = chgts[cCh].lSrc;
          int nBrd = chgts[cCh].lBrd /*,nNo=chgts[cCh].ptNo */ ;
          bool hit;

          do
        {
          hit = false;
          for (int n = chRiN; n >= chLeN; n--)
            {
              if (TesteAdjacency
              (nSrc, nBrd, getPoint(n).x, n, false))
            {
              if (nSrc->swsData[nBrd].leftRnd < lastChgtPt)
                {
                  nSrc->swsData[nBrd].leftRnd = n;
                  nSrc->swsData[nBrd].rightRnd = n;
                }
              else
                {
                  if (n < nSrc->swsData[nBrd].leftRnd)
                nSrc->swsData[nBrd].leftRnd = n;
                  if (n > nSrc->swsData[nBrd].rightRnd)
                nSrc->swsData[nBrd].rightRnd = n;
                }
              hit = true;
            }
            }
          for (int n = chLeN - 1; n >= lastChgtPt; n--)
            {
              if (TesteAdjacency
              (nSrc, nBrd, getPoint(n).x, n, false) == false)
            break;
              if (nSrc->swsData[nBrd].leftRnd < lastChgtPt)
            {
              nSrc->swsData[nBrd].leftRnd = n;
              nSrc->swsData[nBrd].rightRnd = n;
            }
              else
            {
              if (n < nSrc->swsData[nBrd].leftRnd)
                nSrc->swsData[nBrd].leftRnd = n;
              if (n > nSrc->swsData[nBrd].rightRnd)
                nSrc->swsData[nBrd].rightRnd = n;
            }
              hit = true;
            }
          if (hit)
            {
              SweepTree *node =
            static_cast < SweepTree * >(nSrc->swsData[nBrd].misc);
              if (node == NULL)
            break;
              node = static_cast < SweepTree * >(node->elem[LEFT]);
              if (node == NULL)
            break;
              nSrc = node->src;
              nBrd = node->bord;
              if (nSrc->swsData[nBrd].leftRnd >= lastChgtPt)
            break;
            }
        }
          while (hit);

        }
    }
      if (chgts[cCh].rSrc)
    {
      if (chgts[cCh].rSrc->swsData[chgts[cCh].rBrd].leftRnd < lastChgtPt)
        {
          Shape *nSrc = chgts[cCh].rSrc;
          int nBrd = chgts[cCh].rBrd /*,nNo=chgts[cCh].ptNo */ ;
          bool hit;
          do
        {
          hit = false;
          for (int n = chLeN; n <= chRiN; n++)
            {
              if (TesteAdjacency
              (nSrc, nBrd, getPoint(n).x, n, false))
            {
              if (nSrc->swsData[nBrd].leftRnd < lastChgtPt)
                {
                  nSrc->swsData[nBrd].leftRnd = n;
                  nSrc->swsData[nBrd].rightRnd = n;
                }
              else
                {
                  if (n < nSrc->swsData[nBrd].leftRnd)
                nSrc->swsData[nBrd].leftRnd = n;
                  if (n > nSrc->swsData[nBrd].rightRnd)
                nSrc->swsData[nBrd].rightRnd = n;
                }
              hit = true;
            }
            }
          for (int n = chRiN + 1; n < lastPointNo; n++)
            {
              if (TesteAdjacency
              (nSrc, nBrd, getPoint(n).x, n, false) == false)
            break;
              if (nSrc->swsData[nBrd].leftRnd < lastChgtPt)
            {
              nSrc->swsData[nBrd].leftRnd = n;
              nSrc->swsData[nBrd].rightRnd = n;
            }
              else
            {
              if (n < nSrc->swsData[nBrd].leftRnd)
                nSrc->swsData[nBrd].leftRnd = n;
              if (n > nSrc->swsData[nBrd].rightRnd)
                nSrc->swsData[nBrd].rightRnd = n;
            }
              hit = true;
            }
          if (hit)
            {
              SweepTree *node =
            static_cast < SweepTree * >(nSrc->swsData[nBrd].misc);
              if (node == NULL)
            break;
              node = static_cast < SweepTree * >(node->elem[RIGHT]);
              if (node == NULL)
            break;
              nSrc = node->src;
              nBrd = node->bord;
              if (nSrc->swsData[nBrd].leftRnd >= lastChgtPt)
            break;
            }
        }
          while (hit);
        }
    }
    }
}

void Shape::CheckEdges ( int  lastPointNo,
int  lastChgtPt,
Shape a,
Shape b,
BooleanOp  mod 
) [private]

Definition at line 3041 of file ShapeSweep.cpp.

References Avance(), SweepTree::bord, chgts, AVLTree::elem, NULL, SweepTree::src, swsData, and type.

Referenced by Booleen(), and ConvertToShape().

{

  for (unsigned int cCh = 0; cCh < chgts.size(); cCh++)
    {
      if (chgts[cCh].type == 0)
    {
      Shape *lS = chgts[cCh].src;
      int lB = chgts[cCh].bord;
      lS->swsData[lB].curPoint = chgts[cCh].ptNo;
    }
    }
  for (unsigned int cCh = 0; cCh < chgts.size(); cCh++)
    {
//              int   chLeN=chgts[cCh].ptNo;
//              int   chRiN=chgts[cCh].ptNo;
      if (chgts[cCh].src)
    {
      Shape *lS = chgts[cCh].src;
      int lB = chgts[cCh].bord;
      Avance (lastPointNo, lastChgtPt, lS, lB, a, b, mod);
    }
      if (chgts[cCh].osrc)
    {
      Shape *rS = chgts[cCh].osrc;
      int rB = chgts[cCh].obord;
      Avance (lastPointNo, lastChgtPt, rS, rB, a, b, mod);
    }
      if (chgts[cCh].lSrc)
    {
      Shape *nSrc = chgts[cCh].lSrc;
      int nBrd = chgts[cCh].lBrd;
      while (nSrc->swsData[nBrd].leftRnd >=
         lastChgtPt /*&& nSrc->swsData[nBrd].doneTo < lastChgtPt */ )
        {
          Avance (lastPointNo, lastChgtPt, nSrc, nBrd, a, b, mod);

          SweepTree *node =
        static_cast < SweepTree * >(nSrc->swsData[nBrd].misc);
          if (node == NULL)
        break;
          node = static_cast < SweepTree * >(node->elem[LEFT]);
          if (node == NULL)
        break;
          nSrc = node->src;
          nBrd = node->bord;
        }
    }
      if (chgts[cCh].rSrc)
    {
      Shape *nSrc = chgts[cCh].rSrc;
      int nBrd = chgts[cCh].rBrd;
      while (nSrc->swsData[nBrd].rightRnd >=
         lastChgtPt /*&& nSrc->swsData[nBrd].doneTo < lastChgtPt */ )
        {
          Avance (lastPointNo, lastChgtPt, nSrc, nBrd, a, b, mod);

          SweepTree *node =
        static_cast < SweepTree * >(nSrc->swsData[nBrd].misc);
          if (node == NULL)
        break;
          node = static_cast < SweepTree * >(node->elem[RIGHT]);
          if (node == NULL)
        break;
          nSrc = node->src;
          nBrd = node->bord;
        }
    }
    }
}

void Shape::CleanupSweep ( void   )  [private]

Definition at line 55 of file ShapeSweep.cpp.

References MakeEdgeData(), MakePointData(), and MakeSweepSrcData().

Referenced by Booleen(), and ConvertToShape().

{
  MakePointData (false);
  MakeEdgeData (false);
  MakeSweepSrcData (false);
}

void Shape::clearIncidenceData (  )  [private]

Definition at line 2157 of file Shape.cpp.

References iData, maxInc, and nbInc.

Referenced by Booleen(), and ConvertToShape().

{
    g_free(iData);
    iData = NULL;
    nbInc = maxInc = 0;
}

static int Shape::CmpQRs ( const quick_raster_data p1,
const quick_raster_data p2 
) [inline, static, private]

Definition at line 556 of file Shape.h.

References Shape::quick_raster_data::x.

Referenced by QuickRasterAddEdge(), and QuickRasterSort().

                                                                                {
        if ( fabs(p1.x - p2.x) < 0.00001 ) {
            return 0;
        }

        return ( ( p1.x < p2.x ) ? -1 : 1 );
    };

int Shape::CmpToVert ( const Geom::Point  ax,
const Geom::Point  bx,
bool  as,
bool  bs 
) [static, private]

Definition at line 1555 of file Shape.cpp.

References Geom::cross().

Referenced by SortEdgesList().

{
  int tstAX = 0;
  int tstAY = 0;
  int tstBX = 0;
  int tstBY = 0;
  if (ax[0] > 0)
    tstAX = 1;
  if (ax[0] < 0)
    tstAX = -1;
  if (ax[1] > 0)
    tstAY = 1;
  if (ax[1] < 0)
    tstAY = -1;
  if (bx[0] > 0)
    tstBX = 1;
  if (bx[0] < 0)
    tstBX = -1;
  if (bx[1] > 0)
    tstBY = 1;
  if (bx[1] < 0)
    tstBY = -1;

  int quadA = 0, quadB = 0;
  if (tstAX < 0)
    {
      if (tstAY < 0)
        {
          quadA = 7;
        }
      else if (tstAY == 0)
        {
          quadA = 6;
        }
      else if (tstAY > 0)
        {
          quadA = 5;
        }
    }
  else if (tstAX == 0)
    {
      if (tstAY < 0)
        {
          quadA = 0;
        }
      else if (tstAY == 0)
        {
          quadA = -1;
        }
      else if (tstAY > 0)
        {
          quadA = 4;
        }
    }
  else if (tstAX > 0)
    {
      if (tstAY < 0)
        {
          quadA = 1;
        }
      else if (tstAY == 0)
        {
          quadA = 2;
        }
      else if (tstAY > 0)
        {
          quadA = 3;
        }
    }
  if (tstBX < 0)
    {
      if (tstBY < 0)
        {
          quadB = 7;
        }
      else if (tstBY == 0)
        {
          quadB = 6;
        }
      else if (tstBY > 0)
        {
          quadB = 5;
        }
    }
  else if (tstBX == 0)
    {
      if (tstBY < 0)
        {
          quadB = 0;
        }
      else if (tstBY == 0)
        {
          quadB = -1;
        }
      else if (tstBY > 0)
        {
          quadB = 4;
        }
    }
  else if (tstBX > 0)
    {
      if (tstBY < 0)
        {
          quadB = 1;
        }
      else if (tstBY == 0)
        {
          quadB = 2;
        }
      else if (tstBY > 0)
        {
          quadB = 3;
        }
    }
  if (quadA < quadB)
    return 1;
  if (quadA > quadB)
    return -1;

  Geom::Point av, bv;
  av = ax;
  bv = bx;
  double si = cross (bv, av);
  int tstSi = 0;
  if (si > 0.000001) tstSi = 1;
  if (si < -0.000001) tstSi = -1;
  if ( tstSi == 0 ) {
    if ( as == true && bs == false ) return -1;
    if ( as == false && bs == true ) return 1;
  }
  return tstSi;
}

void Shape::ConnectEnd ( int  p,
int  b 
)

Definition at line 1878 of file Shape.cpp.

References _aretes, _pts, DisconnectEnd(), FIRST, getEdge(), getPoint(), Shape::dg_point::incidentEdge, and LAST.

Referenced by AddEdge(), and Path::Fill().

{
  if (getEdge(b).en >= 0)
    DisconnectEnd (b);
  _aretes[b].en = p;
  _pts[p].dI++;
  _aretes[b].nextE = -1;
  _aretes[b].prevE = getPoint(p).incidentEdge[LAST];
  if (getPoint(p).incidentEdge[LAST] >= 0)
    {
      if (getEdge(getPoint(p).incidentEdge[LAST]).st == p)
        {
          _aretes[getPoint(p).incidentEdge[LAST]].nextS = b;
        }
      else if (getEdge(getPoint(p).incidentEdge[LAST]).en == p)
        {
          _aretes[getPoint(p).incidentEdge[LAST]].nextE = b;
        }
    }
  _pts[p].incidentEdge[LAST] = b;
  if (getPoint(p).incidentEdge[FIRST] < 0)
    _pts[p].incidentEdge[FIRST] = b;
}

void Shape::ConnectStart ( int  p,
int  b 
)

Definition at line 1852 of file Shape.cpp.

References _aretes, _pts, DisconnectStart(), FIRST, getEdge(), getPoint(), Shape::dg_point::incidentEdge, and LAST.

Referenced by AddEdge(), and Path::Fill().

{
  if (getEdge(b).st >= 0)
    DisconnectStart (b);
  
  _aretes[b].st = p;
  _pts[p].dO++;
  _aretes[b].nextS = -1;
  _aretes[b].prevS = getPoint(p).incidentEdge[LAST];
  if (getPoint(p).incidentEdge[LAST] >= 0)
    {
      if (getEdge(getPoint(p).incidentEdge[LAST]).st == p)
        {
          _aretes[getPoint(p).incidentEdge[LAST]].nextS = b;
        }
      else if (getEdge(getPoint(p).incidentEdge[LAST]).en == p)
        {
          _aretes[getPoint(p).incidentEdge[LAST]].nextE = b;
        }
    }
  _pts[p].incidentEdge[LAST] = b;
  if (getPoint(p).incidentEdge[FIRST] < 0)
    _pts[p].incidentEdge[FIRST] = b;
}

void Shape::ConvertToForme ( Path dest  ) 

Definition at line 38 of file ShapeMisc.cpp.

References Path::Close(), CycleNextAt(), eData, Shape::dg_arete::en, getEdge(), getPoint(), Barcode::Code39Ext::i, Shape::dg_point::incidentEdge, Path::LineTo(), MakeEdgeData(), MakePointData(), MakeSweepDestData(), Path::MoveTo(), NextAt(), numberOfEdges(), numberOfPoints(), pData, Path::Reset(), Round(), SortEdges(), Shape::dg_arete::st, swdData, and voronoi::x.

Referenced by ConvertToForme(), ConvertToFormeNested(), do_trace(), item_outline(), refresh_offset_source(), sp_offset_set_shape(), sp_selected_path_boolop(), sp_selected_path_create_offset_object(), sp_selected_path_do_offset(), sp_selected_path_outline(), and sp_tweak_dilate_recursive().

{
  if (numberOfPoints() <= 1 || numberOfEdges() <= 1)
    return;
  
  // prepare
  dest->Reset ();
  
  MakePointData (true);
  MakeEdgeData (true);
  MakeSweepDestData (true);
  
  for (int i = 0; i < numberOfPoints(); i++)
  {
    pData[i].rx[0] = Round (getPoint(i).x[0]);
    pData[i].rx[1] = Round (getPoint(i).x[1]);
  }
  for (int i = 0; i < numberOfEdges(); i++)
  {
    eData[i].rdx = pData[getEdge(i).en].rx - pData[getEdge(i).st].rx;
  }
  
  // sort edge clockwise, with the closest after midnight being first in the doubly-linked list
  // that's vital to the algorithm...
  SortEdges ();
  
  // depth-first search implies: we make a stack of edges traversed.
  // precParc: previous in the stack
  // suivParc: next in the stack
  for (int i = 0; i < numberOfEdges(); i++)
  {
    swdData[i].misc = 0;
    swdData[i].precParc = swdData[i].suivParc = -1;
  }
  
  int searchInd = 0;
  
  int lastPtUsed = 0;
  do
  {
    // first get a starting point, and a starting edge
    // -> take the upper left point, and take its first edge
    // points traversed have swdData[].misc != 0, so it's easy
    int startBord = -1;
    {
      int fi = 0;
      for (fi = lastPtUsed; fi < numberOfPoints(); fi++)
      {
        if (getPoint(fi).incidentEdge[FIRST] >= 0 && swdData[getPoint(fi).incidentEdge[FIRST]].misc == 0)
          break;
      }
      lastPtUsed = fi + 1;
      if (fi < numberOfPoints())
      {
        int bestB = getPoint(fi).incidentEdge[FIRST];
        while (bestB >= 0 && getEdge(bestB).st != fi)
          bestB = NextAt (fi, bestB);
        if (bestB >= 0)
          {
          startBord = bestB;
          dest->MoveTo (getPoint(getEdge(startBord).en).x);
          }
      }
    }
    // and walk the graph, doing contours when needed
    if (startBord >= 0)
    {
      // parcours en profondeur pour mettre les leF et riF a leurs valeurs
      swdData[startBord].misc = (void *) 1;
      //                      printf("part de %d\n",startBord);
      int curBord = startBord;
      bool back = false;
      swdData[curBord].precParc = -1;
      swdData[curBord].suivParc = -1;
      do
        {
          int cPt = getEdge(curBord).en;
          int nb = curBord;
        //                              printf("de curBord= %d au point %i  -> ",curBord,cPt);
        // get next edge
          do
        {
          int nnb = CycleNextAt (cPt, nb);
          if (nnb == nb)
          {
            // cul-de-sac
            nb = -1;
            break;
          }
          nb = nnb;
          if (nb < 0 || nb == curBord)
            break;
        }
          while (swdData[nb].misc != 0 || getEdge(nb).st != cPt);
        
          if (nb < 0 || nb == curBord)
        {
          // no next edge: end of this contour, we get back
          if (back == false)
            dest->Close ();
          back = true;
          // retour en arriere
          curBord = swdData[curBord].precParc;
          //                                      printf("retour vers %d\n",curBord);
          if (curBord < 0)
            break;
        }
          else
        {
          // new edge, maybe for a new contour
          if (back)
          {
            // we were backtracking, so if we have a new edge, that means we're creating a new contour
            dest->MoveTo (getPoint(cPt).x);
            back = false;
          }
          swdData[nb].misc = (void *) 1;
          swdData[nb].ind = searchInd++;
          swdData[nb].precParc = curBord;
          swdData[curBord].suivParc = nb;
          curBord = nb;
          //                                      printf("suite %d\n",curBord);
          {
            // add that edge
            dest->LineTo (getPoint(getEdge(nb).en).x);
          }
        }
        }
      while (1 /*swdData[curBord].precParc >= 0 */ );
      // fin du cas non-oriente
    }
  }
  while (lastPtUsed < numberOfPoints());
  
  MakePointData (false);
  MakeEdgeData (false);
  MakeSweepDestData (false);
}

void Shape::ConvertToForme ( Path dest,
int  nbP,
Path **  orig,
bool  splitWhenForced = false 
)

Definition at line 181 of file ShapeMisc.cpp.

References _has_back_data, AddContour(), ConvertToForme(), CycleNextAt(), eData, Shape::dg_arete::en, getEdge(), getPoint(), Barcode::Code39Ext::i, Shape::dg_point::incidentEdge, MakeEdgeData(), MakePointData(), MakeSweepDestData(), NextAt(), numberOfEdges(), numberOfPoints(), pData, Path::Reset(), Round(), SortEdges(), Shape::dg_arete::st, swdData, and voronoi::x.

{
  if (numberOfPoints() <= 1 || numberOfEdges() <= 1)
    return;
//  if (Eulerian (true) == false)
//    return;
  
  if (_has_back_data == false)
  {
    ConvertToForme (dest);
    return;
  }
  
  dest->Reset ();
  
  MakePointData (true);
  MakeEdgeData (true);
  MakeSweepDestData (true);
  
  for (int i = 0; i < numberOfPoints(); i++)
  {
    pData[i].rx[0] = Round (getPoint(i).x[0]);
    pData[i].rx[1] = Round (getPoint(i).x[1]);
  }
  for (int i = 0; i < numberOfEdges(); i++)
  {
    eData[i].rdx = pData[getEdge(i).en].rx - pData[getEdge(i).st].rx;
  }
  
  SortEdges ();
  
  for (int i = 0; i < numberOfEdges(); i++)
  {
    swdData[i].misc = 0;
    swdData[i].precParc = swdData[i].suivParc = -1;
  }
  
  int searchInd = 0;
  
  int lastPtUsed = 0;
  do
  {
    int startBord = -1;
    {
      int fi = 0;
      for (fi = lastPtUsed; fi < numberOfPoints(); fi++)
      {
        if (getPoint(fi).incidentEdge[FIRST] >= 0 && swdData[getPoint(fi).incidentEdge[FIRST]].misc == 0)
          break;
      }
      lastPtUsed = fi + 1;
      if (fi < numberOfPoints())
      {
        int bestB = getPoint(fi).incidentEdge[FIRST];
        while (bestB >= 0 && getEdge(bestB).st != fi)
          bestB = NextAt (fi, bestB);
        if (bestB >= 0)
          {
          startBord = bestB;
          }
      }
    }
    if (startBord >= 0)
    {
      // parcours en profondeur pour mettre les leF et riF a leurs valeurs
      swdData[startBord].misc = (void *) 1;
      //printf("part de %d\n",startBord);
      int curBord = startBord;
      bool back = false;
      swdData[curBord].precParc = -1;
      swdData[curBord].suivParc = -1;
      int curStartPt=getEdge(curBord).st;
      do
        {
          int cPt = getEdge(curBord).en;
          int nb = curBord;
        //printf("de curBord= %d au point %i  -> ",curBord,cPt);
          do
        {
          int nnb = CycleNextAt (cPt, nb);
          if (nnb == nb)
          {
            // cul-de-sac
            nb = -1;
            break;
          }
          nb = nnb;
          if (nb < 0 || nb == curBord)
            break;
        }
          while (swdData[nb].misc != 0 || getEdge(nb).st != cPt);
        
          if (nb < 0 || nb == curBord)
        {
          if (back == false)
          {
            if (curBord == startBord || curBord < 0)
            {
              // probleme -> on vire le moveto
              //                                                      dest->descr_nb--;
            }
            else
            {
              swdData[curBord].suivParc = -1;
              AddContour (dest, nbP, orig, startBord, curBord,splitWhenForced);
            }
            //                                              dest->Close();
          }
          back = true;
          // retour en arriere
          curBord = swdData[curBord].precParc;
          //printf("retour vers %d\n",curBord);
          if (curBord < 0)
            break;
        }
          else
        {
          if (back)
          {
            back = false;
            startBord = nb;
            curStartPt=getEdge(nb).st;
          } else {
            if ( getEdge(curBord).en == curStartPt ) {
              //printf("contour %i ",curStartPt);
              swdData[curBord].suivParc = -1;
              AddContour (dest, nbP, orig, startBord, curBord,splitWhenForced);
              startBord=nb;
            }
          }
          swdData[nb].misc = (void *) 1;
          swdData[nb].ind = searchInd++;
          swdData[nb].precParc = curBord;
          swdData[curBord].suivParc = nb;
          curBord = nb;
          //printf("suite %d\n",curBord);
        }
        }
      while (1 /*swdData[curBord].precParc >= 0 */ );
      // fin du cas non-oriente
    }
  }
  while (lastPtUsed < numberOfPoints());
  
  MakePointData (false);
  MakeEdgeData (false);
  MakeSweepDestData (false);
}

void Shape::ConvertToFormeNested ( Path dest,
int  nbP,
Path **  orig,
int  wildPath,
int &  nbNest,
int *&  nesting,
int *&  contStart,
bool  splitWhenForced = false 
)

Definition at line 330 of file ShapeMisc.cpp.

References _has_back_data, AddContour(), ConvertToForme(), CycleNextAt(), Path::descr_cmd, ebData, eData, Shape::dg_arete::en, getEdge(), getPoint(), Barcode::Code39Ext::i, Shape::dg_point::incidentEdge, MakeEdgeData(), MakePointData(), MakeSweepDestData(), NextAt(), numberOfEdges(), numberOfPoints(), pData, Path::Reset(), Round(), SortEdges(), Shape::dg_arete::st, swdData, and voronoi::x.

Referenced by sp_selected_path_boolop().

{
  nesting=NULL;
  contStart=NULL;
  nbNest=0;

  if (numberOfPoints() <= 1 || numberOfEdges() <= 1)
    return;
  //  if (Eulerian (true) == false)
  //    return;
  
  if (_has_back_data == false)
  {
    ConvertToForme (dest);
    return;
  }
  
  dest->Reset ();
  
//  MakePointData (true);
  MakeEdgeData (true);
  MakeSweepDestData (true);
  
  for (int i = 0; i < numberOfPoints(); i++)
  {
    pData[i].rx[0] = Round (getPoint(i).x[0]);
    pData[i].rx[1] = Round (getPoint(i).x[1]);
  }
  for (int i = 0; i < numberOfEdges(); i++)
  {
    eData[i].rdx = pData[getEdge(i).en].rx - pData[getEdge(i).st].rx;
  }
  
  SortEdges ();
  
  for (int i = 0; i < numberOfEdges(); i++)
  {
    swdData[i].misc = 0;
    swdData[i].precParc = swdData[i].suivParc = -1;
  }
  
  int searchInd = 0;
  
  int lastPtUsed = 0;
  do
  {
    int dadContour=-1;
    int startBord = -1;
    {
      int fi = 0;
      for (fi = lastPtUsed; fi < numberOfPoints(); fi++)
      {
        if (getPoint(fi).incidentEdge[FIRST] >= 0 && swdData[getPoint(fi).incidentEdge[FIRST]].misc == 0)
          break;
      }
      {
        int askTo = pData[fi].askForWindingB;
        if (askTo < 0 || askTo >= numberOfEdges() ) {
          dadContour=-1;
        } else {
          dadContour = GPOINTER_TO_INT(swdData[askTo].misc);
          dadContour-=1; // pour compenser le decalage
        }
      }
      lastPtUsed = fi + 1;
      if (fi < numberOfPoints())
      {
        int bestB = getPoint(fi).incidentEdge[FIRST];
        while (bestB >= 0 && getEdge(bestB).st != fi)
          bestB = NextAt (fi, bestB);
        if (bestB >= 0)
          {
          startBord = bestB;
          }
      }
    }
    if (startBord >= 0)
    {
      // parcours en profondeur pour mettre les leF et riF a leurs valeurs
      swdData[startBord].misc = (void *) (1+nbNest);
      //printf("part de %d\n",startBord);
      int curBord = startBord;
      bool back = false;
      swdData[curBord].precParc = -1;
      swdData[curBord].suivParc = -1;
      int curStartPt=getEdge(curBord).st;
      do
        {
          int cPt = getEdge(curBord).en;
          int nb = curBord;
        //printf("de curBord= %d au point %i  -> ",curBord,cPt);
          do
        {
          int nnb = CycleNextAt (cPt, nb);
          if (nnb == nb)
          {
            // cul-de-sac
            nb = -1;
            break;
          }
          nb = nnb;
          if (nb < 0 || nb == curBord)
            break;
        }
          while (swdData[nb].misc != 0 || getEdge(nb).st != cPt);
        
          if (nb < 0 || nb == curBord)
        {
          if (back == false)
          {
            if (curBord == startBord || curBord < 0)
            {
              // probleme -> on vire le moveto
              //                                                      dest->descr_nb--;
            }
            else
            {
              bool escapePath=false;
              int tb=curBord;
              while ( tb >= 0 && tb < numberOfEdges() ) {
                if ( ebData[tb].pathID == wildPath ) {
                  escapePath=true;
                  break;
                }
                tb=swdData[tb].precParc;
              }
              nesting=(int*)g_realloc(nesting,(nbNest+1)*sizeof(int));
              contStart=(int*)g_realloc(contStart,(nbNest+1)*sizeof(int));
              contStart[nbNest]=dest->descr_cmd.size();
              if ( escapePath ) {
                nesting[nbNest++]=-1; // contient des bouts de coupure -> a part
              } else {
                nesting[nbNest++]=dadContour;
              }
              swdData[curBord].suivParc = -1;
              AddContour (dest, nbP, orig, startBord, curBord,splitWhenForced);
            }
            //                                              dest->Close();
          }
          back = true;
          // retour en arriere
          curBord = swdData[curBord].precParc;
          //printf("retour vers %d\n",curBord);
          if (curBord < 0)
            break;
        }
          else
        {
          if (back)
          {
            back = false;
            startBord = nb;
            curStartPt=getEdge(nb).st;
          } else {
            if ( getEdge(curBord).en == curStartPt ) {
              //printf("contour %i ",curStartPt);
              
              bool escapePath=false;
              int tb=curBord;
              while ( tb >= 0 && tb < numberOfEdges() ) {
                if ( ebData[tb].pathID == wildPath ) {
                  escapePath=true;
                  break;
                }
                tb=swdData[tb].precParc;
              }
              nesting=(int*)g_realloc(nesting,(nbNest+1)*sizeof(int));
              contStart=(int*)g_realloc(contStart,(nbNest+1)*sizeof(int));
              contStart[nbNest]=dest->descr_cmd.size();
              if ( escapePath ) {
                nesting[nbNest++]=-1; // contient des bouts de coupure -> a part
              } else {
                nesting[nbNest++]=dadContour;
              }

              swdData[curBord].suivParc = -1;
              AddContour (dest, nbP, orig, startBord, curBord,splitWhenForced);
              startBord=nb;
            }
          }
          swdData[nb].misc = (void *) (1+nbNest);
          swdData[nb].ind = searchInd++;
          swdData[nb].precParc = curBord;
          swdData[curBord].suivParc = nb;
          curBord = nb;
          //printf("suite %d\n",curBord);
        }
        }
      while (1 /*swdData[curBord].precParc >= 0 */ );
      // fin du cas non-oriente
    }
  }
  while (lastPtUsed < numberOfPoints());
  
  MakePointData (false);
  MakeEdgeData (false);
  MakeSweepDestData (false);
}

int Shape::ConvertToShape ( Shape a,
FillRule  directed = fill_nonZero,
bool  invert = false 
)

Definition at line 168 of file ShapeSweep.cpp.

References _has_back_data, _need_edges_sorting, _pts, SweepTreeList::add(), AddChgt(), AddPoint(), AssembleAretes(), AssemblePoints(), bool_op_union, SweepTree::bord, CheckAdjacencies(), CheckEdges(), chgts, CleanupSweep(), clearIncidenceData(), SweepTree::ConvertTo(), Shape::dg_point::dI, directedEulerian(), Shape::dg_point::dO, eData, EDGE_INSERTED, EDGE_REMOVED, AVLTree::elem, Shape::dg_arete::en, SweepEventQueue::extract(), fill_justDont, fill_nonZero, fill_oddEven, fill_positive, getEdge(), getPoint(), GetWindings(), Barcode::Code39Ext::i, Shape::dg_point::incidentEdge, initialiseEdgeData(), initialisePointData(), SweepTree::Insert(), SweepTree::InsertAt(), INTERSECTION, Inverse(), LEFT, MakeBackData(), MakeEdgeData(), MakePointData(), MakeSweepDestData(), MakeSweepSrcData(), NextAt(), NULL, numberOfEdges(), numberOfPoints(), pData, SweepEventQueue::peek(), SweepTree::Remove(), SweepTree::RemoveEvent(), SweepTree::RemoveEvents(), Reset(), ResetSweep(), RIGHT, Round(), sEvts, SweepEventQueue::size(), SortEdges(), SortPointsRounded(), SweepTree::src, Shape::dg_arete::st, sTree, SubEdge(), SweepTree::SwapWithRight(), swdData, SweepEventQueue, swsData, TesteIntersection(), Shape::dg_point::totalDegree(), and type.

Referenced by do_trace(), GetDest(), item_outline(), raster_font::LoadRasterGlyph(), nr_arena_shape_update_fill(), nr_arena_shape_update_stroke(), refresh_offset_source(), Inkscape::Text::Layout::ShapeScanlineMaker::ShapeScanlineMaker(), sp_offset_distance_to_original(), sp_offset_set_shape(), sp_selected_path_boolop(), sp_selected_path_create_offset_object(), sp_selected_path_do_offset(), sp_selected_path_outline(), and sp_tweak_dilate_recursive().

{
    Reset (0, 0);

    if (a->numberOfPoints() <= 1 || a->numberOfEdges() <= 1) {
    return 0;
    }
    
    if ( directed != fill_justDont && directedEulerian(a) == false ) {
            g_warning ("Shape error in ConvertToShape: directedEulerian(a) == false\n");
                return shape_input_err;
    }
  
    a->ResetSweep();

    if (sTree == NULL) {
    sTree = new SweepTreeList(a->numberOfEdges());
    }
    if (sEvts == NULL) {
    sEvts = new SweepEventQueue(a->numberOfEdges());
    }
  
    MakePointData(true);
    MakeEdgeData(true);
    MakeSweepSrcData(true);
    MakeSweepDestData(true);
    MakeBackData(a->_has_back_data);

    a->initialisePointData();
    a->initialiseEdgeData();

    a->SortPointsRounded();

    chgts.clear();

    double lastChange = a->pData[0].rx[1] - 1.0;
    int lastChgtPt = 0;
    int edgeHead = -1;
    Shape *shapeHead = NULL;

    clearIncidenceData();
    
    int curAPt = 0;

    while (curAPt < a->numberOfPoints() || sEvts->size() > 0) {
    Geom::Point ptX;
      double ptL, ptR;
      SweepTree *intersL = NULL;
      SweepTree *intersR = NULL;
      int nPt = -1;
      Shape *ptSh = NULL;
      bool isIntersection = false;
      if (sEvts->peek(intersL, intersR, ptX, ptL, ptR))
    {
      if (a->pData[curAPt].pending > 0
          || (a->pData[curAPt].rx[1] > ptX[1]
          || (a->pData[curAPt].rx[1] == ptX[1]
              && a->pData[curAPt].rx[0] > ptX[0])))
        {
          /* FIXME: could just be pop? */
          sEvts->extract(intersL, intersR, ptX, ptL, ptR);
          isIntersection = true;
        }
      else
        {
          nPt = curAPt++;
          ptSh = a;
          ptX = ptSh->pData[nPt].rx;
          isIntersection = false;
        }
    }
      else
    {
      nPt = curAPt++;
      ptSh = a;
      ptX = ptSh->pData[nPt].rx;
      isIntersection = false;
    }

      if (isIntersection == false)
    {
      if (ptSh->getPoint(nPt).dI == 0 && ptSh->getPoint(nPt).dO == 0)
        continue;
    }

      Geom::Point rPtX;
      rPtX[0]= Round (ptX[0]);
      rPtX[1]= Round (ptX[1]);
      int lastPointNo = -1;
      lastPointNo = AddPoint (rPtX);
      pData[lastPointNo].rx = rPtX;

      if (rPtX[1] > lastChange)
    {
      int lastI = AssemblePoints (lastChgtPt, lastPointNo);

      Shape *curSh = shapeHead;
      int curBo = edgeHead;
      while (curSh)
        {
          curSh->swsData[curBo].leftRnd =
        pData[curSh->swsData[curBo].leftRnd].newInd;
          curSh->swsData[curBo].rightRnd =
        pData[curSh->swsData[curBo].rightRnd].newInd;

          Shape *neSh = curSh->swsData[curBo].nextSh;
          curBo = curSh->swsData[curBo].nextBo;
          curSh = neSh;
        }

      for (unsigned int i = 0; i < chgts.size(); i++)
        {
          chgts[i].ptNo = pData[chgts[i].ptNo].newInd;
          if (chgts[i].type == 0)
        {
          if (chgts[i].src->getEdge(chgts[i].bord).st <
              chgts[i].src->getEdge(chgts[i].bord).en)
            {
              chgts[i].src->swsData[chgts[i].bord].stPt =
            chgts[i].ptNo;
            }
          else
            {
              chgts[i].src->swsData[chgts[i].bord].enPt =
            chgts[i].ptNo;
            }
        }
          else if (chgts[i].type == 1)
        {
          if (chgts[i].src->getEdge(chgts[i].bord).st >
              chgts[i].src->getEdge(chgts[i].bord).en)
            {
              chgts[i].src->swsData[chgts[i].bord].stPt =
            chgts[i].ptNo;
            }
          else
            {
              chgts[i].src->swsData[chgts[i].bord].enPt =
            chgts[i].ptNo;
            }
        }
        }

      CheckAdjacencies (lastI, lastChgtPt, shapeHead, edgeHead);

      CheckEdges (lastI, lastChgtPt, a, NULL, bool_op_union);

      for (int i = lastChgtPt; i < lastI; i++) {
        if (pData[i].askForWindingS) {
            Shape *windS = pData[i].askForWindingS;
            int windB = pData[i].askForWindingB;
            pData[i].nextLinkedPoint = windS->swsData[windB].firstLinkedPoint;
            windS->swsData[windB].firstLinkedPoint = i;
          }
       }

    if (lastI < lastPointNo) {
          _pts[lastI] = getPoint(lastPointNo);
       pData[lastI] = pData[lastPointNo];
      }
      lastPointNo = lastI;
      _pts.resize(lastI + 1);

      lastChgtPt = lastPointNo;
      lastChange = rPtX[1];
      chgts.clear();
      edgeHead = -1;
      shapeHead = NULL;
    }


      if (isIntersection)
    {
//                      printf("(%i %i [%i %i]) ",intersL->bord,intersR->bord,intersL->startPoint,intersR->startPoint);
      intersL->RemoveEvent (*sEvts, LEFT);
      intersR->RemoveEvent (*sEvts, RIGHT);

      AddChgt (lastPointNo, lastChgtPt, shapeHead, edgeHead, INTERSECTION,
           intersL->src, intersL->bord, intersR->src, intersR->bord);

      intersL->SwapWithRight (*sTree, *sEvts);

      TesteIntersection (intersL, LEFT, false);
      TesteIntersection (intersR, RIGHT, false);
    }
      else
    {
      int cb;

      int nbUp = 0, nbDn = 0;
      int upNo = -1, dnNo = -1;
      cb = ptSh->getPoint(nPt).incidentEdge[FIRST];
      while (cb >= 0 && cb < ptSh->numberOfEdges())
        {
          if ((ptSh->getEdge(cb).st < ptSh->getEdge(cb).en
           && nPt == ptSh->getEdge(cb).en)
          || (ptSh->getEdge(cb).st > ptSh->getEdge(cb).en
              && nPt == ptSh->getEdge(cb).st))
        {
          upNo = cb;
          nbUp++;
        }
          if ((ptSh->getEdge(cb).st > ptSh->getEdge(cb).en
           && nPt == ptSh->getEdge(cb).en)
          || (ptSh->getEdge(cb).st < ptSh->getEdge(cb).en
              && nPt == ptSh->getEdge(cb).st))
        {
          dnNo = cb;
          nbDn++;
        }
          cb = ptSh->NextAt (nPt, cb);
        }

      if (nbDn <= 0)
        {
          upNo = -1;
        }
      if (upNo >= 0 && (SweepTree *) ptSh->swsData[upNo].misc == NULL)
        {
          upNo = -1;
        }

      bool doWinding = true;

      if (nbUp > 0)
        {
          cb = ptSh->getPoint(nPt).incidentEdge[FIRST];
          while (cb >= 0 && cb < ptSh->numberOfEdges())
        {
          if ((ptSh->getEdge(cb).st < ptSh->getEdge(cb).en
               && nPt == ptSh->getEdge(cb).en)
              || (ptSh->getEdge(cb).st > ptSh->getEdge(cb).en
              && nPt == ptSh->getEdge(cb).st))
            {
              if (cb != upNo)
            {
              SweepTree *node =
                (SweepTree *) ptSh->swsData[cb].misc;
              if (node == NULL)
                {
                }
              else
                {
                  AddChgt (lastPointNo, lastChgtPt, shapeHead,
                       edgeHead, EDGE_REMOVED, node->src, node->bord,
                       NULL, -1);
                  ptSh->swsData[cb].misc = NULL;

                  int onLeftB = -1, onRightB = -1;
                  Shape *onLeftS = NULL;
                  Shape *onRightS = NULL;
                  if (node->elem[LEFT])
                {
                  onLeftB =
                    (static_cast <
                     SweepTree * >(node->elem[LEFT]))->bord;
                  onLeftS =
                    (static_cast <
                     SweepTree * >(node->elem[LEFT]))->src;
                }
                  if (node->elem[RIGHT])
                {
                  onRightB =
                    (static_cast <
                     SweepTree * >(node->elem[RIGHT]))->bord;
                  onRightS =
                    (static_cast <
                     SweepTree * >(node->elem[RIGHT]))->src;
                }

                  node->Remove (*sTree, *sEvts, true);
                  if (onLeftS && onRightS)
                {
                  SweepTree *onLeft =
                    (SweepTree *) onLeftS->swsData[onLeftB].
                    misc;
                  if (onLeftS == ptSh
                      && (onLeftS->getEdge(onLeftB).en == nPt
                      || onLeftS->getEdge(onLeftB).st ==
                      nPt))
                    {
                    }
                  else
                    {
                      if (onRightS == ptSh
                      && (onRightS->getEdge(onRightB).en ==
                          nPt
                          || onRightS->getEdge(onRightB).
                          st == nPt))
                    {
                    }
                      else
                    {
                      TesteIntersection (onLeft, RIGHT, false);
                    }
                    }
                }
                }
            }
            }
          cb = ptSh->NextAt (nPt, cb);
        }
        }

      // traitement du "upNo devient dnNo"
      SweepTree *insertionNode = NULL;
      if (dnNo >= 0)
        {
          if (upNo >= 0)
        {
          SweepTree *node = (SweepTree *) ptSh->swsData[upNo].misc;

          AddChgt (lastPointNo, lastChgtPt, shapeHead, edgeHead, EDGE_REMOVED,
               node->src, node->bord, NULL, -1);

          ptSh->swsData[upNo].misc = NULL;

          node->RemoveEvents (*sEvts);
          node->ConvertTo (ptSh, dnNo, 1, lastPointNo);
          ptSh->swsData[dnNo].misc = node;
          TesteIntersection (node, RIGHT, false);
          TesteIntersection (node, LEFT, false);
          insertionNode = node;

          ptSh->swsData[dnNo].curPoint = lastPointNo;
          AddChgt (lastPointNo, lastChgtPt, shapeHead, edgeHead, EDGE_INSERTED,
               node->src, node->bord, NULL, -1);
        }
          else
        {
          SweepTree *node = sTree->add(ptSh, dnNo, 1, lastPointNo, this);
          ptSh->swsData[dnNo].misc = node;
          node->Insert (*sTree, *sEvts, this, lastPointNo, true);
          if (doWinding)
            {
              SweepTree *myLeft =
            static_cast < SweepTree * >(node->elem[LEFT]);
              if (myLeft)
            {
              pData[lastPointNo].askForWindingS = myLeft->src;
              pData[lastPointNo].askForWindingB = myLeft->bord;
            }
              else
            {
              pData[lastPointNo].askForWindingB = -1;
            }
              doWinding = false;
            }
          TesteIntersection (node, RIGHT, false);
          TesteIntersection (node, LEFT, false);
          insertionNode = node;

          ptSh->swsData[dnNo].curPoint = lastPointNo;
          AddChgt (lastPointNo, lastChgtPt, shapeHead, edgeHead, EDGE_INSERTED,
               node->src, node->bord, NULL, -1);
        }
        }

      if (nbDn > 1)
        {           // si nbDn == 1 , alors dnNo a deja ete traite
          cb = ptSh->getPoint(nPt).incidentEdge[FIRST];
          while (cb >= 0 && cb < ptSh->numberOfEdges())
        {
          if ((ptSh->getEdge(cb).st > ptSh->getEdge(cb).en
               && nPt == ptSh->getEdge(cb).en)
              || (ptSh->getEdge(cb).st < ptSh->getEdge(cb).en
              && nPt == ptSh->getEdge(cb).st))
            {
              if (cb != dnNo)
            {
              SweepTree *node = sTree->add(ptSh, cb, 1, lastPointNo, this);
              ptSh->swsData[cb].misc = node;
              node->InsertAt (*sTree, *sEvts, this, insertionNode,
                      nPt, true);
              if (doWinding)
                {
                  SweepTree *myLeft =
                static_cast < SweepTree * >(node->elem[LEFT]);
                  if (myLeft)
                {
                  pData[lastPointNo].askForWindingS =
                    myLeft->src;
                  pData[lastPointNo].askForWindingB =
                    myLeft->bord;
                }
                  else
                {
                  pData[lastPointNo].askForWindingB = -1;
                }
                  doWinding = false;
                }
              TesteIntersection (node, RIGHT, false);
              TesteIntersection (node, LEFT, false);

              ptSh->swsData[cb].curPoint = lastPointNo;
              AddChgt (lastPointNo, lastChgtPt, shapeHead,
                   edgeHead, EDGE_INSERTED, node->src, node->bord, NULL,
                   -1);
            }
            }
          cb = ptSh->NextAt (nPt, cb);
        }
        }
    }
    }
  {
    int lastI = AssemblePoints (lastChgtPt, numberOfPoints());


    Shape *curSh = shapeHead;
    int curBo = edgeHead;
    while (curSh)
      {
    curSh->swsData[curBo].leftRnd =
      pData[curSh->swsData[curBo].leftRnd].newInd;
    curSh->swsData[curBo].rightRnd =
      pData[curSh->swsData[curBo].rightRnd].newInd;

    Shape *neSh = curSh->swsData[curBo].nextSh;
    curBo = curSh->swsData[curBo].nextBo;
    curSh = neSh;
      }

    for (unsigned int i = 0; i < chgts.size(); i++)
      {
    chgts[i].ptNo = pData[chgts[i].ptNo].newInd;
    if (chgts[i].type == 0)
      {
        if (chgts[i].src->getEdge(chgts[i].bord).st <
        chgts[i].src->getEdge(chgts[i].bord).en)
          {
        chgts[i].src->swsData[chgts[i].bord].stPt = chgts[i].ptNo;
          }
        else
          {
        chgts[i].src->swsData[chgts[i].bord].enPt = chgts[i].ptNo;
          }
      }
    else if (chgts[i].type == 1)
      {
        if (chgts[i].src->getEdge(chgts[i].bord).st >
        chgts[i].src->getEdge(chgts[i].bord).en)
          {
        chgts[i].src->swsData[chgts[i].bord].stPt = chgts[i].ptNo;
          }
        else
          {
        chgts[i].src->swsData[chgts[i].bord].enPt = chgts[i].ptNo;
          }
      }
      }

    CheckAdjacencies (lastI, lastChgtPt, shapeHead, edgeHead);

    CheckEdges (lastI, lastChgtPt, a, NULL, bool_op_union);

    for (int i = lastChgtPt; i < lastI; i++)
      {
    if (pData[i].askForWindingS)
      {
        Shape *windS = pData[i].askForWindingS;
        int windB = pData[i].askForWindingB;
        pData[i].nextLinkedPoint = windS->swsData[windB].firstLinkedPoint;
        windS->swsData[windB].firstLinkedPoint = i;
      }
      }

    _pts.resize(lastI);

    edgeHead = -1;
    shapeHead = NULL;
  }

    chgts.clear();

//  Plot (98.0, 112.0, 8.0, 400.0, 400.0, true, true, true, true);
//      Plot(200.0,200.0,2.0,400.0,400.0,true,true,true,true);

  //      AssemblePoints(a);

//      GetAdjacencies(a);

//      MakeAretes(a);
    clearIncidenceData();

  AssembleAretes (directed);

//  Plot (98.0, 112.0, 8.0, 400.0, 400.0, true, true, true, true);

  for (int i = 0; i < numberOfPoints(); i++)
    {
      _pts[i].oldDegree = getPoint(i).totalDegree();
    }
//      Validate();

  _need_edges_sorting = true;
  if ( directed == fill_justDont ) {
    SortEdges();
  } else {
    GetWindings (a);
  }
//  Plot (98.0, 112.0, 8.0, 400.0, 400.0, true, true, true, true);
//   if ( doDebug ) {
//   a->CalcBBox();
//     a->Plot(a->leftX,a->topY,32.0,0.0,0.0,true,true,true,true,"orig.svg");
//     Plot(a->leftX,a->topY,32.0,0.0,0.0,true,true,true,true,"winded.svg");
//   }
  if (directed == fill_positive)
  {
    if (invert)
    {
      for (int i = 0; i < numberOfEdges(); i++)
        {
          if (swdData[i].leW < 0 && swdData[i].riW >= 0)
        {
          eData[i].weight = 1;
        }
          else if (swdData[i].leW >= 0 && swdData[i].riW < 0)
        {
          Inverse (i);
          eData[i].weight = 1;
        }
          else
        {
          eData[i].weight = 0;
          SubEdge (i);
          i--;
        }
        }
    }
    else
    {
      for (int i = 0; i < numberOfEdges(); i++)
        {
          if (swdData[i].leW > 0 && swdData[i].riW <= 0)
        {
          eData[i].weight = 1;
        }
          else if (swdData[i].leW <= 0 && swdData[i].riW > 0)
        {
          Inverse (i);
          eData[i].weight = 1;
        }
          else
        {
           eData[i].weight = 0;
          SubEdge (i);
          i--;
        }
        }
    }
  }
  else if (directed == fill_nonZero)
  {
    if (invert)
    {
      for (int i = 0; i < numberOfEdges(); i++)
        {
          if (swdData[i].leW < 0 && swdData[i].riW == 0)
        {
          eData[i].weight = 1;
        }
          else if (swdData[i].leW > 0 && swdData[i].riW == 0)
        {
          eData[i].weight = 1;
        }
          else if (swdData[i].leW == 0 && swdData[i].riW < 0)
        {
          Inverse (i);
          eData[i].weight = 1;
        }
          else if (swdData[i].leW == 0 && swdData[i].riW > 0)
        {
          Inverse (i);
          eData[i].weight = 1;
        }
          else
        {
          eData[i].weight = 0;
          SubEdge (i);
          i--;
        }
        }
    }
    else
    {
      for (int i = 0; i < numberOfEdges(); i++)
        {
          if (swdData[i].leW > 0 && swdData[i].riW == 0)
        {
          eData[i].weight = 1;
        }
          else if (swdData[i].leW < 0 && swdData[i].riW == 0)
        {
          eData[i].weight = 1;
        }
          else if (swdData[i].leW == 0 && swdData[i].riW > 0)
        {
          Inverse (i);
          eData[i].weight = 1;
        }
          else if (swdData[i].leW == 0 && swdData[i].riW < 0)
        {
          Inverse (i);
          eData[i].weight = 1;
        }
          else
        {
          eData[i].weight = 0;
          SubEdge (i);
          i--;
        }
        }
    }
  }
  else if (directed == fill_oddEven)
  {
    for (int i = 0; i < numberOfEdges(); i++)
    {
      swdData[i].leW %= 2;
      swdData[i].riW %= 2;
      if (swdData[i].leW < 0)
        swdData[i].leW = -swdData[i].leW;
      if (swdData[i].riW < 0)
        swdData[i].riW = -swdData[i].riW;
      if (swdData[i].leW > 0 && swdData[i].riW <= 0)
        {
          eData[i].weight = 1;
        }
      else if (swdData[i].leW <= 0 && swdData[i].riW > 0)
        {
          Inverse (i);
          eData[i].weight = 1;
        }
      else
        {
          eData[i].weight = 0;
          SubEdge (i);
          i--;
        }
    }
  } else if ( directed == fill_justDont ) {
    for (int i=0;i<numberOfEdges();i++) {
      if ( getEdge(i).st < 0 || getEdge(i).en < 0 ) {
        SubEdge(i);
        i--;
      } else {
          eData[i].weight = 0;
      }
    }
  }
  
//      Plot(200.0,200.0,2.0,400.0,400.0,true,true,true,true);

  delete sTree;
  sTree = NULL;
  delete sEvts;
  sEvts = NULL;

  MakePointData (false);
  MakeEdgeData (false);
  MakeSweepSrcData (false);
  MakeSweepDestData (false);
  a->CleanupSweep ();
  type = shape_polygon;
  return 0;
}

void Shape::Copy ( Shape a  ) 

Copy point and edge data from `who' into this object, discarding any cached data that we have.

Definition at line 234 of file Shape.cpp.

References _aretes, _bbox_up_to_date, _has_back_data, _has_edges_data, _has_points_data, _has_quick_raster_data, _has_raster_data, _has_sweep_dest_data, _has_sweep_src_data, _has_voronoi_data, _need_edges_sorting, _need_points_sorting, _point_data_initialised, _pts, MakeBackData(), MakeEdgeData(), MakePointData(), MakeQuickRasterData(), MakeRasterData(), MakeSweepDestData(), MakeSweepSrcData(), NULL, numberOfEdges(), numberOfPoints(), Reset(), sEvts, sTree, and type.

Referenced by SPFlowtext::_buildExclusionShape(), nr_arena_shape_update_fill(), nr_arena_shape_update_stroke(), Inkscape::Text::Layout::ShapeScanlineMaker::ShapeScanlineMaker(), and UnionShape().

{
  if (who == NULL)
    {
      Reset (0, 0);
      return;
    }
  MakePointData (false);
  MakeEdgeData (false);
  MakeSweepSrcData (false);
  MakeSweepDestData (false);
  MakeRasterData (false);
  MakeQuickRasterData (false);
  MakeBackData (false);

  delete sTree;
  sTree = NULL;
  delete sEvts;
  sEvts = NULL;

  Reset (who->numberOfPoints(), who->numberOfEdges());
  type = who->type;
  _need_points_sorting = who->_need_points_sorting;
  _need_edges_sorting = who->_need_edges_sorting;
  _has_points_data = false;
  _point_data_initialised = false;
  _has_edges_data = false;
  _has_sweep_src_data = false;
  _has_sweep_dest_data = false;
  _has_raster_data = false;
  _has_quick_raster_data = false;
  _has_back_data = false;
  _has_voronoi_data = false;
  _bbox_up_to_date = false;

  _pts = who->_pts;
  _aretes = who->_aretes;
}

void Shape::CreateEdge ( int  no,
float  to,
float  step 
) [private]

Definition at line 1622 of file ShapeRaster.cpp.

References Shape::dg_arete::dx, Shape::dg_arete::en, getEdge(), getPoint(), Shape::dg_arete::st, swrData, and Shape::dg_point::x.

Referenced by DirectQuickScan(), DirectScan(), QuickScan(), and Scan().

{
    int cPt;
    Geom::Point dir;
    if ( getEdge(no).st < getEdge(no).en ) {
        cPt = getEdge(no).st;
        swrData[no].sens = true;
        dir = getEdge(no).dx;
    } else {
        cPt = getEdge(no).en;
        swrData[no].sens = false;
        dir = -getEdge(no).dx;
    }

    swrData[no].lastX = swrData[no].curX = getPoint(cPt).x[0];
    swrData[no].lastY = swrData[no].curY = getPoint(cPt).x[1];
    
    if ( fabs(dir[1]) < 0.000001 ) {
        swrData[no].dxdy = 0;
    } else {
        swrData[no].dxdy = dir[0]/dir[1];
    }
    
    if ( fabs(dir[0]) < 0.000001 ) {
        swrData[no].dydx = 0;
    } else {
        swrData[no].dydx = dir[1]/dir[0];
    }
    
    swrData[no].calcX = swrData[no].curX + (to - step - swrData[no].curY) * swrData[no].dxdy;
    swrData[no].guess = -1;
}

int Shape::CreateIncidence ( Shape a,
int  cb,
int  pt 
) [private]

Definition at line 2002 of file ShapeSweep.cpp.

References ffgeom::dot(), eData, getEdge(), getPoint(), pData, PushIncidence(), Shape::dg_arete::st, and Shape::dg_point::x.

{
  Geom::Point adir, diff;
  adir = a->eData[no].rdx;
  diff = getPoint(nPt).x - a->pData[a->getEdge(no).st].rx;
  double t = dot (diff, adir);
  t *= a->eData[no].ilength;
  return PushIncidence (a, no, nPt, t);
}

int Shape::CycleNextAt ( int  p,
int  b 
) const [inline]

Definition at line 189 of file Shape.h.

References getEdge(), getPoint(), Shape::dg_point::incidentEdge, Shape::dg_arete::nextE, and Shape::dg_arete::nextS.

Referenced by ConvertToForme(), ConvertToFormeNested(), MakeOffset(), and MakeTweak().

    {
        if (p == getEdge(b).st) {
            if (getEdge(b).nextS < 0) {
                return getPoint(p).incidentEdge[FIRST];
            }
            return getEdge(b).nextS;
        } else if (p == getEdge(b).en) {
            if (getEdge(b).nextE < 0) {
                return getPoint(p).incidentEdge[FIRST];
            }

            return getEdge(b).nextE;
        }

        return -1;
    }

int Shape::CyclePrevAt ( int  p,
int  b 
) const [inline]

Definition at line 208 of file Shape.h.

References getEdge(), getPoint(), Shape::dg_point::incidentEdge, Shape::dg_arete::prevE, and Shape::dg_arete::prevS.

Referenced by GetWindings(), MakeOffset(), and MakeTweak().

    {
        if (p == getEdge(b).st) {
            if (getEdge(b).prevS < 0) {
                return getPoint(p).incidentEdge[LAST];
            }
            return getEdge(b).prevS;
        } else if (p == getEdge(b).en) {
            if (getEdge(b).prevE < 0) {
                return getPoint(p).incidentEdge[LAST];
            }
            return getEdge(b).prevE;
        }

        return -1;
    }

void Shape::DestroyEdge ( int  no,
float  to,
FloatLigne line 
) [private]

Definition at line 1688 of file ShapeRaster.cpp.

References FloatLigne::AddBord(), FloatLigne::AddBordR(), and swrData.

Referenced by QuickScan(), and Scan().

{
    if ( swrData[no].sens ) {

        if ( swrData[no].curX < swrData[no].lastX ) {

            swrData[no].guess = line->AddBordR(swrData[no].curX,
                                               to - swrData[no].curY,
                                               swrData[no].lastX,
                                               to - swrData[no].lastY,
                                               -swrData[no].dydx,
                                               swrData[no].guess);
            
        } else if ( swrData[no].curX > swrData[no].lastX ) {
            
            swrData[no].guess = line->AddBord(swrData[no].lastX,
                                              -(to - swrData[no].lastY),
                                              swrData[no].curX,
                                              -(to - swrData[no].curY),
                                              swrData[no].dydx,
                                              swrData[no].guess);
        }
        
    } else {
        
        if ( swrData[no].curX < swrData[no].lastX ) {

            swrData[no].guess = line->AddBordR(swrData[no].curX,
                                               -(to - swrData[no].curY),
                                               swrData[no].lastX,
                                               -(to - swrData[no].lastY),
                                               swrData[no].dydx,
                                               swrData[no].guess);
            
        } else if ( swrData[no].curX > swrData[no].lastX ) {
            
            swrData[no].guess = line->AddBord(swrData[no].lastX,
                                              to - swrData[no].lastY,
                                              swrData[no].curX,
                                              to - swrData[no].curY,
                                              -swrData[no].dydx,
                                              swrData[no].guess);
        }
    }
}

void Shape::DestroyEdge ( int  no,
BitLigne line 
) [private]

Definition at line 1785 of file ShapeRaster.cpp.

References BitLigne::AddBord(), and swrData.

{
    if ( swrData[no].sens ) {
        
        if ( swrData[no].curX < swrData[no].lastX ) {
            
            line->AddBord(swrData[no].curX, swrData[no].lastX, false);
            
        } else if ( swrData[no].curX > swrData[no].lastX ) {
            
            line->AddBord(swrData[no].lastX,swrData[no].curX,false);
        }
        
    } else {

    if ( swrData[no].curX < swrData[no].lastX ) {
            
            line->AddBord(swrData[no].curX, swrData[no].lastX, false);
            
        } else if ( swrData[no].curX > swrData[no].lastX ) {
            
            line->AddBord(swrData[no].lastX, swrData[no].curX, false);
            
        }
    }
}

void Shape::DestroyEdge ( int  no,
AlphaLigne line 
) [private]

Definition at line 1842 of file ShapeRaster.cpp.

References AlphaLigne::AddBord(), and swrData.

{
    if ( swrData[no].sens ) {
        
        if ( swrData[no].curX <= swrData[no].lastX ) {

            line->AddBord(swrData[no].curX,
                          0,
                          swrData[no].lastX,
                          swrData[no].curY - swrData[no].lastY,
                          -swrData[no].dydx);
            
        } else if ( swrData[no].curX > swrData[no].lastX ) {
            
            line->AddBord(swrData[no].lastX,
                          0,
                          swrData[no].curX,
                          swrData[no].curY - swrData[no].lastY,
                          swrData[no].dydx);
        }
        
    } else {
        
        if ( swrData[no].curX <= swrData[no].lastX ) {

            line->AddBord(swrData[no].curX,
                          0,
                          swrData[no].lastX,
                          swrData[no].lastY - swrData[no].curY,
                          swrData[no].dydx);

        } else if ( swrData[no].curX > swrData[no].lastX ) {

            line->AddBord(swrData[no].lastX,
                          0,
                          swrData[no].curX,
                          swrData[no].lastY - swrData[no].curY,
                          -swrData[no].dydx);
        }
    }
}

void Shape::DirectQuickScan ( float &  pos,
int &  curP,
float  to,
bool  doSort,
float  step 
)

Definition at line 709 of file ShapeRaster.cpp.

References AvanceEdge(), Shape::quick_raster_data::bord, CreateEdge(), addnodes::e, Shape::dg_arete::en, getEdge(), getPoint(), Barcode::Code39Ext::i, nbQRas, numberOfEdges(), numberOfPoints(), qrsData, QuickRasterAddEdge(), QuickRasterSort(), QuickRasterSubEdge(), Shape::dg_arete::st, swrData, Shape::quick_raster_data::x, Shape::dg_point::x, and voronoi::x.

Referenced by raster_glyph::LoadSubPixelPosition(), and nr_pixblock_render_shape_mask_or().

{
    if ( numberOfEdges() <= 1 ) {
        return;
    }

    if ( pos == to ) {
        return;
    }
    
    if ( pos < to ) {
        // we're moving downwards
        // points of the polygon are sorted top-down, so we take them in order, starting with the one at index curP,
        // until we reach the wanted position to.
        // don't forget to update curP and pos when we're done
        int curPt=curP;
        while ( curPt < numberOfPoints() && getPoint(curPt).x[1] <= to ) {
            curPt++;
        }
        
        for (int i = 0; i < numberOfEdges(); i++) {
            if ( qrsData[i].ind < 0 ) {
                QuickRasterSubEdge(i);
            }
        }
        
        for (int i = 0; i < numberOfEdges(); i++) {
            Shape::dg_arete const &e = getEdge(i);
            if ( ( e.st < curPt && e.en >= curPt ) || ( e.en < curPt && e.st >= curPt )) {
                // crosses sweepline
                int nPt = (e.st < e.en) ? e.st : e.en;
                QuickRasterAddEdge(i, getPoint(nPt).x[0], -1);
                CreateEdge(i, to, step);
            }
        }
    
        curP = curPt;
        if ( curPt > 0 ) {
            pos=getPoint(curPt-1).x[1];
        } else {
            pos = to;
        }
        
    } else {

        // same thing, but going up. so the sweepSens is inverted for the Find() function
        int curPt=curP;
        while ( curPt > 0 && getPoint(curPt-1).x[1] >= to ) {
            curPt--;
        }
    
        for (int i = 0; i < numberOfEdges(); i++) {
            if ( qrsData[i].ind < 0 ) {
                QuickRasterSubEdge(i);
            }
        }
        
        for (int i=0;i<numberOfEdges();i++) {
            Shape::dg_arete const &e = getEdge(i);
            if ( ( e.st < curPt-1 && e.en >= curPt-1 ) || ( e.en < curPt-1 && e.st >= curPt-1 )) {
                // crosses sweepline
                int nPt = (e.st > e.en) ? e.st : e.en;
                QuickRasterAddEdge(i, getPoint(nPt).x[0], -1);
                CreateEdge(i, to, step);
            }
        }
        
        curP = curPt;
        if ( curPt > 0 ) {
            pos = getPoint(curPt-1).x[1];
        } else {
            pos = to;
        }
        
    }
    
    pos = to;
    for (int i = 0; i < nbQRas; i++) {
        int cb = qrsData[i].bord;
        AvanceEdge(cb, to, true, step);
        qrsData[i].x = swrData[cb].curX;
    }
    
    QuickRasterSort();
}

void Shape::DirectScan ( float &  pos,
int &  curP,
float  to,
float  step 
)

Definition at line 610 of file ShapeRaster.cpp.

References SweepTreeList::add(), AvanceEdge(), SweepTree::bord, CreateEdge(), addnodes::e, AVLTree::elem, Shape::dg_arete::en, getEdge(), getPoint(), Barcode::Code39Ext::i, AVLTree::Leftmost(), numberOfEdges(), numberOfPoints(), Other(), SweepTreeList::racine, SweepTree::Remove(), sEvts, Shape::dg_arete::st, sTree, swrData, Shape::dg_point::x, and voronoi::x.

{
    if ( numberOfEdges() <= 1 ) {
        return;
    }
    
    if ( pos == to ) {
        return;
    }
    
    if ( pos < to ) {
        // we're moving downwards
        // points of the polygon are sorted top-down, so we take them in order, starting with the one at index curP,
        // until we reach the wanted position to.
        // don't forget to update curP and pos when we're done
        int curPt = curP;
        while ( curPt < numberOfPoints() && getPoint(curPt).x[1] <= to ) {
            curPt++;
        }
        
        for (int i=0;i<numberOfEdges();i++) {
            if ( swrData[i].misc ) {
                SweepTree* node = swrData[i].misc;
                swrData[i].misc = NULL;
                node->Remove(*sTree, *sEvts, true);
            }
        }

        for (int i=0; i < numberOfEdges(); i++) {
            Shape::dg_arete const &e = getEdge(i);
            if ( ( e.st < curPt && e.en >= curPt ) || ( e.en < curPt && e.st >= curPt )) {
                // crosses sweepline
                int nPt = (e.st < curPt) ? e.st : e.en;
                SweepTree* node = sTree->add(this, i, 1, nPt, this);
                swrData[i].misc = node;
                node->Insert(*sTree, *sEvts, this, nPt, true);
                CreateEdge(i, to, step);
            }
        }
        
        curP = curPt;
        if ( curPt > 0 ) {
            pos = getPoint(curPt - 1).x[1];
        } else {
            pos = to;
        }
        
    } else {
        
        // same thing, but going up. so the sweepSens is inverted for the Find() function
        int curPt=curP;
        while ( curPt > 0 && getPoint(curPt-1).x[1] >= to ) {
            curPt--;
        }

        for (int i = 0; i < numberOfEdges(); i++) {
            if ( swrData[i].misc ) {
                SweepTree* node = swrData[i].misc;
                swrData[i].misc = NULL;
                node->Remove(*sTree, *sEvts, true);
            }
        }
        
        for (int i=0;i<numberOfEdges();i++) {
            Shape::dg_arete const &e = getEdge(i);
            if ( ( e.st > curPt - 1 && e.en <= curPt - 1 ) || ( e.en > curPt - 1 && e.st <= curPt - 1 )) {
                // crosses sweepline
                int nPt = (e.st > curPt) ? e.st : e.en;
                SweepTree* node = sTree->add(this, i, 1, nPt, this);
                swrData[i].misc = node;
                node->Insert(*sTree, *sEvts, this, nPt, false);
                node->startPoint = Other(nPt, i);
                CreateEdge(i, to, step);
            }
        }
        
        curP = curPt;
        if ( curPt > 0 ) {
            pos = getPoint(curPt - 1).x[1];
        } else {
            pos = to;
        }
    }
        
    // the final touch: edges intersecting the sweepline must be update so that their intersection with
    // said sweepline is correct.
    pos = to;
    if ( sTree->racine ) {
        SweepTree* curS=static_cast<SweepTree*>(sTree->racine->Leftmost());
        while ( curS ) {
            int cb = curS->bord;
            AvanceEdge(cb, to, true, step);
            curS = static_cast<SweepTree*>(curS->elem[RIGHT]);
        }
    }
}

void Shape::DisconnectEnd ( int  b  ) 

Definition at line 1938 of file Shape.cpp.

References _aretes, _pts, Shape::dg_arete::en, FIRST, getEdge(), getPoint(), LAST, Shape::dg_arete::nextE, and Shape::dg_arete::prevE.

Referenced by AssembleAretes(), ConnectEnd(), Path::Fill(), and SubEdge().

{
  if (getEdge(b).en < 0)
    return;
  _pts[getEdge(b).en].dI--;
  if (getEdge(b).prevE >= 0)
    {
      if (getEdge(getEdge(b).prevE).st == getEdge(b).en)
        {
          _aretes[getEdge(b).prevE].nextS = getEdge(b).nextE;
        }
      else if (getEdge(getEdge(b).prevE).en == getEdge(b).en)
        {
          _aretes[getEdge(b).prevE].nextE = getEdge(b).nextE;
        }
    }
  if (getEdge(b).nextE >= 0)
    {
      if (getEdge(getEdge(b).nextE).st == getEdge(b).en)
        {
          _aretes[getEdge(b).nextE].prevS = getEdge(b).prevE;
        }
      else if (getEdge(getEdge(b).nextE).en == getEdge(b).en)
        {
          _aretes[getEdge(b).nextE].prevE = getEdge(b).prevE;
        }
    }
  if (getPoint(getEdge(b).en).incidentEdge[FIRST] == b)
    _pts[getEdge(b).en].incidentEdge[FIRST] = getEdge(b).nextE;
  if (getPoint(getEdge(b).en).incidentEdge[LAST] == b)
    _pts[getEdge(b).en].incidentEdge[LAST] = getEdge(b).prevE;
  _aretes[b].en = -1;
}

void Shape::DisconnectStart ( int  b  ) 

Definition at line 1903 of file Shape.cpp.

References _aretes, _pts, FIRST, getEdge(), getPoint(), LAST, Shape::dg_arete::nextS, Shape::dg_arete::prevS, and Shape::dg_arete::st.

Referenced by AssembleAretes(), ConnectStart(), Path::Fill(), and SubEdge().

{
  if (getEdge(b).st < 0)
    return;
  _pts[getEdge(b).st].dO--;
  if (getEdge(b).prevS >= 0)
    {
      if (getEdge(getEdge(b).prevS).st == getEdge(b).st)
        {
          _aretes[getEdge(b).prevS].nextS = getEdge(b).nextS;
        }
      else if (getEdge(getEdge(b).prevS).en == getEdge(b).st)
        {
          _aretes[getEdge(b).prevS].nextE = getEdge(b).nextS;
        }
    }
  if (getEdge(b).nextS >= 0)
    {
      if (getEdge(getEdge(b).nextS).st == getEdge(b).st)
        {
          _aretes[getEdge(b).nextS].prevS = getEdge(b).prevS;
        }
      else if (getEdge(getEdge(b).nextS).en == getEdge(b).st)
        {
          _aretes[getEdge(b).nextS].prevE = getEdge(b).prevS;
        }
    }
  if (getPoint(getEdge(b).st).incidentEdge[FIRST] == b)
    _pts[getEdge(b).st].incidentEdge[FIRST] = getEdge(b).nextS;
  if (getPoint(getEdge(b).st).incidentEdge[LAST] == b)
    _pts[getEdge(b).st].incidentEdge[LAST] = getEdge(b).prevS;
  _aretes[b].st = -1;
}

void Shape::DoEdgeTo ( Shape iS,
int  iB,
int  iTo,
bool  direct,
bool  sens 
) [private]

Definition at line 3263 of file ShapeSweep.cpp.

References _has_back_data, AddEdge(), ffgeom::dot(), ebData, eData, getEdge(), getPoint(), pData, Shape::dg_arete::st, swsData, and Shape::dg_point::x.

Referenced by Avance().

{
  int lp = iS->swsData[iB].curPoint;
  int ne = -1;
  if (sens)
    {
      if (direct)
    ne = AddEdge (lp, iTo);
      else
    ne = AddEdge (iTo, lp);
    }
  else
    {
      if (direct)
    ne = AddEdge (iTo, lp);
      else
    ne = AddEdge (lp, iTo);
    }
  if (ne >= 0 && _has_back_data)
    {
      ebData[ne].pathID = iS->ebData[iB].pathID;
      ebData[ne].pieceID = iS->ebData[iB].pieceID;
      if (iS->eData[iB].length < 0.00001)
    {
      ebData[ne].tSt = ebData[ne].tEn = iS->ebData[iB].tSt;
    }
      else
    {
      double bdl = iS->eData[iB].ilength;
    Geom::Point bpx = iS->pData[iS->getEdge(iB).st].rx;
      Geom::Point bdx = iS->eData[iB].rdx;
      Geom::Point psx = getPoint(getEdge(ne).st).x;
      Geom::Point pex = getPoint(getEdge(ne).en).x;
        Geom::Point psbx=psx-bpx;
        Geom::Point pebx=pex-bpx;
      double pst = dot(psbx,bdx) * bdl;
      double pet = dot(pebx,bdx) * bdl;
      pst = iS->ebData[iB].tSt * (1 - pst) + iS->ebData[iB].tEn * pst;
      pet = iS->ebData[iB].tSt * (1 - pet) + iS->ebData[iB].tEn * pet;
      ebData[ne].tEn = pet;
      ebData[ne].tSt = pst;
    }
    }
  iS->swsData[iB].curPoint = iTo;
  if (ne >= 0)
    {
      int cp = iS->swsData[iB].firstLinkedPoint;
      swsData[ne].firstLinkedPoint = iS->swsData[iB].firstLinkedPoint;
      while (cp >= 0)
    {
      pData[cp].askForWindingB = ne;
      cp = pData[cp].nextLinkedPoint;
    }
      iS->swsData[iB].firstLinkedPoint = -1;
    }
}

void Shape::EndQuickRaster (  ) 
void Shape::EndRaster (  ) 

Definition at line 65 of file ShapeRaster.cpp.

References MakeEdgeData(), MakePointData(), MakeRasterData(), sEvts, and sTree.

Referenced by Inkscape::Text::Layout::ShapeScanlineMaker::~ShapeScanlineMaker().

{
    delete sTree;
    sTree = NULL;
    delete sEvts;
    sEvts = NULL;
    
    MakePointData(false);
    MakeEdgeData(false);
    MakeRasterData(false);
}

void Shape::ForceToPolygon ( void   ) 

Definition at line 63 of file ShapeSweep.cpp.

References type.

Referenced by nr_arena_shape_update_fill(), and nr_arena_shape_update_stroke().

{
  type = shape_polygon;
}

void Shape::GetWindings ( Shape a,
Shape b = NULL,
BooleanOp  mod = bool_op_union,
bool  brutal = false 
) [private]

Definition at line 2355 of file ShapeSweep.cpp.

References CyclePrevAt(), eData, Shape::dg_arete::en, getEdge(), getPoint(), Barcode::Code39Ext::i, Shape::dg_point::incidentEdge, Inverse(), numberOfEdges(), numberOfPoints(), pData, SortEdges(), Shape::dg_arete::st, swdData, Winding(), and voronoi::x.

Referenced by Booleen(), ConvertToShape(), and Reoriente().

{
  // preparation du parcours
  for (int i = 0; i < numberOfEdges(); i++)
    {
      swdData[i].misc = 0;
      swdData[i].precParc = swdData[i].suivParc = -1;
    }

  // chainage
  SortEdges ();

  int searchInd = 0;

  int lastPtUsed = 0;
  do
    {
      int startBord = -1;
      int outsideW = 0;
      {
    int fi = 0;
    for (fi = lastPtUsed; fi < numberOfPoints(); fi++)
      {
        if (getPoint(fi).incidentEdge[FIRST] >= 0 && swdData[getPoint(fi).incidentEdge[FIRST]].misc == 0)
          break;
      }
    lastPtUsed = fi + 1;
    if (fi < numberOfPoints())
      {
        int bestB = getPoint(fi).incidentEdge[FIRST];
        if (bestB >= 0)
          {
        startBord = bestB;
        if (fi == 0)
          {
            outsideW = 0;
          }
        else
          {
            if (brutal)
              {
            outsideW = Winding (getPoint(fi).x);
              }
            else
              {
            outsideW = Winding (fi);
              }
          }
    if ( getPoint(fi).totalDegree() == 1 ) {
      if ( fi == getEdge(startBord).en ) {
        if ( eData[startBord].weight == 0 ) {
          // on se contente d'inverser
          Inverse(startBord);
        } else {
          // on passe le askForWinding (sinon ca va rester startBord)
          pData[getEdge(startBord).st].askForWindingB=pData[getEdge(startBord).en].askForWindingB;
        }
      }
    }
        if (getEdge(startBord).en == fi)
          outsideW += eData[startBord].weight;
          }
      }
      }
      if (startBord >= 0)
    {
      // parcours en profondeur pour mettre les leF et riF a leurs valeurs
      swdData[startBord].misc = (void *) 1;
      swdData[startBord].leW = outsideW;
      swdData[startBord].riW = outsideW - eData[startBord].weight;
//    if ( doDebug ) printf("part de %d\n",startBord);
      int curBord = startBord;
      bool curDir = true;
      swdData[curBord].precParc = -1;
      swdData[curBord].suivParc = -1;
      do
        {
          int cPt;
          if (curDir)
        cPt = getEdge(curBord).en;
          else
        cPt = getEdge(curBord).st;
          int nb = curBord;
//        if ( doDebug ) printf("de curBord= %d avec leF= %d et riF= %d  -> ",curBord,swdData[curBord].leW,swdData[curBord].riW);
          do
        {
          int nnb = -1;
          if (getEdge(nb).en == cPt)
            {
              outsideW = swdData[nb].riW;
              nnb = CyclePrevAt (cPt, nb);
            }
          else
            {
              outsideW = swdData[nb].leW;
              nnb = CyclePrevAt (cPt, nb);
            }
          if (nnb == nb)
            {
              // cul-de-sac
              nb = -1;
              break;
            }
          nb = nnb;
        }
          while (nb >= 0 && nb != curBord && swdData[nb].misc != 0);
          if (nb < 0 || nb == curBord)
        {
          // retour en arriere
          int oPt;
          if (curDir)
            oPt = getEdge(curBord).st;
          else
            oPt = getEdge(curBord).en;
          curBord = swdData[curBord].precParc;
//    if ( doDebug ) printf("retour vers %d\n",curBord);
          if (curBord < 0)
            break;
          if (oPt == getEdge(curBord).en)
            curDir = true;
          else
            curDir = false;
        }
          else
        {
          swdData[nb].misc = (void *) 1;
          swdData[nb].ind = searchInd++;
          if (cPt == getEdge(nb).st)
            {
              swdData[nb].riW = outsideW;
              swdData[nb].leW = outsideW + eData[nb].weight;
            }
          else
            {
              swdData[nb].leW = outsideW;
              swdData[nb].riW = outsideW - eData[nb].weight;
            }
          swdData[nb].precParc = curBord;
          swdData[curBord].suivParc = nb;
          curBord = nb;
//        if ( doDebug ) printf("suite %d\n",curBord);
          if (cPt == getEdge(nb).en)
            curDir = false;
          else
            curDir = true;
        }
        }
      while (1 /*swdData[curBord].precParc >= 0 */ );
      // fin du cas non-oriente
    }
    }
  while (lastPtUsed < numberOfPoints());
//      fflush(stdout);
}

static double Shape::HalfRound ( double  x  )  [inline, static]

Definition at line 273 of file Shape.h.

Referenced by Avance(), and TesteAdjacency().

    {
        return ldexp(x, -5);
    }

bool Shape::hasBackData (  )  const [inline]

Definition at line 375 of file Shape.h.

References _has_back_data.

Referenced by Booleen(), Path::DoLeftJoin(), Path::DoRightJoin(), and sp_selected_path_boolop().

{ return _has_back_data; }

bool Shape::hasEdges (  )  const [inline]

Definition at line 370 of file Shape.h.

References _aretes.

Referenced by SPFlowtext::_buildExclusionShape(), SPFlowtext::_buildLayoutInput(), and UnionShape().

{ return (_aretes.empty() == false); }

bool Shape::hasPoints (  )  const [inline]

Definition at line 368 of file Shape.h.

References _pts.

Referenced by AssemblePoints(), CalcBBox(), distance(), distanceLessThanOrEqual(), SortPoints(), SortPointsRounded(), and sp_offset_top_point().

{ return (_pts.empty() == false); }

static double Shape::IHalfRound ( double  x  )  [inline, static]

Definition at line 278 of file Shape.h.

Referenced by TesteAdjacency().

    {
        return ldexp(x, 5);
    }

void Shape::initialiseEdgeData (  )  [private]

Definition at line 2127 of file Shape.cpp.

References ffgeom::dot(), eData, Shape::dg_arete::en, getEdge(), Barcode::Code39Ext::i, polyhedron_3d::length(), N, numberOfEdges(), pData, Geom::sqrt(), Shape::dg_arete::st, and swsData.

Referenced by Booleen(), and ConvertToShape().

{
    int const N = numberOfEdges();

    for (int i = 0; i < N; i++) {
        eData[i].rdx = pData[getEdge(i).en].rx - pData[getEdge(i).st].rx;
        eData[i].length = dot(eData[i].rdx, eData[i].rdx);
        eData[i].ilength = 1 / eData[i].length;
        eData[i].sqlength = sqrt(eData[i].length);
        eData[i].isqlength = 1 / eData[i].sqlength;
        eData[i].siEd = eData[i].rdx[1] * eData[i].isqlength;
        eData[i].coEd = eData[i].rdx[0] * eData[i].isqlength;
        
        if (eData[i].siEd < 0) {
            eData[i].siEd = -eData[i].siEd;
            eData[i].coEd = -eData[i].coEd;
        }

        swsData[i].misc = NULL;
        swsData[i].firstLinkedPoint = -1;
        swsData[i].stPt = swsData[i].enPt = -1;
        swsData[i].leftRnd = swsData[i].rightRnd = -1;
        swsData[i].nextSh = NULL;
        swsData[i].nextBo = -1;
        swsData[i].curPoint = -1;
        swsData[i].doneTo = -1;
  }
}

void Shape::initialisePointData (  )  [private]

Definition at line 2110 of file Shape.cpp.

References _point_data_initialised, getPoint(), Barcode::Code39Ext::i, N, numberOfPoints(), pData, Round(), and voronoi::x.

Referenced by BeginQuickRaster(), Booleen(), ConvertToShape(), and Reoriente().

{
    if (_point_data_initialised)
        return;
    int const N = numberOfPoints();
  
    for (int i = 0; i < N; i++) {
        pData[i].pending = 0;
        pData[i].edgeOnLeft = -1;
        pData[i].nextLinkedPoint = -1;
        pData[i].rx[0] = Round(getPoint(i).x[0]);
        pData[i].rx[1] = Round(getPoint(i).x[1]);
    }

    _point_data_initialised = true;
}

void Shape::Inverse ( int  b  ) 

Definition at line 1974 of file Shape.cpp.

References _aretes, _has_back_data, _has_edges_data, _has_sweep_dest_data, _has_voronoi_data, _pts, Shape::dg_arete::dx, ebData, eData, Shape::dg_arete::en, getEdge(), Shape::dg_arete::nextE, Shape::dg_arete::nextS, Shape::dg_arete::prevE, Shape::dg_arete::prevS, Shape::dg_arete::st, swdData, and voreData.

Referenced by AssembleAretes(), Booleen(), ConvertToShape(), GetWindings(), MakeOffset(), MakeTweak(), and Reoriente().

{
  int swap;
  swap = getEdge(b).st;
  _aretes[b].st = getEdge(b).en;
  _aretes[b].en = swap;
  swap = getEdge(b).prevE;
  _aretes[b].prevE = getEdge(b).prevS;
  _aretes[b].prevS = swap;
  swap = getEdge(b).nextE;
  _aretes[b].nextE = getEdge(b).nextS;
  _aretes[b].nextS = swap;
  _aretes[b].dx = -getEdge(b).dx;
  if (getEdge(b).st >= 0)
    {
      _pts[getEdge(b).st].dO++;
      _pts[getEdge(b).st].dI--;
    }
  if (getEdge(b).en >= 0)
    {
      _pts[getEdge(b).en].dO--;
      _pts[getEdge(b).en].dI++;
    }
  if (_has_edges_data)
    eData[b].weight = -eData[b].weight;
  if (_has_sweep_dest_data)
    {
      int swap = swdData[b].leW;
      swdData[b].leW = swdData[b].riW;
      swdData[b].riW = swap;
    }
  if (_has_back_data)
    {
      double swat = ebData[b].tSt;
      ebData[b].tSt = ebData[b].tEn;
      ebData[b].tEn = swat;
    }
  if (_has_voronoi_data)
    {
      int swai = voreData[b].leF;
      voreData[b].leF = voreData[b].riF;
      voreData[b].riF = swai;
    }
}

void Shape::MakeBackData ( bool  nVal  ) 

Definition at line 186 of file Shape.cpp.

References _has_back_data, ebData, and maxAr.

Referenced by Booleen(), ConvertToShape(), Copy(), Path::Fill(), MakeOffset(), MakeTweak(), and Path::Stroke().

{
  if (nVal)
    {
      if (_has_back_data == false)
        {
          _has_back_data = true;
          ebData.resize(maxAr);
        }
    }
  else
    {
      if (_has_back_data)
        {
          _has_back_data = false;
          ebData.clear();
        }
    }
}

void Shape::MakeEdgeData ( bool  nVal  )  [private]

Definition at line 86 of file Shape.cpp.

References _has_edges_data, eData, and maxAr.

Referenced by BeginQuickRaster(), BeginRaster(), Booleen(), CleanupSweep(), ConvertToForme(), ConvertToFormeNested(), ConvertToShape(), Copy(), EndQuickRaster(), EndRaster(), Reoriente(), and ResetSweep().

{
  if (nVal)
    {
      if (_has_edges_data == false)
        {
          _has_edges_data = true;
          eData.resize(maxAr);
        }
    }
  else
    {
      if (_has_edges_data)
        {
          _has_edges_data = false;
          eData.clear();
        }
    }
}

int Shape::MakeOffset ( Shape of,
double  dec,
JoinType  join,
double  miter,
bool  do_profile = false,
double  cx = 0,
double  cy = 0,
double  radius = 0,
Geom::Matrix i2doc = NULL 
)

Definition at line 721 of file ShapeMisc.cpp.

References _aretes, _bbox_up_to_date, _has_back_data, _has_edges_data, _has_points_data, _has_raster_data, _has_sweep_dest_data, _has_sweep_src_data, _point_data_initialised, _pts, AddEdge(), Geom::cos(), CycleNextAt(), CyclePrevAt(), Path::DoLeftJoin(), Path::DoRightJoin(), ffgeom::dot(), Shape::dg_arete::dx, ebData, eData, Shape::dg_arete::en, getEdge(), getPoint(), Barcode::Code39Ext::i, Inverse(), Geom::L2(), M_PI, MakeBackData(), MakeSweepDestData(), MakeSweepSrcData(), maxAr, maxPt, MiscNormalize, numberOfEdges(), numberOfPoints(), pData, Geom::pow(), Reset(), shape_input_err, shape_nothing_to_do, SortEdges(), Geom::sqrt(), Shape::dg_arete::st, swdData, swrData, swsData, type, and voronoi::x.

Referenced by do_trace(), sp_offset_set_shape(), and sp_selected_path_do_offset().

{
  Reset (0, 0);
  MakeBackData(a->_has_back_data);

    bool done_something = false;
  
  if (dec == 0)
  {
    _pts = a->_pts;
    if (numberOfPoints() > maxPt)
    {
      maxPt = numberOfPoints();
      if (_has_points_data) {
        pData.resize(maxPt);
        _point_data_initialised = false;
        _bbox_up_to_date = false;
        }
    }
    
    _aretes = a->_aretes;
    if (numberOfEdges() > maxAr)
    {
      maxAr = numberOfEdges();
      if (_has_edges_data)
    eData.resize(maxAr);
      if (_has_sweep_src_data)
        swsData.resize(maxAr);
      if (_has_sweep_dest_data)
        swdData.resize(maxAr);
      if (_has_raster_data)
        swrData.resize(maxAr);
      if (_has_back_data)
        ebData.resize(maxAr);
    }
    return 0;
  }
  if (a->numberOfPoints() <= 1 || a->numberOfEdges() <= 1 || a->type != shape_polygon)
    return shape_input_err;
  
  a->SortEdges ();
  
  a->MakeSweepDestData (true);
  a->MakeSweepSrcData (true);
  
  for (int i = 0; i < a->numberOfEdges(); i++)
  {
    //              int    stP=a->swsData[i].stPt/*,enP=a->swsData[i].enPt*/;
    int stB = -1, enB = -1;
    if (dec > 0)
    {
      stB = a->CycleNextAt (a->getEdge(i).st, i);
      enB = a->CyclePrevAt (a->getEdge(i).en, i);
    }
    else
    {
      stB = a->CyclePrevAt (a->getEdge(i).st, i);
      enB = a->CycleNextAt (a->getEdge(i).en, i);
    }
    
    Geom::Point stD, seD, enD;
    double stL, seL, enL;
    stD = a->getEdge(stB).dx;
    seD = a->getEdge(i).dx;
    enD = a->getEdge(enB).dx;

    stL = sqrt (dot(stD,stD));
    seL = sqrt (dot(seD,seD));
    enL = sqrt (dot(enD,enD));
    MiscNormalize (stD);
    MiscNormalize (enD);
    MiscNormalize (seD);
    
    Geom::Point ptP;
    int stNo, enNo;
    ptP = a->getPoint(a->getEdge(i).st).x;

        double this_dec;
        if (do_profile && i2doc) {
            double alpha = 1;
            double x = (Geom::L2(ptP * (*i2doc) - Geom::Point(cx,cy))/radius);
            if (x > 1) {
                this_dec = 0;
            } else if (x <= 0) {
                this_dec = dec;
            } else {
                this_dec = dec * (0.5 * cos (M_PI * (pow(x, alpha))) + 0.5);
            }
        } else {
            this_dec = dec;
        }

        if (this_dec != 0)
            done_something = true;

    int   usePathID=-1;
    int   usePieceID=0;
    double useT=0.0;
    if ( a->_has_back_data ) {
      if ( a->ebData[i].pathID >= 0 && a->ebData[stB].pathID == a->ebData[i].pathID && a->ebData[stB].pieceID == a->ebData[i].pieceID
           && a->ebData[stB].tEn == a->ebData[i].tSt ) {
        usePathID=a->ebData[i].pathID;
        usePieceID=a->ebData[i].pieceID;
        useT=a->ebData[i].tSt;
      } else {
        usePathID=a->ebData[i].pathID;
        usePieceID=0;
        useT=0;
      }
    }
    if (dec > 0)
    {
      Path::DoRightJoin (this, this_dec, join, ptP, stD, seD, miter, stL, seL,
                         stNo, enNo,usePathID,usePieceID,useT);
      a->swsData[i].stPt = enNo;
      a->swsData[stB].enPt = stNo;
    }
    else
    {
      Path::DoLeftJoin (this, -this_dec, join, ptP, stD, seD, miter, stL, seL,
                        stNo, enNo,usePathID,usePieceID,useT);
      a->swsData[i].stPt = enNo;
      a->swsData[stB].enPt = stNo;
    }
  }

  if (dec < 0)
  {
    for (int i = 0; i < numberOfEdges(); i++)
      Inverse (i);
  }

  if ( _has_back_data ) {
    for (int i = 0; i < a->numberOfEdges(); i++)
    {
      int nEd=AddEdge (a->swsData[i].stPt, a->swsData[i].enPt);
      ebData[nEd]=a->ebData[i];
    }
  } else {
    for (int i = 0; i < a->numberOfEdges(); i++)
    {
      AddEdge (a->swsData[i].stPt, a->swsData[i].enPt);
    }
  }

  a->MakeSweepSrcData (false);
  a->MakeSweepDestData (false);
  
  return (done_something? 0 : shape_nothing_to_do);
}

void Shape::MakePointData ( bool  nVal  )  [private]

Allocates space for point cache or clears the cache.

Parameters:
nVal Allocate a cache (true) or clear it (false)

Definition at line 70 of file Shape.cpp.

References _bbox_up_to_date, _has_points_data, _point_data_initialised, maxPt, and pData.

Referenced by BeginQuickRaster(), BeginRaster(), Booleen(), CleanupSweep(), ConvertToForme(), ConvertToFormeNested(), ConvertToShape(), Copy(), EndQuickRaster(), EndRaster(), Reoriente(), and ResetSweep().

{
  if (nVal)
    {
      if (_has_points_data == false)
        {
          _has_points_data = true;
          _point_data_initialised = false;
          _bbox_up_to_date = false;
          pData.resize(maxPt);
        }
    }
    /* no need to clean point data - keep it cached*/
}

void Shape::MakeQuickRasterData ( bool  nVal  )  [private]

Definition at line 127 of file Shape.cpp.

References _has_quick_raster_data, maxAr, and qrsData.

Referenced by BeginQuickRaster(), Copy(), and EndQuickRaster().

{
  if (nVal)
    {
      if (_has_quick_raster_data == false)
        {
          _has_quick_raster_data = true;
          qrsData = (quick_raster_data*)realloc(qrsData, maxAr * sizeof(quick_raster_data));
        }
    }
  else
    {
      if (_has_quick_raster_data)
        {
          _has_quick_raster_data = false;
        }
    }
}

void Shape::MakeRasterData ( bool  nVal  )  [private]

Definition at line 107 of file Shape.cpp.

References _has_raster_data, maxAr, and swrData.

Referenced by BeginQuickRaster(), BeginRaster(), Copy(), EndQuickRaster(), and EndRaster().

{
  if (nVal)
    {
      if (_has_raster_data == false)
        {
          _has_raster_data = true;
          swrData.resize(maxAr);
        }
    }
  else
    {
      if (_has_raster_data)
        {
          _has_raster_data = false;
          swrData.clear();
        }
    }
}

void Shape::MakeSweepDestData ( bool  nVal  )  [private]

Definition at line 166 of file Shape.cpp.

References _has_sweep_dest_data, maxAr, and swdData.

Referenced by Booleen(), ConvertToForme(), ConvertToFormeNested(), ConvertToShape(), Copy(), MakeOffset(), MakeTweak(), and Reoriente().

{
  if (nVal)
    {
      if (_has_sweep_dest_data == false)
        {
          _has_sweep_dest_data = true;
          swdData.resize(maxAr);
        }
    }
  else
    {
      if (_has_sweep_dest_data)
        {
          _has_sweep_dest_data = false;
          swdData.clear();
        }
    }
}

void Shape::MakeSweepSrcData ( bool  nVal  )  [private]

Definition at line 146 of file Shape.cpp.

References _has_sweep_src_data, maxAr, and swsData.

Referenced by Booleen(), CleanupSweep(), ConvertToShape(), Copy(), MakeOffset(), MakeTweak(), and ResetSweep().

{
  if (nVal)
    {
      if (_has_sweep_src_data == false)
        {
          _has_sweep_src_data = true;
          swsData.resize(maxAr);
        }
    }
  else
    {
      if (_has_sweep_src_data)
        {
          _has_sweep_src_data = false;
          swsData.clear();
        }
    }
}

int Shape::MakeTweak ( int  mode,
Shape a,
double  dec,
JoinType  join,
double  miter,
bool  do_profile,
Geom::Point  c,
Geom::Point  vector,
double  radius,
Geom::Matrix i2doc 
)

Definition at line 531 of file ShapeMisc.cpp.

References _aretes, _bbox_up_to_date, _has_back_data, _has_edges_data, _has_points_data, _has_raster_data, _has_sweep_dest_data, _has_sweep_src_data, _point_data_initialised, _pts, AddEdge(), Geom::detail::bezier_clipping::angle(), Geom::cos(), CycleNextAt(), CyclePrevAt(), Path::DoLeftJoin(), Path::DoRightJoin(), ffgeom::dot(), Shape::dg_arete::dx, ebData, eData, Shape::dg_arete::en, getEdge(), getPoint(), Barcode::Code39Ext::i, Inverse(), Geom::Matrix::inverse(), Geom::L2(), M_PI, MakeBackData(), MakeSweepDestData(), MakeSweepSrcData(), maxAr, maxPt, MiscNormalize, numberOfEdges(), numberOfPoints(), pData, Point, Geom::pow(), Reset(), shape_input_err, shape_nothing_to_do, Geom::sin(), SortEdges(), Geom::sqrt(), Shape::dg_arete::st, swdData, swrData, swsData, tweak_mode_push, tweak_mode_repel, tweak_mode_roughen, type, and voronoi::x.

Referenced by sp_tweak_dilate_recursive().

{
  Reset (0, 0);
  MakeBackData(a->_has_back_data);

    bool done_something = false;

  if (power == 0)
  {
    _pts = a->_pts;
    if (numberOfPoints() > maxPt)
    {
      maxPt = numberOfPoints();
      if (_has_points_data) {
        pData.resize(maxPt);
        _point_data_initialised = false;
        _bbox_up_to_date = false;
        }
    }
    
    _aretes = a->_aretes;
    if (numberOfEdges() > maxAr)
    {
      maxAr = numberOfEdges();
      if (_has_edges_data)
          eData.resize(maxAr);
      if (_has_sweep_src_data)
        swsData.resize(maxAr);
      if (_has_sweep_dest_data)
        swdData.resize(maxAr);
      if (_has_raster_data)
        swrData.resize(maxAr);
      if (_has_back_data)
        ebData.resize(maxAr);
    }
    return 0;
  }
  if (a->numberOfPoints() <= 1 || a->numberOfEdges() <= 1 || a->type != shape_polygon)
    return shape_input_err;
  
  a->SortEdges ();
  
  a->MakeSweepDestData (true);
  a->MakeSweepSrcData (true);
  
  for (int i = 0; i < a->numberOfEdges(); i++)
  {
    int stB = -1, enB = -1;
    if (power <= 0 || mode == tweak_mode_push || mode == tweak_mode_repel || mode == tweak_mode_roughen)  {
      stB = a->CyclePrevAt (a->getEdge(i).st, i);
      enB = a->CycleNextAt (a->getEdge(i).en, i);
    } else {
      stB = a->CycleNextAt (a->getEdge(i).st, i);
      enB = a->CyclePrevAt (a->getEdge(i).en, i);
    }
    
    Geom::Point stD, seD, enD;
    double stL, seL, enL;
    stD = a->getEdge(stB).dx;
    seD = a->getEdge(i).dx;
    enD = a->getEdge(enB).dx;

    stL = sqrt (dot(stD,stD));
    seL = sqrt (dot(seD,seD));
    enL = sqrt (dot(enD,enD));
    MiscNormalize (stD);
    MiscNormalize (enD);
    MiscNormalize (seD);
    
    Geom::Point ptP;
    int stNo, enNo;
    ptP = a->getPoint(a->getEdge(i).st).x;

    Geom::Point to_center = ptP * (*i2doc) - c;
    Geom::Point to_center_normalized = (1/Geom::L2(to_center)) * to_center;

        double this_power;
        if (do_profile && i2doc) {
            double alpha = 1;
            double x;
        if (mode == tweak_mode_repel) {
                x = (Geom::L2(to_center)/radius);
            } else {
                x = (Geom::L2(ptP * (*i2doc) - c)/radius);
            }
            if (x > 1) {
                this_power = 0;
            } else if (x <= 0) {
            if (mode == tweak_mode_repel) {
                    this_power = 0;
                } else {
                    this_power = power;
                }
            } else {
                this_power = power * (0.5 * cos (M_PI * (pow(x, alpha))) + 0.5);
            }
        } else {
        if (mode == tweak_mode_repel) {
                this_power = 0;
            } else {
                this_power = power;
            }
        }

        if (this_power != 0)
            done_something = true;

        double scaler = 1 / (*i2doc).descrim();

        Geom::Point this_vec(0,0);
    if (mode == tweak_mode_push) {
            Geom::Matrix tovec (*i2doc);
            tovec[4] = tovec[5] = 0;
            tovec = tovec.inverse();
            this_vec = this_power * (vector * tovec) ;
        } else if (mode == tweak_mode_repel) {
            this_vec = this_power * scaler * to_center_normalized;
        } else if (mode == tweak_mode_roughen) {
        double angle = g_random_double_range(0, 2*M_PI);
        this_vec = g_random_double_range(0, 1) * this_power * scaler * Geom::Point(sin(angle), cos(angle));
        }

    int   usePathID=-1;
    int   usePieceID=0;
    double useT=0.0;
    if ( a->_has_back_data ) {
      if ( a->ebData[i].pathID >= 0 && a->ebData[stB].pathID == a->ebData[i].pathID && a->ebData[stB].pieceID == a->ebData[i].pieceID
           && a->ebData[stB].tEn == a->ebData[i].tSt ) {
        usePathID=a->ebData[i].pathID;
        usePieceID=a->ebData[i].pieceID;
        useT=a->ebData[i].tSt;
      } else {
        usePathID=a->ebData[i].pathID;
        usePieceID=0;
        useT=0;
      }
    }

        if (mode == tweak_mode_push || mode == tweak_mode_repel || mode == tweak_mode_roughen) {
            Path::DoLeftJoin (this, 0, join, ptP+this_vec, stD+this_vec, seD+this_vec, miter, stL, seL,
                                                stNo, enNo,usePathID,usePieceID,useT);
            a->swsData[i].stPt = enNo;
            a->swsData[stB].enPt = stNo;
        } else {
            if (power > 0) {
                Path::DoRightJoin (this, this_power * scaler, join, ptP, stD, seD, miter, stL, seL,
                                                     stNo, enNo,usePathID,usePieceID,useT);
                a->swsData[i].stPt = enNo;
                a->swsData[stB].enPt = stNo;
            } else {
                Path::DoLeftJoin (this, -this_power * scaler, join, ptP, stD, seD, miter, stL, seL,
                                                    stNo, enNo,usePathID,usePieceID,useT);
                a->swsData[i].stPt = enNo;
                a->swsData[stB].enPt = stNo;
            }
        }
  }

  if (power < 0 || mode == tweak_mode_push || mode == tweak_mode_repel || mode == tweak_mode_roughen)
  {
    for (int i = 0; i < numberOfEdges(); i++)
      Inverse (i);
  }

  if ( _has_back_data ) {
    for (int i = 0; i < a->numberOfEdges(); i++)
    {
      int nEd=AddEdge (a->swsData[i].stPt, a->swsData[i].enPt);
      ebData[nEd]=a->ebData[i];
    }
  } else {
    for (int i = 0; i < a->numberOfEdges(); i++)
    {
      AddEdge (a->swsData[i].stPt, a->swsData[i].enPt);
    }
  }

  a->MakeSweepSrcData (false);
  a->MakeSweepDestData (false);
  
  return (done_something? 0 : shape_nothing_to_do);
}

void Shape::MakeVoronoiData ( bool  nVal  ) 

Definition at line 206 of file Shape.cpp.

References _has_voronoi_data, maxAr, maxPt, voreData, and vorpData.

{
  if (nVal)
    {
      if (_has_voronoi_data == false)
        {
          _has_voronoi_data = true;
          vorpData.resize(maxPt);
          voreData.resize(maxAr);
        }
    }
  else
    {
      if (_has_voronoi_data)
        {
          _has_voronoi_data = false;
          vorpData.clear();
          voreData.clear();
        }
    }
}

void Shape::needEdgesSorting (  )  [inline]

Definition at line 373 of file Shape.h.

References _need_edges_sorting.

Referenced by nr_arena_shape_update_fill(), and nr_arena_shape_update_stroke().

{ _need_edges_sorting = true; }

void Shape::needPointsSorting (  )  [inline]

Definition at line 372 of file Shape.h.

References _need_points_sorting.

Referenced by nr_arena_shape_update_fill(), and nr_arena_shape_update_stroke().

int Shape::NextAt ( int  p,
int  b 
) const [inline]
int Shape::Other ( int  p,
int  b 
) const [inline]

Definition at line 154 of file Shape.h.

References Shape::dg_arete::en, getEdge(), and Shape::dg_arete::st.

Referenced by AssembleAretes(), DirectScan(), and Scan().

    {
        if (getEdge(b).st == p) {
            return getEdge(b).en;
        }
        return getEdge(b).st;
    }

void Shape::Plot ( double  ix,
double  iy,
double  ir,
double  mx,
double  my,
bool  doPoint,
bool  edgesNo,
bool  pointNo,
bool  doDir,
char *  fileName 
)

Definition at line 17 of file ShapeDraw.cpp.

References Shape::dg_arete::en, getEdge(), getPoint(), Barcode::Code39Ext::i, numberOfEdges(), numberOfPoints(), Shape::dg_arete::st, and Shape::dg_point::x.

{
  FILE*  outFile=fopen(fileName,"w+");
//  fprintf(outFile,"\n\n\n");
  fprintf(outFile,"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");
  fprintf(outFile,"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\"\n");
  fprintf(outFile,"\"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">\n");
  fprintf(outFile,"<svg:svg\n");
  fprintf(outFile,"   id=\"svg1\"\n");
  fprintf(outFile,"   inkscape:version=\"0.38cvs\"\n");
  fprintf(outFile,"   xmlns:svg=\"http://www.w3.org/2000/svg\"\n");
  fprintf(outFile,"   xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n");
  fprintf(outFile,"   xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"\n");
  fprintf(outFile,"   xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n");
  fprintf(outFile,"   width=\"210mm\"\n");
  fprintf(outFile,"   height=\"297mm\"\n");
  fprintf(outFile,"   sodipodi:docbase=\"/Volumes/Sancho/inkscapecvs\"\n");
  fprintf(outFile,"   sodipodi:docname=\"/Volumes/Sancho/inkscapecvs/modele.svg\">\n");
  fprintf(outFile,"  <svg:defs\n");
  fprintf(outFile,"     id=\"defs3\" />\n");
  fprintf(outFile,"  <sodipodi:namedview\n");
  fprintf(outFile,"     id=\"base\"\n");
  fprintf(outFile,"     pagecolor=\"#ffffff\"\n");
  fprintf(outFile,"     bordercolor=\"#666666\"\n");
  fprintf(outFile,"     borderopacity=\"1.0\"\n");
  fprintf(outFile,"     inkscape:pageopacity=\"0.0\"\n");
  fprintf(outFile,"     inkscape:pageshadow=\"2\"\n");
  fprintf(outFile,"     inkscape:zoom=\"0.43415836\"\n");
  fprintf(outFile,"     inkscape:cx=\"305.25952637\"\n");
  fprintf(outFile,"     inkscape:cy=\"417.84947271\"\n");
  fprintf(outFile,"     inkscape:window-width=\"640\"\n");
  fprintf(outFile,"     inkscape:window-height=\"496\"\n");
  fprintf(outFile,"     inkscape:window-x=\"20\"\n");
  fprintf(outFile,"     inkscape:window-y=\"42\" />\n");
  
    if ( doPoint ) {
        for (int i=0;i<numberOfPoints();i++) {
            double   ph=(getPoint(i).x[0]-ix)*ir+mx;
            double   pv=(getPoint(i).x[1]-iy)*ir+my;
      fprintf(outFile,"     <svg:circle cx=\"%f\" cy=\"%f\" r=\"5\" fill=\"none\" stroke=\"red\" stroke-width=\"0.25\" />\n",ph,pv); // localizing ok
    }
    }
  if ( pointsNo ) {
        for (int i=0;i<numberOfPoints();i++) {
            double   ph=(getPoint(i).x[0]-ix)*ir+mx;
            double   pv=(getPoint(i).x[1]-iy)*ir+my;
      fprintf(outFile,"     <svg:text x=\"%f\" y=\"%f\" font-family=\"Monaco\" font-size=\"5\" fill=\"blue\" >\n",ph-2,pv+1); // localizing ok
      fprintf(outFile,"%i\n",i);
      fprintf(outFile,"     </text>\n");
    }
  }
    {
        for (int i=0;i<numberOfEdges();i++) {
            int     stP=getEdge(i).st;
            int     enP=getEdge(i).en;
            if ( stP < 0 || enP < 0 ) continue;
            double   sh=(getPoint(stP).x[0]-ix)*ir+mx;
            double   sv=(getPoint(stP).x[1]-iy)*ir+my;
            double   eh=(getPoint(enP).x[0]-ix)*ir+mx;
            double   ev=(getPoint(enP).x[1]-iy)*ir+my;
            if ( doDir ) {
                double   endh=(9*eh+1*sh)/10;
                double   endv=(9*ev+1*sv)/10;
        fprintf(outFile,"     <svg:line x1=\"%f\" y1=\"%f\" x2=\"%f\" y2=\"%f\" stroke=\"black\" stroke-width=\"0.5\" />\n",sh,sv,endh,endv); // localizing ok
            } else {
        fprintf(outFile,"     <svg:line x1=\"%f\" y1=\"%f\" x2=\"%f\" y2=\"%f\" stroke=\"black\" stroke-width=\"0.5\" />\n",sh,sv,eh,ev); // localizing ok
            }
        }
    }
  if ( edgesNo ) {
        for (int i=0;i<numberOfEdges();i++) {
            int     stP=getEdge(i).st;
            int     enP=getEdge(i).en;
            if ( stP < 0 || enP < 0 ) continue;
            double   sh=(getPoint(stP).x[0]-ix)*ir+mx;
            double   sv=(getPoint(stP).x[1]-iy)*ir+my;
            double   eh=(getPoint(enP).x[0]-ix)*ir+mx;
            double   ev=(getPoint(enP).x[1]-iy)*ir+my;
      fprintf(outFile,"     <svg:text x=\"%f\" y=\"%f\" font-family=\"Monaco\" font-size=\"5\" fill=\"blue\" >\n",(sh+eh)/2+2,(sv+ev)/2); // localizing ok
      fprintf(outFile,"%i\n",i);
      fprintf(outFile,"     </text>\n");
        }
  }
  
  fprintf(outFile,"</svg>\n");
  fclose(outFile);

}

int Shape::PrevAt ( int  p,
int  b 
) const [inline]

Definition at line 176 of file Shape.h.

References getEdge(), Shape::dg_arete::prevE, and Shape::dg_arete::prevS.

    {
        if (p == getEdge(b).st) {
            return getEdge(b).prevS;
        }
        else if (p == getEdge(b).en) {
            return getEdge(b).prevE;
        }

        return -1;
    }

int Shape::PtWinding ( const Geom::Point  px  )  const

Definition at line 2057 of file Shape.cpp.

References Geom::cross(), Shape::dg_arete::dx, getEdge(), getPoint(), Barcode::Code39Ext::i, numberOfEdges(), and Shape::dg_point::x.

{
  int lr = 0, ll = 0, rr = 0;
  
  for (int i = 0; i < numberOfEdges(); i++)
  {
    Geom::Point const adir = getEdge(i).dx;

    Geom::Point const ast = getPoint(getEdge(i).st).x;
    Geom::Point const aen = getPoint(getEdge(i).en).x;
    
    //int const nWeight = eData[i].weight;
    int const nWeight = 1;

    if (ast[0] < aen[0]) {
      if (ast[0] > px[0]) continue;
      if (aen[0] < px[0]) continue;
    } else {
      if (ast[0] < px[0]) continue;
      if (aen[0] > px[0]) continue;
    }
    if (ast[0] == px[0]) {
      if (ast[1] >= px[1]) continue;
      if (aen[0] == px[0]) continue;
      if (aen[0] < px[0]) ll += nWeight;  else rr -= nWeight;
      continue;
    }
    if (aen[0] == px[0]) {
      if (aen[1] >= px[1]) continue;
      if (ast[0] == px[0]) continue;
      if (ast[0] < px[0]) ll -= nWeight; else rr += nWeight;
      continue;
    }
    
    if (ast[1] < aen[1]) {
      if (ast[1] >= px[1])  continue;
    } else {
      if (aen[1] >= px[1]) continue;
    }

    Geom::Point const diff = px - ast;
    double const cote = cross(diff, adir);
    if (cote == 0) continue;
    if (cote < 0) {
      if (ast[0] > px[0]) lr += nWeight;
    } else {
      if (ast[0] < px[0]) lr -= nWeight;
    }
  }
  return lr + (ll + rr) / 2;
}

int Shape::PushIncidence ( Shape a,
int  cb,
int  pt,
double  theta 
) [private]

Definition at line 1982 of file ShapeSweep.cpp.

References iData, maxInc, n, nbInc, Shape::incidenceData::nextInc, Shape::incidenceData::pt, swsData, and Shape::incidenceData::theta.

Referenced by CreateIncidence(), and TesteAdjacency().

{
  if (theta < 0 || theta > 1)
    return -1;

  if (nbInc >= maxInc)
    {
      maxInc = 2 * nbInc + 1;
      iData =
    (incidenceData *) g_realloc(iData, maxInc * sizeof (incidenceData));
    }
  int n = nbInc++;
  iData[n].nextInc = a->swsData[cb].firstLinkedPoint;
  iData[n].pt = pt;
  iData[n].theta = theta;
  a->swsData[cb].firstLinkedPoint = n;
  return n;
}

int Shape::QuickRasterAddEdge ( int  bord,
double  x,
int  guess 
) [private]

Definition at line 395 of file ShapeRaster.cpp.

References Shape::quick_raster_data::bord, c, CmpQRs(), firstQRas, Shape::quick_raster_data::ind, lastQRas, nbQRas, Shape::quick_raster_data::next, Shape::quick_raster_data::prev, qrsData, and Shape::quick_raster_data::x.

Referenced by DirectQuickScan(), and QuickScan().

{
    int no = nbQRas++;
    qrsData[no].bord = bord;
    qrsData[no].x = x;
    qrsData[bord].ind = no;
    qrsData[no].prev = -1;
    qrsData[no].next = -1;
    
    if ( no < 0 || no >= nbQRas ) {
        return -1;
    }
  
    if ( firstQRas < 0 ) {
        firstQRas = lastQRas = no;
        qrsData[no].prev = -1;
        qrsData[no].next = -1;
        return no;
    }

    if ( guess < 0 || guess >= nbQRas ) {

        int c = firstQRas;
        while ( c >= 0 && c < nbQRas && CmpQRs(qrsData[c],qrsData[no]) < 0 ) {
            c = qrsData[c].next;
        }
        
        if ( c < 0 || c >= nbQRas ) {
            qrsData[no].prev = lastQRas;
            qrsData[lastQRas].next = no;
            lastQRas = no;
        } else {
            qrsData[no].prev = qrsData[c].prev;
            if ( qrsData[no].prev >= 0 ) {
                qrsData[qrsData[no].prev].next=no;
            } else {
                firstQRas = no;
            }
            
            qrsData[no].next = c;
            qrsData[c].prev = no;
        }
        
    } else {
        int c = guess;
        int stTst = CmpQRs(qrsData[c],qrsData[no]);
        if ( stTst == 0 ) {

            qrsData[no].prev = qrsData[c].prev;
            if ( qrsData[no].prev >= 0 ) {
                qrsData[qrsData[no].prev].next = no;
            } else {
                firstQRas = no;
            }
            
            qrsData[no].next = c;
            qrsData[c].prev = no;
            
        } else if ( stTst > 0 ) {

            while ( c >= 0 && c < nbQRas && CmpQRs(qrsData[c],qrsData[no]) > 0 ) {
                c = qrsData[c].prev;
            }
            
            if ( c < 0 || c >= nbQRas ) {
                qrsData[no].next = firstQRas;
                qrsData[firstQRas].prev = no; // firstQRas != -1
                firstQRas = no;
            } else {
                qrsData[no].next = qrsData[c].next;
                if ( qrsData[no].next >= 0 ) {
                    qrsData[qrsData[no].next].prev = no;
                } else {
                    lastQRas = no;
                }
                qrsData[no].prev = c;
                qrsData[c].next = no;
            }
            
        } else {

            while ( c >= 0 && c < nbQRas && CmpQRs(qrsData[c],qrsData[no]) < 0 ) {
                c = qrsData[c].next;
            }
            
            if ( c < 0 || c >= nbQRas ) {
                qrsData[no].prev = lastQRas;
                qrsData[lastQRas].next = no;
                lastQRas = no;
            } else {
                qrsData[no].prev = qrsData[c].prev;
                if ( qrsData[no].prev >= 0 ) {
                    qrsData[qrsData[no].prev].next = no;
                } else {
                    firstQRas = no;
                }
                
                qrsData[no].next = c;
                qrsData[c].prev = no;
            }
        }
    }
  
    return no;
}

int Shape::QuickRasterChgEdge ( int  oBord,
int  nbord,
double  x 
) [private]

Definition at line 376 of file ShapeRaster.cpp.

References Shape::quick_raster_data::bord, Shape::quick_raster_data::ind, qrsData, and Shape::quick_raster_data::x.

Referenced by QuickScan().

{
    if ( oBord == nBord ) {
        return -1;
    }
    
    int no = qrsData[oBord].ind;
    if ( no >= 0 ) {
        qrsData[no].bord = nBord;
        qrsData[no].x = x;
        qrsData[oBord].ind = -1;
        qrsData[nBord].ind = no;
    }
    
    return no;
}

void Shape::QuickRasterSort (  )  [private]

Definition at line 575 of file ShapeRaster.cpp.

References Shape::quick_raster_data::bord, CmpQRs(), firstQRas, Shape::quick_raster_data::ind, nbQRas, Shape::quick_raster_data::next, Shape::quick_raster_data::prev, qrsData, and QuickRasterSwapEdge().

Referenced by DirectQuickScan(), and QuickScan().

{
    if ( nbQRas <= 1 ) {
        return;
    }
    
    int cb = qrsData[firstQRas].bord;
    
    while ( cb >= 0 ) {
        int bI = qrsData[cb].ind;
        int nI = qrsData[bI].next;
        
        if ( nI < 0 ) {
            break;
        }
    
        int ncb = qrsData[nI].bord;
        if ( CmpQRs(qrsData[nI], qrsData[bI]) < 0 ) {
            QuickRasterSwapEdge(cb, ncb);
            int pI = qrsData[bI].prev; // ca reste bI, puisqu'on a juste echange les contenus
            if ( pI < 0 ) {
                cb = ncb; // en fait inutile; mais bon...
            } else {
                int pcb = qrsData[pI].bord;
                cb = pcb;
            }
        } else {
            cb = ncb;
        }
    }
}

void Shape::QuickRasterSubEdge ( int  bord  )  [private]

Definition at line 503 of file ShapeRaster.cpp.

References Shape::quick_raster_data::bord, firstQRas, Shape::quick_raster_data::ind, lastQRas, nbQRas, Shape::quick_raster_data::next, Shape::quick_raster_data::prev, and qrsData.

Referenced by DirectQuickScan(), and QuickScan().

{
    int no = qrsData[bord].ind;
    if ( no < 0 || no >= nbQRas ) {
        return; // euuhHHH
    }
    
    if ( qrsData[no].prev >= 0 ) {
        qrsData[qrsData[no].prev].next=qrsData[no].next;
    }
    
    if ( qrsData[no].next >= 0 ) {
        qrsData[qrsData[no].next].prev = qrsData[no].prev;
    }
    
    if ( no == firstQRas ) {
        firstQRas = qrsData[no].next;
    }
    
    if ( no == lastQRas ) {
        lastQRas = qrsData[no].prev;
    }
    
    qrsData[no].prev = qrsData[no].next = -1;
  
    int savInd = qrsData[no].ind;
    qrsData[no] = qrsData[--nbQRas];
    qrsData[no].ind = savInd;
    qrsData[qrsData[no].bord].ind = no;
    qrsData[bord].ind = -1;
  
    if ( nbQRas > 0 ) {
        if ( firstQRas == nbQRas ) {
            firstQRas = no;
        }
        if ( lastQRas == nbQRas ) {
            lastQRas = no;
        }
        if ( qrsData[no].prev >= 0 ) {
            qrsData[qrsData[no].prev].next = no;
        }
        if ( qrsData[no].next >= 0 ) {
            qrsData[qrsData[no].next].prev = no;
        }
    }  
}

void Shape::QuickRasterSwapEdge ( int  a,
int  b 
) [private]

Definition at line 552 of file ShapeRaster.cpp.

References Shape::quick_raster_data::bord, Shape::quick_raster_data::ind, nbQRas, qrsData, and Shape::quick_raster_data::x.

Referenced by QuickRasterSort().

{
    if ( a == b ) {
        return;
    }
    
    int na = qrsData[a].ind;
    int nb = qrsData[b].ind;
    if ( na < 0 || na >= nbQRas || nb < 0 || nb >= nbQRas ) {
        return; // errrm
    }
  
    qrsData[na].bord = b;
    qrsData[nb].bord = a;
    qrsData[a].ind = nb;
    qrsData[b].ind = na;
    
    double swd = qrsData[na].x;
    qrsData[na].x = qrsData[nb].x;
    qrsData[nb].x = swd;
}

void Shape::QuickScan ( float &  pos,
int &  curP,
float  to,
bool  doSort,
float  step 
)

Definition at line 276 of file ShapeRaster.cpp.

References _countUpDown(), AvanceEdge(), Shape::quick_raster_data::bord, CreateEdge(), NR::d, addnodes::e, Shape::dg_arete::en, getEdge(), getPoint(), Barcode::Code39Ext::i, Shape::dg_point::incidentEdge, max, min, nbQRas, NextAt(), NULL, numberOfEdges(), numberOfPoints(), qrsData, QuickRasterAddEdge(), QuickRasterChgEdge(), QuickRasterSort(), QuickRasterSubEdge(), Shape::dg_arete::st, swrData, Shape::quick_raster_data::x, Shape::dg_point::x, and voronoi::x.

Referenced by raster_glyph::LoadSubPixelPosition(), and nr_pixblock_render_shape_mask_or().

{
    if ( numberOfEdges() <= 1 ) {
        return;
    }
    
    if ( pos == to ) {
        return;
    }

    enum Direction {
        DOWNWARDS,
        UPWARDS
    };

    Direction const d = (pos < to) ? DOWNWARDS : UPWARDS;
    
    int curPt = curP;
    while ( (d == DOWNWARDS && curPt < numberOfPoints() && getPoint(curPt    ).x[1] <= to) ||
            (d == UPWARDS   && curPt > 0                && getPoint(curPt - 1).x[1] >= to) )
    {
        int nPt = (d == DOWNWARDS) ? curPt++ : --curPt;

        int nbUp;
        int nbDn;
        int upNo;
        int dnNo;
        _countUpDown(nPt, &nbUp, &nbDn, &upNo, &dnNo);
            
        if ( nbDn <= 0 ) {
            upNo = -1;
        }
        if ( upNo >= 0 && swrData[upNo].misc == NULL ) {
            upNo = -1;
        }

        if ( nbUp > 0 ) {
            int cb = getPoint(nPt).incidentEdge[FIRST];
            while ( cb >= 0 && cb < numberOfEdges() ) {
                Shape::dg_arete const &e = getEdge(cb);
                if ( (d == DOWNWARDS && nPt == std::max(e.st, e.en)) ||
                     (d == UPWARDS && nPt == std::min(e.st, e.en)) )
                {
                    if ( cb != upNo ) {
                        QuickRasterSubEdge(cb);
                    }
                }
                cb = NextAt(nPt,cb);
            }
        }

        // traitement du "upNo devient dnNo"
        int ins_guess = -1;
        if ( dnNo >= 0 ) {
            if ( upNo >= 0 ) {
                ins_guess = QuickRasterChgEdge(upNo, dnNo, getPoint(nPt).x[0]);
            } else {
                ins_guess = QuickRasterAddEdge(dnNo, getPoint(nPt).x[0], ins_guess);
            }
            CreateEdge(dnNo, to, step);
        }

        if ( nbDn > 1 ) { // si nbDn == 1 , alors dnNo a deja ete traite
            int cb = getPoint(nPt).incidentEdge[FIRST];
            while ( cb >= 0 && cb < numberOfEdges() ) {
                Shape::dg_arete const &e = getEdge(cb);
                if ( (d == DOWNWARDS && nPt == std::min(e.st, e.en)) ||
                     (d == UPWARDS && nPt == std::max(e.st, e.en)) )
                {
                    if ( cb != dnNo ) {
                        ins_guess = QuickRasterAddEdge(cb, getPoint(nPt).x[0], ins_guess);
                        CreateEdge(cb, to, step);
                    }
                }
                cb = NextAt(nPt,cb);
            }
        }
    
        
        curP = curPt;
        if ( curPt > 0 ) {
            pos = getPoint(curPt-1).x[1];
        } else {
            pos = to;
        }
    }

    pos = to;
        
    for (int i=0; i < nbQRas; i++) {
        int cb = qrsData[i].bord;
        AvanceEdge(cb, to, true, step);
        qrsData[i].x=swrData[cb].curX;
    }
    
    QuickRasterSort();
}

void Shape::QuickScan ( float &  pos,
int &  curP,
float  to,
FloatLigne line,
float  step 
)

Definition at line 1234 of file ShapeRaster.cpp.

References _countUpDown(), _countUpDownTotalDegree2(), _updateIntersection(), FloatLigne::AppendBord(), AvanceEdge(), Shape::quick_raster_data::bord, CreateEdge(), DestroyEdge(), addnodes::e, Shape::dg_arete::en, firstQRas, getEdge(), getPoint(), Barcode::Code39Ext::i, Shape::dg_point::incidentEdge, max, min, nbQRas, Shape::quick_raster_data::next, NextAt(), NULL, numberOfEdges(), numberOfPoints(), qrsData, QuickRasterAddEdge(), QuickRasterChgEdge(), QuickRasterSort(), QuickRasterSubEdge(), Shape::dg_arete::st, swrData, Shape::quick_raster_data::x, Shape::dg_point::x, and voronoi::x.

{
    if ( numberOfEdges() <= 1 ) {
        return;
    }
    
    if ( pos >= to ) {
        return;
    }
    
    if ( nbQRas > 1 ) {
        int curW = 0;
        float lastX = 0;
        float lastY = 0;
        int lastGuess = -1;
        int lastB = -1;
        
        for (int i = firstQRas; i >= 0 && i < nbQRas; i = qrsData[i].next) {
            int cb = qrsData[i].bord;
            int oW = curW;
            if ( swrData[cb].sens ) {
                curW++;
            } else {
                curW--;
            }

            if ( curW % 2 == 0 && oW % 2 != 0) {

                lastGuess = line->AppendBord(swrData[lastB].curX,
                                             to - swrData[lastB].curY,
                                             swrData[cb].curX,
                                             to - swrData[cb].curY,
                                             0.0);
                
                swrData[cb].guess = lastGuess;
                if ( lastB >= 0 ) {
                    swrData[lastB].guess = lastGuess - 1;
                }
                
            } else if ( curW%2 != 0 && oW%2 == 0 ) {

                lastX = swrData[cb].curX;
                lastY = swrData[cb].curY;
                lastB = cb;
                swrData[cb].guess = -1;
                
            } else {
                swrData[cb].guess = -1;
            }
        }
    }

    int curPt = curP;
    while ( curPt < numberOfPoints() && getPoint(curPt).x[1] <= to ) {
        int nPt = curPt++;

        int nbUp;
        int nbDn;
        int upNo;
        int dnNo;
        if ( getPoint(nPt).totalDegree() == 2 ) {
            _countUpDownTotalDegree2(nPt, &nbUp, &nbDn, &upNo, &dnNo);
        } else {
            _countUpDown(nPt, &nbUp, &nbDn, &upNo, &dnNo);
        }

        if ( nbDn <= 0 ) {
            upNo = -1;
        }
        if ( upNo >= 0 && swrData[upNo].misc == NULL ) {
            upNo = -1;
        }

        if ( nbUp > 1 || ( nbUp == 1 && upNo < 0 ) ) {
            int cb = getPoint(nPt).incidentEdge[FIRST];
            while ( cb >= 0 && cb < numberOfEdges() ) {
                Shape::dg_arete const &e = getEdge(cb);
                if ( nPt == std::max(e.st, e.en) ) {
                    if ( cb != upNo ) {
                        QuickRasterSubEdge(cb);
                        _updateIntersection(cb, nPt);
                        DestroyEdge(cb, to, line);
                    }
                }
                cb = NextAt(nPt, cb);
            }
        }

        // traitement du "upNo devient dnNo"
        int ins_guess=-1;
        if ( dnNo >= 0 ) {
            if ( upNo >= 0 ) {
                ins_guess = QuickRasterChgEdge(upNo ,dnNo, getPoint(nPt).x[0]);
                _updateIntersection(upNo, nPt);
                DestroyEdge(upNo, to, line);

                CreateEdge(dnNo, to, step);
                swrData[dnNo].guess = swrData[upNo].guess;
            } else {
                ins_guess = QuickRasterAddEdge(dnNo, getPoint(nPt).x[0], ins_guess);
                CreateEdge(dnNo, to, step);
            }
        }
        
        if ( nbDn > 1 ) { // si nbDn == 1 , alors dnNo a deja ete traite
            int cb = getPoint(nPt).incidentEdge[FIRST];
            while ( cb >= 0 && cb < numberOfEdges() ) {
                Shape::dg_arete const &e = getEdge(cb);
                if ( nPt == std::min(e.st, e.en) ) {
                    if ( cb != dnNo ) {
                        ins_guess = QuickRasterAddEdge(cb, getPoint(nPt).x[0], ins_guess);
                        CreateEdge(cb, to, step);
                    }
                }
                cb = NextAt(nPt, cb);
            }
        }
    }
    
    curP = curPt;
    if ( curPt > 0 ) {
        pos = getPoint(curPt-1).x[1];
    } else {
        pos=to;
    }
    
    pos = to;
    for (int i=0; i < nbQRas; i++) {
        int cb = qrsData[i].bord;
        AvanceEdge(cb, to, line, true, step);
        qrsData[i].x = swrData[cb].curX;
    }
    
    QuickRasterSort();
}

void Shape::QuickScan ( float &  pos,
int &  curP,
float  to,
FillRule  directed,
BitLigne line,
float  step 
)

Definition at line 1373 of file ShapeRaster.cpp.

References _countUpDown(), _countUpDownTotalDegree2(), _updateIntersection(), BitLigne::AddBord(), AvanceEdge(), Shape::quick_raster_data::bord, CreateEdge(), DestroyEdge(), addnodes::e, Shape::dg_arete::en, fill_nonZero, fill_oddEven, fill_positive, firstQRas, getEdge(), getPoint(), Barcode::Code39Ext::i, Shape::dg_point::incidentEdge, max, min, nbQRas, Shape::quick_raster_data::next, NextAt(), NULL, numberOfEdges(), numberOfPoints(), qrsData, QuickRasterAddEdge(), QuickRasterChgEdge(), QuickRasterSort(), QuickRasterSubEdge(), Shape::dg_arete::st, swrData, Shape::quick_raster_data::x, Shape::dg_point::x, and voronoi::x.

{
    if ( numberOfEdges() <= 1 ) {
        return;
    }

    if ( pos >= to ) {
        return;
    }
    
    if ( nbQRas > 1 ) {
        int curW = 0;
        float lastX = 0;

        if ( directed == fill_oddEven ) {

            for (int i = firstQRas; i >= 0 && i < nbQRas; i = qrsData[i].next) {
                int cb = qrsData[i].bord;
                curW++;
                curW &= 1;
                if ( curW == 0 ) {
                    line->AddBord(lastX, swrData[cb].curX, true);
                } else {
                    lastX = swrData[cb].curX;
                }
            }

        } else if ( directed == fill_positive ) {
            // doesn't behave correctly; no way i know to do this without a ConvertToShape()
            for (int i = firstQRas; i >= 0 && i < nbQRas; i = qrsData[i].next) {
                int cb = qrsData[i].bord;
                int oW = curW;
                if ( swrData[cb].sens ) {
                    curW++;
                } else {
                    curW--;
                }

                if ( curW <= 0 && oW > 0) {
                    line->AddBord(lastX, swrData[cb].curX, true);
                } else if ( curW > 0 && oW <= 0 ) {
                    lastX = swrData[cb].curX;
                }
            }

        } else if ( directed == fill_nonZero ) {
            for (int i = firstQRas; i >= 0 && i < nbQRas; i = qrsData[i].next) {
                int cb = qrsData[i].bord;
                int oW = curW;
                if ( swrData[cb].sens ) {
                    curW++;
                } else {
                    curW--;
                }

                if ( curW == 0 && oW != 0) {
                    line->AddBord(lastX, swrData[cb].curX, true);
                } else if ( curW != 0 && oW == 0 ) {
                    lastX = swrData[cb].curX;
                }
            }
        }
    }

    int curPt = curP;
    while ( curPt < numberOfPoints() && getPoint(curPt).x[1] <= to ) {
        int nPt = -1;
        nPt = curPt++;
        
        int nbUp;
        int nbDn;
        int upNo;
        int dnNo;
        if ( getPoint(nPt).totalDegree() == 2 ) {
            _countUpDownTotalDegree2(nPt, &nbUp, &nbDn, &upNo, &dnNo);
        } else {
            _countUpDown(nPt, &nbUp, &nbDn, &upNo, &dnNo);
        }

        if ( nbDn <= 0 ) {
            upNo = -1;
        }
        
        if ( upNo >= 0 && swrData[upNo].misc == NULL ) {
            upNo = -1;
        }

        if ( nbUp > 1 || ( nbUp == 1 && upNo < 0 ) ) {
            int cb = getPoint(nPt).incidentEdge[FIRST];
            while ( cb >= 0 && cb < numberOfEdges() ) {
                Shape::dg_arete const &e = getEdge(cb);
                if ( nPt == std::max(e.st, e.en) ) {
                    if ( cb != upNo ) {
                        QuickRasterSubEdge(cb);
                        _updateIntersection(cb, nPt);
                        DestroyEdge(cb, line);
                    }
                }
                cb = NextAt(nPt, cb);
            }
        }
        
        // traitement du "upNo devient dnNo"
        int ins_guess = -1;
        if ( dnNo >= 0 ) {
            if ( upNo >= 0 ) {
                ins_guess = QuickRasterChgEdge(upNo, dnNo, getPoint(nPt).x[0]);
                _updateIntersection(upNo, nPt);
                DestroyEdge(upNo, line);
                
                CreateEdge(dnNo, to, step);
            } else {
                ins_guess = QuickRasterAddEdge(dnNo, getPoint(nPt).x[0], ins_guess);
                CreateEdge(dnNo, to, step);
            }
        }

        if ( nbDn > 1 ) { // si nbDn == 1 , alors dnNo a deja ete traite
            int cb = getPoint(nPt).incidentEdge[FIRST];
            while ( cb >= 0 && cb < numberOfEdges() ) {
                Shape::dg_arete const &e = getEdge(cb);
                if ( nPt == std::min(e.st, e.en) ) {
                    if ( cb != dnNo ) {
                        ins_guess = QuickRasterAddEdge(cb, getPoint(nPt).x[0], ins_guess);
                        CreateEdge(cb, to, step);
                    }
                }
                cb = NextAt(nPt,cb);
            }
        }
    }
    
    curP = curPt;
    if ( curPt > 0 ) {
        pos=getPoint(curPt - 1).x[1];
    } else {
        pos = to;
    }
    
    pos = to;
    for (int i = 0; i < nbQRas; i++) {
        int cb = qrsData[i].bord;
        AvanceEdge(cb, to, line, true, step);
        qrsData[i].x = swrData[cb].curX;
    }
    
    QuickRasterSort();
}

void Shape::QuickScan ( float &  pos,
int &  curP,
float  to,
AlphaLigne line,
float  step 
)

Definition at line 1524 of file ShapeRaster.cpp.

References _countUpDown(), _countUpDownTotalDegree2(), _updateIntersection(), AvanceEdge(), Shape::quick_raster_data::bord, CreateEdge(), DestroyEdge(), addnodes::e, Shape::dg_arete::en, getEdge(), getPoint(), Barcode::Code39Ext::i, Shape::dg_point::incidentEdge, max, min, nbQRas, NextAt(), NULL, numberOfEdges(), numberOfPoints(), qrsData, QuickRasterAddEdge(), QuickRasterChgEdge(), QuickRasterSort(), QuickRasterSubEdge(), Shape::dg_arete::st, swrData, Shape::quick_raster_data::x, Shape::dg_point::x, and voronoi::x.

{
    if ( numberOfEdges() <= 1 ) {
        return;
    }
    if ( pos >= to ) {
        return;
    }
    
    int curPt = curP;
    while ( curPt < numberOfPoints() && getPoint(curPt).x[1] <= to ) {
        int nPt = curPt++;

        int nbUp;
        int nbDn;
        int upNo;
        int dnNo;
        if ( getPoint(nPt).totalDegree() == 2 ) {
            _countUpDownTotalDegree2(nPt, &nbUp, &nbDn, &upNo, &dnNo);
        } else {
            _countUpDown(nPt, &nbUp, &nbDn, &upNo, &dnNo);
        }
        
        if ( nbDn <= 0 ) {
            upNo = -1;
        }
        if ( upNo >= 0 && swrData[upNo].misc == NULL ) {
            upNo = -1;
        }

        if ( nbUp > 1 || ( nbUp == 1 && upNo < 0 ) ) {
            int cb = getPoint(nPt).incidentEdge[FIRST];
            while ( cb >= 0 && cb < numberOfEdges() ) {
                Shape::dg_arete const &e = getEdge(cb);
                if ( nPt == std::max(e.st, e.en) ) {
                    if ( cb != upNo ) {
                        QuickRasterSubEdge(cb);
                        _updateIntersection(cb, nPt);
                        DestroyEdge(cb, line);
                    }
                }
                cb = NextAt(nPt,cb);
            }
        }

        // traitement du "upNo devient dnNo"
        int ins_guess = -1;
        if ( dnNo >= 0 ) {
            if ( upNo >= 0 ) {
                ins_guess = QuickRasterChgEdge(upNo, dnNo, getPoint(nPt).x[0]);
                _updateIntersection(upNo, nPt);
                DestroyEdge(upNo, line);

                CreateEdge(dnNo, to, step);
                swrData[dnNo].guess = swrData[upNo].guess;
            } else {
                ins_guess = QuickRasterAddEdge(dnNo, getPoint(nPt).x[0], ins_guess);
                CreateEdge(dnNo, to, step);
            }
        }

        if ( nbDn > 1 ) { // si nbDn == 1 , alors dnNo a deja ete traite
            int cb = getPoint(nPt).incidentEdge[FIRST];
            while ( cb >= 0 && cb < numberOfEdges() ) {
                Shape::dg_arete const &e = getEdge(cb);
                if ( nPt == std::min(e.st, e.en) ) {
                    if ( cb != dnNo ) {
                        ins_guess = QuickRasterAddEdge(cb,getPoint(nPt).x[0], ins_guess);
                        CreateEdge(cb, to, step);
                    }
                }
                cb = NextAt(nPt,cb);
            }
        }
    }

    curP = curPt;
    if ( curPt > 0 ) {
        pos = getPoint(curPt-1).x[1];
    } else {
        pos = to;
    }
    
    pos = to;
    for (int i = 0; i < nbQRas; i++) {
        int cb = qrsData[i].bord;
        AvanceEdge(cb, to, line, true, step);
        qrsData[i].x = swrData[cb].curX;
    }
    
    QuickRasterSort();
}

int Shape::ReFormeArcTo ( int  bord,
int  curBord,
Path dest,
Path orig 
) [private]

Definition at line 1019 of file ShapeMisc.cpp.

References PathDescrArcTo::angle, Path::ArcAngles(), Path::ArcTo(), PathDescrArcTo::clockwise, CxxTest::delta(), Path::descr_cmd, ebData, getEdge(), getPoint(), PathDescrArcTo::large, M_PI, PathDescrArcTo::p, Path::PrevPoint(), PathDescrArcTo::rx, PathDescrArcTo::ry, swdData, and Shape::dg_point::x.

Referenced by AddContour().

{
  int nPiece = ebData[bord].pieceID;
  int nPath = ebData[bord].pathID;
  double ts = ebData[bord].tSt, te = ebData[bord].tEn;
  //      double  px=pts[getEdge(bord).st].x,py=pts[getEdge(bord).st].y;
  Geom::Point nx = getPoint(getEdge(bord).en).x;
  bord = swdData[bord].suivParc;
  while (bord >= 0)
  {
    if (getPoint(getEdge(bord).st).totalDegree() > 2
        || getPoint(getEdge(bord).st).oldDegree > 2)
    {
      break;
    }
    if (ebData[bord].pieceID == nPiece && ebData[bord].pathID == nPath)
    {
      if (fabs (te - ebData[bord].tSt) > 0.0001)
        {
          break;
        }
      nx = getPoint(getEdge(bord).en).x;
      te = ebData[bord].tEn;
    }
    else
    {
      break;
    }
    bord = swdData[bord].suivParc;
  }
  double sang, eang;
  PathDescrArcTo* nData = dynamic_cast<PathDescrArcTo *>(from->descr_cmd[nPiece]);
  bool nLarge = nData->large;
  bool nClockwise = nData->clockwise;
  Path::ArcAngles (from->PrevPoint (nPiece - 1), nData->p,nData->rx,nData->ry,nData->angle, nLarge, nClockwise,  sang, eang);
  if (nClockwise)
  {
    if (sang < eang)
      sang += 2 * M_PI;
  }
  else
  {
    if (sang > eang)
      sang -= 2 * M_PI;
  }
  double delta = eang - sang;
  double ndelta = delta * (te - ts);
  if (ts > te)
    nClockwise = !nClockwise;
  if (ndelta < 0)
    ndelta = -ndelta;
  if (ndelta > M_PI)
    nLarge = true;
  else
    nLarge = false;
  /*    if ( delta < 0 ) delta=-delta;
    if ( ndelta < 0 ) ndelta=-ndelta;
    if ( ( delta < M_PI && ndelta < M_PI ) || ( delta >= M_PI && ndelta >= M_PI ) ) {
        if ( ts < te ) {
        } else {
            nClockwise=!(nClockwise);
        }
    } else {
    //      nLarge=!(nLarge);
        nLarge=false; // c'est un sous-segment -> l'arc ne peut que etre plus petit
        if ( ts < te ) {
        } else {
            nClockwise=!(nClockwise);
        }
    }*/
  {
    PathDescrArcTo *nData = dynamic_cast<PathDescrArcTo *>(from->descr_cmd[nPiece]);
    dest->ArcTo (nx, nData->rx,nData->ry,nData->angle, nLarge, nClockwise);
  }
  return bord;
}

void Shape::ReFormeBezierChunk ( const Geom::Point  px,
const Geom::Point  nx,
Path dest,
int  inBezier,
int  nbInterm,
Path from,
int  p,
double  ts,
double  te 
) [private]

Definition at line 1386 of file ShapeMisc.cpp.

References Path::BezierTo(), Path::descr_cmd, Path::EndBezierTo(), Path::IntermBezierTo(), PathDescrIntermBezierTo::p, PathDescrBezierTo::p, Path::PrevPoint(), and Path::QuadraticPoint().

Referenced by ReFormeBezierTo().

{
  PathDescrBezierTo* nBData = dynamic_cast<PathDescrBezierTo*>(from->descr_cmd[inBezier]);
  Geom::Point bstx = from->PrevPoint (inBezier - 1);
  Geom::Point benx = nBData->p;
  
  Geom::Point mx;
  if (p == inBezier)
  {
    // premier bout
    if (nbInterm <= 1)
    {
      // seul bout de la spline
      PathDescrIntermBezierTo *nData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[inBezier+1]);
      mx = nData->p;
    }
    else
    {
      // premier bout d'une spline qui en contient plusieurs
      PathDescrIntermBezierTo *nData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[inBezier+1]);
      mx = nData->p;
      nData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[inBezier+2]);
      benx = (nData->p + mx) / 2;
    }
  }
  else if (p == inBezier + nbInterm - 1)
  {
    // dernier bout
    // si nbInterm == 1, le cas a deja ete traite
    // donc dernier bout d'une spline qui en contient plusieurs
    PathDescrIntermBezierTo* nData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[inBezier+nbInterm]);
    mx = nData->p;
    nData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[inBezier+nbInterm-1]);
    bstx = (nData->p + mx) / 2;
  }
  else
  {
    // la spline contient forcément plusieurs bouts, et ce n'est ni le premier ni le dernier
    PathDescrIntermBezierTo *nData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[p+1]);
    mx = nData->p;
    nData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[p]);
    bstx = (nData->p + mx) / 2;
    nData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[p+2]);
    benx = (nData->p + mx) / 2;
  }
  Geom::Point cx;
  {
    Path::QuadraticPoint ((ts + te) / 2, cx, bstx, mx, benx);
  }
  cx = 2 * cx - (px + nx) / 2;
  {
    dest->BezierTo (nx);
    dest->IntermBezierTo (cx);
    dest->EndBezierTo ();
  }
}

int Shape::ReFormeBezierTo ( int  bord,
int  curBord,
Path dest,
Path orig 
) [private]

Definition at line 1143 of file ShapeMisc.cpp.

References Path::BezierTo(), descr_bezierto, Path::descr_cmd, ebData, Path::EndBezierTo(), getEdge(), getPoint(), Barcode::Code39Ext::i, Path::IntermBezierTo(), Path::LineTo(), n, PathDescrBezierTo::nb, NULL, PathDescrIntermBezierTo::p, ReFormeBezierChunk(), swdData, and Shape::dg_point::x.

Referenced by AddContour().

{
  int nPiece = ebData[bord].pieceID;
  int nPath = ebData[bord].pathID;
  double ts = ebData[bord].tSt, te = ebData[bord].tEn;
  int ps = nPiece, pe = nPiece;
  Geom::Point px = getPoint(getEdge(bord).st).x;
  Geom::Point nx = getPoint(getEdge(bord).en).x;
  int inBezier = -1, nbInterm = -1;
  int typ;
  typ = from->descr_cmd[nPiece]->getType();
  PathDescrBezierTo *nBData = NULL;
  if (typ == descr_bezierto)
  {
    nBData = dynamic_cast<PathDescrBezierTo *>(from->descr_cmd[nPiece]);
    inBezier = nPiece;
    nbInterm = nBData->nb;
  }
  else
  {
    int n = nPiece - 1;
    while (n > 0)
    {
      typ = from->descr_cmd[n]->getType();
      if (typ == descr_bezierto)
      {
        inBezier = n;
        nBData = dynamic_cast<PathDescrBezierTo *>(from->descr_cmd[n]);
        nbInterm = nBData->nb;
        break;
      }
      n--;
    }
    if (inBezier < 0)
    {
      bord = swdData[bord].suivParc;
      dest->LineTo (nx);
      return bord;
    }
  }
  bord = swdData[bord].suivParc;
  while (bord >= 0)
  {
    if (getPoint(getEdge(bord).st).totalDegree() > 2
        || getPoint(getEdge(bord).st).oldDegree > 2)
    {
      break;
    }
    if (ebData[bord].pathID == nPath)
    {
      if (ebData[bord].pieceID < inBezier
          || ebData[bord].pieceID >= inBezier + nbInterm)
        break;
      if (ebData[bord].pieceID == pe
          && fabs (te - ebData[bord].tSt) > 0.0001)
        break;
      if (ebData[bord].pieceID != pe
          && (ebData[bord].tSt > 0.0001 && ebData[bord].tSt < 0.9999))
        break;
      if (ebData[bord].pieceID != pe && (te > 0.0001 && te < 0.9999))
        break;
      nx = getPoint(getEdge(bord).en).x;
      te = ebData[bord].tEn;
      pe = ebData[bord].pieceID;
    }
    else
    {
      break;
    }
    bord = swdData[bord].suivParc;
  }

  g_return_val_if_fail(nBData != NULL, 0);
  
  if (pe == ps)
  {
    ReFormeBezierChunk (px, nx, dest, inBezier, nbInterm, from, ps,
                        ts, te);
  }
  else if (ps < pe)
  {
    if (ts < 0.0001)
    {
      if (te > 0.9999)
      {
        dest->BezierTo (nx);
        for (int i = ps; i <= pe; i++)
        {
          PathDescrIntermBezierTo *nData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[i+1]);
          dest->IntermBezierTo (nData->p);
        }
        dest->EndBezierTo ();
      }
      else
      {
        Geom::Point tx;
        {
          PathDescrIntermBezierTo* psData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[pe]);
          PathDescrIntermBezierTo* pnData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[pe+1]);
          tx = (pnData->p + psData->p) / 2;
        }
        dest->BezierTo (tx);
        for (int i = ps; i < pe; i++)
        {
          PathDescrIntermBezierTo* nData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[i+1]);
          dest->IntermBezierTo (nData->p);
        }
        dest->EndBezierTo ();
        ReFormeBezierChunk (tx, nx, dest, inBezier, nbInterm,
                            from, pe, 0.0, te);
      }
    }
    else
    {
      if (te > 0.9999)
      {
        Geom::Point tx;
        {
          PathDescrIntermBezierTo* psData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[ps+1]);
          PathDescrIntermBezierTo* pnData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[ps+2]);
          tx = (psData->p +  pnData->p) / 2;
        }
        ReFormeBezierChunk (px, tx, dest, inBezier, nbInterm,
                            from, ps, ts, 1.0);
        dest->BezierTo (nx);
        for (int i = ps + 1; i <= pe; i++)
        {
          PathDescrIntermBezierTo *nData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[i+1]);
          dest->IntermBezierTo (nData->p);
        }
        dest->EndBezierTo ();
      }
      else
      {
        Geom::Point tx;
        {
          PathDescrIntermBezierTo* psData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[ps+1]);
          PathDescrIntermBezierTo* pnData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[ps+2]);
          tx = (pnData->p + psData->p) / 2;
        }
        ReFormeBezierChunk (px, tx, dest, inBezier, nbInterm,
                            from, ps, ts, 1.0);
        {
          PathDescrIntermBezierTo* psData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[pe]);
          PathDescrIntermBezierTo* pnData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[pe+1]);
          tx = (pnData->p + psData->p) / 2;
        }
         dest->BezierTo (tx);
        for (int i = ps + 1; i <= pe; i++)
        {
          PathDescrIntermBezierTo* nData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[i+1]);
          dest->IntermBezierTo (nData->p);
        }
        dest->EndBezierTo ();
        ReFormeBezierChunk (tx, nx, dest, inBezier, nbInterm,
                            from, pe, 0.0, te);
      }
    }
  }
  else
  {
    if (ts > 0.9999)
    {
      if (te < 0.0001)
      {
        dest->BezierTo (nx);
        for (int i = ps; i >= pe; i--)
        {
          PathDescrIntermBezierTo* nData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[i+1]);
          dest->IntermBezierTo (nData->p);
        }
        dest->EndBezierTo ();
      }
      else
      {
        Geom::Point tx;
        {
          PathDescrIntermBezierTo* psData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[pe+1]);
          PathDescrIntermBezierTo* pnData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[pe+2]);
          tx = (pnData->p + psData->p) / 2;
        }
        dest->BezierTo (tx);
        for (int i = ps; i > pe; i--)
        {
          PathDescrIntermBezierTo* nData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[i+1]);
          dest->IntermBezierTo (nData->p);
        }
        dest->EndBezierTo ();
        ReFormeBezierChunk (tx, nx, dest, inBezier, nbInterm,
                            from, pe, 1.0, te);
      }
    }
    else
    {
      if (te < 0.0001)
      {
        Geom::Point tx;
        {
          PathDescrIntermBezierTo* psData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[ps]);
          PathDescrIntermBezierTo* pnData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[ps+1]);
          tx = (pnData->p + psData->p) / 2;
        }
         ReFormeBezierChunk (px, tx, dest, inBezier, nbInterm,
                            from, ps, ts, 0.0);
        dest->BezierTo (nx);
        for (int i = ps + 1; i >= pe; i--)
        {
          PathDescrIntermBezierTo* nData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[i]);
          dest->IntermBezierTo (nData->p);
        }
        dest->EndBezierTo ();
      }
      else
      {
        Geom::Point tx;
        {
          PathDescrIntermBezierTo* psData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[ps]);
          PathDescrIntermBezierTo* pnData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[ps+1]);
          tx = (pnData->p + psData->p) / 2;
        }
        ReFormeBezierChunk (px, tx, dest, inBezier, nbInterm,
                            from, ps, ts, 0.0);
        {
          PathDescrIntermBezierTo* psData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[pe+1]);
          PathDescrIntermBezierTo* pnData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[pe+2]);
          tx = (pnData->p + psData->p) / 2;
        }
        dest->BezierTo (tx);
        for (int i = ps + 1; i > pe; i--)
        {
          PathDescrIntermBezierTo* nData = dynamic_cast<PathDescrIntermBezierTo*>(from->descr_cmd[i]);
          dest->IntermBezierTo (nData->p);
        }
        dest->EndBezierTo ();
        ReFormeBezierChunk (tx, nx, dest, inBezier, nbInterm,
                            from, pe, 1.0, te);
      }
    }
  }
  return bord;
}

int Shape::ReFormeCubicTo ( int  bord,
int  curBord,
Path dest,
Path orig 
) [private]

Definition at line 1097 of file ShapeMisc.cpp.

References Path::CubicTangent(), Path::CubicTo(), Path::descr_cmd, ebData, PathDescrCubicTo::end, getEdge(), getPoint(), PathDescrCubicTo::p, Path::PrevPoint(), PathDescrCubicTo::start, swdData, and Shape::dg_point::x.

Referenced by AddContour().

{
  int nPiece = ebData[bord].pieceID;
  int nPath = ebData[bord].pathID;
  double ts = ebData[bord].tSt, te = ebData[bord].tEn;
  Geom::Point nx = getPoint(getEdge(bord).en).x;
  bord = swdData[bord].suivParc;
  while (bord >= 0)
  {
    if (getPoint(getEdge(bord).st).totalDegree() > 2
        || getPoint(getEdge(bord).st).oldDegree > 2)
    {
      break;
    }
    if (ebData[bord].pieceID == nPiece && ebData[bord].pathID == nPath)
    {
      if (fabs (te - ebData[bord].tSt) > 0.0001)
        {
          break;
        }
      nx = getPoint(getEdge(bord).en).x;
      te = ebData[bord].tEn;
    }
    else
    {
      break;
    }
    bord = swdData[bord].suivParc;
  }
  Geom::Point prevx = from->PrevPoint (nPiece - 1);
  
  Geom::Point sDx, eDx;
  {
    PathDescrCubicTo *nData = dynamic_cast<PathDescrCubicTo *>(from->descr_cmd[nPiece]);
    Path::CubicTangent (ts, sDx, prevx,nData->start,nData->p,nData->end);
    Path::CubicTangent (te, eDx, prevx,nData->start,nData->p,nData->end);
  }
  sDx *= (te - ts);
  eDx *= (te - ts);
  {
    dest->CubicTo (nx,sDx,eDx);
  }
  return bord;
}

int Shape::ReFormeLineTo ( int  bord,
int  curBord,
Path dest,
Path orig 
) [private]

Definition at line 985 of file ShapeMisc.cpp.

References ebData, getEdge(), getPoint(), Path::LineTo(), swdData, and Shape::dg_point::x.

Referenced by AddContour().

{
  int nPiece = ebData[bord].pieceID;
  int nPath = ebData[bord].pathID;
  double /*ts=ebData[bord].tSt, */ te = ebData[bord].tEn;
  Geom::Point nx = getPoint(getEdge(bord).en).x;
  bord = swdData[bord].suivParc;
  while (bord >= 0)
  {
    if (getPoint(getEdge(bord).st).totalDegree() > 2
        || getPoint(getEdge(bord).st).oldDegree > 2)
    {
      break;
    }
    if (ebData[bord].pieceID == nPiece && ebData[bord].pathID == nPath)
    {
      if (fabs (te - ebData[bord].tSt) > 0.0001)
        break;
      nx = getPoint(getEdge(bord).en).x;
      te = ebData[bord].tEn;
    }
    else
    {
      break;
    }
    bord = swdData[bord].suivParc;
  }
  {
    dest->LineTo (nx);
  }
  return bord;
}

int Shape::Reoriente ( Shape a  ) 

Definition at line 69 of file ShapeSweep.cpp.

References _aretes, _bbox_up_to_date, _has_edges_data, _has_points_data, _has_raster_data, _has_sweep_dest_data, _has_sweep_src_data, _need_edges_sorting, _point_data_initialised, _pts, bool_op_union, directedEulerian(), eData, Shape::dg_arete::en, getEdge(), getPoint(), GetWindings(), Barcode::Code39Ext::i, initialisePointData(), Inverse(), MakeEdgeData(), MakePointData(), MakeSweepDestData(), maxAr, maxPt, NULL, numberOfEdges(), numberOfPoints(), pData, Reset(), shape_input_err, SortPointsRounded(), Shape::dg_arete::st, SubEdge(), swdData, swrData, swsData, Shape::dg_point::totalDegree(), and type.

{
  Reset (0, 0);
  if (a->numberOfPoints() <= 1 || a->numberOfEdges() <= 1)
    return 0;
  if (directedEulerian(a) == false)
    return shape_input_err;

  _pts = a->_pts;
  if (numberOfPoints() > maxPt)
    {
      maxPt = numberOfPoints();
      if (_has_points_data) {
        pData.resize(maxPt);
        _point_data_initialised = false;
        _bbox_up_to_date = false;
        }
    }

  _aretes = a->_aretes;
  if (numberOfEdges() > maxAr)
    {
      maxAr = numberOfEdges();
      if (_has_edges_data)
    eData.resize(maxAr);
      if (_has_sweep_src_data)
    swsData.resize(maxAr);
      if (_has_sweep_dest_data)
    swdData.resize(maxAr);
      if (_has_raster_data)
    swrData.resize(maxAr);
    }

  MakePointData (true);
  MakeEdgeData (true);
  MakeSweepDestData (true);

  initialisePointData();

  for (int i = 0; i < numberOfPoints(); i++) {
      _pts[i].x = pData[i].rx;
      _pts[i].oldDegree = getPoint(i).totalDegree();
  }
  
  for (int i = 0; i < a->numberOfEdges(); i++)
    {
      eData[i].rdx = pData[getEdge(i).en].rx - pData[getEdge(i).st].rx;
      eData[i].weight = 1;
      _aretes[i].dx = eData[i].rdx;
    }

  SortPointsRounded ();

  _need_edges_sorting = true;
  GetWindings (this, NULL, bool_op_union, true);

//      Plot(341,56,8,400,400,true,true,false,true);
  for (int i = 0; i < numberOfEdges(); i++)
    {
      swdData[i].leW %= 2;
      swdData[i].riW %= 2;
      if (swdData[i].leW < 0)
    swdData[i].leW = -swdData[i].leW;
      if (swdData[i].riW < 0)
    swdData[i].riW = -swdData[i].riW;
      if (swdData[i].leW > 0 && swdData[i].riW <= 0)
    {
      eData[i].weight = 1;
    }
      else if (swdData[i].leW <= 0 && swdData[i].riW > 0)
    {
      Inverse (i);
      eData[i].weight = 1;
    }
      else
    {
      eData[i].weight = 0;
      SubEdge (i);
      i--;
    }
    }

  MakePointData (false);
  MakeEdgeData (false);
  MakeSweepDestData (false);

  if (directedEulerian(this) == false)
    {
//              printf( "pas euclidian2");
      _pts.clear();
      _aretes.clear();
      return shape_euler_err;
    }

  type = shape_polygon;
  return 0;
}

void Shape::Reset ( int  n = 0,
int  m = 0 
)
void Shape::ResetSweep ( void   )  [private]

Definition at line 47 of file ShapeSweep.cpp.

References MakeEdgeData(), MakePointData(), and MakeSweepSrcData().

Referenced by Booleen(), and ConvertToShape().

{
  MakePointData (true);
  MakeEdgeData (true);
  MakeSweepSrcData (true);
}

static double Shape::Round ( double  x  )  [inline, static]

Definition at line 267 of file Shape.h.

Referenced by AddPoint(), Booleen(), ConvertToForme(), ConvertToFormeNested(), ConvertToShape(), and initialisePointData().

    {
        return ldexp(rint(ldexp(x, 5)), -5);
    }

void Shape::Scan ( float &  pos,
int &  curP,
float  to,
float  step 
)

Definition at line 119 of file ShapeRaster.cpp.

References _countUpDown(), SweepTreeList::add(), AvanceEdge(), SweepTree::bord, SweepTree::ConvertTo(), CreateEdge(), NR::d, addnodes::e, AVLTree::elem, Shape::dg_arete::en, getEdge(), getPoint(), Shape::dg_point::incidentEdge, SweepTree::Insert(), SweepTree::InsertAt(), AVLTree::Leftmost(), max, min, NextAt(), NULL, numberOfEdges(), numberOfPoints(), Other(), SweepTreeList::racine, SweepTree::Remove(), sEvts, Shape::dg_arete::st, SweepTree::startPoint, sTree, swrData, Shape::dg_point::x, and voronoi::x.

Referenced by Inkscape::Text::Layout::ShapeScanlineMaker::makeScanline().

{
    if ( numberOfEdges() <= 1 ) {
        return;
    }

    if ( pos == to ) {
        return;
    }

    enum Direction {
        DOWNWARDS,
        UPWARDS
    };

    Direction const d = (pos < to) ? DOWNWARDS : UPWARDS;

    // points of the polygon are sorted top-down, so we take them in order, starting with the one at index curP,
    // until we reach the wanted position to.
    // don't forget to update curP and pos when we're done
    int curPt = curP;
    while ( ( d == DOWNWARDS && curPt < numberOfPoints() && getPoint(curPt).x[1]     <= to) ||
            ( d == UPWARDS   && curPt > 0                && getPoint(curPt - 1).x[1] >= to) )
    {
        int nPt = (d == DOWNWARDS) ? curPt++ : --curPt;
      
        // treat a new point: remove and add edges incident to it
        int nbUp;
        int nbDn;
        int upNo;
        int dnNo;
        _countUpDown(nPt, &nbUp, &nbDn, &upNo, &dnNo);

                if ( d == DOWNWARDS ) {
                    if ( nbDn <= 0 ) {
            upNo = -1;
                    }
                    if ( upNo >= 0 && swrData[upNo].misc == NULL ) {
            upNo = -1;
                    }
                } else {
                    if ( nbUp <= 0 ) {
            dnNo = -1;
                    }
                    if ( dnNo >= 0 && swrData[dnNo].misc == NULL ) {
            dnNo = -1;
                    }
                }
        
        if ( ( d == DOWNWARDS && nbUp > 0 ) || ( d == UPWARDS && nbDn > 0 ) ) {
            // first remove edges coming from above or below, as appropriate
            int cb = getPoint(nPt).incidentEdge[FIRST];
            while ( cb >= 0 && cb < numberOfEdges() ) {

                Shape::dg_arete const &e = getEdge(cb);
                if ( (d == DOWNWARDS && nPt == std::max(e.st, e.en)) ||
                     (d == UPWARDS   && nPt == std::min(e.st, e.en)) )
                {
                    if ( ( d == DOWNWARDS && cb != upNo ) || ( d == UPWARDS && cb != dnNo ) ) {
                        // we salvage the edge upNo to plug the edges we'll be addingat its place
                        // but the other edge don't have this chance
                        SweepTree *node = swrData[cb].misc;
                        if ( node ) {
                            swrData[cb].misc = NULL;
                            node->Remove(*sTree, *sEvts, true);
                        }
                    }
                }
                cb = NextAt(nPt, cb);
            }
                }
      
        // if there is one edge going down and one edge coming from above, we don't Insert() the new edge,
        // but replace the upNo edge by the new one (faster)
        SweepTree* insertionNode = NULL;
        if ( dnNo >= 0 ) {
            if ( upNo >= 0 ) {
                            int    rmNo=(d == DOWNWARDS) ? upNo:dnNo;
                            int    neNo=(d == DOWNWARDS) ? dnNo:upNo;
                              SweepTree* node = swrData[rmNo].misc;
                swrData[rmNo].misc = NULL;

                int const P = (d == DOWNWARDS) ? nPt : Other(nPt, neNo);
                node->ConvertTo(this, neNo, 1, P);
                
                swrData[neNo].misc = node;
                insertionNode = node;
                CreateEdge(neNo, to, step);
            } else {
                            // always DOWNWARDS
                SweepTree* node = sTree->add(this, dnNo, 1, nPt, this);
                swrData[dnNo].misc = node;
                node->Insert(*sTree, *sEvts, this, nPt, true);
                //if (d == UPWARDS) {
                //    node->startPoint = Other(nPt, dnNo);
                //}
                insertionNode = node;
                CreateEdge(dnNo,to,step);
            }
        } else {
                    if ( upNo >= 0 ) {
                        // always UPWARDS
                        SweepTree* node = sTree->add(this, upNo, 1, nPt, this);
                        swrData[upNo].misc = node;
                        node->Insert(*sTree, *sEvts, this, nPt, true);
                        //if (d == UPWARDS) {
                            node->startPoint = Other(nPt, upNo);
                        //}
                        insertionNode = node;
                        CreateEdge(upNo,to,step);
                    }
                }
      
        // add the remaining edges
        if ( ( d == DOWNWARDS && nbDn > 1 ) || ( d == UPWARDS && nbUp > 1 ) ) {
            // si nbDn == 1 , alors dnNo a deja ete traite
            int cb = getPoint(nPt).incidentEdge[FIRST];
            while ( cb >= 0 && cb < numberOfEdges() ) {
                Shape::dg_arete const &e = getEdge(cb);
                if ( nPt == std::min(e.st, e.en) ) {
                    if ( cb != dnNo && cb != upNo ) {
                        SweepTree *node = sTree->add(this, cb, 1, nPt, this);
                        swrData[cb].misc = node;
                        node->InsertAt(*sTree, *sEvts, this, insertionNode, nPt, true);
                        if (d == UPWARDS) {
                            node->startPoint = Other(nPt, cb);
                        }
                        CreateEdge(cb, to, step);
                    }
                }
                cb = NextAt(nPt,cb);
            }
        }
    }
        
    curP = curPt;
    if ( curPt > 0 ) {
        pos = getPoint(curPt - 1).x[1];
    } else {
        pos = to;
    }
    
    // the final touch: edges intersecting the sweepline must be update so that their intersection with
    // said sweepline is correct.
    pos = to;
    if ( sTree->racine ) {
        SweepTree* curS = static_cast<SweepTree*>(sTree->racine->Leftmost());
        while ( curS ) {
            int cb = curS->bord;
            AvanceEdge(cb, to, true, step);
            curS = static_cast<SweepTree*>(curS->elem[RIGHT]);
        }
    }
}

void Shape::Scan ( float &  pos,
int &  curP,
float  to,
FloatLigne line,
bool  exact,
float  step 
)

Definition at line 802 of file ShapeRaster.cpp.

References _countUpDown(), _countUpDownTotalDegree2(), _updateIntersection(), SweepTreeList::add(), FloatLigne::AppendBord(), AvanceEdge(), SweepTree::bord, SweepTree::ConvertTo(), CreateEdge(), DestroyEdge(), addnodes::e, AVLTree::elem, Shape::dg_arete::en, getEdge(), getPoint(), Shape::dg_point::incidentEdge, SweepTree::Insert(), SweepTree::InsertAt(), LEFT, AVLTree::Leftmost(), max, min, NextAt(), NULL, numberOfEdges(), numberOfPoints(), SweepTreeList::racine, SweepTree::Remove(), sEvts, Shape::dg_arete::st, sTree, swrData, Shape::dg_point::totalDegree(), and Shape::dg_point::x.

{
    if ( numberOfEdges() <= 1 ) {
        return;
    }
    
    if ( pos >= to ) {
        return;
    }
    
    // first step: the rectangles since we read the sweepline left to right, we know the
    // boundaries of the rectangles are appended in a list, hence the AppendBord(). we salvage
    // the guess value for the trapezoids the edges will induce
        
    if ( sTree->racine ) {
        SweepTree *curS = static_cast<SweepTree*>(sTree->racine->Leftmost());
        while ( curS ) {
            
            int lastGuess = -1;
            int cb = curS->bord;
            
            if ( swrData[cb].sens == false && curS->elem[LEFT] ) {
                
                int lb = (static_cast<SweepTree*>(curS->elem[LEFT]))->bord;
                
                lastGuess = line->AppendBord(swrData[lb].curX,
                                             to - swrData[lb].curY,
                                             swrData[cb].curX,
                                             to - swrData[cb].curY,0.0);
                
                swrData[lb].guess = lastGuess - 1;
                swrData[cb].guess = lastGuess;
            } else {
                int lb = curS->bord;
                swrData[lb].guess = -1;
            }
            
            curS=static_cast <SweepTree*> (curS->elem[RIGHT]);
        }
    }
    
    int curPt = curP;
    while ( curPt < numberOfPoints() && getPoint(curPt).x[1] <= to ) {
        
        int nPt = curPt++;

        // same thing as the usual Scan(), just with a hardcoded "indegree+outdegree=2" case, since
        // it's the most common one
        
        int nbUp;
        int nbDn;
        int upNo;
        int dnNo;
        if ( getPoint(nPt).totalDegree() == 2 ) {
            _countUpDownTotalDegree2(nPt, &nbUp, &nbDn, &upNo, &dnNo);
        } else {
            _countUpDown(nPt, &nbUp, &nbDn, &upNo, &dnNo);
        }
        
        if ( nbDn <= 0 ) {
            upNo = -1;
        }
        if ( upNo >= 0 && swrData[upNo].misc == NULL ) {
            upNo = -1;
        }

        if ( nbUp > 1 || ( nbUp == 1 && upNo < 0 ) ) {
            int cb = getPoint(nPt).incidentEdge[FIRST];
            while ( cb >= 0 && cb < numberOfEdges() ) {
                Shape::dg_arete const &e = getEdge(cb);
                if ( nPt == std::max(e.st, e.en) ) {
                    if ( cb != upNo ) {
                        SweepTree* node = swrData[cb].misc;
                        if ( node ) {
                            _updateIntersection(cb, nPt);
                            // create trapezoid for the chunk of edge intersecting with the line
                            DestroyEdge(cb, to, line);
                            node->Remove(*sTree, *sEvts, true);
                        }
                    }
                }
                
                cb = NextAt(nPt,cb);
            }
        }

        // traitement du "upNo devient dnNo"
        SweepTree *insertionNode = NULL;
        if ( dnNo >= 0 ) {
            if ( upNo >= 0 ) {
                SweepTree* node = swrData[upNo].misc;
                _updateIntersection(upNo, nPt);
                DestroyEdge(upNo, to, line);
                
                node->ConvertTo(this, dnNo, 1, nPt);
                
                swrData[dnNo].misc = node;
                insertionNode = node;
                CreateEdge(dnNo, to, step);
                swrData[dnNo].guess = swrData[upNo].guess;
            } else {
                SweepTree *node = sTree->add(this, dnNo, 1, nPt, this);
                swrData[dnNo].misc = node;
                node->Insert(*sTree, *sEvts, this, nPt, true);
                insertionNode = node;
                CreateEdge(dnNo, to, step);
            }
        }
        
        if ( nbDn > 1 ) { // si nbDn == 1 , alors dnNo a deja ete traite
            int cb = getPoint(nPt).incidentEdge[FIRST];
            while ( cb >= 0 && cb < numberOfEdges() ) {
                Shape::dg_arete const &e = getEdge(cb);
                if ( nPt == std::min(e.st, e.en) ) {
                    if ( cb != dnNo ) {
                        SweepTree *node = sTree->add(this, cb, 1, nPt, this);
                        swrData[cb].misc = node;
                        node->InsertAt(*sTree, *sEvts, this, insertionNode, nPt, true);
                        CreateEdge(cb, to, step);
                    }
                }
                cb = NextAt(nPt,cb);
            }
        }
    }
    
    curP = curPt;
    if ( curPt > 0 ) {
        pos = getPoint(curPt - 1).x[1];
    } else {
        pos = to;
    } 
    
    // update intersections with the sweepline, and add trapezoids for edges crossing the line
    pos = to;
    if ( sTree->racine ) {
        SweepTree* curS = static_cast<SweepTree*>(sTree->racine->Leftmost());
        while ( curS ) {
            int cb = curS->bord;
            AvanceEdge(cb, to, line, exact, step);
            curS = static_cast<SweepTree*>(curS->elem[RIGHT]);
        }
    }
}

void Shape::Scan ( float &  pos,
int &  curP,
float  to,
FillRule  directed,
BitLigne line,
bool  exact,
float  step 
)

Definition at line 950 of file ShapeRaster.cpp.

References _countUpDown(), _countUpDownTotalDegree2(), _updateIntersection(), SweepTreeList::add(), BitLigne::AddBord(), AvanceEdge(), SweepTree::bord, SweepTree::ConvertTo(), CreateEdge(), DestroyEdge(), addnodes::e, AVLTree::elem, Shape::dg_arete::en, fill_nonZero, fill_oddEven, fill_positive, getEdge(), getPoint(), Shape::dg_point::incidentEdge, SweepTree::Insert(), SweepTree::InsertAt(), AVLTree::Leftmost(), max, min, NextAt(), NULL, numberOfEdges(), numberOfPoints(), SweepTreeList::racine, SweepTree::Remove(), sEvts, Shape::dg_arete::st, sTree, swrData, Shape::dg_point::totalDegree(), and Shape::dg_point::x.

{
    if ( numberOfEdges() <= 1 ) {
        return;
    }
    
    if ( pos >= to ) {
        return;
    }
    
    if ( sTree->racine ) {
        int curW = 0;
        float lastX = 0;
        SweepTree* curS = static_cast<SweepTree*>(sTree->racine->Leftmost());

        if ( directed == fill_oddEven ) {

            while ( curS ) {
                int cb = curS->bord;
                curW++;
                curW &= 0x00000001;
                if ( curW == 0 ) {
                    line->AddBord(lastX,swrData[cb].curX,true);
                } else {
                    lastX = swrData[cb].curX;
                }
                curS = static_cast<SweepTree*>(curS->elem[RIGHT]);
            }
            
        } else if ( directed == fill_positive ) {

            // doesn't behave correctly; no way i know to do this without a ConvertToShape()
            while ( curS ) {
                int cb = curS->bord;
              int oW = curW;
              if ( swrData[cb].sens ) {
                  curW++;
              } else {
                  curW--;
              }

              if ( curW <= 0 && oW > 0) {
                  line->AddBord(lastX, swrData[cb].curX, true);
              } else if ( curW > 0 && oW <= 0 ) {
                  lastX = swrData[cb].curX;
              }
              
              curS = static_cast<SweepTree*>(curS->elem[RIGHT]);
            }
          
        } else if ( directed == fill_nonZero ) {

            while ( curS ) {
                int cb = curS->bord;
                int oW = curW;
                if ( swrData[cb].sens ) {
                    curW++;
                } else {
                    curW--;
                }
                
                if ( curW == 0 && oW != 0) {
                    line->AddBord(lastX,swrData[cb].curX,true);
                } else if ( curW != 0 && oW == 0 ) {
                    lastX=swrData[cb].curX;
                }
                curS = static_cast<SweepTree*>(curS->elem[RIGHT]);
            }
        }
        
    }
  
    int curPt = curP;
    while ( curPt < numberOfPoints() && getPoint(curPt).x[1] <= to ) {
        int nPt = curPt++;
        
        int cb;
        int nbUp;
        int nbDn;
        int upNo;
        int dnNo;
        
        if ( getPoint(nPt).totalDegree() == 2 ) {
            _countUpDownTotalDegree2(nPt, &nbUp, &nbDn, &upNo, &dnNo);
        } else {
            _countUpDown(nPt, &nbUp, &nbDn, &upNo, &dnNo);
        }
        
        if ( nbDn <= 0 ) {
            upNo = -1;
        }
        if ( upNo >= 0 && swrData[upNo].misc == NULL ) {
            upNo = -1;
        }
        
        if ( nbUp > 1 || ( nbUp == 1 && upNo < 0 ) ) {
            int cb = getPoint(nPt).incidentEdge[FIRST];
            while ( cb >= 0 && cb < numberOfEdges() ) {
                Shape::dg_arete const &e = getEdge(cb);
                if ( nPt == std::max(e.st, e.en) ) {
                    if ( cb != upNo ) {
                        SweepTree* node=swrData[cb].misc;
                        if ( node ) {
                            _updateIntersection(cb, nPt);
                            DestroyEdge(cb, line);
                            node->Remove(*sTree,*sEvts,true);
                        }
                    }
                }
                cb = NextAt(nPt,cb);
            }
        }
        
        // traitement du "upNo devient dnNo"
        SweepTree* insertionNode = NULL;
        if ( dnNo >= 0 ) {
            if ( upNo >= 0 ) {
                SweepTree* node = swrData[upNo].misc;
                _updateIntersection(upNo, nPt);
                DestroyEdge(upNo, line);
                
                node->ConvertTo(this, dnNo, 1, nPt);
                
                swrData[dnNo].misc = node;
                insertionNode = node;
                CreateEdge(dnNo, to, step);
                
            } else {
              
                SweepTree* node = sTree->add(this,dnNo,1,nPt,this);
                swrData[dnNo].misc = node;
                node->Insert(*sTree, *sEvts, this, nPt, true);
                insertionNode = node;
                CreateEdge(dnNo, to, step);
            }
        }
        
        if ( nbDn > 1 ) { // si nbDn == 1 , alors dnNo a deja ete traite
            cb = getPoint(nPt).incidentEdge[FIRST];
            while ( cb >= 0 && cb < numberOfEdges() ) {
                Shape::dg_arete const &e = getEdge(cb);
                if ( nPt == std::min(e.st, e.en) ) {
                    if ( cb != dnNo ) {
                        SweepTree* node = sTree->add(this, cb, 1, nPt, this);
                        swrData[cb].misc = node;
                        node->InsertAt(*sTree, *sEvts, this, insertionNode, nPt, true);
                        CreateEdge(cb, to, step);
                    }
                }
                cb = NextAt(nPt, cb);
            }
        }
    }
  
    curP = curPt;
    if ( curPt > 0 ) {
        pos = getPoint(curPt - 1).x[1];
    } else {
        pos = to;
    }
    
    pos = to;
    if ( sTree->racine ) {
        SweepTree* curS = static_cast<SweepTree*>(sTree->racine->Leftmost());
        while ( curS ) {
            int cb = curS->bord;
            AvanceEdge(cb, to, line, exact, step);
            curS = static_cast<SweepTree*>(curS->elem[RIGHT]);
        }
    }
}

void Shape::Scan ( float &  pos,
int &  curP,
float  to,
AlphaLigne line,
bool  exact,
float  step 
)

Definition at line 1123 of file ShapeRaster.cpp.

References _countUpDown(), _countUpDownTotalDegree2(), _updateIntersection(), SweepTreeList::add(), AvanceEdge(), SweepTree::bord, SweepTree::ConvertTo(), CreateEdge(), DestroyEdge(), addnodes::e, AVLTree::elem, Shape::dg_arete::en, getEdge(), getPoint(), Shape::dg_point::incidentEdge, SweepTree::Insert(), SweepTree::InsertAt(), AVLTree::Leftmost(), max, min, NextAt(), NULL, numberOfEdges(), numberOfPoints(), SweepTreeList::racine, SweepTree::Remove(), sEvts, Shape::dg_arete::st, sTree, swrData, Shape::dg_point::x, and voronoi::x.

{
    if ( numberOfEdges() <= 1 ) {
        return;
    }

    if ( pos >= to ) {
        return;
    }

    int curPt = curP;
    while ( curPt < numberOfPoints() && getPoint(curPt).x[1] <= to ) {
        int nPt = -1;
        nPt = curPt++;

        int nbUp;
        int nbDn;
        int upNo;
        int dnNo;
        if ( getPoint(nPt).totalDegree() == 2 ) {
            _countUpDownTotalDegree2(nPt, &nbUp, &nbDn, &upNo, &dnNo);
        } else {
            _countUpDown(nPt, &nbUp, &nbDn, &upNo, &dnNo);
        }

        if ( nbDn <= 0 ) {
            upNo=-1;
        }
        if ( upNo >= 0 && swrData[upNo].misc == NULL ) {
            upNo=-1;
        }

        if ( nbUp > 1 || ( nbUp == 1 && upNo < 0 ) ) {
            int cb = getPoint(nPt).incidentEdge[FIRST];
            while ( cb >= 0 && cb < numberOfEdges() ) {
                Shape::dg_arete const &e = getEdge(cb);
                if ( nPt == std::max(e.st, e.en) ) {
                    if ( cb != upNo ) {
                        SweepTree* node = swrData[cb].misc;
                        if ( node ) {
                            _updateIntersection(cb, nPt);
                            DestroyEdge(cb, line);
                            node->Remove(*sTree, *sEvts, true);
                        }
                    }
                }
                
                cb = NextAt(nPt,cb);
            }
        }

        // traitement du "upNo devient dnNo"
        SweepTree* insertionNode = NULL;
        if ( dnNo >= 0 ) {
            if ( upNo >= 0 ) {
                SweepTree* node = swrData[upNo].misc;
                _updateIntersection(upNo, nPt);
                DestroyEdge(upNo, line);

                node->ConvertTo(this, dnNo, 1, nPt);

                swrData[dnNo].misc = node;
                insertionNode = node;
                CreateEdge(dnNo, to, step);
                swrData[dnNo].guess = swrData[upNo].guess;
            } else {
                SweepTree* node = sTree->add(this, dnNo, 1, nPt, this);
                swrData[dnNo].misc = node;
                node->Insert(*sTree, *sEvts, this, nPt, true);
                insertionNode = node;
                CreateEdge(dnNo, to, step);
            }
        }

        if ( nbDn > 1 ) { // si nbDn == 1 , alors dnNo a deja ete traite
            int cb = getPoint(nPt).incidentEdge[FIRST];
            while ( cb >= 0 && cb < numberOfEdges() ) {
                Shape::dg_arete const &e = getEdge(cb);
                if ( nPt == std::min(e.st, e.en) ) {
                    if ( cb != dnNo ) {
                        SweepTree* node = sTree->add(this, cb, 1, nPt, this);
                        swrData[cb].misc = node;
                        node->InsertAt(*sTree, *sEvts, this, insertionNode, nPt, true);
                        CreateEdge(cb, to, step);
                    }
                }
                cb = NextAt(nPt,cb);
            }
        }
    }

    curP = curPt;
    if ( curPt > 0 ) {
        pos = getPoint(curPt - 1).x[1];
    } else {
        pos = to;
    }
    
    pos = to;
    if ( sTree->racine ) {
        SweepTree* curS = static_cast<SweepTree*>(sTree->racine->Leftmost());
        while ( curS ) {
            int cb = curS->bord;
            AvanceEdge(cb, to, line, exact, step);
            curS = static_cast<SweepTree*>(curS->elem[RIGHT]);
        }
    }
}

void Shape::SortEdges ( void   ) 

Definition at line 1473 of file Shape.cpp.

References _aretes, _need_edges_sorting, _pts, NR::d, Shape::dg_arete::dx, getEdge(), getPoint(), Barcode::Code39Ext::i, Shape::dg_point::incidentEdge, n, NextAt(), Shape::edge_list::no, numberOfEdges(), numberOfPoints(), uniconv-ext::p, SortEdgesList(), Shape::edge_list::starting, Shape::dg_point::totalDegree(), and Shape::edge_list::x.

Referenced by ConvertToForme(), ConvertToFormeNested(), ConvertToShape(), GetWindings(), MakeOffset(), and MakeTweak().

{
  if (_need_edges_sorting == false) {
    return;
  }
  _need_edges_sorting = false;

  edge_list *list = (edge_list *) g_malloc(numberOfEdges() * sizeof (edge_list));
  for (int p = 0; p < numberOfPoints(); p++)
    {
      int const d = getPoint(p).totalDegree();
      if (d > 1)
        {
          int cb;
          cb = getPoint(p).incidentEdge[FIRST];
          int nb = 0;
          while (cb >= 0)
            {
              int n = nb++;
              list[n].no = cb;
              if (getEdge(cb).st == p)
                {
                  list[n].x = getEdge(cb).dx;
                  list[n].starting = true;
                }
              else
                {
                  list[n].x = -getEdge(cb).dx;
                  list[n].starting = false;
                }
              cb = NextAt (p, cb);
            }
          SortEdgesList (list, 0, nb - 1);
          _pts[p].incidentEdge[FIRST] = list[0].no;
          _pts[p].incidentEdge[LAST] = list[nb - 1].no;
          for (int i = 0; i < nb; i++)
            {
              if (list[i].starting)
                {
                  if (i > 0)
                    {
                      _aretes[list[i].no].prevS = list[i - 1].no;
                    }
                  else
                    {
                      _aretes[list[i].no].prevS = -1;
                    }
                  if (i < nb - 1)
                    {
                      _aretes[list[i].no].nextS = list[i + 1].no;
                    }
                  else
                    {
                      _aretes[list[i].no].nextS = -1;
                    }
                }
              else
                {
                  if (i > 0)
                    {
                      _aretes[list[i].no].prevE = list[i - 1].no;
                    }
                  else
                    {
                      _aretes[list[i].no].prevE = -1;
                    }
                  if (i < nb - 1)
                    {
                      _aretes[list[i].no].nextE = list[i + 1].no;
                    }
                  else
                    {
                      _aretes[list[i].no].nextE = -1;
                    }
                }
            }
        }
    }
  g_free(list);
}

void Shape::SortEdgesList ( edge_list edges,
int  s,
int  e 
) [private]

Definition at line 1689 of file Shape.cpp.

References CmpToVert(), Shape::edge_list::starting, Geom::NL::swap(), Shape::edge_list::x, and voronoi::x.

Referenced by SortEdges().

{
  if (s >= e)
    return;
  if (e == s + 1) {
    int cmpval=CmpToVert (list[e].x, list[s].x,list[e].starting,list[s].starting);
    if ( cmpval > 0 )  { // priorite aux sortants
      edge_list swap = list[s];
      list[s] = list[e];
      list[e] = swap;
    }
    return;
 }

  int ppos = (s + e) / 2;
  int plast = ppos;
  Geom::Point pvalx = list[ppos].x;
  bool      pvals = list[ppos].starting;
  
  int le = s, ri = e;
  while (le < ppos || ri > plast)
    {
      if (le < ppos)
        {
          do
            {
        int test = CmpToVert (pvalx, list[le].x,pvals,list[le].starting);
              if (test == 0)
                {
                  // on colle les valeurs egales au pivot ensemble
                  if (le < ppos - 1)
                    {
                      edge_list swap = list[le];
                      list[le] = list[ppos - 1];
                      list[ppos - 1] = list[ppos];
                      list[ppos] = swap;
                      ppos--;
                      continue; // sans changer le
                    }
                  else if (le == ppos - 1)
                    {
                      ppos--;
                      break;
                    }
                  else
                    {
                      // oupsie
                      break;
                    }
                }
              if (test > 0)
                {
                  break;
                }
              le++;
            }
          while (le < ppos);
        }
      if (ri > plast)
        {
          do
            {
        int test = CmpToVert (pvalx, list[ri].x,pvals,list[ri].starting);
              if (test == 0)
                {
                  // on colle les valeurs egales au pivot ensemble
                  if (ri > plast + 1)
                    {
                      edge_list swap = list[ri];
                      list[ri] = list[plast + 1];
                      list[plast + 1] = list[plast];
                      list[plast] = swap;
                      plast++;
                      continue; // sans changer ri
                    }
                  else if (ri == plast + 1)
                    {
                      plast++;
                      break;
                    }
                  else
                    {
                      // oupsie
                      break;
                    }
                }
              if (test < 0)
                {
                  break;
                }
              ri--;
            }
          while (ri > plast);
        }

      if (le < ppos)
        {
          if (ri > plast)
            {
              edge_list swap = list[le];
              list[le] = list[ri];
              list[ri] = swap;
              le++;
              ri--;
            }
          else if (le < ppos - 1)
            {
              edge_list swap = list[ppos - 1];
              list[ppos - 1] = list[plast];
              list[plast] = list[le];
              list[le] = swap;
              ppos--;
              plast--;
            }
          else if (le == ppos - 1)
            {
              edge_list swap = list[plast];
              list[plast] = list[le];
              list[le] = swap;
              ppos--;
              plast--;
            }
          else
            {
              break;
            }
        }
      else
        {
          if (ri > plast + 1)
            {
              edge_list swap = list[plast + 1];
              list[plast + 1] = list[ppos];
              list[ppos] = list[ri];
              list[ri] = swap;
              ppos++;
              plast++;
            }
          else if (ri == plast + 1)
            {
              edge_list swap = list[ppos];
              list[ppos] = list[ri];
              list[ri] = swap;
              ppos++;
              plast++;
            }
          else
            {
              break;
            }
        }
    }
  SortEdgesList (list, s, ppos - 1);
  SortEdgesList (list, plast + 1, e);

}

void Shape::SortPoints ( void   ) 
void Shape::SortPoints ( int  s,
int  e 
) [private]

Definition at line 542 of file Shape.cpp.

References getPoint(), SortPoints(), SwapPoints(), Shape::dg_point::x, and voronoi::x.

{
  if (s >= e)
    return;
  if (e == s + 1)
    {
      if (getPoint(s).x[1] > getPoint(e).x[1]
          || (getPoint(s).x[1] == getPoint(e).x[1] && getPoint(s).x[0] > getPoint(e).x[0]))
        SwapPoints (s, e);
      return;
    }

  int ppos = (s + e) / 2;
  int plast = ppos;
  double pvalx = getPoint(ppos).x[0];
  double pvaly = getPoint(ppos).x[1];

  int le = s, ri = e;
  while (le < ppos || ri > plast)
    {
      if (le < ppos)
        {
          do
            {
              int test = 0;
              if (getPoint(le).x[1] > pvaly)
                {
                  test = 1;
                }
              else if (getPoint(le).x[1] == pvaly)
                {
                  if (getPoint(le).x[0] > pvalx)
                    {
                      test = 1;
                    }
                  else if (getPoint(le).x[0] == pvalx)
                    {
                      test = 0;
                    }
                  else
                    {
                      test = -1;
                    }
                }
              else
                {
                  test = -1;
                }
              if (test == 0)
                {
                  // on colle les valeurs egales au pivot ensemble
                  if (le < ppos - 1)
                    {
                      SwapPoints (le, ppos - 1, ppos);
                      ppos--;
                      continue; // sans changer le
                    }
                  else if (le == ppos - 1)
                    {
                      ppos--;
                      break;
                    }
                  else
                    {
                      // oupsie
                      break;
                    }
                }
              if (test > 0)
                {
                  break;
                }
              le++;
            }
          while (le < ppos);
        }
      if (ri > plast)
        {
          do
            {
              int test = 0;
              if (getPoint(ri).x[1] > pvaly)
                {
                  test = 1;
                }
              else if (getPoint(ri).x[1] == pvaly)
                {
                  if (getPoint(ri).x[0] > pvalx)
                    {
                      test = 1;
                    }
                  else if (getPoint(ri).x[0] == pvalx)
                    {
                      test = 0;
                    }
                  else
                    {
                      test = -1;
                    }
                }
              else
                {
                  test = -1;
                }
              if (test == 0)
                {
                  // on colle les valeurs egales au pivot ensemble
                  if (ri > plast + 1)
                    {
                      SwapPoints (ri, plast + 1, plast);
                      plast++;
                      continue; // sans changer ri
                    }
                  else if (ri == plast + 1)
                    {
                      plast++;
                      break;
                    }
                  else
                    {
                      // oupsie
                      break;
                    }
                }
              if (test < 0)
                {
                  break;
                }
              ri--;
            }
          while (ri > plast);
        }
      if (le < ppos)
        {
          if (ri > plast)
            {
              SwapPoints (le, ri);
              le++;
              ri--;
            }
          else
            {
              if (le < ppos - 1)
                {
                  SwapPoints (ppos - 1, plast, le);
                  ppos--;
                  plast--;
                }
              else if (le == ppos - 1)
                {
                  SwapPoints (plast, le);
                  ppos--;
                  plast--;
                }
            }
        }
      else
        {
          if (ri > plast + 1)
            {
              SwapPoints (plast + 1, ppos, ri);
              ppos++;
              plast++;
            }
          else if (ri == plast + 1)
            {
              SwapPoints (ppos, ri);
              ppos++;
              plast++;
            }
          else
            {
              break;
            }
        }
    }
  SortPoints (s, ppos - 1);
  SortPoints (plast + 1, e);
}

void Shape::SortPointsByOldInd ( int  s,
int  e 
) [private]

Definition at line 723 of file Shape.cpp.

References getPoint(), pData, SwapPoints(), Shape::dg_point::x, and voronoi::x.

Referenced by AssemblePoints().

{
  if (s >= e)
    return;
  if (e == s + 1)
    {
      if (getPoint(s).x[1] > getPoint(e).x[1] || (getPoint(s).x[1] == getPoint(e).x[1] && getPoint(s).x[0] > getPoint(e).x[0])
          || (getPoint(s).x[1] == getPoint(e).x[1] && getPoint(s).x[0] == getPoint(e).x[0]
              && pData[s].oldInd > pData[e].oldInd))
        SwapPoints (s, e);
      return;
    }

  int ppos = (s + e) / 2;
  int plast = ppos;
  double pvalx = getPoint(ppos).x[0];
  double pvaly = getPoint(ppos).x[1];
  int pvali = pData[ppos].oldInd;

  int le = s, ri = e;
  while (le < ppos || ri > plast)
    {
      if (le < ppos)
        {
          do
            {
              int test = 0;
              if (getPoint(le).x[1] > pvaly)
                {
                  test = 1;
                }
              else if (getPoint(le).x[1] == pvaly)
                {
                  if (getPoint(le).x[0] > pvalx)
                    {
                      test = 1;
                    }
                  else if (getPoint(le).x[0] == pvalx)
                    {
                      if (pData[le].oldInd > pvali)
                        {
                          test = 1;
                        }
                      else if (pData[le].oldInd == pvali)
                        {
                          test = 0;
                        }
                      else
                        {
                          test = -1;
                        }
                    }
                  else
                    {
                      test = -1;
                    }
                }
              else
                {
                  test = -1;
                }
              if (test == 0)
                {
                  // on colle les valeurs egales au pivot ensemble
                  if (le < ppos - 1)
                    {
                      SwapPoints (le, ppos - 1, ppos);
                      ppos--;
                      continue; // sans changer le
                    }
                  else if (le == ppos - 1)
                    {
                      ppos--;
                      break;
                    }
                  else
                    {
                      // oupsie
                      break;
                    }
                }
              if (test > 0)
                {
                  break;
                }
              le++;
            }
          while (le < ppos);
        }
      if (ri > plast)
        {
          do
            {
              int test = 0;
              if (getPoint(ri).x[1] > pvaly)
                {
                  test = 1;
                }
              else if (getPoint(ri).x[1] == pvaly)
                {
                  if (getPoint(ri).x[0] > pvalx)
                    {
                      test = 1;
                    }
                  else if (getPoint(ri).x[0] == pvalx)
                    {
                      if (pData[ri].oldInd > pvali)
                        {
                          test = 1;
                        }
                      else if (pData[ri].oldInd == pvali)
                        {
                          test = 0;
                        }
                      else
                        {
                          test = -1;
                        }
                    }
                  else
                    {
                      test = -1;
                    }
                }
              else
                {
                  test = -1;
                }
              if (test == 0)
                {
                  // on colle les valeurs egales au pivot ensemble
                  if (ri > plast + 1)
                    {
                      SwapPoints (ri, plast + 1, plast);
                      plast++;
                      continue; // sans changer ri
                    }
                  else if (ri == plast + 1)
                    {
                      plast++;
                      break;
                    }
                  else
                    {
                      // oupsie
                      break;
                    }
                }
              if (test < 0)
                {
                  break;
                }
              ri--;
            }
          while (ri > plast);
        }
      if (le < ppos)
        {
          if (ri > plast)
            {
              SwapPoints (le, ri);
              le++;
              ri--;
            }
          else
            {
              if (le < ppos - 1)
                {
                  SwapPoints (ppos - 1, plast, le);
                  ppos--;
                  plast--;
                }
              else if (le == ppos - 1)
                {
                  SwapPoints (plast, le);
                  ppos--;
                  plast--;
                }
            }
        }
      else
        {
          if (ri > plast + 1)
            {
              SwapPoints (plast + 1, ppos, ri);
              ppos++;
              plast++;
            }
          else if (ri == plast + 1)
            {
              SwapPoints (ppos, ri);
              ppos++;
              plast++;
            }
          else
            {
              break;
            }
        }
    }
  SortPointsByOldInd (s, ppos - 1);
  SortPointsByOldInd (plast + 1, e);
}

void Shape::SortPointsRounded ( void   )  [private]

Definition at line 535 of file Shape.cpp.

References hasPoints(), and numberOfPoints().

Referenced by Booleen(), ConvertToShape(), Reoriente(), and SortPointsRounded().

void Shape::SortPointsRounded ( int  s,
int  e 
) [private]

Definition at line 928 of file Shape.cpp.

References pData, SortPointsRounded(), and SwapPoints().

{
  if (s >= e)
    return;
  if (e == s + 1)
    {
      if (pData[s].rx[1] > pData[e].rx[1]
          || (pData[s].rx[1] == pData[e].rx[1] && pData[s].rx[0] > pData[e].rx[0]))
        SwapPoints (s, e);
      return;
    }

  int ppos = (s + e) / 2;
  int plast = ppos;
  double pvalx = pData[ppos].rx[0];
  double pvaly = pData[ppos].rx[1];

  int le = s, ri = e;
  while (le < ppos || ri > plast)
    {
      if (le < ppos)
        {
          do
            {
              int test = 0;
              if (pData[le].rx[1] > pvaly)
                {
                  test = 1;
                }
              else if (pData[le].rx[1] == pvaly)
                {
                  if (pData[le].rx[0] > pvalx)
                    {
                      test = 1;
                    }
                  else if (pData[le].rx[0] == pvalx)
                    {
                      test = 0;
                    }
                  else
                    {
                      test = -1;
                    }
                }
              else
                {
                  test = -1;
                }
              if (test == 0)
                {
                  // on colle les valeurs egales au pivot ensemble
                  if (le < ppos - 1)
                    {
                      SwapPoints (le, ppos - 1, ppos);
                      ppos--;
                      continue; // sans changer le
                    }
                  else if (le == ppos - 1)
                    {
                      ppos--;
                      break;
                    }
                  else
                    {
                      // oupsie
                      break;
                    }
                }
              if (test > 0)
                {
                  break;
                }
              le++;
            }
          while (le < ppos);
        }
      if (ri > plast)
        {
          do
            {
              int test = 0;
              if (pData[ri].rx[1] > pvaly)
                {
                  test = 1;
                }
              else if (pData[ri].rx[1] == pvaly)
                {
                  if (pData[ri].rx[0] > pvalx)
                    {
                      test = 1;
                    }
                  else if (pData[ri].rx[0] == pvalx)
                    {
                      test = 0;
                    }
                  else
                    {
                      test = -1;
                    }
                }
              else
                {
                  test = -1;
                }
              if (test == 0)
                {
                  // on colle les valeurs egales au pivot ensemble
                  if (ri > plast + 1)
                    {
                      SwapPoints (ri, plast + 1, plast);
                      plast++;
                      continue; // sans changer ri
                    }
                  else if (ri == plast + 1)
                    {
                      plast++;
                      break;
                    }
                  else
                    {
                      // oupsie
                      break;
                    }
                }
              if (test < 0)
                {
                  break;
                }
              ri--;
            }
          while (ri > plast);
        }
      if (le < ppos)
        {
          if (ri > plast)
            {
              SwapPoints (le, ri);
              le++;
              ri--;
            }
          else
            {
              if (le < ppos - 1)
                {
                  SwapPoints (ppos - 1, plast, le);
                  ppos--;
                  plast--;
                }
              else if (le == ppos - 1)
                {
                  SwapPoints (plast, le);
                  ppos--;
                  plast--;
                }
            }
        }
      else
        {
          if (ri > plast + 1)
            {
              SwapPoints (plast + 1, ppos, ri);
              ppos++;
              plast++;
            }
          else if (ri == plast + 1)
            {
              SwapPoints (ppos, ri);
              ppos++;
              plast++;
            }
          else
            {
              break;
            }
        }
    }
  SortPointsRounded (s, ppos - 1);
  SortPointsRounded (plast + 1, e);
}

void Shape::SubEdge ( int  e  ) 

Definition at line 1251 of file Shape.cpp.

References _aretes, _need_edges_sorting, DisconnectEnd(), DisconnectStart(), numberOfEdges(), SwapEdges(), and type.

Referenced by Booleen(), ConvertToShape(), Reoriente(), and sp_selected_path_boolop().

{
  if (e < 0 || e >= numberOfEdges())
    return;
  type = shape_graph;
  DisconnectStart (e);
  DisconnectEnd (e);
  if (e < numberOfEdges() - 1)
    SwapEdges (e, numberOfEdges() - 1);
  _aretes.pop_back();
  _need_edges_sorting = true;
}

void Shape::SubPoint ( int  p  ) 

Definition at line 352 of file Shape.cpp.

References _aretes, _need_points_sorting, _pts, getEdge(), getPoint(), Shape::dg_point::incidentEdge, Shape::dg_arete::nextE, Shape::dg_arete::nextS, numberOfEdges(), numberOfPoints(), and SwapPoints().

{
  if (p < 0 || p >= numberOfPoints())
    return;
  _need_points_sorting = true;
  int cb;
  cb = getPoint(p).incidentEdge[FIRST];
  while (cb >= 0 && cb < numberOfEdges())
    {
      if (getEdge(cb).st == p)
        {
          int ncb = getEdge(cb).nextS;
          _aretes[cb].nextS = _aretes[cb].prevS = -1;
          _aretes[cb].st = -1;
          cb = ncb;
        }
      else if (getEdge(cb).en == p)
        {
          int ncb = getEdge(cb).nextE;
          _aretes[cb].nextE = _aretes[cb].prevE = -1;
          _aretes[cb].en = -1;
          cb = ncb;
        }
      else
        {
          break;
        }
    }
  _pts[p].incidentEdge[FIRST] = _pts[p].incidentEdge[LAST] = -1;
  if (p < numberOfPoints() - 1)
    SwapPoints (p, numberOfPoints() - 1);
  _pts.pop_back();
}

void Shape::SwapEdges ( int  a,
int  b 
)

Definition at line 1265 of file Shape.cpp.

References _aretes, _has_back_data, _has_edges_data, _has_raster_data, _has_sweep_dest_data, _has_sweep_src_data, _has_voronoi_data, _pts, ebData, eData, Shape::dg_arete::en, FIRST, getEdge(), getPoint(), Barcode::Code39Ext::i, LAST, Shape::dg_arete::nextE, Shape::dg_arete::nextS, numberOfEdges(), uniconv-ext::p, Shape::dg_arete::prevE, Shape::dg_arete::prevS, Shape::dg_arete::st, Geom::NL::swap(), swdData, swrData, swsData, and voreData.

Referenced by AssembleAretes(), Booleen(), SubEdge(), and SwapEdges().

{
  if (a == b)
    return;
  if (getEdge(a).prevS >= 0 && getEdge(a).prevS != b)
    {
      if (getEdge(getEdge(a).prevS).st == getEdge(a).st)
        {
          _aretes[getEdge(a).prevS].nextS = b;
        }
      else if (getEdge(getEdge(a).prevS).en == getEdge(a).st)
        {
          _aretes[getEdge(a).prevS].nextE = b;
        }
    }
  if (getEdge(a).nextS >= 0 && getEdge(a).nextS != b)
    {
      if (getEdge(getEdge(a).nextS).st == getEdge(a).st)
        {
          _aretes[getEdge(a).nextS].prevS = b;
        }
      else if (getEdge(getEdge(a).nextS).en == getEdge(a).st)
        {
          _aretes[getEdge(a).nextS].prevE = b;
        }
    }
  if (getEdge(a).prevE >= 0 && getEdge(a).prevE != b)
    {
      if (getEdge(getEdge(a).prevE).st == getEdge(a).en)
        {
          _aretes[getEdge(a).prevE].nextS = b;
        }
      else if (getEdge(getEdge(a).prevE).en == getEdge(a).en)
        {
          _aretes[getEdge(a).prevE].nextE = b;
        }
    }
  if (getEdge(a).nextE >= 0 && getEdge(a).nextE != b)
    {
      if (getEdge(getEdge(a).nextE).st == getEdge(a).en)
        {
          _aretes[getEdge(a).nextE].prevS = b;
        }
      else if (getEdge(getEdge(a).nextE).en == getEdge(a).en)
        {
          _aretes[getEdge(a).nextE].prevE = b;
        }
    }
  if (getEdge(a).st >= 0)
    {
      if (getPoint(getEdge(a).st).incidentEdge[FIRST] == a)
        _pts[getEdge(a).st].incidentEdge[FIRST] = numberOfEdges();
      if (getPoint(getEdge(a).st).incidentEdge[LAST] == a)
        _pts[getEdge(a).st].incidentEdge[LAST] = numberOfEdges();
    }
  if (getEdge(a).en >= 0)
    {
      if (getPoint(getEdge(a).en).incidentEdge[FIRST] == a)
        _pts[getEdge(a).en].incidentEdge[FIRST] = numberOfEdges();
      if (getPoint(getEdge(a).en).incidentEdge[LAST] == a)
        _pts[getEdge(a).en].incidentEdge[LAST] = numberOfEdges();
    }


  if (getEdge(b).prevS >= 0 && getEdge(b).prevS != a)
    {
      if (getEdge(getEdge(b).prevS).st == getEdge(b).st)
        {
          _aretes[getEdge(b).prevS].nextS = a;
        }
      else if (getEdge(getEdge(b).prevS).en == getEdge(b).st)
        {
          _aretes[getEdge(b).prevS].nextE = a;
        }
    }
  if (getEdge(b).nextS >= 0 && getEdge(b).nextS != a)
    {
      if (getEdge(getEdge(b).nextS).st == getEdge(b).st)
        {
          _aretes[getEdge(b).nextS].prevS = a;
        }
      else if (getEdge(getEdge(b).nextS).en == getEdge(b).st)
        {
          _aretes[getEdge(b).nextS].prevE = a;
        }
    }
  if (getEdge(b).prevE >= 0 && getEdge(b).prevE != a)
    {
      if (getEdge(getEdge(b).prevE).st == getEdge(b).en)
        {
          _aretes[getEdge(b).prevE].nextS = a;
        }
      else if (getEdge(getEdge(b).prevE).en == getEdge(b).en)
        {
          _aretes[getEdge(b).prevE].nextE = a;
        }
    }
  if (getEdge(b).nextE >= 0 && getEdge(b).nextE != a)
    {
      if (getEdge(getEdge(b).nextE).st == getEdge(b).en)
        {
          _aretes[getEdge(b).nextE].prevS = a;
        }
      else if (getEdge(getEdge(b).nextE).en == getEdge(b).en)
        {
          _aretes[getEdge(b).nextE].prevE = a;
        }
    }

  
  for (int i = 0; i < 2; i++) {
    int p = getEdge(b).st;
    if (p >= 0) {
      if (getPoint(p).incidentEdge[i] == b) {
        _pts[p].incidentEdge[i] = a;
      }
    }

    p = getEdge(b).en;
    if (p >= 0) {
      if (getPoint(p).incidentEdge[i] == b) {
        _pts[p].incidentEdge[i] = a;
      }
    }

    p = getEdge(a).st;
    if (p >= 0) {
      if (getPoint(p).incidentEdge[i] == numberOfEdges()) {
        _pts[p].incidentEdge[i] = b;
      }
    }

    p = getEdge(a).en;
    if (p >= 0) {
      if (getPoint(p).incidentEdge[i] == numberOfEdges()) {
        _pts[p].incidentEdge[i] = b;
      }
    }

  }
    
  if (getEdge(a).prevS == b)
    _aretes[a].prevS = a;
  if (getEdge(a).prevE == b)
    _aretes[a].prevE = a;
  if (getEdge(a).nextS == b)
    _aretes[a].nextS = a;
  if (getEdge(a).nextE == b)
    _aretes[a].nextE = a;
  if (getEdge(b).prevS == a)
    _aretes[a].prevS = b;
  if (getEdge(b).prevE == a)
    _aretes[a].prevE = b;
  if (getEdge(b).nextS == a)
    _aretes[a].nextS = b;
  if (getEdge(b).nextE == a)
    _aretes[a].nextE = b;

  dg_arete swap = getEdge(a);
  _aretes[a] = getEdge(b);
  _aretes[b] = swap;
  if (_has_edges_data)
    {
      edge_data swae = eData[a];
      eData[a] = eData[b];
      eData[b] = swae;
    }
  if (_has_sweep_src_data)
    {
      sweep_src_data swae = swsData[a];
      swsData[a] = swsData[b];
      swsData[b] = swae;
    }
  if (_has_sweep_dest_data)
    {
      sweep_dest_data swae = swdData[a];
      swdData[a] = swdData[b];
      swdData[b] = swae;
    }
  if (_has_raster_data)
    {
      raster_data swae = swrData[a];
      swrData[a] = swrData[b];
      swrData[b] = swae;
    }
  if (_has_back_data)
    {
      back_data swae = ebData[a];
      ebData[a] = ebData[b];
      ebData[b] = swae;
    }
  if (_has_voronoi_data)
    {
      voronoi_edge swav = voreData[a];
      voreData[a] = voreData[b];
      voreData[b] = swav;
    }
}

void Shape::SwapEdges ( int  a,
int  b,
int  c 
)

Definition at line 1464 of file Shape.cpp.

References SwapEdges().

{
  if (a == b || b == c || a == c)
    return;
  SwapEdges (a, b);
  SwapEdges (b, c);
}

void Shape::SwapPoints ( int  a,
int  b 
)

Definition at line 387 of file Shape.cpp.

References _aretes, _has_points_data, _has_voronoi_data, _pts, getEdge(), getPoint(), Shape::dg_point::incidentEdge, NextAt(), numberOfPoints(), pData, Geom::NL::swap(), and vorpData.

Referenced by SortPoints(), SortPointsByOldInd(), SortPointsRounded(), SubPoint(), and SwapPoints().

{
  if (a == b)
    return;
  if (getPoint(a).totalDegree() == 2 && getPoint(b).totalDegree() == 2)
    {
      int cb = getPoint(a).incidentEdge[FIRST];
      if (getEdge(cb).st == a)
        {
          _aretes[cb].st = numberOfPoints();
        }
      else if (getEdge(cb).en == a)
        {
          _aretes[cb].en = numberOfPoints();
        }
      cb = getPoint(a).incidentEdge[LAST];
      if (getEdge(cb).st == a)
        {
          _aretes[cb].st = numberOfPoints();
        }
      else if (getEdge(cb).en == a)
        {
          _aretes[cb].en = numberOfPoints();
        }

      cb = getPoint(b).incidentEdge[FIRST];
      if (getEdge(cb).st == b)
        {
          _aretes[cb].st = a;
        }
      else if (getEdge(cb).en == b)
        {
          _aretes[cb].en = a;
        }
      cb = getPoint(b).incidentEdge[LAST];
      if (getEdge(cb).st == b)
        {
          _aretes[cb].st = a;
        }
      else if (getEdge(cb).en == b)
        {
          _aretes[cb].en = a;
        }

      cb = getPoint(a).incidentEdge[FIRST];
      if (getEdge(cb).st == numberOfPoints())
        {
          _aretes[cb].st = b;
        }
      else if (getEdge(cb).en == numberOfPoints())
        {
          _aretes[cb].en = b;
        }
      cb = getPoint(a).incidentEdge[LAST];
      if (getEdge(cb).st == numberOfPoints())
        {
          _aretes[cb].st = b;
        }
      else if (getEdge(cb).en == numberOfPoints())
        {
          _aretes[cb].en = b;
        }

    }
  else
    {
      int cb;
      cb = getPoint(a).incidentEdge[FIRST];
      while (cb >= 0)
        {
          int ncb = NextAt (a, cb);
          if (getEdge(cb).st == a)
            {
              _aretes[cb].st = numberOfPoints();
            }
          else if (getEdge(cb).en == a)
            {
              _aretes[cb].en = numberOfPoints();
            }
          cb = ncb;
        }
      cb = getPoint(b).incidentEdge[FIRST];
      while (cb >= 0)
        {
          int ncb = NextAt (b, cb);
          if (getEdge(cb).st == b)
            {
              _aretes[cb].st = a;
            }
          else if (getEdge(cb).en == b)
            {
              _aretes[cb].en = a;
            }
          cb = ncb;
        }
      cb = getPoint(a).incidentEdge[FIRST];
      while (cb >= 0)
        {
          int ncb = NextAt (numberOfPoints(), cb);
          if (getEdge(cb).st == numberOfPoints())
            {
              _aretes[cb].st = b;
            }
          else if (getEdge(cb).en == numberOfPoints())
            {
              _aretes[cb].en = b;
            }
          cb = ncb;
        }
    }
  {
    dg_point swap = getPoint(a);
    _pts[a] = getPoint(b);
    _pts[b] = swap;
  }
  if (_has_points_data)
    {
      point_data swad = pData[a];
      pData[a] = pData[b];
      pData[b] = swad;
      //              pData[pData[a].oldInd].newInd=a;
      //              pData[pData[b].oldInd].newInd=b;
    }
  if (_has_voronoi_data)
    {
      voronoi_point swav = vorpData[a];
      vorpData[a] = vorpData[b];
      vorpData[b] = swav;
    }
}

void Shape::SwapPoints ( int  a,
int  b,
int  c 
)

Definition at line 518 of file Shape.cpp.

References SwapPoints().

{
  if (a == b || b == c || a == c)
    return;
  SwapPoints (a, b);
  SwapPoints (b, c);
}

bool Shape::TesteAdjacency ( Shape iL,
int  ilb,
const Geom::Point  atx,
int  nPt,
bool  push 
) [private]

Definition at line 2657 of file ShapeSweep.cpp.

References Geom::cross(), ffgeom::dot(), addnodes::e, eData, Shape::dg_arete::en, getEdge(), HalfRound(), IHalfRound(), pData, PushIncidence(), Shape::dg_arete::st, and swsData.

Referenced by CheckAdjacencies().

{
  if (nPt == a->swsData[no].stPt || nPt == a->swsData[no].enPt)
    return false;

  Geom::Point adir, diff, ast, aen, diff1, diff2, diff3, diff4;

  ast = a->pData[a->getEdge(no).st].rx;
  aen = a->pData[a->getEdge(no).en].rx;

  adir = a->eData[no].rdx;

  double sle = a->eData[no].length;
  double ile = a->eData[no].ilength;

  diff = atx - ast;
 
  double e = IHalfRound ((cross (diff,adir)) * a->eData[no].isqlength);
  if (-3 < e && e < 3)
    {
      double rad = HalfRound (0.501); // when using single precision, 0.505 is better (0.5 would be the correct value, 
                                      // but it produces lots of bugs)
      diff1[0] = diff[0] - rad;
      diff1[1] = diff[1] - rad;
      diff2[0] = diff[0] + rad;
      diff2[1] = diff[1] - rad;
      diff3[0] = diff[0] + rad;
      diff3[1] = diff[1] + rad;
      diff4[0] = diff[0] - rad;
      diff4[1] = diff[1] + rad;
      double di1, di2;
      bool adjacent = false;
      di1 = cross (diff1,adir);
      di2 = cross (diff3,adir);
      if ((di1 < 0 && di2 > 0) || (di1 > 0 && di2 < 0))
    {
      adjacent = true;
    }
      else
    {
      di1 = cross ( diff2,adir);
      di2 = cross (diff4,adir);
      if ((di1 < 0 && di2 > 0) || (di1 > 0 && di2 < 0))
        {
          adjacent = true;
        }
    }
      if (adjacent)
    {
      double t = dot (diff, adir);
      if (t > 0 && t < sle)
        {
          if (push)
        {
          t *= ile;
          PushIncidence (a, no, nPt, t);
        }
          return true;
        }
    }
    }
  return false;
}

void Shape::TesteIntersection ( SweepTree t,
Side  s,
bool  onlyDiff 
) [private]

Definition at line 1659 of file ShapeSweep.cpp.

References org::w3c::dom::svg::a, SweepEventQueue::add(), b, AVLTree::elem, NULL, and sEvts.

Referenced by Booleen(), ConvertToShape(), and Validate().

{
    SweepTree *tt = static_cast<SweepTree*>(t->elem[s]);
    if (tt == NULL) {
    return;
    }

    SweepTree *a = (s == LEFT) ? tt : t;
    SweepTree *b = (s == LEFT) ? t : tt;

    Geom::Point atx;
    double atl;
    double atr;
    if (TesteIntersection(a, b, atx, atl, atr, onlyDiff)) {
    sEvts->add(a, b, atx, atl, atr);
    }
}

bool Shape::TesteIntersection ( Shape iL,
Shape iR,
int  ilb,
int  irb,
Geom::Point atx,
double atL,
double atR,
bool  onlyDiff 
) [private]

Definition at line 2511 of file ShapeSweep.cpp.

References Geom::cross(), Geom::Matrix::det(), Geom::detail::bezier_clipping::det(), eData, Shape::dg_arete::en, getEdge(), pData, Shape::dg_arete::st, and Geom::NL::swap().

{
  int lSt = ils->getEdge(ilb).st, lEn = ils->getEdge(ilb).en;
  int rSt = irs->getEdge(irb).st, rEn = irs->getEdge(irb).en;
  if (lSt == rSt || lSt == rEn)
    {
      return false;
    }
  if (lEn == rSt || lEn == rEn)
    {
      return false;
    }

  Geom::Point ldir, rdir;
  ldir = ils->eData[ilb].rdx;
  rdir = irs->eData[irb].rdx;

  double il = ils->pData[lSt].rx[0], it = ils->pData[lSt].rx[1], ir =
    ils->pData[lEn].rx[0], ib = ils->pData[lEn].rx[1];
  if (il > ir)
    {
      double swf = il;
      il = ir;
      ir = swf;
    }
  if (it > ib)
    {
      double swf = it;
      it = ib;
      ib = swf;
    }
  double jl = irs->pData[rSt].rx[0], jt = irs->pData[rSt].rx[1], jr =
    irs->pData[rEn].rx[0], jb = irs->pData[rEn].rx[1];
  if (jl > jr)
    {
      double swf = jl;
      jl = jr;
      jr = swf;
    }
  if (jt > jb)
    {
      double swf = jt;
      jt = jb;
      jb = swf;
    }

  if (il > jr || it > jb || ir < jl || ib < jt)
    return false;

  // pre-test
  {
    Geom::Point sDiff, eDiff;
    double slDot, elDot;
    double srDot, erDot;
    sDiff = ils->pData[lSt].rx - irs->pData[rSt].rx;
    eDiff = ils->pData[lEn].rx - irs->pData[rSt].rx;
    srDot = cross (sDiff,rdir );
    erDot = cross (eDiff,rdir );
    if ((srDot >= 0 && erDot >= 0) || (srDot <= 0 && erDot <= 0))
      return false;

    sDiff = irs->pData[rSt].rx - ils->pData[lSt].rx;
    eDiff = irs->pData[rEn].rx - ils->pData[lSt].rx;
    slDot = cross (sDiff,ldir );
    elDot = cross (eDiff,ldir);
    if ((slDot >= 0 && elDot >= 0) || (slDot <= 0 && elDot <= 0))
      return false;

    double slb = slDot - elDot, srb = srDot - erDot;
    if (slb < 0)
      slb = -slb;
    if (srb < 0)
      srb = -srb;
    if (slb > srb)
      {
    atx =
      (slDot * irs->pData[rEn].rx - elDot * irs->pData[rSt].rx) / (slDot -
                                       elDot);
      }
    else
      {
    atx =
      (srDot * ils->pData[lEn].rx - erDot * ils->pData[lSt].rx) / (srDot -
                                       erDot);
      }
    atL = srDot / (srDot - erDot);
    atR = slDot / (slDot - elDot);
    return true;
  }

  // a mettre en double precision pour des resultats exacts
  Geom::Point usvs;
  usvs = irs->pData[rSt].rx - ils->pData[lSt].rx;

  // pas sur de l'ordre des coefs de m
  Geom::Matrix m(ldir[0], ldir[1],
           rdir[0], rdir[1],
           0, 0);
  double det = m.det();

  double tdet = det * ils->eData[ilb].isqlength * irs->eData[irb].isqlength;

  if (tdet > -0.0001 && tdet < 0.0001)
    {               // ces couillons de vecteurs sont colineaires
      Geom::Point sDiff, eDiff;
      double sDot, eDot;
      sDiff = ils->pData[lSt].rx - irs->pData[rSt].rx;
      eDiff = ils->pData[lEn].rx - irs->pData[rSt].rx;
      sDot = cross (sDiff,rdir );
      eDot = cross (eDiff,rdir);

      atx =
    (sDot * irs->pData[lEn].rx - eDot * irs->pData[lSt].rx) / (sDot -
                                   eDot);
      atL = sDot / (sDot - eDot);

      sDiff = irs->pData[rSt].rx - ils->pData[lSt].rx;
       eDiff = irs->pData[rEn].rx - ils->pData[lSt].rx;
      sDot = cross (sDiff,ldir );
      eDot = cross (eDiff,ldir );

      atR = sDot / (sDot - eDot);

      return true;
    }

  // plus de colinearite ni d'extremites en commun
  m[1] = -m[1];
  m[2] = -m[2];
  {
    double swap = m[0];
    m[0] = m[3];
    m[3] = swap;
  }

  atL = (m[0]* usvs[0] + m[1] * usvs[1]) / det;
  atR = -(m[2] * usvs[0] + m[3] * usvs[1]) / det;
  atx = ils->pData[lSt].rx + atL * ldir;


  return true;
}

bool Shape::TesteIntersection ( SweepTree iL,
SweepTree iR,
Geom::Point atx,
double atL,
double atR,
bool  onlyDiff 
) [private]

Definition at line 1679 of file ShapeSweep.cpp.

References SweepTree::bord, Geom::cross(), eData, Shape::dg_arete::en, getEdge(), pData, SweepTree::src, Shape::dg_arete::st, and Geom::NL::swap().

{
  int lSt = iL->src->getEdge(iL->bord).st, lEn = iL->src->getEdge(iL->bord).en;
  int rSt = iR->src->getEdge(iR->bord).st, rEn = iR->src->getEdge(iR->bord).en;
  Geom::Point ldir, rdir;
  ldir = iL->src->eData[iL->bord].rdx;
  rdir = iR->src->eData[iR->bord].rdx;
  // first, a round of checks to quickly dismiss edge which obviously dont intersect,
  // such as having disjoint bounding boxes
  if (lSt < lEn)
    {
    }
  else
    {
      int swap = lSt;
      lSt = lEn;
      lEn = swap;
      ldir = -ldir;
    }
  if (rSt < rEn)
    {
    }
  else
    {
      int swap = rSt;
      rSt = rEn;
      rEn = swap;
      rdir = -rdir;
    }

  if (iL->src->pData[lSt].rx[0] < iL->src->pData[lEn].rx[0])
    {
      if (iR->src->pData[rSt].rx[0] < iR->src->pData[rEn].rx[0])
    {
      if (iL->src->pData[lSt].rx[0] > iR->src->pData[rEn].rx[0])
        return false;
      if (iL->src->pData[lEn].rx[0] < iR->src->pData[rSt].rx[0])
        return false;
    }
      else
    {
      if (iL->src->pData[lSt].rx[0] > iR->src->pData[rSt].rx[0])
        return false;
      if (iL->src->pData[lEn].rx[0] < iR->src->pData[rEn].rx[0])
        return false;
    }
    }
  else
    {
      if (iR->src->pData[rSt].rx[0] < iR->src->pData[rEn].rx[0])
    {
      if (iL->src->pData[lEn].rx[0] > iR->src->pData[rEn].rx[0])
        return false;
      if (iL->src->pData[lSt].rx[0] < iR->src->pData[rSt].rx[0])
        return false;
    }
      else
    {
      if (iL->src->pData[lEn].rx[0] > iR->src->pData[rSt].rx[0])
        return false;
      if (iL->src->pData[lSt].rx[0] < iR->src->pData[rEn].rx[0])
        return false;
    }
    }

  double ang = cross (rdir, ldir);
//      ang*=iL->src->eData[iL->bord].isqlength;
//      ang*=iR->src->eData[iR->bord].isqlength;
  if (ang <= 0) return false;       // edges in opposite directions:  <-left  ... right ->
                                // they can't intersect

  // d'abord tester les bords qui partent d'un meme point
  if (iL->src == iR->src && lSt == rSt)
    {
      if (iL->src == iR->src && lEn == rEn)
    return false;       // c'est juste un doublon
      atx = iL->src->pData[lSt].rx;
      atR = atL = -1;
      return true;      // l'ordre est mauvais
    }
  if (iL->src == iR->src && lEn == rEn)
    return false;       // rien a faire=ils vont terminer au meme endroit

  // tester si on est dans une intersection multiple

  if (onlyDiff && iL->src == iR->src)
    return false;

  // on reprend les vrais points
  lSt = iL->src->getEdge(iL->bord).st;
  lEn = iL->src->getEdge(iL->bord).en;
  rSt = iR->src->getEdge(iR->bord).st;
  rEn = iR->src->getEdge(iR->bord).en;

  // compute intersection (if there is one)
  // Boissonat anr Preparata said in one paper that double precision floats were sufficient for get single precision
  // coordinates for the intersection, if the endpoints are single precision. i hope they're right...
  {
    Geom::Point sDiff, eDiff;
    double slDot, elDot;
    double srDot, erDot;
    sDiff = iL->src->pData[lSt].rx - iR->src->pData[rSt].rx;
    eDiff = iL->src->pData[lEn].rx - iR->src->pData[rSt].rx;
    srDot = cross (sDiff,rdir);
    erDot = cross (eDiff,rdir);
    sDiff = iR->src->pData[rSt].rx - iL->src->pData[lSt].rx;
    eDiff = iR->src->pData[rEn].rx - iL->src->pData[lSt].rx;
    slDot = cross (sDiff,ldir);
    elDot = cross (eDiff,ldir);

    if ((srDot >= 0 && erDot >= 0) || (srDot <= 0 && erDot <= 0))
      {
    if (srDot == 0)
      {
        if (lSt < lEn)
          {
        atx = iL->src->pData[lSt].rx;
        atL = 0;
        atR = slDot / (slDot - elDot);
        return true;
          }
        else
          {
        return false;
          }
      }
    else if (erDot == 0)
      {
        if (lSt > lEn)
          {
        atx = iL->src->pData[lEn].rx;
        atL = 1;
        atR = slDot / (slDot - elDot);
        return true;
          }
        else
          {
        return false;
          }
      }
    if (srDot > 0 && erDot > 0)
      {
        if (rEn < rSt)
          {
        if (srDot < erDot)
          {
            if (lSt < lEn)
              {
            atx = iL->src->pData[lSt].rx;
            atL = 0;
            atR = slDot / (slDot - elDot);
            return true;
              }
          }
        else
          {
            if (lEn < lSt)
              {
            atx = iL->src->pData[lEn].rx;
            atL = 1;
            atR = slDot / (slDot - elDot);
            return true;
              }
          }
          }
      }
    if (srDot < 0 && erDot < 0)
      {
        if (rEn > rSt)
          {
        if (srDot > erDot)
          {
            if (lSt < lEn)
              {
            atx = iL->src->pData[lSt].rx;
            atL = 0;
            atR = slDot / (slDot - elDot);
            return true;
              }
          }
        else
          {
            if (lEn < lSt)
              {
            atx = iL->src->pData[lEn].rx;
            atL = 1;
            atR = slDot / (slDot - elDot);
            return true;
              }
          }
          }
      }
    return false;
      }
    if ((slDot >= 0 && elDot >= 0) || (slDot <= 0 && elDot <= 0))
      {
    if (slDot == 0)
      {
        if (rSt < rEn)
          {
        atx = iR->src->pData[rSt].rx;
        atR = 0;
        atL = srDot / (srDot - erDot);
        return true;
          }
        else
          {
        return false;
          }
      }
    else if (elDot == 0)
      {
        if (rSt > rEn)
          {
        atx = iR->src->pData[rEn].rx;
        atR = 1;
        atL = srDot / (srDot - erDot);
        return true;
          }
        else
          {
        return false;
          }
      }
    if (slDot > 0 && elDot > 0)
      {
        if (lEn > lSt)
          {
        if (slDot < elDot)
          {
            if (rSt < rEn)
              {
            atx = iR->src->pData[rSt].rx;
            atR = 0;
            atL = srDot / (srDot - erDot);
            return true;
              }
          }
        else
          {
            if (rEn < rSt)
              {
            atx = iR->src->pData[rEn].rx;
            atR = 1;
            atL = srDot / (srDot - erDot);
            return true;
              }
          }
          }
      }
    if (slDot < 0 && elDot < 0)
      {
        if (lEn < lSt)
          {
        if (slDot > elDot)
          {
            if (rSt < rEn)
              {
            atx = iR->src->pData[rSt].rx;
            atR = 0;
            atL = srDot / (srDot - erDot);
            return true;
              }
          }
        else
          {
            if (rEn < rSt)
              {
            atx = iR->src->pData[rEn].rx;
            atR = 1;
            atL = srDot / (srDot - erDot);
            return true;
              }
          }
          }
      }
    return false;
      }

/*      double  slb=slDot-elDot,srb=srDot-erDot;
        if ( slb < 0 ) slb=-slb;
        if ( srb < 0 ) srb=-srb;*/
    if (iL->src->eData[iL->bord].siEd > iR->src->eData[iR->bord].siEd)
      {
    atx =
      (slDot * iR->src->pData[rEn].rx -
       elDot * iR->src->pData[rSt].rx) / (slDot - elDot);
      }
    else
      {
    atx =
      (srDot * iL->src->pData[lEn].rx -
       erDot * iL->src->pData[lSt].rx) / (srDot - erDot);
      }
    atL = srDot / (srDot - erDot);
    atR = slDot / (slDot - elDot);
    return true;
  }

  return true;
}

void Shape::Transform ( Geom::Matrix const &  tr  )  [inline]

Definition at line 317 of file Shape.h.

References _pts.

Referenced by Inkscape::Text::Layout::ShapeScanlineMaker::ShapeScanlineMaker().

        {for(std::vector<dg_point>::iterator it=_pts.begin();it!=_pts.end();it++) it->x*=tr;}

void Shape::Validate ( void   )  [private]

Definition at line 3015 of file ShapeSweep.cpp.

References Shape::dg_arete::dx, eData, getEdge(), getPoint(), Barcode::Code39Ext::i, numberOfEdges(), numberOfPoints(), pData, TesteIntersection(), and Shape::dg_point::x.

{
  for (int i = 0; i < numberOfPoints(); i++)
    {
      pData[i].rx = getPoint(i).x;
    }
  for (int i = 0; i < numberOfEdges(); i++)
    {
      eData[i].rdx = getEdge(i).dx;
    }
  for (int i = 0; i < numberOfEdges(); i++)
    {
      for (int j = i + 1; j < numberOfEdges(); j++)
    {
        Geom::Point atx;
        double   atL, atR;
      if (TesteIntersection (this, this, i, j, atx, atL, atR, false))
        {
          printf ("%i %i  %f %f di=%f %f  dj=%f %f\n", i, j, atx[0],atx[1],getEdge(i).dx[0],getEdge(i).dx[1],getEdge(j).dx[0],getEdge(j).dx[1]);
        }
    }
    }
  fflush (stdout);
}

int Shape::Winding ( int  nPt  )  const [private]

Definition at line 2013 of file ShapeSweep.cpp.

References getEdge(), numberOfEdges(), pData, and swdData.

{
  int askTo = pData[nPt].askForWindingB;
  if (askTo < 0 || askTo >= numberOfEdges())
    return 0;
  if (getEdge(askTo).st < getEdge(askTo).en)
    {
      return swdData[askTo].leW;
    }
  else
    {
      return swdData[askTo].riW;
    }
  return 0;
}

int Shape::Winding ( const Geom::Point  px  )  const

Definition at line 2030 of file ShapeSweep.cpp.

References Geom::cross(), eData, Shape::dg_arete::en, getEdge(), Barcode::Code39Ext::i, numberOfEdges(), pData, and Shape::dg_arete::st.

Referenced by GetWindings().

{
  int lr = 0, ll = 0, rr = 0;

  for (int i = 0; i < numberOfEdges(); i++)
    {
      Geom::Point adir, diff, ast, aen;
      adir = eData[i].rdx;

      ast = pData[getEdge(i).st].rx;
      aen = pData[getEdge(i).en].rx;

      int nWeight = eData[i].weight;

      if (ast[0] < aen[0])
    {
      if (ast[0] > px[0])
        continue;
      if (aen[0] < px[0])
        continue;
    }
      else
    {
      if (ast[0] < px[0])
        continue;
      if (aen[0] > px[0])
        continue;
    }
      if (ast[0] == px[0])
    {
      if (ast[1] >= px[1])
        continue;
      if (aen[0] == px[0])
        continue;
      if (aen[0] < px[0])
        ll += nWeight;
      else
        rr -= nWeight;
      continue;
    }
      if (aen[0] == px[0])
    {
      if (aen[1] >= px[1])
        continue;
      if (ast[0] == px[0])
        continue;
      if (ast[0] < px[0])
        ll -= nWeight;
      else
        rr += nWeight;
      continue;
    }

      if (ast[1] < aen[1])
    {
      if (ast[1] >= px[1])
        continue;
    }
      else
    {
      if (aen[1] >= px[1])
        continue;
    }

      diff = px - ast;
      double cote = cross (diff,adir);
      if (cote == 0)
    continue;
      if (cote < 0)
    {
      if (ast[0] > px[0])
        lr += nWeight;
    }
      else
    {
      if (ast[0] < px[0])
        lr -= nWeight;
    }
    }
  return lr + (ll + rr) / 2;
}


Friends And Related Function Documentation

friend class SweepEvent [friend]

Definition at line 383 of file Shape.h.

friend class SweepEventQueue [friend]

Definition at line 384 of file Shape.h.

Referenced by BeginRaster(), Booleen(), and ConvertToShape().

friend class SweepTree [friend]

Definition at line 382 of file Shape.h.


Member Data Documentation

bool Shape::_bbox_up_to_date [private]

the leftX/rightX/topY/bottomY are up to date

Definition at line 543 of file Shape.h.

Referenced by CalcBBox(), Copy(), MakeOffset(), MakePointData(), MakeTweak(), Reoriente(), and Reset().

bool Shape::_has_edges_data [private]

the eData array is allocated

Definition at line 536 of file Shape.h.

Referenced by AddEdge(), Copy(), Inverse(), MakeEdgeData(), MakeOffset(), MakeTweak(), Reoriente(), Reset(), and SwapEdges().

bool Shape::_has_points_data [private]

the pData array is allocated

Definition at line 534 of file Shape.h.

Referenced by AddPoint(), Copy(), MakeOffset(), MakePointData(), MakeTweak(), Reoriente(), Reset(), and SwapPoints().

the swrData array is allocated

Definition at line 540 of file Shape.h.

Referenced by Copy(), and MakeQuickRasterData().

bool Shape::_has_raster_data [private]

the swrData array is allocated

Definition at line 539 of file Shape.h.

Referenced by AddEdge(), Copy(), MakeOffset(), MakeRasterData(), MakeTweak(), Reoriente(), and SwapEdges().

the swdData array is allocated

Definition at line 538 of file Shape.h.

Referenced by AddEdge(), Copy(), Inverse(), MakeOffset(), MakeSweepDestData(), MakeTweak(), Reoriente(), Reset(), and SwapEdges().

the swsData array is allocated

Definition at line 537 of file Shape.h.

Referenced by AddEdge(), Copy(), MakeOffset(), MakeSweepSrcData(), MakeTweak(), Reoriente(), Reset(), and SwapEdges().

bool Shape::_has_voronoi_data [private]

Definition at line 542 of file Shape.h.

Referenced by AddEdge(), AddPoint(), Copy(), Inverse(), MakeVoronoiData(), Reset(), SwapEdges(), and SwapPoints().

edges have been added: maybe they are not ordered clockwise

nota: if you remove an edge, the clockwise order still holds

Definition at line 532 of file Shape.h.

Referenced by AddEdge(), Booleen(), ConvertToShape(), Copy(), needEdgesSorting(), Reoriente(), Reset(), SortEdges(), and SubEdge().

points have been added or removed: we need to sort the points again

Definition at line 531 of file Shape.h.

Referenced by AddPoint(), Copy(), needPointsSorting(), Reset(), SortPoints(), and SubPoint().

the pData array is up to date

Definition at line 535 of file Shape.h.

Referenced by Copy(), initialisePointData(), MakeOffset(), MakePointData(), MakeTweak(), Reoriente(), and Reset().

Definition at line 333 of file Shape.h.

Referenced by AssemblePoints(), clearIncidenceData(), and PushIncidence().

Definition at line 326 of file Shape.h.

Referenced by BeginQuickRaster(), QuickRasterAddEdge(), and QuickRasterSubEdge().

Definition at line 331 of file Shape.h.

Referenced by clearIncidenceData(), and PushIncidence().

Definition at line 330 of file Shape.h.

Referenced by AssemblePoints(), clearIncidenceData(), and PushIncidence().


The documentation for this class was generated from the following files: