1f220fa62Smrg/*
2f220fa62Smrg** License Applicability. Except to the extent portions of this file are
3f220fa62Smrg** made subject to an alternative license as permitted in the SGI Free
4f220fa62Smrg** Software License B, Version 1.1 (the "License"), the contents of this
5f220fa62Smrg** file are subject only to the provisions of the License. You may not use
6f220fa62Smrg** this file except in compliance with the License. You may obtain a copy
7f220fa62Smrg** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
8f220fa62Smrg** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
9f220fa62Smrg**
10f220fa62Smrg** http://oss.sgi.com/projects/FreeB
11f220fa62Smrg**
12f220fa62Smrg** Note that, as provided in the License, the Software is distributed on an
13f220fa62Smrg** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
14f220fa62Smrg** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
15f220fa62Smrg** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
16f220fa62Smrg** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
17f220fa62Smrg**
18f220fa62Smrg** Original Code. The Original Code is: OpenGL Sample Implementation,
19f220fa62Smrg** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
20f220fa62Smrg** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
21f220fa62Smrg** Copyright in any portions created by third parties is as indicated
22f220fa62Smrg** elsewhere herein. All Rights Reserved.
23f220fa62Smrg**
24f220fa62Smrg** Additional Notice Provisions: The application programming interfaces
25f220fa62Smrg** established by SGI in conjunction with the Original Code are The
26f220fa62Smrg** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
27f220fa62Smrg** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
28f220fa62Smrg** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
29f220fa62Smrg** Window System(R) (Version 1.3), released October 19, 1998. This software
30f220fa62Smrg** was created using the OpenGL(R) version 1.2.1 Sample Implementation
31f220fa62Smrg** published by SGI, but has not been independently verified as being
32f220fa62Smrg** compliant with the OpenGL(R) version 1.2.1 Specification.
33f220fa62Smrg*/
34f220fa62Smrg
35f220fa62Smrg/*
36f220fa62Smrg * mesher.c++
37f220fa62Smrg *
38f220fa62Smrg */
39f220fa62Smrg
40f220fa62Smrg#include "glimports.h"
41f220fa62Smrg#include "myassert.h"
42f220fa62Smrg#include "mystdio.h"
43f220fa62Smrg#include "gridvertex.h"
44f220fa62Smrg#include "gridtrimvertex.h"
45f220fa62Smrg#include "jarcloc.h"
46f220fa62Smrg#include "gridline.h"
47f220fa62Smrg#include "trimline.h"
48f220fa62Smrg#include "uarray.h"
49f220fa62Smrg#include "backend.h"
50f220fa62Smrg#include "mesher.h"
51f220fa62Smrg
52f220fa62Smrg
53f220fa62Smrgconst float Mesher::ZERO = 0.0;
54f220fa62Smrg
55f220fa62SmrgMesher::Mesher( Backend& b )
56f220fa62Smrg	: backend( b ),
57f220fa62Smrg	p( sizeof( GridTrimVertex ), 100, "GridTrimVertexPool" )
58f220fa62Smrg{
59f220fa62Smrg    stacksize = 0;
60f220fa62Smrg    vdata = 0;
61f220fa62Smrg    last[0] = 0;
62f220fa62Smrg    last[1] = 0;
63f220fa62Smrg    itop = 0;
64f220fa62Smrg    lastedge = 0; //needed to prevent purify UMR
65f220fa62Smrg}
66f220fa62Smrg
67f220fa62SmrgMesher::~Mesher( void )
68f220fa62Smrg{
69f220fa62Smrg    if( vdata ) delete[] vdata;
70f220fa62Smrg}
71f220fa62Smrg
72f220fa62Smrgvoid
73f220fa62SmrgMesher::init( unsigned int npts )
74f220fa62Smrg{
75f220fa62Smrg    p.clear();
76f220fa62Smrg    if( stacksize < npts ) {
77f220fa62Smrg	stacksize = 2 * npts;
78f220fa62Smrg	if( vdata ) delete[] vdata;
79f220fa62Smrg	vdata = new GridTrimVertex_p[stacksize];
80f220fa62Smrg    }
81f220fa62Smrg}
82f220fa62Smrg
83f220fa62Smrginline void
84f220fa62SmrgMesher::push( GridTrimVertex *gt )
85f220fa62Smrg{
86f220fa62Smrg    assert( itop+1 != (int)stacksize );
87f220fa62Smrg    vdata[++itop] = gt;
88f220fa62Smrg}
89f220fa62Smrg
90f220fa62Smrginline void
91f220fa62SmrgMesher::pop( long )
92f220fa62Smrg{
93f220fa62Smrg}
94f220fa62Smrg
95f220fa62Smrginline void
96f220fa62SmrgMesher::openMesh()
97f220fa62Smrg{
98f220fa62Smrg    backend.bgntmesh( "addedge" );
99f220fa62Smrg}
100f220fa62Smrg
101f220fa62Smrginline void
102f220fa62SmrgMesher::closeMesh()
103f220fa62Smrg{
104f220fa62Smrg    backend.endtmesh();
105f220fa62Smrg}
106f220fa62Smrg
107f220fa62Smrginline void
108f220fa62SmrgMesher::swapMesh()
109f220fa62Smrg{
110f220fa62Smrg    backend.swaptmesh();
111f220fa62Smrg}
112f220fa62Smrg
113f220fa62Smrginline void
114f220fa62SmrgMesher::clearStack()
115f220fa62Smrg{
116f220fa62Smrg    itop = -1;
117f220fa62Smrg    last[0] = 0;
118f220fa62Smrg}
119f220fa62Smrg
120f220fa62Smrgvoid
121f220fa62SmrgMesher::finishLower( GridTrimVertex *gtlower )
122f220fa62Smrg{
123f220fa62Smrg    for( push(gtlower);
124f220fa62Smrg	 nextlower( gtlower=new(p) GridTrimVertex );
125f220fa62Smrg	 push(gtlower) )
126f220fa62Smrg	    addLower();
127f220fa62Smrg    addLast();
128f220fa62Smrg}
129f220fa62Smrg
130f220fa62Smrgvoid
131f220fa62SmrgMesher::finishUpper( GridTrimVertex *gtupper )
132f220fa62Smrg{
133f220fa62Smrg    for( push(gtupper);
134f220fa62Smrg	 nextupper( gtupper=new(p) GridTrimVertex );
135f220fa62Smrg	 push(gtupper) )
136f220fa62Smrg	    addUpper();
137f220fa62Smrg    addLast();
138f220fa62Smrg}
139f220fa62Smrg
140f220fa62Smrgvoid
141f220fa62SmrgMesher::mesh( void )
142f220fa62Smrg{
143f220fa62Smrg    GridTrimVertex *gtlower, *gtupper;
144f220fa62Smrg
145f220fa62Smrg    Hull::init( );
146f220fa62Smrg    nextupper( gtupper = new(p) GridTrimVertex );
147f220fa62Smrg    nextlower( gtlower = new(p) GridTrimVertex );
148f220fa62Smrg
149f220fa62Smrg    clearStack();
150f220fa62Smrg    openMesh();
151f220fa62Smrg    push(gtupper);
152f220fa62Smrg
153f220fa62Smrg    nextupper( gtupper = new(p) GridTrimVertex );
154f220fa62Smrg    nextlower( gtlower );
155f220fa62Smrg
156f220fa62Smrg    assert( gtupper->t && gtlower->t );
157f220fa62Smrg
158f220fa62Smrg    if( gtupper->t->param[0] < gtlower->t->param[0] ) {
159f220fa62Smrg	push(gtupper);
160f220fa62Smrg	lastedge = 1;
161f220fa62Smrg	if( nextupper( gtupper=new(p) GridTrimVertex ) == 0 ) {
162f220fa62Smrg	    finishLower(gtlower);
163f220fa62Smrg	    return;
164f220fa62Smrg	}
165f220fa62Smrg    } else if( gtupper->t->param[0] > gtlower->t->param[0] ) {
166f220fa62Smrg	push(gtlower);
167f220fa62Smrg	lastedge = 0;
168f220fa62Smrg	if( nextlower( gtlower=new(p) GridTrimVertex ) == 0 ) {
169f220fa62Smrg	    finishUpper(gtupper);
170f220fa62Smrg	    return;
171f220fa62Smrg	}
172f220fa62Smrg    } else {
173f220fa62Smrg	if( lastedge == 0 ) {
174f220fa62Smrg	    push(gtupper);
175f220fa62Smrg	    lastedge = 1;
176f220fa62Smrg	    if( nextupper(gtupper=new(p) GridTrimVertex) == 0 ) {
177f220fa62Smrg		finishLower(gtlower);
178f220fa62Smrg		return;
179f220fa62Smrg	    }
180f220fa62Smrg	} else {
181f220fa62Smrg	    push(gtlower);
182f220fa62Smrg	    lastedge = 0;
183f220fa62Smrg	    if( nextlower( gtlower=new(p) GridTrimVertex ) == 0 ) {
184f220fa62Smrg		finishUpper(gtupper);
185f220fa62Smrg		return;
186f220fa62Smrg	    }
187f220fa62Smrg	}
188f220fa62Smrg    }
189f220fa62Smrg
190f220fa62Smrg    while ( 1 ) {
191f220fa62Smrg	if( gtupper->t->param[0] < gtlower->t->param[0] ) {
192f220fa62Smrg            push(gtupper);
193f220fa62Smrg	    addUpper();
194f220fa62Smrg	    if( nextupper( gtupper=new(p) GridTrimVertex ) == 0 ) {
195f220fa62Smrg		finishLower(gtlower);
196f220fa62Smrg		return;
197f220fa62Smrg	    }
198f220fa62Smrg	} else if( gtupper->t->param[0] > gtlower->t->param[0] ) {
199f220fa62Smrg    	    push(gtlower);
200f220fa62Smrg	    addLower();
201f220fa62Smrg	    if( nextlower( gtlower=new(p) GridTrimVertex ) == 0 ) {
202f220fa62Smrg		finishUpper(gtupper);
203f220fa62Smrg		return;
204f220fa62Smrg	    }
205f220fa62Smrg	} else {
206f220fa62Smrg	    if( lastedge == 0 ) {
207f220fa62Smrg		push(gtupper);
208f220fa62Smrg		addUpper();
209f220fa62Smrg		if( nextupper( gtupper=new(p) GridTrimVertex ) == 0 ) {
210f220fa62Smrg		    finishLower(gtlower);
211f220fa62Smrg		    return;
212f220fa62Smrg		}
213f220fa62Smrg	    } else {
214f220fa62Smrg		push(gtlower);
215f220fa62Smrg		addLower();
216f220fa62Smrg		if( nextlower( gtlower=new(p) GridTrimVertex ) == 0 ) {
217f220fa62Smrg		    finishUpper(gtupper);
218f220fa62Smrg		    return;
219f220fa62Smrg		}
220f220fa62Smrg	    }
221f220fa62Smrg	}
222f220fa62Smrg    }
223f220fa62Smrg}
224f220fa62Smrg
225f220fa62Smrginline int
226f220fa62SmrgMesher::isCcw( int ilast )
227f220fa62Smrg{
228f220fa62Smrg    REAL area = det3( vdata[ilast]->t, vdata[itop-1]->t, vdata[itop-2]->t );
229f220fa62Smrg    return (area < ZERO) ? 0 : 1;
230f220fa62Smrg}
231f220fa62Smrg
232f220fa62Smrginline int
233f220fa62SmrgMesher::isCw( int ilast  )
234f220fa62Smrg{
235f220fa62Smrg    REAL area = det3( vdata[ilast]->t, vdata[itop-1]->t, vdata[itop-2]->t );
236f220fa62Smrg    return (area > -ZERO) ? 0 : 1;
237f220fa62Smrg}
238f220fa62Smrg
239f220fa62Smrginline int
240f220fa62SmrgMesher::equal( int x, int y )
241f220fa62Smrg{
242f220fa62Smrg    return( last[0] == vdata[x] && last[1] == vdata[y] );
243f220fa62Smrg}
244f220fa62Smrg
245f220fa62Smrginline void
246f220fa62SmrgMesher::copy( int x, int y )
247f220fa62Smrg{
248f220fa62Smrg    last[0] = vdata[x]; last[1] = vdata[y];
249f220fa62Smrg}
250f220fa62Smrg
251f220fa62Smrginline void
252f220fa62SmrgMesher::move( int x, int y )
253f220fa62Smrg{
254f220fa62Smrg    vdata[x] = vdata[y];
255f220fa62Smrg}
256f220fa62Smrg
257f220fa62Smrginline void
258f220fa62SmrgMesher::output( int x )
259f220fa62Smrg{
260f220fa62Smrg    backend.tmeshvert( vdata[x] );
261f220fa62Smrg}
262f220fa62Smrg
263f220fa62Smrg/*---------------------------------------------------------------------------
264f220fa62Smrg * addedge - addedge an edge to the triangulation
265f220fa62Smrg *
266f220fa62Smrg *	This code has been re-written to generate large triangle meshes
267f220fa62Smrg *	from a monotone polygon.  Although smaller triangle meshes
268f220fa62Smrg *	could be generated faster and with less code, larger meshes
269f220fa62Smrg *	actually give better SYSTEM performance.  This is because
270f220fa62Smrg *	vertices are processed in the backend slower than they are
271f220fa62Smrg *	generated by this code and any decrease in the number of vertices
272f220fa62Smrg *	results in a decrease in the time spent in the backend.
273f220fa62Smrg *---------------------------------------------------------------------------
274f220fa62Smrg */
275f220fa62Smrg
276f220fa62Smrgvoid
277f220fa62SmrgMesher::addLast( )
278f220fa62Smrg{
279e7980a23Smrg    int ilast = itop;
280f220fa62Smrg
281f220fa62Smrg    if( lastedge == 0 ) {
282f220fa62Smrg	if( equal( 0, 1 ) ) {
283f220fa62Smrg	    output( ilast );
284f220fa62Smrg	    swapMesh();
285e7980a23Smrg	    for( int i = 2; i < ilast; i++ ) {
286f220fa62Smrg		swapMesh();
287f220fa62Smrg		output( i );
288f220fa62Smrg	    }
289f220fa62Smrg	    copy( ilast, ilast-1 );
290f220fa62Smrg	} else if( equal( ilast-2, ilast-1) ) {
291f220fa62Smrg	    swapMesh();
292f220fa62Smrg	    output( ilast );
293e7980a23Smrg	    for( int i = ilast-3; i >= 0; i-- ) {
294f220fa62Smrg		output( i );
295f220fa62Smrg		swapMesh();
296f220fa62Smrg	    }
297f220fa62Smrg	    copy( 0, ilast );
298f220fa62Smrg	} else {
299f220fa62Smrg	    closeMesh();	openMesh();
300f220fa62Smrg	    output( ilast );
301f220fa62Smrg	    output( 0 );
302e7980a23Smrg	    for( int i = 1; i < ilast; i++ ) {
303f220fa62Smrg		swapMesh();
304f220fa62Smrg		output( i );
305f220fa62Smrg	    }
306f220fa62Smrg	    copy( ilast, ilast-1 );
307f220fa62Smrg	}
308f220fa62Smrg    } else {
309f220fa62Smrg	if( equal( 1, 0) ) {
310f220fa62Smrg	    swapMesh();
311f220fa62Smrg	    output( ilast );
312e7980a23Smrg	    for( int i = 2; i < ilast; i++ ) {
313f220fa62Smrg		output( i );
314f220fa62Smrg		swapMesh();
315f220fa62Smrg	    }
316f220fa62Smrg	    copy( ilast-1, ilast );
317f220fa62Smrg	} else if( equal( ilast-1, ilast-2) ) {
318f220fa62Smrg	    output( ilast );
319f220fa62Smrg	    swapMesh();
320e7980a23Smrg	    for( int i = ilast-3; i >= 0; i-- ) {
321f220fa62Smrg		swapMesh();
322f220fa62Smrg		output( i );
323f220fa62Smrg	    }
324f220fa62Smrg	    copy( ilast, 0 );
325f220fa62Smrg	} else {
326f220fa62Smrg	    closeMesh();	openMesh();
327f220fa62Smrg	    output( 0 );
328f220fa62Smrg	    output( ilast );
329e7980a23Smrg	    for( int i = 1; i < ilast; i++ ) {
330f220fa62Smrg		output( i );
331f220fa62Smrg		swapMesh();
332f220fa62Smrg	    }
333f220fa62Smrg	    copy( ilast-1, ilast );
334f220fa62Smrg	}
335f220fa62Smrg    }
336f220fa62Smrg    closeMesh();
337e7980a23Smrg    //for( long k=0; k<=ilast; k++ ) pop( k );
338f220fa62Smrg}
339f220fa62Smrg
340f220fa62Smrgvoid
341f220fa62SmrgMesher::addUpper( )
342f220fa62Smrg{
343e7980a23Smrg    int ilast = itop;
344f220fa62Smrg
345f220fa62Smrg    if( lastedge == 0 ) {
346f220fa62Smrg	if( equal( 0, 1 ) ) {
347f220fa62Smrg	    output( ilast );
348f220fa62Smrg	    swapMesh();
349e7980a23Smrg	    for( int i = 2; i < ilast; i++ ) {
350f220fa62Smrg		swapMesh();
351f220fa62Smrg		output( i );
352f220fa62Smrg	    }
353f220fa62Smrg	    copy( ilast, ilast-1 );
354f220fa62Smrg	} else if( equal( ilast-2, ilast-1) ) {
355f220fa62Smrg	    swapMesh();
356f220fa62Smrg	    output( ilast );
357e7980a23Smrg	    for( int i = ilast-3; i >= 0; i-- ) {
358f220fa62Smrg		output( i );
359f220fa62Smrg		swapMesh();
360f220fa62Smrg	    }
361f220fa62Smrg	    copy( 0, ilast );
362f220fa62Smrg	} else {
363f220fa62Smrg	    closeMesh();	openMesh();
364f220fa62Smrg	    output( ilast );
365f220fa62Smrg	    output( 0 );
366e7980a23Smrg	    for( int i = 1; i < ilast; i++ ) {
367f220fa62Smrg		swapMesh();
368f220fa62Smrg		output( i );
369f220fa62Smrg	    }
370f220fa62Smrg	    copy( ilast, ilast-1 );
371f220fa62Smrg	}
372f220fa62Smrg	lastedge = 1;
373e7980a23Smrg        //for( long k=0; k<ilast-1; k++ ) pop( k );
374f220fa62Smrg	move( 0, ilast-1 );
375f220fa62Smrg	move( 1, ilast );
376f220fa62Smrg	itop = 1;
377f220fa62Smrg    } else {
378f220fa62Smrg	if( ! isCcw( ilast ) ) return;
379f220fa62Smrg	do {
380f220fa62Smrg	    itop--;
381f220fa62Smrg	} while( (itop > 1) && isCcw( ilast ) );
382f220fa62Smrg
383f220fa62Smrg	if( equal( ilast-1, ilast-2 ) ) {
384f220fa62Smrg	    output( ilast );
385f220fa62Smrg	    swapMesh();
386e7980a23Smrg	    for( int i=ilast-3; i>=itop-1; i-- ) {
387f220fa62Smrg		swapMesh();
388f220fa62Smrg		output( i );
389f220fa62Smrg	    }
390f220fa62Smrg	    copy( ilast, itop-1 );
391f220fa62Smrg	} else if( equal( itop, itop-1 ) ) {
392f220fa62Smrg	    swapMesh();
393f220fa62Smrg	    output( ilast );
394e7980a23Smrg	    for( int i = itop+1; i < ilast; i++ ) {
395f220fa62Smrg		output( i );
396f220fa62Smrg		swapMesh();
397f220fa62Smrg	    }
398f220fa62Smrg	    copy( ilast-1, ilast );
399f220fa62Smrg	} else {
400f220fa62Smrg	    closeMesh();	openMesh();
401f220fa62Smrg	    output( ilast );
402f220fa62Smrg	    output( ilast-1 );
403e7980a23Smrg	    for( int i=ilast-2; i>=itop-1; i-- ) {
404f220fa62Smrg		swapMesh();
405f220fa62Smrg		output( i );
406f220fa62Smrg	    }
407f220fa62Smrg	    copy( ilast, itop-1 );
408f220fa62Smrg	}
409e7980a23Smrg        //for( int k=itop; k<ilast; k++ ) pop( k );
410f220fa62Smrg	move( itop, ilast );
411f220fa62Smrg    }
412f220fa62Smrg}
413f220fa62Smrg
414f220fa62Smrgvoid
415f220fa62SmrgMesher::addLower()
416f220fa62Smrg{
417e7980a23Smrg    int ilast = itop;
418f220fa62Smrg
419f220fa62Smrg    if( lastedge == 1 ) {
420f220fa62Smrg	if( equal( 1, 0) ) {
421f220fa62Smrg	    swapMesh();
422f220fa62Smrg	    output( ilast );
423e7980a23Smrg	    for( int i = 2; i < ilast; i++ ) {
424f220fa62Smrg		output( i );
425f220fa62Smrg		swapMesh();
426f220fa62Smrg	    }
427f220fa62Smrg	    copy( ilast-1, ilast );
428f220fa62Smrg	} else if( equal( ilast-1, ilast-2) ) {
429f220fa62Smrg	    output( ilast );
430f220fa62Smrg	    swapMesh();
431e7980a23Smrg	    for( int i = ilast-3; i >= 0; i-- ) {
432f220fa62Smrg		swapMesh();
433f220fa62Smrg		output( i );
434f220fa62Smrg	    }
435f220fa62Smrg	    copy( ilast, 0 );
436f220fa62Smrg	} else {
437f220fa62Smrg	    closeMesh();	openMesh();
438f220fa62Smrg	    output( 0 );
439f220fa62Smrg	    output( ilast );
440e7980a23Smrg	    for( int i = 1; i < ilast; i++ ) {
441f220fa62Smrg		output( i );
442f220fa62Smrg		swapMesh();
443f220fa62Smrg	    }
444f220fa62Smrg	    copy( ilast-1, ilast );
445f220fa62Smrg	}
446f220fa62Smrg
447f220fa62Smrg	lastedge = 0;
448e7980a23Smrg        //for( long k=0; k<ilast-1; k++ ) pop( k );
449f220fa62Smrg	move( 0, ilast-1 );
450f220fa62Smrg	move( 1, ilast );
451f220fa62Smrg	itop = 1;
452f220fa62Smrg    } else {
453f220fa62Smrg	if( ! isCw( ilast ) ) return;
454f220fa62Smrg	do {
455f220fa62Smrg	    itop--;
456f220fa62Smrg	} while( (itop > 1) && isCw( ilast ) );
457f220fa62Smrg
458f220fa62Smrg	if( equal( ilast-2, ilast-1) ) {
459f220fa62Smrg	    swapMesh();
460f220fa62Smrg	    output( ilast );
461e7980a23Smrg	    for( int i=ilast-3; i>=itop-1; i--) {
462f220fa62Smrg		output( i );
463f220fa62Smrg		swapMesh( );
464f220fa62Smrg	    }
465f220fa62Smrg	    copy( itop-1, ilast );
466f220fa62Smrg	} else if( equal( itop-1, itop) ) {
467f220fa62Smrg	    output( ilast );
468f220fa62Smrg	    swapMesh();
469e7980a23Smrg	    for( int i=itop+1; i<ilast; i++ ) {
470f220fa62Smrg		swapMesh( );
471f220fa62Smrg		output( i );
472f220fa62Smrg	    }
473f220fa62Smrg	    copy( ilast, ilast-1 );
474f220fa62Smrg	} else {
475f220fa62Smrg	    closeMesh();	openMesh();
476f220fa62Smrg	    output( ilast-1 );
477f220fa62Smrg	    output( ilast );
478e7980a23Smrg	    for( int i=ilast-2; i>=itop-1; i-- ) {
479f220fa62Smrg		output( i );
480f220fa62Smrg		swapMesh( );
481f220fa62Smrg	    }
482f220fa62Smrg	    copy( itop-1, ilast );
483f220fa62Smrg	}
484e7980a23Smrg        //for( int k=itop; k<ilast; k++ ) pop( k );
485f220fa62Smrg	move( itop, ilast );
486f220fa62Smrg    }
487f220fa62Smrg}
488f220fa62Smrg
489f220fa62Smrg
490