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.
38 *To partition a v-monotone polygon into some uv-monotone polygons.
39 *The algorithm is different from the general monotone partition algorithm.
40 *while the general monotone partition algorithm works for this special case,
41 *but it is more expensive (O(nlogn)). The algorithm implemented here takes
42 *advantage of the fact that the input is a v-monotone polygon and it is
43 *conceptually simpler and computationally cheaper (a linear time algorithm).
44 *The algorithm is described in Zicheng Liu's paper
45 * "Quality-Oriented Linear Time Tessellation".
50 #include "directedLine.h"
51 #include "monoPolyPart.h"
53 /*a vertex is u_maximal if both of its two neightbors are to the left of this
56 static Int
is_u_maximal(directedLine
* v
)
58 if (compV2InX(v
->getPrev()->head(), v
->head()) == -1 &&
59 compV2InX(v
->getNext()->head(), v
->head()) == -1)
65 /*a vertex is u_minimal if both of its two neightbors are to the right of this
68 static Int
is_u_minimal(directedLine
* v
)
70 if (compV2InX(v
->getPrev()->head(), v
->head()) == 1 &&
71 compV2InX(v
->getNext()->head(), v
->head()) == 1)
77 /*poly: a v-monotone polygon
78 *return: a linked list of uv-monotone polygons.
80 directedLine
* monoPolyPart(directedLine
* polygon
)
82 //handle special cases:
85 if(polygon
->getPrev() == polygon
)
87 if(polygon
->getPrev() == polygon
->getNext())
89 if(polygon
->getPrev()->getPrev() == polygon
->getNext())
92 //find the top and bottom vertexes
93 directedLine
*tempV
, *topV
, *botV
;
94 topV
= botV
= polygon
;
95 for(tempV
= polygon
->getNext(); tempV
!= polygon
; tempV
= tempV
->getNext())
97 if(compV2InY(topV
->head(), tempV
->head())<0) {
100 if(compV2InY(botV
->head(), tempV
->head())>0) {
106 directedLine
*A
, *B
, *C
, *D
, *G
, *H
;
107 //find A:the first u_maximal vertex on the left chain
108 //and C: the left most vertex between top and A
111 for(tempV
=topV
->getNext(); tempV
!= botV
; tempV
= tempV
->getNext())
113 if(tempV
->head()[0] < C
->head()[0])
116 if(is_u_maximal(tempV
))
125 if(A
->head()[0] < C
->head()[0])
129 //find B: the first u_minimal vertex on the right chain
130 //and D: the right most vertex between top and B
133 for(tempV
=topV
->getPrev(); tempV
!= botV
; tempV
= tempV
->getPrev())
135 if(tempV
->head()[0] > D
->head()[0])
137 if(is_u_minimal(tempV
))
146 if(B
->head()[0] > D
->head()[0])
151 if(C
->head()[0] >= D
->head()[0])
154 //find G on the left chain that is right above B
155 for(tempV
=topV
; compV2InY(tempV
->head(), B
->head()) == 1; tempV
=tempV
->getNext());
156 G
= tempV
->getPrev();
157 //find H on the right chain that is right above A
158 for(tempV
=topV
; compV2InY(tempV
->head(), A
->head()) == 1; tempV
= tempV
->getPrev());
159 H
= tempV
->getNext();
162 directedLine
* ret
= NULL
;
163 directedLine
* currentPolygon
= polygon
;
166 //if both B and D are equal to botV, then this polygon is already
168 if(A
== botV
&& B
== botV
)
170 ret
= currentPolygon
->insertPolygon(ret
);
173 else //not u-monotone
175 directedLine
*ret_p1
, *ret_p2
;
176 if(compV2InY(A
->head(),B
->head()) == 1) //A is above B
178 directedLine
* E
= NULL
;
179 for(tempV
= C
; tempV
!= D
; tempV
= tempV
->getPrev())
181 if(tempV
->head()[0] >= A
->head()[0])
190 if(E
->head()[0]> H
->head()[0])
192 //connect AE and output polygon ECA
193 polygon
->connectDiagonal_2slines(A
, E
,
197 ret
= ret_p2
->insertPolygon(ret
);
198 currentPolygon
= ret_p1
;
204 if(G
->head()[1] >= A
->head()[1])
206 //update A to be the next u-maxiaml vertex on left chain
207 //and C the leftmost vertex between the old A and the new A
209 for(tempV
= A
->getNext(); tempV
!= botV
; tempV
= tempV
->getNext())
212 if(tempV
->head()[0] < C
->head()[0])
214 if(is_u_maximal(tempV
))
224 if(botV
->head()[0] < C
->head()[0])
233 for(tempV
= H
; compV2InY(tempV
->head(), A
->head()) == 1; tempV
= tempV
->getPrev());
234 H
= tempV
->getNext();
241 directedLine
* F
= NULL
;
242 for(tempV
= D
; tempV
!= C
; tempV
= tempV
->getNext())
244 if(tempV
->head()[0] <= B
->head()[0])
252 if(F
->head()[0] < G
->head()[0])
256 polygon
->connectDiagonal_2slines(F
, B
,
260 ret
= ret_p2
->insertPolygon(ret
);
261 currentPolygon
= ret_p1
;
263 if(H
->head()[1] >= B
->head()[1])
266 //update B to be the next u-minimal vertex on right chain
267 //and D the rightmost vertex between the old B and the new B
269 for(tempV
= B
->getPrev(); tempV
!= botV
; tempV
= tempV
->getPrev())
271 if(tempV
->head()[0] > D
->head()[0])
273 if(is_u_minimal(tempV
))
282 if(botV
->head()[0] > D
->head()[0])
290 for(tempV
= G
; compV2InY(tempV
->head(), B
->head()) == 1; tempV
= tempV
->getNext());
291 G
= tempV
->getPrev();
293 } //end of A is below B
294 } //end not u-monotone