source: trunk/src/opengl/glu/nurbs/internals/splitarcs.cpp

Last change on this file was 2689, checked in by jeroen, 26 years ago

* empty log message *

File size: 9.0 KB
Line 
1/* $Id: splitarcs.cpp,v 1.1 2000-02-09 08:50:29 jeroen Exp $ */
2/*
3** License Applicability. Except to the extent portions of this file are
4** made subject to an alternative license as permitted in the SGI Free
5** Software License B, Version 1.0 (the "License"), the contents of this
6** file are subject only to the provisions of the License. You may not use
7** this file except in compliance with the License. You may obtain a copy
8** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
9** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
10**
11** http://oss.sgi.com/projects/FreeB
12**
13** Note that, as provided in the License, the Software is distributed on an
14** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
15** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
16** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
17** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
18**
19** Original Code. The Original Code is: OpenGL Sample Implementation,
20** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
21** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
22** Copyright in any portions created by third parties is as indicated
23** elsewhere herein. All Rights Reserved.
24**
25** Additional Notice Provisions: The application programming interfaces
26** established by SGI in conjunction with the Original Code are The
27** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
28** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
29** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
30** Window System(R) (Version 1.3), released October 19, 1998. This software
31** was created using the OpenGL(R) version 1.2.1 Sample Implementation
32** published by SGI, but has not been independently verified as being
33** compliant with the OpenGL(R) version 1.2.1 Specification.
34*/
35
36/*
37 * splitarcs.c++
38 *
39 * $Date: 2000-02-09 08:50:29 $ $Revision: 1.1 $
40 * $Header: /home/ktk/tmp/odin/2007/netlabs.cvs/odin32/src/opengl/glu/nurbs/internals/splitarcs.cpp,v 1.1 2000-02-09 08:50:29 jeroen Exp $
41 */
42
43#include "glimports.h"
44#include "myassert.h"
45#include "mysetjmp.h"
46#include "mystdio.h"
47#include "subdivider.h"
48#include "arcsorter.h"
49#include "arc.h"
50#include "bin.h"
51
52/* local preprocessor definitions */
53#define MAXARCS 10
54
55/*----------------------------------------------------------------------------
56 * Subdivider::split - split trim regions in source bin by line (param == value).
57 *----------------------------------------------------------------------------
58 */
59
60void
61Subdivider::split( Bin& bin, Bin& left, Bin& right, int param, REAL value )
62{
63 Bin intersections, unknown;
64
65 partition( bin, left, intersections, right, unknown, param, value );
66
67 int count = intersections.numarcs();
68 if( count % 2 ) {
69#ifndef NDEBUG
70 left.show( "left" );
71 intersections.show( "intersections" );
72 right.show( "right" );
73#endif
74 ::mylongjmp( jumpbuffer, 29 );
75 }
76
77 Arc_ptr arclist[MAXARCS], *list;
78 if( count >= MAXARCS ) {
79 list = new Arc_ptr[count];
80 } else {
81 list = arclist;
82 }
83
84 Arc_ptr jarc, *last, *lptr;
85 for( last = list; jarc=intersections.removearc(); last++ )
86 *last = jarc;
87
88 if( param == 0 ) { /* sort into increasing t order */
89 ArcSdirSorter sorter(*this);
90 sorter.qsort( list, count );
91
92 //::qsort ((void *)list, count, sizeof(Arc_ptr), (cmpfunc)compare_s);
93 for( lptr=list; lptr<last; lptr+=2 )
94 check_s ( lptr[0], lptr[1] );
95 for( lptr=list; lptr<last; lptr+=2 )
96 join_s ( left, right, lptr[0], lptr[1] );
97 for( lptr=list; lptr != last; lptr++ ) {
98 if( ((*lptr)->head()[0] <= value) && ((*lptr)->tail()[0] <= value) )
99 left.addarc( *lptr );
100 else
101 right.addarc( *lptr );
102 }
103 } else { /* sort into decreasing s order */
104 ArcTdirSorter sorter(*this);
105 sorter.qsort( list, count );
106 //::qsort ((void *)list, count, sizeof(Arc_ptr), (cmpfunc)compare_t);
107 for( lptr=list; lptr<last; lptr+=2 )
108 check_t ( lptr[0], lptr[1] );
109 for( lptr=list; lptr<last; lptr+=2 )
110 join_t ( left, right, lptr[0], lptr[1] );
111 for( lptr=list; lptr != last; lptr++ ) {
112 if( ((*lptr)->head()[1] <= value) && ((*lptr)->tail()[1] <= value) )
113 left.addarc( *lptr );
114 else
115 right.addarc( *lptr );
116 }
117 }
118
119 if( list != arclist ) delete[] list;
120 unknown.adopt();
121}
122
123
124void
125Subdivider::check_s( Arc_ptr jarc1, Arc_ptr jarc2 )
126{
127 assert( jarc1->check( ) != 0 );
128 assert( jarc2->check( ) != 0 );
129 assert( jarc1->next->check( ) != 0 );
130 assert( jarc2->next->check( ) != 0 );
131 assert( jarc1 != jarc2 );
132
133 /* XXX - if these assertions fail, it is due to user error or
134 undersampling */
135 if( ! ( jarc1->tail()[0] < (jarc1)->head()[0] ) ) {
136#ifndef NDEBUG
137 dprintf( "s difference %f\n", (jarc1)->tail()[0] - (jarc1)->head()[0] );
138#endif
139 ::mylongjmp( jumpbuffer, 28 );
140 }
141
142 if( ! ( jarc2->tail()[0] > (jarc2)->head()[0] ) ) {
143#ifndef NDEBUG
144 dprintf( "s difference %f\n", (jarc2)->tail()[0] - (jarc2)->head()[0] );
145#endif
146 ::mylongjmp( jumpbuffer, 28 );
147 }
148}
149
150inline void
151Subdivider::link( Arc_ptr jarc1, Arc_ptr jarc2, Arc_ptr up, Arc_ptr down )
152{
153 up->nuid = down->nuid = 0; // XXX
154
155 up->next = jarc2;
156 down->next = jarc1;
157 up->prev = jarc1->prev;
158 down->prev = jarc2->prev;
159
160 down->next->prev = down;
161 up->next->prev = up;
162 down->prev->next = down;
163 up->prev->next = up;
164}
165
166inline void
167Subdivider::simple_link( Arc_ptr jarc1, Arc_ptr jarc2 )
168{
169 Arc_ptr tmp = jarc2->prev;
170 jarc2->prev = jarc1->prev;
171 jarc1->prev = tmp;
172 jarc2->prev->next = jarc2;
173 jarc1->prev->next = jarc1;
174}
175
176
177/*----------------------------------------------------------------------------
178 * join - add a pair of oppositely directed jordan arcs between two arcs
179 *----------------------------------------------------------------------------
180 */
181
182void
183Subdivider::join_s( Bin& left, Bin& right, Arc_ptr jarc1, Arc_ptr jarc2 )
184{
185 assert( jarc1->check( ) != 0);
186 assert( jarc2->check( ) != 0);
187 assert( jarc1 != jarc2 );
188
189 if( ! jarc1->getitail() )
190 jarc1 = jarc1->next;
191
192 if( ! jarc2->getitail() )
193 jarc2 = jarc2->next;
194
195 REAL s = jarc1->tail()[0];
196 REAL t1 = jarc1->tail()[1];
197 REAL t2 = jarc2->tail()[1];
198
199 if( t1 == t2 ) {
200 simple_link( jarc1, jarc2 );
201 } else {
202 Arc_ptr newright = new(arcpool) Arc( arc_right, 0 );
203 Arc_ptr newleft = new(arcpool) Arc( arc_left, 0 );
204 assert( t1 < t2 );
205 if( isBezierArcType() ) {
206 arctessellator.bezier( newright, s, s, t1, t2 );
207 arctessellator.bezier( newleft, s, s, t2, t1 );
208 } else {
209 arctessellator.pwl_right( newright, s, t1, t2, stepsizes[0] );
210 arctessellator.pwl_left( newleft, s, t2, t1, stepsizes[2] );
211 }
212 link( jarc1, jarc2, newright, newleft );
213 left.addarc( newright );
214 right.addarc( newleft );
215 }
216
217 assert( jarc1->check( ) != 0 );
218 assert( jarc2->check( ) != 0 );
219 assert( jarc1->next->check( ) != 0);
220 assert( jarc2->next->check( ) != 0);
221}
222
223void
224Subdivider::check_t( Arc_ptr jarc1, Arc_ptr jarc2 )
225{
226 assert( jarc1->check( ) != 0 );
227 assert( jarc2->check( ) != 0 );
228 assert( jarc1->next->check( ) != 0 );
229 assert( jarc2->next->check( ) != 0 );
230 assert( jarc1 != jarc2 );
231
232 /* XXX - if these assertions fail, it is due to user error or
233 undersampling */
234 if( ! ( jarc1->tail()[1] < (jarc1)->head()[1] ) ) {
235#ifndef NDEBUG
236 dprintf( "t difference %f\n", jarc1->tail()[1] - (jarc1)->head()[1] );
237#endif
238 ::mylongjmp( jumpbuffer, 28 );
239 }
240
241 if( ! ( jarc2->tail()[1] > (jarc2)->head()[1] ) ) {
242#ifndef NDEBUG
243 dprintf( "t difference %f\n", jarc2->tail()[1] - (jarc2)->head()[1] );
244#endif
245 ::mylongjmp( jumpbuffer, 28 );
246 }
247}
248
249/*----------------------------------------------------------------------------
250 * join_t - add a pair of oppositely directed jordan arcs between two arcs
251 *----------------------------------------------------------------------------
252 */
253
254void
255Subdivider::join_t( Bin& bottom, Bin& top, Arc_ptr jarc1, Arc_ptr jarc2 )
256{
257 assert( jarc1->check( ) != 0 );
258 assert( jarc2->check( ) != 0 );
259 assert( jarc1->next->check( ) != 0 );
260 assert( jarc2->next->check( ) != 0 );
261 assert( jarc1 != jarc2 );
262
263 if( ! jarc1->getitail() )
264 jarc1 = jarc1->next;
265
266 if( ! jarc2->getitail() )
267 jarc2 = jarc2->next;
268
269 REAL s1 = jarc1->tail()[0];
270 REAL s2 = jarc2->tail()[0];
271 REAL t = jarc1->tail()[1];
272
273 if( s1 == s2 ) {
274 simple_link( jarc1, jarc2 );
275 } else {
276 Arc_ptr newtop = new(arcpool) Arc( arc_top, 0 );
277 Arc_ptr newbot = new(arcpool) Arc( arc_bottom, 0 );
278 assert( s1 > s2 );
279 if( isBezierArcType() ) {
280 arctessellator.bezier( newtop, s1, s2, t, t );
281 arctessellator.bezier( newbot, s2, s1, t, t );
282 } else {
283 arctessellator.pwl_top( newtop, t, s1, s2, stepsizes[1] );
284 arctessellator.pwl_bottom( newbot, t, s2, s1, stepsizes[3] );
285 }
286 link( jarc1, jarc2, newtop, newbot );
287 bottom.addarc( newtop );
288 top.addarc( newbot );
289 }
290
291 assert( jarc1->check( ) != 0 );
292 assert( jarc2->check( ) != 0 );
293 assert( jarc1->next->check( ) != 0 );
294 assert( jarc2->next->check( ) != 0 );
295}
296
Note: See TracBrowser for help on using the repository browser.