41 #include <libnurbs2.h>
44 #include "glimports.h"
47 #include "monoChain.h"
48 #include "quicksort.h"
49 #include "searchTree.h"
53 #define max(a,b) ((a>b)? a:b)
56 #define min(a,b) ((a>b)? b:a)
64 static void drawDiagonals(Int num_diagonals,
directedLine** diagonal_vertices)
67 for(i=0; i<num_diagonals; i++)
70 glVertex2fv(diagonal_vertices[2*i]->head());
71 glVertex2fv(diagonal_vertices[2*i+1]->head());
80 inline Real intersectHoriz(Real x1, Real y1, Real x2, Real y2, Real y)
82 return ((y2==y1)? (x1+x2)*0.5 : x1 + ((y-y1)/(y2-y1)) * (x2-x1));
88 return compV2InY(mc1->getHead()->head(), mc2->getHead()->head());
102 minX = maxX = chainTail->head()[0];
103 minY = maxY = chainTail->head()[1];
105 for(temp=chainHead; temp!=cTail; temp = temp->getNext())
107 if(temp->head()[0] < minX)
108 minX = temp->head()[0];
109 if(temp->head()[0] > maxX)
110 maxX = temp->head()[0];
112 if(temp->head()[1] < minY)
113 minY = temp->head()[1];
114 if(temp->head()[1] > maxY)
115 maxY = temp->head()[1];
119 if(chainHead->compInY(chainTail) <0)
142 void monoChain::deleteLoop()
146 for(temp=
this; temp != NULL; temp = tempNext)
148 tempNext = temp->next;
153 void monoChain::deleteLoopList()
156 for(temp=
this; temp != NULL; temp = tempNext)
158 tempNext = temp->nextPolygon;
163 Int monoChain::toArraySingleLoop(
monoChain** array, Int index)
166 array[index++] =
this;
167 for(temp = next; temp !=
this; temp = temp->next)
169 array[index++] = temp;
174 monoChain** monoChain::toArrayAllLoops(Int& num_chains)
176 num_chains = numChainsAllLoops();
181 for(temp =
this; temp != NULL; temp=temp->nextPolygon){
182 index = temp->toArraySingleLoop(ret, index);
187 Int monoChain::numChainsSingleLoop()
191 if(next ==
this)
return 1;
193 for(temp=next; temp !=
this; temp = temp->next)
198 Int monoChain::numChainsAllLoops()
202 for(temp =
this; temp != NULL; temp = temp->nextPolygon)
203 ret += temp->numChainsSingleLoop();
208 Real monoChain::chainIntersectHoriz(Real y)
213 for(temp= current; temp != chainTail; temp = temp->getNext())
215 if(temp->head()[1] > y)
218 current = temp->getPrev();
222 for(temp = current; temp != chainHead; temp = temp->getPrev())
224 if(temp->head()[1] > y)
227 current = temp->getNext();
229 return intersectHoriz(current->head()[0], current->head()[1], current->tail()[0], current->tail()[1], y);
245 for(temp = loop->getNext(); temp != loop; temp = temp->getNext())
250 firstCusp = prevCusp;
253 for(temp = prevCusp->getNext(); temp != loop; temp = temp->getNext())
263 ret->insert(
new monoChain(prevCusp, temp));
267 ret->insert(
new monoChain(prevCusp, firstCusp));
277 mc = directedLineLoopToMonoChainLoop(list);
279 for(temp = list->getNextPolygon(); temp != NULL; temp = temp->getNextPolygon())
281 monoChain *newLoop = directedLineLoopToMonoChainLoop(temp);
282 mcEnd->setNextPolygon(newLoop);
297 Real* head1 = e1->head();
298 Real* tail1 = e1->tail();
299 Real* head2 = e2->head();
300 Real* tail2 = e2->tail();
311 Real e1_Ymax, e1_Ymin, e2_Ymax, e2_Ymin;
332 if(head1[1]>tail1[1]) {
341 if(head2[1]>tail2[1]) {
356 Real Ymax = min(e1_Ymax, e2_Ymax);
357 Real Ymin = max(e1_Ymin, e2_Ymin);
359 Real y = 0.5*(Ymax + Ymin);
368 Real x1 = intersectHoriz(head1[0], head1[1], tail1[0], tail1[1], y);
369 Real x2 = intersectHoriz(head2[0], head2[1], tail2[0], tail2[1], y);
371 if(x1<= x2)
return -1;
378 assert(mc1->isKey || mc2->isKey);
388 return compEdges(d1, d2);
396 assert(current->head()[1] <= y);
399 assert(chainTail->head()[1] >=y);
400 for(temp=current; temp!=chainTail; temp = temp->getNext())
402 if(temp->head()[1] > y)
405 current = temp->getPrev();
410 for(temp=current; temp != chainHead; temp = temp->getPrev())
412 if(temp->head()[1] > y)
415 current = temp->getNext();
421 void monoChain::printOneChain()
424 for(temp = chainHead; temp != chainTail; temp = temp->getNext())
426 printf(
"(%f,%f) ", temp->head()[0], temp->head()[1]);
428 printf(
"(%f,%f) \n", chainTail->head()[0], chainTail->head()[1]);
431 void monoChain::printChainLoop()
434 this->printOneChain();
435 for(temp = next; temp !=
this; temp = temp->next)
437 temp->printOneChain();
442 void monoChain::printAllLoops()
445 for(temp=
this; temp != NULL; temp = temp->nextPolygon)
446 temp->printChainLoop();
462 for(i=0; i<nVertices; i++)
465 keyY = vert->getHead()->head()[1];
468 if(isBelow(dline, dline) && isBelow(dline, dlinePrev))
475 treeNode* thisNode = TreeNodeFind(searchTree, vert, (Int (*) (
void *,
void *))compChains);
478 vert->getPrev()->isKey = 1;
479 vert->getPrev()->keyY = keyY;
480 treeNode* prevNode = TreeNodeFind(searchTree, vert->getPrev(), (Int (*) (
void *,
void *))compChains);
481 vert->getPrev()->isKey = 0;
483 if(cuspType(dline) == 1)
486 treeNode* leftEdge = TreeNodePredecessor(prevNode);
487 treeNode* rightEdge = TreeNodeSuccessor(thisNode);
488 if(leftEdge == NULL || rightEdge == NULL)
500 ret_ranges[i] = sweepRangeMake(leftEdgeDline, 1, rightEdgeDline, 1);
504 ret_ranges[i] = sweepRangeMake( dline, 1, dlinePrev, 1);
507 searchTree = TreeNodeDeleteSingleNode(searchTree, thisNode);
508 searchTree = TreeNodeDeleteSingleNode(searchTree, prevNode);
511 else if(isAbove(dline, dline) && isAbove(dline, dlinePrev))
515 treeNode* thisNode = TreeNodeMake(vert);
516 treeNode* prevNode = TreeNodeMake(vert->getPrev());
520 searchTree = TreeNodeInsert(searchTree, thisNode, (Int (*) (
void *,
void *))compChains);
523 vert->getPrev()->isKey = 1;
524 vert->getPrev()->keyY = keyY;
525 searchTree = TreeNodeInsert(searchTree, prevNode, (Int (*) (
void *,
void *))compChains);
526 vert->getPrev()->isKey = 0;
528 if(cuspType(dline) == 1)
531 treeNode* leftEdge = TreeNodePredecessor(thisNode);
532 treeNode* rightEdge = TreeNodeSuccessor(prevNode);
533 if(leftEdge == NULL || rightEdge == NULL)
541 ret_ranges[i] = sweepRangeMake( leftEdgeDline, 1, rightEdgeDline, 1);
546 ret_ranges[i] = sweepRangeMake(dlinePrev, 1, dline, 1);
555 fprintf(stderr,
"error in MC_sweepY\n");
562 TreeNodeDeleteWholeTree(searchTree);
566 void MC_findDiagonals(Int total_num_edges,
monoChain** sortedVertices,
573 for(i=0; i<total_num_edges; i++)
574 sortedVertices[i]->resetCurrent();
576 for(i=0; i<total_num_edges; i++)
581 if(isBelow(vert, thisEdge) && isBelow(vert, prevEdge) && compEdges(prevEdge, thisEdge)<0)
584 diagonal_vertices[k++] = vert;
591 assert(leftVert->head()[1] >= vert->head()[1]);
592 assert(rightVert->head()[1] >= vert->head()[1]);
593 directedLine* minVert = (leftVert->head()[1] <= rightVert->head()[1])?leftVert:rightVert;
595 for(j=i+1; j<total_num_edges; j++)
597 if(sortedVertices[j]->getHead()->head()[1] > minVert->head()[1])
600 if(sweepRangeEqual(ranges[i], ranges[j]))
608 diagonal_vertices[k++] = sortedVertices[j]->getHead();
610 diagonal_vertices[k++] = minVert;
612 else if(isAbove(vert, thisEdge) && isAbove(vert, prevEdge) && compEdges(prevEdge, thisEdge)>0)
615 diagonal_vertices[k++] = vert;
620 assert(leftVert->head()[1] <= vert->head()[1]);
621 assert(rightVert->head()[1] <= vert->head()[1]);
622 directedLine* maxVert = (leftVert->head()[1] > rightVert->head()[1])? leftVert:rightVert;
624 for(j=i-1; j>=0; j--)
626 if(sortedVertices[j]->getHead()->head()[1] < maxVert->head()[1])
628 if(sweepRangeEqual(ranges[i], ranges[j]))
635 diagonal_vertices[k++] = sortedVertices[j]->getHead();
637 diagonal_vertices[k++] = maxVert;
649 Int total_num_chains = 0;
650 monoChain* loopList = directedLineLoopListToMonoChainLoopList(polygons);
651 monoChain** array = loopList->toArrayAllLoops(total_num_chains);
653 if(total_num_chains<=2)
655 loopList->deleteLoopList();
657 *retSampledLines = NULL;
663 quicksort( (
void**)array, 0, total_num_chains-1, (Int (*)(
void*,
void*))compChainHeadInY);
669 if(MC_sweepY(total_num_chains, array, ranges))
671 loopList->deleteLoopList();
673 *retSampledLines = NULL;
682 assert(diagonal_vertices);
686 MC_findDiagonals(total_num_chains, array, ranges, num_diagonals, diagonal_vertices);
693 num_diagonals=deleteRepeatDiagonals(num_diagonals, diagonal_vertices, diagonal_vertices);
705 Int *removedDiagonals=(Int*)malloc(
sizeof(Int) * num_diagonals);
706 for(i=0; i<num_diagonals; i++)
707 removedDiagonals[i] = 0;
711 for(i=0,k=0; i<num_diagonals; i++,k+=2)
736 removedDiagonals[i] = 1;
741 v1->connectDiagonal(v1,v2, &ret_p1, &ret_p2, &generatedLine, ret_polygons);
745 newSampledLines = generatedLine->insert(newSampledLines);
756 ret_polygons = ret_polygons->cutoffPolygon(root2);
760 root2->rootLinkSet(root1);
761 ret_p1->rootLinkSet(root1);
762 ret_p2->rootLinkSet(root1);
775 for(ii=0, kk=0; ii<num_diagonals; ii++, kk+=2)
776 if( removedDiagonals[ii]==0)
783 if(! pointLeft2Lines(v1->getPrev()->head(),
784 v1->head(), v1->tail(), d2->head()))
791 diagonal_vertices[kk] = v2->getPrev();
796 if(! pointLeft2Lines(v2->getPrev()->head(),
797 v2->head(), v2->tail(), d2->head()))
804 diagonal_vertices[kk] = v1->getPrev();
810 if(! pointLeft2Lines(v1->getPrev()->head(),
811 v1->head(), v1->tail(), d1->head()))
817 diagonal_vertices[kk+1] = v2->getPrev();
822 if(! pointLeft2Lines(v2->getPrev()->head(),
823 v2->head(), v2->tail(), d1->head()))
829 diagonal_vertices[kk+1] = v1->getPrev();
843 for(i=0,k=0; i<num_diagonals; i++, k += 2)
844 if(removedDiagonals[i] == 0)
873 v1->connectDiagonal(v1,v2, &ret_p1, &ret_p2, &generatedLine, ret_polygons);
874 newSampledLines = generatedLine->insert(newSampledLines);
876 ret_polygons = ret_polygons->cutoffPolygon(root1);
878 ret_polygons = ret_p1->insertPolygon(ret_polygons);
880 ret_polygons = ret_p2->insertPolygon(ret_polygons);
884 for(Int j=i+1; j<num_diagonals; j++)
886 if(removedDiagonals[j] ==0)
891 if(temp1==v1 || temp1==v2 || temp2==v1 || temp2==v2)
892 if(! temp1->samePolygon(temp1, temp2))
900 assert(temp1==v1 || temp1 == v2 || temp2==v1 || temp2 ==v2);
903 diagonal_vertices[2*j] = v2->getPrev();
907 diagonal_vertices[2*j+1] = v2->getPrev();
911 diagonal_vertices[2*j] = v1->getPrev();
915 diagonal_vertices[2*j+1] = v1->getPrev();
925 loopList->deleteLoopList();
928 free(diagonal_vertices);
929 free(removedDiagonals);
931 *retSampledLines = newSampledLines;