Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / glu / sgi / libnurbs / internals / splitarcs.cc
1 /*
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:
9 **
10 ** http://oss.sgi.com/projects/FreeB
11 **
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.
17 **
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.
23 **
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.
33 */
34
35 /*
36  * splitarcs.c++
37  *
38  */
39
40 #include "glimports.h"
41 #include "myassert.h"
42 #include "mysetjmp.h"
43 #include "mystdio.h"
44 #include "subdivider.h"
45 #include "arcsorter.h"
46 #include "arc.h"
47 #include "bin.h"
48
49 /* local preprocessor definitions */
50 #define MAXARCS 10
51
52 /*----------------------------------------------------------------------------
53  * Subdivider::split - split trim regions in source bin by line (param == value). 
54  *----------------------------------------------------------------------------
55  */
56
57 void
58 Subdivider::split( Bin& bin, Bin& left, Bin& right, int param, REAL value )
59 {
60     Bin intersections, unknown; 
61
62     partition( bin, left, intersections, right, unknown, param, value );
63
64     int count = intersections.numarcs();
65     if( count % 2 ) {
66 #ifndef NDEBUG
67         left.show( "left" );
68         intersections.show( "intersections" );
69         right.show( "right" );
70 #endif
71         ::mylongjmp( jumpbuffer, 29 );
72     }
73
74     Arc_ptr arclist[MAXARCS], *list;
75     if( count >= MAXARCS ) {
76         list = new Arc_ptr[count];
77     } else {
78         list = arclist;
79     }
80
81     Arc_ptr jarc, *last, *lptr;
82     for( last = list; (jarc=intersections.removearc()) != NULL; last++ )
83         *last = jarc;
84
85     if( param == 0 ) { /* sort into increasing t order */
86         ArcSdirSorter sorter(*this);
87         sorter.qsort( list, count );
88         
89         //::qsort ((void *)list, count, sizeof(Arc_ptr), (cmpfunc)compare_s);
90         for( lptr=list; lptr<last; lptr+=2 )
91             check_s ( lptr[0], lptr[1] );
92         for( lptr=list; lptr<last; lptr+=2 )
93             join_s ( left, right, lptr[0], lptr[1] );
94         for( lptr=list; lptr != last; lptr++ ) {
95             if( ((*lptr)->head()[0] <= value) && ((*lptr)->tail()[0] <= value) )
96                 left.addarc( *lptr  );
97             else
98                 right.addarc( *lptr  );
99         }
100     } else { /* sort into decreasing s order */
101         ArcTdirSorter sorter(*this);
102         sorter.qsort( list, count );
103         //::qsort ((void *)list, count, sizeof(Arc_ptr), (cmpfunc)compare_t);
104         for( lptr=list; lptr<last; lptr+=2 )
105             check_t ( lptr[0], lptr[1] );
106         for( lptr=list; lptr<last; lptr+=2 )
107             join_t ( left, right, lptr[0], lptr[1] );
108         for( lptr=list; lptr != last; lptr++ ) {
109             if( ((*lptr)->head()[1] <= value) && ((*lptr)->tail()[1] <= value) )
110                 left.addarc( *lptr  );
111             else
112                 right.addarc( *lptr  );
113         }
114     }
115
116     if( list != arclist ) delete[] list;
117     unknown.adopt(); 
118 }
119
120
121 void
122 Subdivider::check_s( Arc_ptr jarc1, Arc_ptr jarc2 )
123 {
124     assert( jarc1->check( ) != 0 );
125     assert( jarc2->check( ) != 0 );
126     assert( jarc1->next->check( ) != 0 );
127     assert( jarc2->next->check( ) != 0 );
128     assert( jarc1 != jarc2 );
129
130     /* XXX - if these assertions fail, it is due to user error or
131              undersampling */
132     if( ! ( jarc1->tail()[0] < (jarc1)->head()[0] ) ) {
133 #ifndef NDEBUG
134         _glu_dprintf( "s difference %f\n",  (jarc1)->tail()[0] - (jarc1)->head()[0] );
135 #endif
136         ::mylongjmp( jumpbuffer, 28 );
137     }
138
139     if( ! ( jarc2->tail()[0] > (jarc2)->head()[0] ) ) { 
140 #ifndef NDEBUG
141         _glu_dprintf( "s difference %f\n",  (jarc2)->tail()[0] - (jarc2)->head()[0] );
142 #endif
143         ::mylongjmp( jumpbuffer, 28 );
144     }
145 }
146
147 inline void
148 Subdivider::link( Arc_ptr jarc1, Arc_ptr jarc2, Arc_ptr up, Arc_ptr down )
149 {
150     up->nuid = down->nuid = 0;          // XXX
151
152     up->next = jarc2;
153     down->next = jarc1;
154     up->prev = jarc1->prev;
155     down->prev = jarc2->prev;
156
157     down->next->prev = down;
158     up->next->prev = up;
159     down->prev->next = down;
160     up->prev->next = up;
161 }
162
163 inline void 
164 Subdivider::simple_link( Arc_ptr jarc1, Arc_ptr jarc2 )
165 {
166     Arc_ptr tmp = jarc2->prev;
167     jarc2->prev = jarc1->prev;
168     jarc1->prev = tmp;
169     jarc2->prev->next = jarc2;
170     jarc1->prev->next = jarc1;
171 }
172
173
174 /*----------------------------------------------------------------------------
175  * join - add a pair of oppositely directed jordan arcs between two arcs
176  *----------------------------------------------------------------------------
177  */
178
179 void
180 Subdivider::join_s( Bin& left, Bin& right, Arc_ptr jarc1, Arc_ptr jarc2 )
181 {
182     assert( jarc1->check( ) != 0);
183     assert( jarc2->check( ) != 0);
184     assert( jarc1 != jarc2 );
185
186     if( ! jarc1->getitail() )
187         jarc1 = jarc1->next;
188
189     if( ! jarc2->getitail() )
190         jarc2 = jarc2->next;
191
192     REAL s = jarc1->tail()[0];
193     REAL t1 = jarc1->tail()[1];
194     REAL t2 = jarc2->tail()[1];
195
196     if( t1 == t2 ) {
197         simple_link( jarc1, jarc2 );
198     } else {
199         Arc_ptr newright = new(arcpool) Arc( arc_right, 0 ); 
200         Arc_ptr newleft = new(arcpool) Arc( arc_left, 0 );
201         assert( t1 < t2 );
202         if( isBezierArcType() ) {
203             arctessellator.bezier( newright, s, s, t1, t2 );
204             arctessellator.bezier( newleft, s, s, t2, t1 );
205         } else {
206             arctessellator.pwl_right( newright, s, t1, t2, stepsizes[0] );
207             arctessellator.pwl_left( newleft, s, t2, t1, stepsizes[2] );
208         }
209         link( jarc1, jarc2, newright, newleft );
210         left.addarc( newright  );
211         right.addarc( newleft  );
212     }
213
214     assert( jarc1->check( ) != 0 );
215     assert( jarc2->check( ) != 0 );
216     assert( jarc1->next->check( ) != 0);
217     assert( jarc2->next->check( ) != 0);
218 }
219
220 void
221 Subdivider::check_t( Arc_ptr jarc1, Arc_ptr jarc2 )
222 {
223     assert( jarc1->check( ) != 0 );
224     assert( jarc2->check( ) != 0 );
225     assert( jarc1->next->check( ) != 0 );
226     assert( jarc2->next->check( ) != 0 );
227     assert( jarc1 != jarc2 );
228
229     /* XXX - if these assertions fail, it is due to user error or
230              undersampling */
231     if( ! ( jarc1->tail()[1] < (jarc1)->head()[1] ) ) {
232 #ifndef NDEBUG
233         _glu_dprintf( "t difference %f\n",  jarc1->tail()[1] - (jarc1)->head()[1] );
234 #endif
235         ::mylongjmp( jumpbuffer, 28 );
236     }
237
238     if( ! ( jarc2->tail()[1] > (jarc2)->head()[1] ) ) { 
239 #ifndef NDEBUG
240         _glu_dprintf( "t difference %f\n",  jarc2->tail()[1] - (jarc2)->head()[1] );
241 #endif
242         ::mylongjmp( jumpbuffer, 28 );
243     }
244 }
245
246 /*----------------------------------------------------------------------------
247  * join_t - add a pair of oppositely directed jordan arcs between two arcs
248  *----------------------------------------------------------------------------
249  */
250
251 void
252 Subdivider::join_t( Bin& bottom, Bin& top, Arc_ptr jarc1, Arc_ptr jarc2 )
253 {
254     assert( jarc1->check( ) != 0 );
255     assert( jarc2->check( ) != 0 );
256     assert( jarc1->next->check( ) != 0 );
257     assert( jarc2->next->check( ) != 0 );
258     assert( jarc1 != jarc2 );
259
260     if( ! jarc1->getitail() )
261         jarc1 = jarc1->next;
262
263     if( ! jarc2->getitail() )
264         jarc2 = jarc2->next;
265
266     REAL s1 = jarc1->tail()[0];
267     REAL s2 = jarc2->tail()[0];
268     REAL t  = jarc1->tail()[1];
269
270     if( s1 == s2 ) {
271         simple_link( jarc1, jarc2 );
272     } else {
273         Arc_ptr newtop = new(arcpool) Arc( arc_top, 0 );
274         Arc_ptr newbot = new(arcpool) Arc( arc_bottom, 0 );
275         assert( s1 > s2 );
276         if( isBezierArcType() ) {
277             arctessellator.bezier( newtop, s1, s2, t, t );
278             arctessellator.bezier( newbot, s2, s1, t, t );
279         } else {
280             arctessellator.pwl_top( newtop, t, s1, s2, stepsizes[1] );
281             arctessellator.pwl_bottom( newbot, t, s2, s1, stepsizes[3] );
282         }
283         link( jarc1, jarc2, newtop, newbot );
284         bottom.addarc( newtop  );
285         top.addarc( newbot  );
286     }
287
288     assert( jarc1->check( ) != 0 );
289     assert( jarc2->check( ) != 0 );
290     assert( jarc1->next->check( ) != 0 );
291     assert( jarc2->next->check( ) != 0 );
292 }
293