00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <cstdio>
00010 #include <cstdlib>
00011 #include <cstring>
00012 #include <glib/gmem.h>
00013 #include "Shape.h"
00014 #include "livarot/sweep-event-queue.h"
00015 #include "livarot/sweep-tree-list.h"
00016 #include "livarot/sweep-tree.h"
00017
00018 #include "libnr/nr-matrix.h"
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 void
00047 Shape::ResetSweep (void)
00048 {
00049 MakePointData (true);
00050 MakeEdgeData (true);
00051 MakeSweepSrcData (true);
00052 }
00053
00054 void
00055 Shape::CleanupSweep (void)
00056 {
00057 MakePointData (false);
00058 MakeEdgeData (false);
00059 MakeSweepSrcData (false);
00060 }
00061
00062 void
00063 Shape::ForceToPolygon (void)
00064 {
00065 type = shape_polygon;
00066 }
00067
00068 int
00069 Shape::Reoriente (Shape * a)
00070 {
00071 Reset (0, 0);
00072 if (a->numberOfPoints() <= 1 || a->numberOfEdges() <= 1)
00073 return 0;
00074 if (directedEulerian(a) == false)
00075 return shape_input_err;
00076
00077 _pts = a->_pts;
00078 if (numberOfPoints() > maxPt)
00079 {
00080 maxPt = numberOfPoints();
00081 if (_has_points_data) {
00082 pData.resize(maxPt);
00083 _point_data_initialised = false;
00084 _bbox_up_to_date = false;
00085 }
00086 }
00087
00088 _aretes = a->_aretes;
00089 if (numberOfEdges() > maxAr)
00090 {
00091 maxAr = numberOfEdges();
00092 if (_has_edges_data)
00093 eData.resize(maxAr);
00094 if (_has_sweep_src_data)
00095 swsData.resize(maxAr);
00096 if (_has_sweep_dest_data)
00097 swdData.resize(maxAr);
00098 if (_has_raster_data)
00099 swrData.resize(maxAr);
00100 }
00101
00102 MakePointData (true);
00103 MakeEdgeData (true);
00104 MakeSweepDestData (true);
00105
00106 initialisePointData();
00107
00108 for (int i = 0; i < numberOfPoints(); i++) {
00109 _pts[i].x = pData[i].rx;
00110 _pts[i].oldDegree = getPoint(i).totalDegree();
00111 }
00112
00113 for (int i = 0; i < a->numberOfEdges(); i++)
00114 {
00115 eData[i].rdx = pData[getEdge(i).en].rx - pData[getEdge(i).st].rx;
00116 eData[i].weight = 1;
00117 _aretes[i].dx = eData[i].rdx;
00118 }
00119
00120 SortPointsRounded ();
00121
00122 _need_edges_sorting = true;
00123 GetWindings (this, NULL, bool_op_union, true);
00124
00125
00126 for (int i = 0; i < numberOfEdges(); i++)
00127 {
00128 swdData[i].leW %= 2;
00129 swdData[i].riW %= 2;
00130 if (swdData[i].leW < 0)
00131 swdData[i].leW = -swdData[i].leW;
00132 if (swdData[i].riW < 0)
00133 swdData[i].riW = -swdData[i].riW;
00134 if (swdData[i].leW > 0 && swdData[i].riW <= 0)
00135 {
00136 eData[i].weight = 1;
00137 }
00138 else if (swdData[i].leW <= 0 && swdData[i].riW > 0)
00139 {
00140 Inverse (i);
00141 eData[i].weight = 1;
00142 }
00143 else
00144 {
00145 eData[i].weight = 0;
00146 SubEdge (i);
00147 i--;
00148 }
00149 }
00150
00151 MakePointData (false);
00152 MakeEdgeData (false);
00153 MakeSweepDestData (false);
00154
00155 if (directedEulerian(this) == false)
00156 {
00157
00158 _pts.clear();
00159 _aretes.clear();
00160 return shape_euler_err;
00161 }
00162
00163 type = shape_polygon;
00164 return 0;
00165 }
00166
00167 int
00168 Shape::ConvertToShape (Shape * a, FillRule directed, bool invert)
00169 {
00170 Reset (0, 0);
00171
00172 if (a->numberOfPoints() <= 1 || a->numberOfEdges() <= 1) {
00173 return 0;
00174 }
00175
00176 if ( directed != fill_justDont && directedEulerian(a) == false ) {
00177 g_warning ("Shape error in ConvertToShape: directedEulerian(a) == false\n");
00178 return shape_input_err;
00179 }
00180
00181 a->ResetSweep();
00182
00183 if (sTree == NULL) {
00184 sTree = new SweepTreeList(a->numberOfEdges());
00185 }
00186 if (sEvts == NULL) {
00187 sEvts = new SweepEventQueue(a->numberOfEdges());
00188 }
00189
00190 MakePointData(true);
00191 MakeEdgeData(true);
00192 MakeSweepSrcData(true);
00193 MakeSweepDestData(true);
00194 MakeBackData(a->_has_back_data);
00195
00196 a->initialisePointData();
00197 a->initialiseEdgeData();
00198
00199 a->SortPointsRounded();
00200
00201 chgts.clear();
00202
00203 double lastChange = a->pData[0].rx[1] - 1.0;
00204 int lastChgtPt = 0;
00205 int edgeHead = -1;
00206 Shape *shapeHead = NULL;
00207
00208 clearIncidenceData();
00209
00210 int curAPt = 0;
00211
00212 while (curAPt < a->numberOfPoints() || sEvts->size() > 0) {
00213 NR::Point ptX;
00214 double ptL, ptR;
00215 SweepTree *intersL = NULL;
00216 SweepTree *intersR = NULL;
00217 int nPt = -1;
00218 Shape *ptSh = NULL;
00219 bool isIntersection = false;
00220 if (sEvts->peek(intersL, intersR, ptX, ptL, ptR))
00221 {
00222 if (a->pData[curAPt].pending > 0
00223 || (a->pData[curAPt].rx[1] > ptX[1]
00224 || (a->pData[curAPt].rx[1] == ptX[1]
00225 && a->pData[curAPt].rx[0] > ptX[0])))
00226 {
00227
00228 sEvts->extract(intersL, intersR, ptX, ptL, ptR);
00229 isIntersection = true;
00230 }
00231 else
00232 {
00233 nPt = curAPt++;
00234 ptSh = a;
00235 ptX = ptSh->pData[nPt].rx;
00236 isIntersection = false;
00237 }
00238 }
00239 else
00240 {
00241 nPt = curAPt++;
00242 ptSh = a;
00243 ptX = ptSh->pData[nPt].rx;
00244 isIntersection = false;
00245 }
00246
00247 if (isIntersection == false)
00248 {
00249 if (ptSh->getPoint(nPt).dI == 0 && ptSh->getPoint(nPt).dO == 0)
00250 continue;
00251 }
00252
00253 NR::Point rPtX;
00254 rPtX[0]= Round (ptX[0]);
00255 rPtX[1]= Round (ptX[1]);
00256 int lastPointNo = -1;
00257 lastPointNo = AddPoint (rPtX);
00258 pData[lastPointNo].rx = rPtX;
00259
00260 if (rPtX[1] > lastChange)
00261 {
00262 int lastI = AssemblePoints (lastChgtPt, lastPointNo);
00263
00264 Shape *curSh = shapeHead;
00265 int curBo = edgeHead;
00266 while (curSh)
00267 {
00268 curSh->swsData[curBo].leftRnd =
00269 pData[curSh->swsData[curBo].leftRnd].newInd;
00270 curSh->swsData[curBo].rightRnd =
00271 pData[curSh->swsData[curBo].rightRnd].newInd;
00272
00273 Shape *neSh = curSh->swsData[curBo].nextSh;
00274 curBo = curSh->swsData[curBo].nextBo;
00275 curSh = neSh;
00276 }
00277
00278 for (unsigned int i = 0; i < chgts.size(); i++)
00279 {
00280 chgts[i].ptNo = pData[chgts[i].ptNo].newInd;
00281 if (chgts[i].type == 0)
00282 {
00283 if (chgts[i].src->getEdge(chgts[i].bord).st <
00284 chgts[i].src->getEdge(chgts[i].bord).en)
00285 {
00286 chgts[i].src->swsData[chgts[i].bord].stPt =
00287 chgts[i].ptNo;
00288 }
00289 else
00290 {
00291 chgts[i].src->swsData[chgts[i].bord].enPt =
00292 chgts[i].ptNo;
00293 }
00294 }
00295 else if (chgts[i].type == 1)
00296 {
00297 if (chgts[i].src->getEdge(chgts[i].bord).st >
00298 chgts[i].src->getEdge(chgts[i].bord).en)
00299 {
00300 chgts[i].src->swsData[chgts[i].bord].stPt =
00301 chgts[i].ptNo;
00302 }
00303 else
00304 {
00305 chgts[i].src->swsData[chgts[i].bord].enPt =
00306 chgts[i].ptNo;
00307 }
00308 }
00309 }
00310
00311 CheckAdjacencies (lastI, lastChgtPt, shapeHead, edgeHead);
00312
00313 CheckEdges (lastI, lastChgtPt, a, NULL, bool_op_union);
00314
00315 for (int i = lastChgtPt; i < lastI; i++) {
00316 if (pData[i].askForWindingS) {
00317 Shape *windS = pData[i].askForWindingS;
00318 int windB = pData[i].askForWindingB;
00319 pData[i].nextLinkedPoint = windS->swsData[windB].firstLinkedPoint;
00320 windS->swsData[windB].firstLinkedPoint = i;
00321 }
00322 }
00323
00324 if (lastI < lastPointNo) {
00325 _pts[lastI] = getPoint(lastPointNo);
00326 pData[lastI] = pData[lastPointNo];
00327 }
00328 lastPointNo = lastI;
00329 _pts.resize(lastI + 1);
00330
00331 lastChgtPt = lastPointNo;
00332 lastChange = rPtX[1];
00333 chgts.clear();
00334 edgeHead = -1;
00335 shapeHead = NULL;
00336 }
00337
00338
00339 if (isIntersection)
00340 {
00341
00342 intersL->RemoveEvent (*sEvts, LEFT);
00343 intersR->RemoveEvent (*sEvts, RIGHT);
00344
00345 AddChgt (lastPointNo, lastChgtPt, shapeHead, edgeHead, INTERSECTION,
00346 intersL->src, intersL->bord, intersR->src, intersR->bord);
00347
00348 intersL->SwapWithRight (*sTree, *sEvts);
00349
00350 TesteIntersection (intersL, LEFT, false);
00351 TesteIntersection (intersR, RIGHT, false);
00352 }
00353 else
00354 {
00355 int cb;
00356
00357 int nbUp = 0, nbDn = 0;
00358 int upNo = -1, dnNo = -1;
00359 cb = ptSh->getPoint(nPt).incidentEdge[FIRST];
00360 while (cb >= 0 && cb < ptSh->numberOfEdges())
00361 {
00362 if ((ptSh->getEdge(cb).st < ptSh->getEdge(cb).en
00363 && nPt == ptSh->getEdge(cb).en)
00364 || (ptSh->getEdge(cb).st > ptSh->getEdge(cb).en
00365 && nPt == ptSh->getEdge(cb).st))
00366 {
00367 upNo = cb;
00368 nbUp++;
00369 }
00370 if ((ptSh->getEdge(cb).st > ptSh->getEdge(cb).en
00371 && nPt == ptSh->getEdge(cb).en)
00372 || (ptSh->getEdge(cb).st < ptSh->getEdge(cb).en
00373 && nPt == ptSh->getEdge(cb).st))
00374 {
00375 dnNo = cb;
00376 nbDn++;
00377 }
00378 cb = ptSh->NextAt (nPt, cb);
00379 }
00380
00381 if (nbDn <= 0)
00382 {
00383 upNo = -1;
00384 }
00385 if (upNo >= 0 && (SweepTree *) ptSh->swsData[upNo].misc == NULL)
00386 {
00387 upNo = -1;
00388 }
00389
00390 bool doWinding = true;
00391
00392 if (nbUp > 0)
00393 {
00394 cb = ptSh->getPoint(nPt).incidentEdge[FIRST];
00395 while (cb >= 0 && cb < ptSh->numberOfEdges())
00396 {
00397 if ((ptSh->getEdge(cb).st < ptSh->getEdge(cb).en
00398 && nPt == ptSh->getEdge(cb).en)
00399 || (ptSh->getEdge(cb).st > ptSh->getEdge(cb).en
00400 && nPt == ptSh->getEdge(cb).st))
00401 {
00402 if (cb != upNo)
00403 {
00404 SweepTree *node =
00405 (SweepTree *) ptSh->swsData[cb].misc;
00406 if (node == NULL)
00407 {
00408 }
00409 else
00410 {
00411 AddChgt (lastPointNo, lastChgtPt, shapeHead,
00412 edgeHead, EDGE_REMOVED, node->src, node->bord,
00413 NULL, -1);
00414 ptSh->swsData[cb].misc = NULL;
00415
00416 int onLeftB = -1, onRightB = -1;
00417 Shape *onLeftS = NULL;
00418 Shape *onRightS = NULL;
00419 if (node->elem[LEFT])
00420 {
00421 onLeftB =
00422 (static_cast <
00423 SweepTree * >(node->elem[LEFT]))->bord;
00424 onLeftS =
00425 (static_cast <
00426 SweepTree * >(node->elem[LEFT]))->src;
00427 }
00428 if (node->elem[RIGHT])
00429 {
00430 onRightB =
00431 (static_cast <
00432 SweepTree * >(node->elem[RIGHT]))->bord;
00433 onRightS =
00434 (static_cast <
00435 SweepTree * >(node->elem[RIGHT]))->src;
00436 }
00437
00438 node->Remove (*sTree, *sEvts, true);
00439 if (onLeftS && onRightS)
00440 {
00441 SweepTree *onLeft =
00442 (SweepTree *) onLeftS->swsData[onLeftB].
00443 misc;
00444 if (onLeftS == ptSh
00445 && (onLeftS->getEdge(onLeftB).en == nPt
00446 || onLeftS->getEdge(onLeftB).st ==
00447 nPt))
00448 {
00449 }
00450 else
00451 {
00452 if (onRightS == ptSh
00453 && (onRightS->getEdge(onRightB).en ==
00454 nPt
00455 || onRightS->getEdge(onRightB).
00456 st == nPt))
00457 {
00458 }
00459 else
00460 {
00461 TesteIntersection (onLeft, RIGHT, false);
00462 }
00463 }
00464 }
00465 }
00466 }
00467 }
00468 cb = ptSh->NextAt (nPt, cb);
00469 }
00470 }
00471
00472
00473 SweepTree *insertionNode = NULL;
00474 if (dnNo >= 0)
00475 {
00476 if (upNo >= 0)
00477 {
00478 SweepTree *node = (SweepTree *) ptSh->swsData[upNo].misc;
00479
00480 AddChgt (lastPointNo, lastChgtPt, shapeHead, edgeHead, EDGE_REMOVED,
00481 node->src, node->bord, NULL, -1);
00482
00483 ptSh->swsData[upNo].misc = NULL;
00484
00485 node->RemoveEvents (*sEvts);
00486 node->ConvertTo (ptSh, dnNo, 1, lastPointNo);
00487 ptSh->swsData[dnNo].misc = node;
00488 TesteIntersection (node, RIGHT, false);
00489 TesteIntersection (node, LEFT, false);
00490 insertionNode = node;
00491
00492 ptSh->swsData[dnNo].curPoint = lastPointNo;
00493 AddChgt (lastPointNo, lastChgtPt, shapeHead, edgeHead, EDGE_INSERTED,
00494 node->src, node->bord, NULL, -1);
00495 }
00496 else
00497 {
00498 SweepTree *node = sTree->add(ptSh, dnNo, 1, lastPointNo, this);
00499 ptSh->swsData[dnNo].misc = node;
00500 node->Insert (*sTree, *sEvts, this, lastPointNo, true);
00501 if (doWinding)
00502 {
00503 SweepTree *myLeft =
00504 static_cast < SweepTree * >(node->elem[LEFT]);
00505 if (myLeft)
00506 {
00507 pData[lastPointNo].askForWindingS = myLeft->src;
00508 pData[lastPointNo].askForWindingB = myLeft->bord;
00509 }
00510 else
00511 {
00512 pData[lastPointNo].askForWindingB = -1;
00513 }
00514 doWinding = false;
00515 }
00516 TesteIntersection (node, RIGHT, false);
00517 TesteIntersection (node, LEFT, false);
00518 insertionNode = node;
00519
00520 ptSh->swsData[dnNo].curPoint = lastPointNo;
00521 AddChgt (lastPointNo, lastChgtPt, shapeHead, edgeHead, EDGE_INSERTED,
00522 node->src, node->bord, NULL, -1);
00523 }
00524 }
00525
00526 if (nbDn > 1)
00527 {
00528 cb = ptSh->getPoint(nPt).incidentEdge[FIRST];
00529 while (cb >= 0 && cb < ptSh->numberOfEdges())
00530 {
00531 if ((ptSh->getEdge(cb).st > ptSh->getEdge(cb).en
00532 && nPt == ptSh->getEdge(cb).en)
00533 || (ptSh->getEdge(cb).st < ptSh->getEdge(cb).en
00534 && nPt == ptSh->getEdge(cb).st))
00535 {
00536 if (cb != dnNo)
00537 {
00538 SweepTree *node = sTree->add(ptSh, cb, 1, lastPointNo, this);
00539 ptSh->swsData[cb].misc = node;
00540 node->InsertAt (*sTree, *sEvts, this, insertionNode,
00541 nPt, true);
00542 if (doWinding)
00543 {
00544 SweepTree *myLeft =
00545 static_cast < SweepTree * >(node->elem[LEFT]);
00546 if (myLeft)
00547 {
00548 pData[lastPointNo].askForWindingS =
00549 myLeft->src;
00550 pData[lastPointNo].askForWindingB =
00551 myLeft->bord;
00552 }
00553 else
00554 {
00555 pData[lastPointNo].askForWindingB = -1;
00556 }
00557 doWinding = false;
00558 }
00559 TesteIntersection (node, RIGHT, false);
00560 TesteIntersection (node, LEFT, false);
00561
00562 ptSh->swsData[cb].curPoint = lastPointNo;
00563 AddChgt (lastPointNo, lastChgtPt, shapeHead,
00564 edgeHead, EDGE_INSERTED, node->src, node->bord, NULL,
00565 -1);
00566 }
00567 }
00568 cb = ptSh->NextAt (nPt, cb);
00569 }
00570 }
00571 }
00572 }
00573 {
00574 int lastI = AssemblePoints (lastChgtPt, numberOfPoints());
00575
00576
00577 Shape *curSh = shapeHead;
00578 int curBo = edgeHead;
00579 while (curSh)
00580 {
00581 curSh->swsData[curBo].leftRnd =
00582 pData[curSh->swsData[curBo].leftRnd].newInd;
00583 curSh->swsData[curBo].rightRnd =
00584 pData[curSh->swsData[curBo].rightRnd].newInd;
00585
00586 Shape *neSh = curSh->swsData[curBo].nextSh;
00587 curBo = curSh->swsData[curBo].nextBo;
00588 curSh = neSh;
00589 }
00590
00591 for (unsigned int i = 0; i < chgts.size(); i++)
00592 {
00593 chgts[i].ptNo = pData[chgts[i].ptNo].newInd;
00594 if (chgts[i].type == 0)
00595 {
00596 if (chgts[i].src->getEdge(chgts[i].bord).st <
00597 chgts[i].src->getEdge(chgts[i].bord).en)
00598 {
00599 chgts[i].src->swsData[chgts[i].bord].stPt = chgts[i].ptNo;
00600 }
00601 else
00602 {
00603 chgts[i].src->swsData[chgts[i].bord].enPt = chgts[i].ptNo;
00604 }
00605 }
00606 else if (chgts[i].type == 1)
00607 {
00608 if (chgts[i].src->getEdge(chgts[i].bord).st >
00609 chgts[i].src->getEdge(chgts[i].bord).en)
00610 {
00611 chgts[i].src->swsData[chgts[i].bord].stPt = chgts[i].ptNo;
00612 }
00613 else
00614 {
00615 chgts[i].src->swsData[chgts[i].bord].enPt = chgts[i].ptNo;
00616 }
00617 }
00618 }
00619
00620 CheckAdjacencies (lastI, lastChgtPt, shapeHead, edgeHead);
00621
00622 CheckEdges (lastI, lastChgtPt, a, NULL, bool_op_union);
00623
00624 for (int i = lastChgtPt; i < lastI; i++)
00625 {
00626 if (pData[i].askForWindingS)
00627 {
00628 Shape *windS = pData[i].askForWindingS;
00629 int windB = pData[i].askForWindingB;
00630 pData[i].nextLinkedPoint = windS->swsData[windB].firstLinkedPoint;
00631 windS->swsData[windB].firstLinkedPoint = i;
00632 }
00633 }
00634
00635 _pts.resize(lastI);
00636
00637 edgeHead = -1;
00638 shapeHead = NULL;
00639 }
00640
00641 chgts.clear();
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651 clearIncidenceData();
00652
00653 AssembleAretes (directed);
00654
00655
00656
00657 for (int i = 0; i < numberOfPoints(); i++)
00658 {
00659 _pts[i].oldDegree = getPoint(i).totalDegree();
00660 }
00661
00662
00663 _need_edges_sorting = true;
00664 if ( directed == fill_justDont ) {
00665 SortEdges();
00666 } else {
00667 GetWindings (a);
00668 }
00669
00670
00671
00672
00673
00674
00675 if (directed == fill_positive)
00676 {
00677 if (invert)
00678 {
00679 for (int i = 0; i < numberOfEdges(); i++)
00680 {
00681 if (swdData[i].leW < 0 && swdData[i].riW >= 0)
00682 {
00683 eData[i].weight = 1;
00684 }
00685 else if (swdData[i].leW >= 0 && swdData[i].riW < 0)
00686 {
00687 Inverse (i);
00688 eData[i].weight = 1;
00689 }
00690 else
00691 {
00692 eData[i].weight = 0;
00693 SubEdge (i);
00694 i--;
00695 }
00696 }
00697 }
00698 else
00699 {
00700 for (int i = 0; i < numberOfEdges(); i++)
00701 {
00702 if (swdData[i].leW > 0 && swdData[i].riW <= 0)
00703 {
00704 eData[i].weight = 1;
00705 }
00706 else if (swdData[i].leW <= 0 && swdData[i].riW > 0)
00707 {
00708 Inverse (i);
00709 eData[i].weight = 1;
00710 }
00711 else
00712 {
00713 eData[i].weight = 0;
00714 SubEdge (i);
00715 i--;
00716 }
00717 }
00718 }
00719 }
00720 else if (directed == fill_nonZero)
00721 {
00722 if (invert)
00723 {
00724 for (int i = 0; i < numberOfEdges(); i++)
00725 {
00726 if (swdData[i].leW < 0 && swdData[i].riW == 0)
00727 {
00728 eData[i].weight = 1;
00729 }
00730 else if (swdData[i].leW > 0 && swdData[i].riW == 0)
00731 {
00732 eData[i].weight = 1;
00733 }
00734 else if (swdData[i].leW == 0 && swdData[i].riW < 0)
00735 {
00736 Inverse (i);
00737 eData[i].weight = 1;
00738 }
00739 else if (swdData[i].leW == 0 && swdData[i].riW > 0)
00740 {
00741 Inverse (i);
00742 eData[i].weight = 1;
00743 }
00744 else
00745 {
00746 eData[i].weight = 0;
00747 SubEdge (i);
00748 i--;
00749 }
00750 }
00751 }
00752 else
00753 {
00754 for (int i = 0; i < numberOfEdges(); i++)
00755 {
00756 if (swdData[i].leW > 0 && swdData[i].riW == 0)
00757 {
00758 eData[i].weight = 1;
00759 }
00760 else if (swdData[i].leW < 0 && swdData[i].riW == 0)
00761 {
00762 eData[i].weight = 1;
00763 }
00764 else if (swdData[i].leW == 0 && swdData[i].riW > 0)
00765 {
00766 Inverse (i);
00767 eData[i].weight = 1;
00768 }
00769 else if (swdData[i].leW == 0 && swdData[i].riW < 0)
00770 {
00771 Inverse (i);
00772 eData[i].weight = 1;
00773 }
00774 else
00775 {
00776 eData[i].weight = 0;
00777 SubEdge (i);
00778 i--;
00779 }
00780 }
00781 }
00782 }
00783 else if (directed == fill_oddEven)
00784 {
00785 for (int i = 0; i < numberOfEdges(); i++)
00786 {
00787 swdData[i].leW %= 2;
00788 swdData[i].riW %= 2;
00789 if (swdData[i].leW < 0)
00790 swdData[i].leW = -swdData[i].leW;
00791 if (swdData[i].riW < 0)
00792 swdData[i].riW = -swdData[i].riW;
00793 if (swdData[i].leW > 0 && swdData[i].riW <= 0)
00794 {
00795 eData[i].weight = 1;
00796 }
00797 else if (swdData[i].leW <= 0 && swdData[i].riW > 0)
00798 {
00799 Inverse (i);
00800 eData[i].weight = 1;
00801 }
00802 else
00803 {
00804 eData[i].weight = 0;
00805 SubEdge (i);
00806 i--;
00807 }
00808 }
00809 } else if ( directed == fill_justDont ) {
00810 for (int i=0;i<numberOfEdges();i++) {
00811 if ( getEdge(i).st < 0 || getEdge(i).en < 0 ) {
00812 SubEdge(i);
00813 i--;
00814 } else {
00815 eData[i].weight = 0;
00816 }
00817 }
00818 }
00819
00820
00821
00822 delete sTree;
00823 sTree = NULL;
00824 delete sEvts;
00825 sEvts = NULL;
00826
00827 MakePointData (false);
00828 MakeEdgeData (false);
00829 MakeSweepSrcData (false);
00830 MakeSweepDestData (false);
00831 a->CleanupSweep ();
00832 type = shape_polygon;
00833 return 0;
00834 }
00835
00836
00837
00838
00839 int
00840 Shape::Booleen (Shape * a, Shape * b, BooleanOp mod,int cutPathID)
00841 {
00842 if (a == b || a == NULL || b == NULL)
00843 return shape_input_err;
00844 Reset (0, 0);
00845 if (a->numberOfPoints() <= 1 || a->numberOfEdges() <= 1)
00846 return 0;
00847 if (b->numberOfPoints() <= 1 || b->numberOfEdges() <= 1)
00848 return 0;
00849 if ( mod == bool_op_cut ) {
00850 } else if ( mod == bool_op_slice ) {
00851 } else {
00852 if (a->type != shape_polygon)
00853 return shape_input_err;
00854 if (b->type != shape_polygon)
00855 return shape_input_err;
00856 }
00857
00858 a->ResetSweep ();
00859 b->ResetSweep ();
00860
00861 if (sTree == NULL) {
00862 sTree = new SweepTreeList(a->numberOfEdges() + b->numberOfEdges());
00863 }
00864 if (sEvts == NULL) {
00865 sEvts = new SweepEventQueue(a->numberOfEdges() + b->numberOfEdges());
00866 }
00867
00868 MakePointData (true);
00869 MakeEdgeData (true);
00870 MakeSweepSrcData (true);
00871 MakeSweepDestData (true);
00872 if (a->hasBackData () && b->hasBackData ())
00873 {
00874 MakeBackData (true);
00875 }
00876 else
00877 {
00878