2 ** License Applicability. Except to the extent portions of this file are
3 ** made subject to an alternative license as permitted in the SGI Free
4 ** Software License B, Version 1.1 (the "License"), the contents of this
5 ** file are subject only to the provisions of the License. You may not use
6 ** this file except in compliance with the License. You may obtain a copy
7 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
8 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
10 ** http://oss.sgi.com/projects/FreeB
12 ** Note that, as provided in the License, the Software is distributed on an
13 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
14 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
15 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
16 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
18 ** Original Code. The Original Code is: OpenGL Sample Implementation,
19 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
20 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
21 ** Copyright in any portions created by third parties is as indicated
22 ** elsewhere herein. All Rights Reserved.
24 ** Additional Notice Provisions: The application programming interfaces
25 ** established by SGI in conjunction with the Original Code are The
26 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
27 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
28 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
29 ** Window System(R) (Version 1.3), released October 19, 1998. This software
30 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
31 ** published by SGI, but has not been independently verified as being
32 ** compliant with the OpenGL(R) version 1.2.1 Specification.
34 ** $Date: 2003/10/14 23:48:57 $ $Revision: 1.3 $
37 ** $Header: /home/krh/git/sync/mesa-cvs-repo/Mesa/src/glu/sgi/libnurbs/nurbtess/polyDBG.cc,v 1.3 2003/10/14 23:48:57 kendallb Exp $
48 #pragma warning 391 10
49 #pragma warning 726 10
52 static Real
area(Real A
[2], Real B
[2], Real C
[2])
62 Int
DBG_isConvex(directedLine
*poly
)
65 if(area(poly
->head(), poly
->tail(), poly
->getNext()->tail()) < 0.00000)
67 for(temp
= poly
->getNext(); temp
!= poly
; temp
= temp
->getNext())
69 if(area(temp
->head(), temp
->tail(), temp
->getNext()->tail()) < 0.00000)
75 Int
DBG_is_U_monotone(directedLine
* poly
)
81 cur_sign
= compV2InX(poly
->tail(), poly
->head());
83 n_changes
= (compV2InX(poly
->getPrev()->tail(), poly
->getPrev()->head())
86 for(temp
= poly
->getNext(); temp
!= poly
; temp
= temp
->getNext())
89 cur_sign
= compV2InX(temp
->tail(), temp
->head());
91 if(cur_sign
!= prev_sign
)
95 if(n_changes
==2) return 1;
99 /*if u-monotone, and there is a long horizontal edge*/
100 Int
DBG_is_U_direction(directedLine
* poly
)
103 if(! DBG_is_U_monotone(poly))
109 if( fabs(poly
->head()[0] - poly
->tail()[0]) <= fabs(poly
->head()[1]-poly
->tail()[1]))
110 V_count
+= poly
->get_npoints();
112 U_count
+= poly
->get_npoints();
114 else if(poly->head()[1] == poly->tail()[1])
115 U_count += poly->get_npoints();
117 for(temp
= poly
->getNext(); temp
!= poly
; temp
= temp
->getNext())
119 if( fabs(temp
->head()[0] - temp
->tail()[0]) <= fabs(temp
->head()[1]-temp
->tail()[1]))
120 V_count
+= temp
->get_npoints();
122 U_count
+= temp
->get_npoints();
124 if(temp->head()[0] == temp->tail()[0])
125 V_count += temp->get_npoints();
126 else if(temp->head()[1] == temp->tail()[1])
127 U_count += temp->get_npoints();
131 if(U_count
> V_count
) return 1;
135 /*given two line segments, determine whether
136 *they intersect each other or not.
137 *return 1 if they do,
140 Int
DBG_edgesIntersect(directedLine
* l1
, directedLine
* l2
)
142 if(l1
->getNext() == l2
)
144 if(area(l1
->head(), l1
->tail(), l2
->tail()) == 0) //colinear
146 if( (l1
->tail()[0] - l1
->head()[0])*(l2
->tail()[0]-l2
->head()[0]) +
147 (l1
->tail()[1] - l1
->head()[1])*(l2
->tail()[1]-l2
->head()[1]) >=0)
148 return 0; //not intersect
152 //else we use the normal code
154 else if(l1
->getPrev() == l2
)
156 if(area(l2
->head(), l2
->tail(), l1
->tail()) == 0) //colinear
158 if( (l2
->tail()[0] - l2
->head()[0])*(l1
->tail()[0]-l1
->head()[0]) +
159 (l2
->tail()[1] - l2
->head()[1])*(l1
->tail()[1]-l1
->head()[1]) >=0)
160 return 0; //not intersect
164 //else we use the normal code
166 else //the two edges are not connected
168 if((l1
->head()[0] == l2
->head()[0] &&
169 l1
->head()[1] == l2
->head()[1]) ||
170 (l1
->tail()[0] == l2
->tail()[0] &&
171 l1
->tail()[1] == l2
->tail()[1]))
179 area(l1
->head(), l1
->tail(), l2
->head())
181 area(l1
->head(), l1
->tail(), l2
->tail())
186 area(l2
->head(), l2
->tail(), l1
->head())
187 *area(l2
->head(), l2
->tail(), l1
->tail())
196 /*whether AB and CD intersect
200 Int
DBG_edgesIntersectGen(Real A
[2], Real B
[2], Real C
[2], Real D
[2])
204 area(A
, B
, C
) * area(A
,B
,D
) <0
208 area(C
,D
,A
) * area(C
,D
,B
) < 0
216 /*determien whether (A,B) interesect chain[start] to [end]
218 Int
DBG_intersectChain(vertexArray
* chain
, Int start
, Int end
, Real A
[2], Real B
[2])
221 for(i
=start
; i
<=end
-2; i
++)
222 if(DBG_edgesIntersectGen(chain
->getVertex(i
), chain
->getVertex(i
+1), A
, B
))
228 /*determine whether a polygon intersect itself or not
229 *return 1 is it does,
232 Int
DBG_polygonSelfIntersect(directedLine
* poly
)
237 for(temp2
=temp1
->getNext(); temp2
!= temp1
; temp2
=temp2
->getNext())
239 if(DBG_edgesIntersect(temp1
, temp2
))
246 for(temp1
=poly
->getNext(); temp1
!= poly
; temp1
= temp1
->getNext())
247 for(temp2
=temp1
->getNext(); temp2
!= temp1
; temp2
=temp2
->getNext())
249 if(DBG_edgesIntersect(temp1
, temp2
))
257 /*check whether a line segment intersects a polygon
259 Int
DBG_edgeIntersectPoly(directedLine
* edge
, directedLine
* poly
)
262 if(DBG_edgesIntersect(edge
, poly
))
264 for(temp
=poly
->getNext(); temp
!= poly
; temp
=temp
->getNext())
265 if(DBG_edgesIntersect(edge
, temp
))
270 /*check whether two polygons intersect
272 Int
DBG_polygonsIntersect(directedLine
* p1
, directedLine
* p2
)
275 if(DBG_edgeIntersectPoly(p1
, p2
))
277 for(temp
=p1
->getNext(); temp
!= p1
; temp
= temp
->getNext())
278 if(DBG_edgeIntersectPoly(temp
, p2
))
283 /*check whether there are polygons intersecting each other in
286 Int
DBG_polygonListIntersect(directedLine
* pList
)
289 for(temp
=pList
; temp
!= NULL
; temp
= temp
->getNextPolygon())
290 if(DBG_polygonSelfIntersect(temp
))
293 for(temp
=pList
; temp
!=NULL
; temp
=temp
->getNextPolygon())
295 for(temp2
=temp
->getNextPolygon(); temp2
!= NULL
; temp2
=temp2
->getNextPolygon())
296 if(DBG_polygonsIntersect(temp
, temp2
))
304 Int
DBG_isCounterclockwise(directedLine
* poly
)
306 return (poly
->polyArea() > 0);
309 /*ray: v0 with direction (dx,dy).
311 * the extra point v10[2] is given for the information at
312 *v1. Basically this edge is connectd to edge
313 * v10-v1. If v1 is on the ray,
314 * then we need v10 to determine whether this ray intersects
315 * the edge or not (that is, return 1 or return 0).
316 * If v1 is on the ray, then if v2 and v10 are on the same side of the ray,
317 * we return 0, otherwise return 1.
318 *For v2, if v2 is on the ray, we always return 0.
319 *Notice that v1 and v2 are not symmetric. So the edge is directed!!!
320 * The purpose for this convention is such that: a point is inside a polygon
321 * if and only if it intersets with odd number of edges.
323 Int
DBG_rayIntersectEdge(Real v0
[2], Real dx
, Real dy
, Real v10
[2], Real v1
[2], Real v2
[2])
326 if( (v1[1] >= v0[1] && v2[1]<= v0[1] )
327 ||(v2[1] >= v0[1] && v1[1]<= v0[1] )
329 printf("rayIntersectEdge, *********\n");
332 Real denom
= (v2
[0]-v1
[0])*(-dy
) - (v2
[1]-v1
[1]) * (-dx
);
333 Real nomRay
= (v2
[0]-v1
[0]) * (v0
[1] - v1
[1]) - (v2
[1]-v1
[1])*(v0
[0]-v1
[0]);
334 Real nomEdge
= (v0
[0]-v1
[0]) * (-dy
) - (v0
[1]-v1
[1])*(-dx
);
337 /*if the ray is parallel to the edge, return 0: not intersect*/
341 /*if v0 is on the edge, return 0: not intersect*/
345 /*if v1 is on the positive ray, and the neighbor of v1 crosses the ray
349 { /*v1 is on the positive or negative ray*/
352 printf("v1 is on the ray\n");
355 if(dx
*(v1
[0]-v0
[0])>=0 && dy
*(v1
[1]-v0
[1])>=0) /*v1 on positive ray*/
357 if(area(v0
, v1
, v10
) * area(v0
, v1
, v2
) >0)
362 else /*v1 on negative ray*/
366 /*if v2 is on the ray, always return 0: not intersect*/
367 if(nomEdge
== denom
) {
368 /* printf("v2 is on the ray\n");*/
373 if(denom
*nomRay
>0 && denom
*nomEdge
>0 && nomEdge
/denom
<=1.0)
379 /*return the number of intersections*/
380 Int
DBG_rayIntersectPoly(Real v0
[2], Real dx
, Real dy
, directedLine
* poly
)
384 if(DBG_rayIntersectEdge(v0
, dx
, dy
, poly
->getPrev()->head(), poly
->head(), poly
->tail()))
387 for(temp
=poly
->getNext(); temp
!= poly
; temp
= temp
->getNext())
388 if(DBG_rayIntersectEdge(v0
, dx
, dy
, temp
->getPrev()->head(), temp
->head(), temp
->tail()))
390 /*printf("ray intersect poly: count=%i\n", count);*/
394 Int
DBG_pointInsidePoly(Real v
[2], directedLine
* poly
)
397 printf("enter pointInsidePoly , v=(%f,%f)\n", v[0], v[1]);
398 printf("the polygon is\n");
401 /*for debug purpose*/
402 assert( (DBG_rayIntersectPoly(v
,1,0,poly
) % 2 )
403 == (DBG_rayIntersectPoly(v
,1,Real(0.1234), poly
) % 2 )
405 if(DBG_rayIntersectPoly(v
, 1, 0, poly
) % 2 == 1)
411 /*return the number of polygons which contain thie polygon
414 Int
DBG_enclosingPolygons(directedLine
* poly
, directedLine
* list
)
419 printf("%i\n", DBG_pointInsidePoly(poly->head(),
420 list->getNextPolygon()
427 for(temp
= list
; temp
!= NULL
; temp
= temp
->getNextPolygon())
430 if(DBG_pointInsidePoly(poly
->head(), temp
))
432 /* printf("count=%i\n", count);*/
437 void DBG_reverse(directedLine
* poly
)
439 if(poly
->getDirection() == INCREASING
)
440 poly
->putDirection(DECREASING
);
442 poly
->putDirection(INCREASING
);
444 directedLine
* oldNext
= poly
->getNext();
445 poly
->putNext(poly
->getPrev());
446 poly
->putPrev(oldNext
);
449 for(temp
=oldNext
; temp
!=poly
; temp
= oldNext
)
451 if(temp
->getDirection() == INCREASING
)
452 temp
->putDirection(DECREASING
);
454 temp
->putDirection(INCREASING
);
456 oldNext
= temp
->getNext();
457 temp
->putNext(temp
->getPrev());
458 temp
->putPrev(oldNext
);
460 printf("reverse done\n");
463 Int
DBG_checkConnectivity(directedLine
*polygon
)
465 if(polygon
== NULL
) return 1;
467 if(polygon
->head()[0] != polygon
->getPrev()->tail()[0] ||
468 polygon
->head()[1] != polygon
->getPrev()->tail()[1])
470 for(temp
=polygon
->getNext(); temp
!= polygon
; temp
=temp
->getNext())
472 if(temp
->head()[0] != temp
->getPrev()->tail()[0] ||
473 temp
->head()[1] != temp
->getPrev()->tail()[1])
479 /*print out error message.
480 *If it cannot modify the polygon list to make it satify the
481 *requirements, return 1.
482 *otherwise modify the polygon list, and return 0
484 Int
DBG_check(directedLine
*polyList
)
487 if(polyList
== NULL
) return 0;
489 /*if there are intersections, print out error message
491 if(DBG_polygonListIntersect(polyList
))
493 fprintf(stderr
, "DBG_check: there are self intersections, don't know to modify the polygons\n");
497 /*check the connectivity of each polygon*/
498 for(temp
= polyList
; temp
!= NULL
; temp
= temp
->getNextPolygon())
500 if(! DBG_checkConnectivity(temp
))
502 fprintf(stderr
, "DBG_check, polygon not connected\n");
507 /*check the orientation of each polygon*/
508 for(temp
= polyList
; temp
!= NULL
; temp
= temp
->getNextPolygon())
514 if( DBG_enclosingPolygons(temp
, polyList
) % 2 == 0)
515 correctDir
= 1; /*counterclockwise*/
517 correctDir
= 0; /*clockwise*/
519 Int actualDir
= DBG_isCounterclockwise(temp
);
521 if(correctDir
!= actualDir
)
523 fprintf(stderr
, "DBG_check: polygon with incorrect orientations. reversed\n");
532 /**************handle self intersections*****************/
533 //determine whether e interects [begin, end] or not
534 static directedLine
* DBG_edgeIntersectChainD(directedLine
*e
,
535 directedLine
*begin
, directedLine
*end
)
538 for(temp
=begin
; temp
!= end
; temp
= temp
->getNext())
540 if(DBG_edgesIntersect(e
, temp
))
543 if(DBG_edgesIntersect(e
, end
))
548 //given a polygon, cut the edges off and finally obtain a
549 //a polygon without intersections. The cut-off edges are
550 //dealloated. The new polygon is returned.
551 directedLine
* DBG_cutIntersectionPoly(directedLine
*polygon
, int& cutOccur
)
553 directedLine
*begin
, *end
, *next
;
557 while( (next
= end
->getNext()) != begin
)
559 directedLine
*interc
= NULL
;
560 if( (interc
= DBG_edgeIntersectChainD(next
, begin
, end
)))
563 if(DBG_edgesIntersect(next
, interc
->getNext()))
569 buf
[0] = interc
->tail()[0];
570 buf
[1] = interc
->tail()[1];
574 Real r
= ((Real
)i
) / ((Real
) n
);
575 Real u
= (1-r
) * interc
->head()[0] + r
* interc
->tail()[0];
576 Real v
= (1-r
) * interc
->head()[1] + r
* interc
->tail()[1];
577 interc
->tail()[0] = interc
->getNext()->head()[0] = u
;
578 interc
->tail()[1] = interc
->getNext()->head()[1] = v
;
579 if( (! DBG_edgesIntersect(next
, interc
)) &&
580 (! DBG_edgesIntersect(next
, interc
->getNext())))
583 if(i
==n
) // we didn't fix it
587 interc
->tail()[0] = interc
->getNext()->head()[0] = buf
[0];
588 interc
->tail()[1] = interc
->getNext()->head()[1] = buf
[1];
598 begin
->deleteSingleLine(next
);
602 if(DBG_polygonSelfIntersect(begin
))
604 directedLine
* newEnd
= end
->getPrev();
605 begin
->deleteSingleLine(end
);
612 end
= end
->getNext();
617 end
= end
->getNext();
623 //given a polygon, cut the edges off and finally obtain a
624 //a polygon without intersections. The cut-off edges are
625 //dealloated. The new polygon is returned.
626 static directedLine
* DBG_cutIntersectionPoly_notwork(directedLine
*polygon
)
628 directedLine
*crt
;//current polygon
637 //if there are less than 3 edges, we should stop
638 if(crt
->getPrev()->getPrev() == crt
)
641 if(DBG_edgesIntersect(crt
, crt
->getNext()) ||
642 (crt
->head()[0] == crt
->getNext()->tail()[0] &&
643 crt
->head()[1] == crt
->getNext()->tail()[1])
647 crt
=crt
->deleteChain(crt
, crt
->getNext());
651 //now we know crt and crt->getNext do not intersect
653 end
= crt
->getNext();
654 //printf("begin=(%f,%f)\n", begin->head()[0], begin->head()[1]);
655 //printf("end=(%f,%f)\n", end->head()[0], end->head()[1]);
656 for(temp
=end
->getNext(); temp
!=begin
; temp
= temp
->getNext())
658 //printf("temp=(%f,%f)\n", temp->head()[0], temp->head()[1]);
659 directedLine
*intersect
= DBG_edgeIntersectChainD(temp
, begin
, end
);
660 if(intersect
!= NULL
)
662 crt
= crt
->deleteChain(intersect
, temp
);
664 break; //the for loop
675 find
= 0; //go to next loop
679 directedLine
* DBG_cutIntersectionAllPoly(directedLine
* list
)
682 directedLine
* tempNext
=NULL
;
683 directedLine
* ret
= NULL
;
685 for(temp
=list
; temp
!= NULL
; temp
= tempNext
)
688 tempNext
= temp
->getNextPolygon();
690 left
= DBG_cutIntersectionPoly(temp
, cutOccur
);
692 ret
=left
->insertPolygon(ret
);
697 sampledLine
* DBG_collectSampledLinesAllPoly(directedLine
*polygonList
)
700 sampledLine
* tempHead
= NULL
;
701 sampledLine
* tempTail
= NULL
;
702 sampledLine
* cHead
= NULL
;
703 sampledLine
* cTail
= NULL
;
705 if(polygonList
== NULL
)
708 DBG_collectSampledLinesPoly(polygonList
, cHead
, cTail
);
712 for(temp
= polygonList
->getNextPolygon(); temp
!= NULL
; temp
= temp
->getNextPolygon())
714 DBG_collectSampledLinesPoly(temp
, tempHead
, tempTail
);
715 cTail
->insert(tempHead
);
721 void DBG_collectSampledLinesPoly(directedLine
*polygon
, sampledLine
*& retHead
, sampledLine
*& retTail
)
724 sampledLine
*ret
= NULL
;
730 retHead
= retTail
= polygon
->getSampledLine();
731 for(temp
= polygon
->getNext(); temp
!= polygon
; temp
=temp
->getNext())
733 retHead
= temp
->getSampledLine()->insert(retHead
);