Shape Class Reference
#include <Shape.h>

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_data > | ebData |
| std::vector< voronoi_point > | vorpData |
| std::vector< voronoi_edge > | voreData |
| int | nbQRas |
| int | firstQRas |
| int | lastQRas |
| quick_raster_data * | qrsData |
| std::vector< sTreeChange > | chgts |
| int | nbInc |
| int | maxInc |
| incidenceData * | iData |
| SweepTreeList * | sTree |
| SweepEventQueue * | sEvts |
| 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_data > | eData |
| std::vector< sweep_src_data > | swsData |
| std::vector< sweep_dest_data > | swdData |
| std::vector< raster_data > | swrData |
| std::vector< point_data > | pData |
Friends | |
| class | SweepTree |
| class | SweepEvent |
| class | SweepEventQueue |
Detailed Description
Definition at line 53 of file Shape.h.
Member Enumeration Documentation
Definition at line 85 of file Shape.h.
{
EDGE_INSERTED = 0,
EDGE_REMOVED = 1,
INTERSECTION = 2
};
Constructor & Destructor Documentation
| Shape::Shape | ( | ) |
Definition at line 23 of file Shape.cpp.
References bottomY, leftX, maxAr, maxPt, rightX, topY, and type.
: qrsData(NULL), iData(NULL), sTree(NULL), sEvts(NULL), _need_points_sorting(false), _need_edges_sorting(false), _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) { leftX = topY = rightX = bottomY = 0; maxPt = 0; maxAr = 0; type = shape_polygon; }
| Shape::~Shape | ( | void | ) | [virtual] |
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().
| 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 | |||
| ) |
Definition at line 78 of file ShapeRaster.cpp.
References eData, Shape::dg_arete::en, firstQRas, getEdge(), getPoint(), Barcode::Code39Ext::i, Shape::quick_raster_data::ind, initialisePointData(), lastQRas, MakeEdgeData(), MakePointData(), MakeQuickRasterData(), MakeRasterData(), nbQRas, numberOfEdges(), numberOfPoints(), pData, qrsData, SortPoints(), Shape::dg_arete::st, swrData, and Shape::dg_point::x.
Referenced by raster_glyph::LoadSubPixelPosition(), and nr_pixblock_render_shape_mask_or().
{
if ( numberOfPoints() <= 1 || numberOfEdges() <= 1 ) {
curPt = 0;
pos = 0;
return;
}
MakeRasterData(true);
MakeQuickRasterData(true);
nbQRas = 0;
firstQRas = lastQRas = -1;
MakePointData(true);
MakeEdgeData(true);
curPt = 0;
pos = getPoint(0).x[1] - 1.0;
initialisePointData();
for (int i=0;i<numberOfEdges();i++) {
swrData[i].misc = NULL;
qrsData[i].ind = -1;
eData[i].rdx = pData[getEdge(i).en].rx - pData[getEdge(i).st].rx;
}
SortPoints();
// SortPointsRounded();
}
| 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;
}
}
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] |
| 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);
}
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);
}
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().
| 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().
| 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 | ( | ) |
Definition at line 109 of file ShapeRaster.cpp.
References MakeEdgeData(), MakePointData(), MakeQuickRasterData(), and MakeRasterData().
Referenced by raster_glyph::LoadSubPixelPosition(), and nr_pixblock_render_shape_mask_or().
{
MakePointData(false);
MakeEdgeData(false);
MakeRasterData(false);
MakeQuickRasterData(false);
}
| 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;
}
| dg_arete const& Shape::getEdge | ( | int | n | ) | const [inline] |
Definition at line 378 of file Shape.h.
References _aretes.
Referenced by _countUpDown(), _countUpDownTotalDegree2(), SweepEventQueue::add(), AddContour(), AddEdge(), AssembleAretes(), AvanceEdge(), BeginQuickRaster(), BeginRaster(), Booleen(), ConnectEnd(), ConnectStart(), SweepTree::ConvertTo(), ConvertToForme(), ConvertToFormeNested(), ConvertToShape(), CreateEdge(), CreateIncidence(), CycleNextAt(), CyclePrevAt(), DirectQuickScan(), DirectScan(), DisconnectEnd(), DisconnectStart(), distance(), distanceLessThanOrEqual(), DoEdgeTo(), SweepTree::Find(), GetWindings(), initialiseEdgeData(), SweepTree::InsertAt(), Inverse(), SweepEvent::MakeDelete(), MakeOffset(), MakeTweak(), NextAt(), nr_arena_shape_update_fill(), nr_arena_shape_update_stroke(), Other(), Plot(), PrevAt(), PtWinding(), QuickScan(), ReFormeArcTo(), ReFormeBezierTo(), ReFormeCubicTo(), ReFormeLineTo(), Reoriente(), Scan(), SortEdges(), sp_offset_distance_to_original(), sp_selected_path_boolop(), SubPoint(), SwapEdges(), SwapPoints(), TesteAdjacency(), TesteIntersection(), Validate(), and Winding().
| dg_point const& Shape::getPoint | ( | int | n | ) | const [inline] |
Definition at line 377 of file Shape.h.
References _pts.
Referenced by _countUpDown(), _countUpDownTotalDegree2(), _updateIntersection(), AddChgt(), AddContour(), AddEdge(), AssembleAretes(), AssemblePoints(), Avance(), AvanceEdge(), BeginQuickRaster(), BeginRaster(), Booleen(), CalcBBox(), CheckAdjacencies(), ConnectEnd(), ConnectStart(), ConvertToForme(), ConvertToFormeNested(), ConvertToShape(), CreateEdge(), CreateIncidence(), CycleNextAt(), CyclePrevAt(), directedEulerian(), DirectQuickScan(), DirectScan(), DisconnectEnd(), DisconnectStart(), distance(), distanceLessThanOrEqual(), DoEdgeTo(), GetWindings(), initialisePointData(), SweepTree::Insert(), MakeOffset(), MakeTweak(), nr_arena_shape_update_fill(), nr_arena_shape_update_stroke(), Plot(), PtWinding(), QuickScan(), ReFormeArcTo(), ReFormeBezierTo(), ReFormeCubicTo(), ReFormeLineTo(), Reoriente(), Scan(), SortEdges(), SortPoints(), SortPointsByOldInd(), sp_offset_distance_to_original(), sp_offset_top_point(), sp_selected_path_boolop(), SubPoint(), SwapEdges(), SwapPoints(), and Validate().
| 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);
}
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); }
| 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().
| 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().
{ _need_points_sorting = true; }
| int Shape::NextAt | ( | int | p, | |
| int | b | |||
| ) | const [inline] |
Definition at line 163 of file Shape.h.
References getEdge(), Shape::dg_arete::nextE, and Shape::dg_arete::nextS.
Referenced by _countUpDown(), AddEdge(), AssembleAretes(), Booleen(), ConvertToForme(), ConvertToFormeNested(), ConvertToShape(), QuickScan(), Scan(), SortEdges(), sp_offset_distance_to_original(), sp_selected_path_boolop(), and SwapPoints().
| int Shape::numberOfEdges | ( | ) | const [inline] |
Definition at line 369 of file Shape.h.
References _aretes.
Referenced by _countUpDown(), AddEdge(), AssembleAretes(), AssemblePoints(), BeginQuickRaster(), BeginRaster(), Booleen(), ConvertToForme(), ConvertToFormeNested(), ConvertToShape(), Copy(), DirectQuickScan(), DirectScan(), distance(), distanceLessThanOrEqual(), GetWindings(), initialiseEdgeData(), MakeOffset(), MakeTweak(), nr_arena_shape_update_fill(), nr_arena_shape_update_stroke(), Plot(), PtWinding(), QuickScan(), Reoriente(), Scan(), SortEdges(), sp_offset_distance_to_original(), sp_selected_path_boolop(), SubEdge(), SubPoint(), SwapEdges(), Validate(), and Winding().
{ return _aretes.size(); }
| int Shape::numberOfPoints | ( | ) | const [inline] |
Definition at line 367 of file Shape.h.
References _pts.
Referenced by AddPoint(), AssembleAretes(), AssemblePoints(), Avance(), BeginQuickRaster(), BeginRaster(), Booleen(), CalcBBox(), ConvertToForme(), ConvertToFormeNested(), ConvertToShape(), Copy(), directedEulerian(), DirectQuickScan(), DirectScan(), distance(), distanceLessThanOrEqual(), Path::Fill(), GetWindings(), initialisePointData(), MakeOffset(), MakeTweak(), nr_arena_shape_update_fill(), nr_arena_shape_update_stroke(), Plot(), QuickScan(), Reoriente(), Scan(), SortEdges(), SortPoints(), SortPointsRounded(), sp_offset_distance_to_original(), sp_selected_path_boolop(), SubPoint(), SwapPoints(), and Validate().
{ return _pts.size(); }
| 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().
| 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] |
| 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;
}
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().
| 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();
}
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 ();
}
}
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;
}
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;
}
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 | |||
| ) |
Clear points and edges and prepare internal data using new size.
Definition at line 277 of file Shape.cpp.
References _aretes, _bbox_up_to_date, _has_back_data, _has_edges_data, _has_points_data, _has_sweep_dest_data, _has_sweep_src_data, _has_voronoi_data, _need_edges_sorting, _need_points_sorting, _point_data_initialised, _pts, ebData, eData, maxAr, maxPt, pData, swdData, swsData, type, voreData, and vorpData.
Referenced by Booleen(), ConvertToShape(), Copy(), Path::Fill(), MakeOffset(), MakeTweak(), nr_arena_shape_update_fill(), nr_arena_shape_update_stroke(), Reoriente(), sp_offset_set_shape(), and Path::Stroke().
{
_pts.clear();
_aretes.clear();
type = shape_polygon;
if (pointCount > maxPt)
{
maxPt = pointCount;
if (_has_points_data)
pData.resize(maxPt);
if (_has_voronoi_data)
vorpData.resize(maxPt);
}
if (edgeCount > maxAr)
{
maxAr = edgeCount;
if (_has_edges_data)
eData.resize(maxAr);
if (_has_sweep_dest_data)
swdData.resize(maxAr);
if (_has_sweep_src_data)
swsData.resize(maxAr);
if (_has_back_data)
ebData.resize(maxAr);
if (_has_voronoi_data)
voreData.resize(maxAr);
}
_need_points_sorting = false;
_need_edges_sorting = false;
_point_data_initialised = false;
_bbox_up_to_date = false;
}
| 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);
}
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 | ) |
Definition at line 527 of file Shape.cpp.
References _need_points_sorting, hasPoints(), and numberOfPoints().
Referenced by BeginQuickRaster(), BeginRaster(), SortPoints(), and sp_offset_top_point().
{
if (_need_points_sorting && hasPoints())
SortPoints (0, numberOfPoints() - 1);
_need_points_sorting = false;
}
| 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().
{
if (hasPoints())
SortPointsRounded (0, numberOfPoints() - 1);
}
| 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 | |||
| ) |
| 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().
| 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;
}
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().
| 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] |
| 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 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] |
friend class SweepEventQueue [friend] |
Definition at line 384 of file Shape.h.
Referenced by BeginRaster(), Booleen(), and ConvertToShape().
Member Data Documentation
std::vector<dg_arete> Shape::_aretes [private] |
Definition at line 546 of file Shape.h.
Referenced by AddEdge(), Affiche(), AssembleAretes(), Booleen(), ConnectEnd(), ConnectStart(), Copy(), DisconnectEnd(), DisconnectStart(), getEdge(), hasEdges(), Inverse(), MakeOffset(), MakeTweak(), numberOfEdges(), Reoriente(), Reset(), SortEdges(), SubEdge(), SubPoint(), SwapEdges(), and SwapPoints().
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_back_data [private] |
Definition at line 541 of file Shape.h.
Referenced by AddContour(), AddEdge(), AssembleAretes(), ConvertToForme(), ConvertToFormeNested(), ConvertToShape(), Copy(), DoEdgeTo(), hasBackData(), Inverse(), MakeBackData(), MakeOffset(), MakeTweak(), Reset(), and SwapEdges().
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().
bool Shape::_has_quick_raster_data [private] |
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().
bool Shape::_has_sweep_dest_data [private] |
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().
bool Shape::_has_sweep_src_data [private] |
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().
bool Shape::_need_edges_sorting [private] |
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().
bool Shape::_need_points_sorting [private] |
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().
bool Shape::_point_data_initialised [private] |
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().
std::vector<dg_point> Shape::_pts [private] |
Definition at line 545 of file Shape.h.
Referenced by AddPoint(), Affiche(), AssemblePoints(), Booleen(), ConnectEnd(), ConnectStart(), ConvertToShape(), Copy(), DisconnectEnd(), DisconnectStart(), getPoint(), hasPoints(), Inverse(), MakeOffset(), MakeTweak(), numberOfPoints(), Reoriente(), Reset(), SortEdges(), SubPoint(), SwapEdges(), SwapPoints(), and Transform().
Definition at line 339 of file Shape.h.
Referenced by CalcBBox(), raster_glyph::LoadSubPixelPosition(), nr_arena_shape_add_bboxes(), nr_pixblock_render_shape_mask_or(), Shape(), Inkscape::Text::Layout::ShapeScanlineMaker::ShapeScanlineMaker(), and sp_offset_set_shape().
Definition at line 329 of file Shape.h.
Referenced by AddChgt(), Booleen(), CheckAdjacencies(), CheckEdges(), and ConvertToShape().
Definition at line 320 of file Shape.h.
Referenced by AddContour(), AddEdge(), AssembleAretes(), Booleen(), ConvertToFormeNested(), DoEdgeTo(), Path::DoLeftJoin(), Path::DoRightJoin(), Path::Fill(), Inverse(), MakeBackData(), MakeOffset(), MakeTweak(), ReFormeArcTo(), ReFormeBezierTo(), ReFormeCubicTo(), ReFormeLineTo(), Reset(), sp_selected_path_boolop(), and SwapEdges().
std::vector<edge_data> Shape::eData [private] |
Definition at line 550 of file Shape.h.
Referenced by AddEdge(), AssembleAretes(), Avance(), BeginQuickRaster(), BeginRaster(), Booleen(), ConvertToForme(), ConvertToFormeNested(), ConvertToShape(), CreateIncidence(), DoEdgeTo(), SweepTree::Find(), GetWindings(), initialiseEdgeData(), Inverse(), MakeEdgeData(), MakeOffset(), MakeTweak(), Reoriente(), Reset(), SwapEdges(), TesteAdjacency(), TesteIntersection(), Validate(), and Winding().
| int Shape::firstQRas |
Definition at line 325 of file Shape.h.
Referenced by BeginQuickRaster(), QuickRasterAddEdge(), QuickRasterSort(), QuickRasterSubEdge(), and QuickScan().
Definition at line 333 of file Shape.h.
Referenced by AssemblePoints(), clearIncidenceData(), and PushIncidence().
| int Shape::lastQRas |
Definition at line 326 of file Shape.h.
Referenced by BeginQuickRaster(), QuickRasterAddEdge(), and QuickRasterSubEdge().
Definition at line 339 of file Shape.h.
Referenced by CalcBBox(), raster_glyph::LoadSubPixelPosition(), nr_arena_shape_add_bboxes(), nr_pixblock_render_shape_mask_or(), Shape(), and sp_offset_set_shape().
| int Shape::maxAr |
Definition at line 362 of file Shape.h.
Referenced by AddEdge(), MakeBackData(), MakeEdgeData(), MakeOffset(), MakeQuickRasterData(), MakeRasterData(), MakeSweepDestData(), MakeSweepSrcData(), MakeTweak(), MakeVoronoiData(), Reoriente(), Reset(), Shape(), and ~Shape().
| int Shape::maxInc |
Definition at line 331 of file Shape.h.
Referenced by clearIncidenceData(), and PushIncidence().
| int Shape::maxPt |
Definition at line 361 of file Shape.h.
Referenced by AddPoint(), MakeOffset(), MakePointData(), MakeTweak(), MakeVoronoiData(), Reoriente(), Reset(), Shape(), and ~Shape().
| int Shape::nbInc |
Definition at line 330 of file Shape.h.
Referenced by AssemblePoints(), clearIncidenceData(), and PushIncidence().
| int Shape::nbQRas |
Definition at line 324 of file Shape.h.
Referenced by BeginQuickRaster(), DirectQuickScan(), QuickRasterAddEdge(), QuickRasterSort(), QuickRasterSubEdge(), QuickRasterSwapEdge(), and QuickScan().
std::vector<point_data> Shape::pData [private] |
Definition at line 554 of file Shape.h.
Referenced by SweepEventQueue::add(), AddPoint(), AssembleAretes(), AssemblePoints(), BeginQuickRaster(), BeginRaster(), Booleen(), ConvertToForme(), ConvertToFormeNested(), ConvertToShape(), CreateIncidence(), DoEdgeTo(), SweepTree::Find(), GetWindings(), initialiseEdgeData(), initialisePointData(), SweepTree::InsertAt(), SweepEvent::MakeDelete(), MakeOffset(), MakePointData(), MakeTweak(), Reoriente(), Reset(), SortPointsByOldInd(), SortPointsRounded(), SwapPoints(), TesteAdjacency(), TesteIntersection(), Validate(), and Winding().
Definition at line 327 of file Shape.h.
Referenced by BeginQuickRaster(), DirectQuickScan(), MakeQuickRasterData(), QuickRasterAddEdge(), QuickRasterChgEdge(), QuickRasterSort(), QuickRasterSubEdge(), QuickRasterSwapEdge(), QuickScan(), and ~Shape().
Definition at line 339 of file Shape.h.
Referenced by CalcBBox(), raster_glyph::LoadSubPixelPosition(), nr_arena_shape_add_bboxes(), nr_pixblock_render_shape_mask_or(), Shape(), and sp_offset_set_shape().
Definition at line 336 of file Shape.h.
Referenced by BeginRaster(), Booleen(), ConvertToShape(), Copy(), DirectScan(), EndRaster(), Scan(), and TesteIntersection().
Definition at line 335 of file Shape.h.
Referenced by BeginRaster(), Booleen(), ConvertToShape(), Copy(), DirectScan(), EndRaster(), and Scan().
std::vector<sweep_dest_data> Shape::swdData [private] |
Definition at line 552 of file Shape.h.
Referenced by AddContour(), AddEdge(), Booleen(), ConvertToForme(), ConvertToFormeNested(), ConvertToShape(), GetWindings(), Inverse(), MakeOffset(), MakeSweepDestData(), MakeTweak(), ReFormeArcTo(), ReFormeBezierTo(), ReFormeCubicTo(), ReFormeLineTo(), Reoriente(), Reset(), SwapEdges(), and Winding().
std::vector<raster_data> Shape::swrData [private] |
Definition at line 553 of file Shape.h.
Referenced by _updateIntersection(), AddEdge(), AvanceEdge(), BeginQuickRaster(), BeginRaster(), CreateEdge(), DestroyEdge(), DirectQuickScan(), DirectScan(), MakeOffset(), MakeRasterData(), MakeTweak(), QuickScan(), SweepTree::Relocate(), Reoriente(), Scan(), and SwapEdges().
std::vector<sweep_src_data> Shape::swsData [private] |
Definition at line 551 of file Shape.h.
Referenced by AddChgt(), AddEdge(), AssembleAretes(), AssemblePoints(), Avance(), Booleen(), CheckAdjacencies(), CheckEdges(), ConvertToShape(), DoEdgeTo(), initialiseEdgeData(), MakeOffset(), MakeSweepSrcData(), MakeTweak(), PushIncidence(), SweepTree::Relocate(), Reoriente(), Reset(), SwapEdges(), SweepTree::SwapWithRight(), and TesteAdjacency().
Definition at line 339 of file Shape.h.
Referenced by CalcBBox(), raster_glyph::LoadSubPixelPosition(), nr_arena_shape_add_bboxes(), nr_pixblock_render_shape_mask_or(), Shape(), Inkscape::Text::Layout::ShapeScanlineMaker::ShapeScanlineMaker(), and sp_offset_set_shape().
| int Shape::type |
Definition at line 365 of file Shape.h.
Referenced by AddEdge(), Booleen(), CheckEdges(), ConvertToShape(), Copy(), ForceToPolygon(), MakeOffset(), MakeTweak(), Reoriente(), Reset(), Shape(), and SubEdge().
Definition at line 322 of file Shape.h.
Referenced by AddEdge(), Inverse(), MakeVoronoiData(), Reset(), and SwapEdges().
Definition at line 321 of file Shape.h.
Referenced by AddPoint(), MakeVoronoiData(), Reset(), and SwapPoints().
The documentation for this class was generated from the following files:
