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 * nurbstess.c++
37f220fa62Smrg *
38f220fa62Smrg */
39f220fa62Smrg
40f220fa62Smrg#include "glimports.h"
41f220fa62Smrg#include "myassert.h"
42f220fa62Smrg#include "mysetjmp.h"
43f220fa62Smrg#include "mystdio.h"
44f220fa62Smrg#include "nurbsconsts.h"
45f220fa62Smrg#include "nurbstess.h"
46f220fa62Smrg#include "bufpool.h"
47f220fa62Smrg#include "quilt.h"
48f220fa62Smrg#include "knotvector.h"
49f220fa62Smrg#include "mapdesc.h"
50f220fa62Smrg#include "maplist.h"
51f220fa62Smrg
52f220fa62Smrgvoid
53f220fa62SmrgNurbsTessellator::set_domain_distance_u_rate(REAL u_rate)
54f220fa62Smrg{
55f220fa62Smrg  subdivider.set_domain_distance_u_rate(u_rate);
56f220fa62Smrg}
57f220fa62Smrg
58f220fa62Smrgvoid
59f220fa62SmrgNurbsTessellator::set_domain_distance_v_rate(REAL v_rate)
60f220fa62Smrg{
61f220fa62Smrg  subdivider.set_domain_distance_v_rate(v_rate);
62f220fa62Smrg}
63f220fa62Smrg
64f220fa62Smrgvoid
65f220fa62SmrgNurbsTessellator::set_is_domain_distance_sampling(int flag)
66f220fa62Smrg{
67f220fa62Smrg  subdivider.set_is_domain_distance_sampling(flag);
68f220fa62Smrg}
69f220fa62Smrg
70f220fa62Smrgvoid
71f220fa62SmrgNurbsTessellator::resetObjects( void )
72f220fa62Smrg{
73f220fa62Smrg    subdivider.clear();
74f220fa62Smrg}
75f220fa62Smrg
76f220fa62Smrgvoid
77f220fa62SmrgNurbsTessellator::makeobj( int )
78f220fa62Smrg{
79f220fa62Smrg#ifndef NDEBUG
80f220fa62Smrg   _glu_dprintf( "makeobj\n" );
81f220fa62Smrg#endif
82f220fa62Smrg}
83f220fa62Smrg
84f220fa62Smrgvoid
85f220fa62SmrgNurbsTessellator::closeobj( void )
86f220fa62Smrg{
87f220fa62Smrg#ifndef NDEBUG
88f220fa62Smrg   _glu_dprintf( "closeobj\n" );
89f220fa62Smrg#endif
90f220fa62Smrg}
91f220fa62Smrg
92f220fa62Smrgvoid
93f220fa62SmrgNurbsTessellator::bgnrender( void )
94f220fa62Smrg{
95f220fa62Smrg#ifndef NDEBUG
96f220fa62Smrg   _glu_dprintf( "bgnrender\n" );
97f220fa62Smrg#endif
98f220fa62Smrg}
99f220fa62Smrg
100f220fa62Smrgvoid
101f220fa62SmrgNurbsTessellator::endrender( void )
102f220fa62Smrg{
103f220fa62Smrg#ifndef NDEBUG
104f220fa62Smrg    _glu_dprintf( "endrender\n" );
105f220fa62Smrg#endif
106f220fa62Smrg}
107f220fa62Smrg
108f220fa62Smrg/*-----------------------------------------------------------------------------
109f220fa62Smrg * do_freebgnsurface - free o_surface structure
110f220fa62Smrg *
111f220fa62Smrg * Client: do_freeall(), bgnsurface()
112f220fa62Smrg *-----------------------------------------------------------------------------
113f220fa62Smrg */
114f220fa62Smrgvoid
115f220fa62SmrgNurbsTessellator::do_freebgnsurface( O_surface *o_surface )
116f220fa62Smrg{
117f220fa62Smrg    o_surface->deleteMe( o_surfacePool );
118f220fa62Smrg}
119f220fa62Smrg
120f220fa62Smrg
121f220fa62Smrg/*-----------------------------------------------------------------------------
122f220fa62Smrg * do_bgnsurface - begin the display of a surface
123f220fa62Smrg *
124f220fa62Smrg * Client: bgnsurface()
125f220fa62Smrg *-----------------------------------------------------------------------------
126f220fa62Smrg */
127f220fa62Smrgvoid
128f220fa62SmrgNurbsTessellator::do_bgnsurface( O_surface *o_surface )
129f220fa62Smrg{
130f220fa62Smrg    if( inSurface ) {
131f220fa62Smrg	do_nurbserror( 27 );
132f220fa62Smrg	endsurface();
133f220fa62Smrg    }
134f220fa62Smrg    inSurface = 1;
135f220fa62Smrg
136f220fa62Smrg    if( ! playBack ) bgnrender();
137f220fa62Smrg
138f220fa62Smrg    isTrimModified = 0;
139f220fa62Smrg    isSurfaceModified = 0;
140f220fa62Smrg    isDataValid = 1;
141f220fa62Smrg    numTrims = 0;
142f220fa62Smrg    currentSurface = o_surface;
143f220fa62Smrg    nextTrim = &( currentSurface->o_trim );
144f220fa62Smrg    nextNurbssurface = &( currentSurface->o_nurbssurface );
145f220fa62Smrg}
146f220fa62Smrg
147f220fa62Smrg/*-----------------------------------------------------------------------------
148f220fa62Smrg * do_bgncurve - begin the display of a curve
149f220fa62Smrg *
150f220fa62Smrg * Client: bgncurve()
151f220fa62Smrg *-----------------------------------------------------------------------------
152f220fa62Smrg */
153f220fa62Smrgvoid
154f220fa62SmrgNurbsTessellator::do_bgncurve( O_curve *o_curve )
155f220fa62Smrg{
156f220fa62Smrg    if ( inCurve ) {
157f220fa62Smrg	do_nurbserror( 6 );
158f220fa62Smrg	endcurve();
159f220fa62Smrg    }
160f220fa62Smrg
161f220fa62Smrg    inCurve = 1;
162f220fa62Smrg    currentCurve = o_curve;
163f220fa62Smrg    currentCurve->curvetype = ct_none;
164f220fa62Smrg
165f220fa62Smrg    if( inTrim ) {
166f220fa62Smrg        if( *nextCurve != o_curve ) {
167f220fa62Smrg	    isCurveModified = 1;
168f220fa62Smrg	    *nextCurve = o_curve;
169f220fa62Smrg	}
170f220fa62Smrg    } else {
171f220fa62Smrg        if( ! playBack ) bgnrender();
172f220fa62Smrg        isDataValid = 1;
173f220fa62Smrg    }
174f220fa62Smrg    nextCurve = &(o_curve->next);
175f220fa62Smrg    nextPwlcurve = &(o_curve->curve.o_pwlcurve);
176f220fa62Smrg    nextNurbscurve = &(o_curve->curve.o_nurbscurve);
177f220fa62Smrg}
178f220fa62Smrg
179f220fa62Smrg/*-----------------------------------------------------------------------------
180f220fa62Smrg * do_endcurve -
181f220fa62Smrg *
182f220fa62Smrg * Client: endcurve()
183f220fa62Smrg *-----------------------------------------------------------------------------
184f220fa62Smrg */
185f220fa62Smrg
186f220fa62Smrgvoid
187f220fa62SmrgNurbsTessellator::do_endcurve( void )
188f220fa62Smrg{
189f220fa62Smrg    if( ! inCurve ) {
190f220fa62Smrg	do_nurbserror( 7 );
191f220fa62Smrg	return;
192f220fa62Smrg    }
193f220fa62Smrg    inCurve = 0;
194f220fa62Smrg
195f220fa62Smrg    *nextCurve = 0;
196f220fa62Smrg    if (currentCurve->curvetype == ct_nurbscurve)
197f220fa62Smrg	*nextNurbscurve = 0;
198f220fa62Smrg    else
199f220fa62Smrg	*nextPwlcurve = 0;
200f220fa62Smrg
201f220fa62Smrg    if ( ! inTrim ) {
202f220fa62Smrg        if( ! isDataValid ) {
203f220fa62Smrg            do_freecurveall( currentCurve );
204f220fa62Smrg	    return;
205f220fa62Smrg        }
206f220fa62Smrg
207f220fa62Smrg	int errval;
208f220fa62Smrg	errval = ::mysetjmp( jumpbuffer );
209f220fa62Smrg	if( errval == 0 ) {
210f220fa62Smrg	    if( currentCurve->curvetype == ct_nurbscurve ) {
211f220fa62Smrg		subdivider.beginQuilts();
212f220fa62Smrg		for( O_nurbscurve *n = currentCurve->curve.o_nurbscurve; n != 0; n = n->next )
213f220fa62Smrg		    subdivider.addQuilt( n->bezier_curves );
214f220fa62Smrg		subdivider.endQuilts();
215f220fa62Smrg		subdivider.drawCurves();
216f220fa62Smrg		if( ! playBack ) endrender();
217f220fa62Smrg	    } else {
218f220fa62Smrg		/* XXX */
219f220fa62Smrg	        if( ! playBack ) endrender();
220f220fa62Smrg	        /*do_draw_pwlcurve( currentCurve->curve.o_pwlcurve ) */;
221f220fa62Smrg	        do_nurbserror( 9 );
222f220fa62Smrg	    }
223f220fa62Smrg	} else {
224f220fa62Smrg	    if( ! playBack ) endrender();
225f220fa62Smrg	    do_nurbserror( errval );
226f220fa62Smrg	}
227f220fa62Smrg	do_freecurveall( currentCurve );
228f220fa62Smrg	resetObjects();
229f220fa62Smrg    }
230f220fa62Smrg}
231f220fa62Smrg
232f220fa62Smrg/*-----------------------------------------------------------------------------
233f220fa62Smrg * do_endsurface - mark end of surface, display surface, free immediate data
234f220fa62Smrg *
235f220fa62Smrg * Client:
236f220fa62Smrg *-----------------------------------------------------------------------------
237f220fa62Smrg */
238f220fa62Smrgvoid
239f220fa62SmrgNurbsTessellator::do_endsurface( void )
240f220fa62Smrg{
241f220fa62Smrg    if( inTrim ) {
242f220fa62Smrg	do_nurbserror( 12 );
243f220fa62Smrg	endtrim();
244f220fa62Smrg    }
245f220fa62Smrg
246f220fa62Smrg    if( ! inSurface ) {
247f220fa62Smrg	do_nurbserror( 13 );
248f220fa62Smrg	return;
249f220fa62Smrg    }
250f220fa62Smrg    inSurface = 0;
251f220fa62Smrg
252f220fa62Smrg    *nextNurbssurface = 0;
253f220fa62Smrg
254f220fa62Smrg    if( ! isDataValid ) {
255f220fa62Smrg        do_freeall( );
256f220fa62Smrg	return;
257f220fa62Smrg    }
258f220fa62Smrg
259f220fa62Smrg    if( *nextTrim != 0 ) {
260f220fa62Smrg	isTrimModified = 1;
261f220fa62Smrg        *nextTrim = 0;
262f220fa62Smrg    }
263f220fa62Smrg
264f220fa62Smrg    int errval;
265f220fa62Smrg
266f220fa62Smrg    errval = ::mysetjmp( jumpbuffer );
267f220fa62Smrg    if( errval == 0 ) {
268f220fa62Smrg        if( numTrims > 0 ) {
269f220fa62Smrg
270f220fa62Smrg	    subdivider.beginTrims();
271f220fa62Smrg	    for( O_trim	*trim = currentSurface->o_trim; trim; trim = trim->next ) {
272f220fa62Smrg		subdivider.beginLoop();
273f220fa62Smrg		for( O_curve *curve = trim->o_curve; curve; curve = curve->next ) {
274f220fa62Smrg		    curve->used = 0;
275f220fa62Smrg		    assert( curve->curvetype != ct_none );
276f220fa62Smrg		    if (curve->curvetype == ct_pwlcurve) {
277f220fa62Smrg			O_pwlcurve *c = curve->curve.o_pwlcurve;
278f220fa62Smrg			subdivider.addArc( c->npts, c->pts, curve->nuid );
279f220fa62Smrg		    } else {
280f220fa62Smrg			Quilt	   *quilt = curve->curve.o_nurbscurve->bezier_curves;
281f220fa62Smrg			Quiltspec  *qspec = quilt->qspec;
282f220fa62Smrg			REAL       *cpts  = quilt->cpts + qspec->offset;
283f220fa62Smrg			REAL       *cptsend = cpts + (qspec->width * qspec->order * qspec->stride);
284f220fa62Smrg			for( ; cpts != cptsend; cpts += qspec->order*qspec->stride )
285f220fa62Smrg			     subdivider.addArc( cpts, quilt, curve->nuid );
286f220fa62Smrg		    }
287f220fa62Smrg		}
288f220fa62Smrg		subdivider.endLoop();
289f220fa62Smrg	    }
290f220fa62Smrg	    subdivider.endTrims();
291f220fa62Smrg	}
292f220fa62Smrg
293f220fa62Smrg	subdivider.beginQuilts();
294f220fa62Smrg	for( O_nurbssurface *n = currentSurface->o_nurbssurface; n; n = n->next )
295f220fa62Smrg	    subdivider.addQuilt( n->bezier_patches );
296f220fa62Smrg	subdivider.endQuilts();
297f220fa62Smrg        subdivider.drawSurfaces( currentSurface->nuid );
298f220fa62Smrg	if( ! playBack ) endrender();
299f220fa62Smrg    } else {
300f220fa62Smrg	if( ! playBack ) endrender();
301f220fa62Smrg	do_nurbserror( errval );
302f220fa62Smrg    }
303f220fa62Smrg
304f220fa62Smrg    do_freeall( );
305f220fa62Smrg    resetObjects();
306f220fa62Smrg}
307f220fa62Smrg
308f220fa62Smrg/*-----------------------------------------------------------------------------
309f220fa62Smrg * do_freeall - free all data allocated in immediate mode
310f220fa62Smrg *
311f220fa62Smrg * Client:
312f220fa62Smrg *-----------------------------------------------------------------------------
313f220fa62Smrg */
314f220fa62Smrgvoid
315f220fa62SmrgNurbsTessellator::do_freeall( void )
316f220fa62Smrg{
317f220fa62Smrg    for( O_trim *o_trim = currentSurface->o_trim; o_trim; ) {
318f220fa62Smrg	O_trim *next_o_trim = o_trim->next;
319f220fa62Smrg        for( O_curve *curve = o_trim->o_curve; curve; ) {
320f220fa62Smrg	    O_curve *next_o_curve = curve->next;
321f220fa62Smrg	    do_freecurveall( curve );
322f220fa62Smrg	    curve = next_o_curve;
323f220fa62Smrg	}
324f220fa62Smrg	if( o_trim->save == 0 ) do_freebgntrim( o_trim );
325f220fa62Smrg	o_trim = next_o_trim;
326f220fa62Smrg    }
327f220fa62Smrg
328f220fa62Smrg    O_nurbssurface *nurbss, *next_nurbss;
329f220fa62Smrg    for( nurbss= currentSurface->o_nurbssurface; nurbss; nurbss = next_nurbss) {
330f220fa62Smrg	next_nurbss = nurbss->next;
331f220fa62Smrg	if( nurbss->save == 0 )
332f220fa62Smrg	    do_freenurbssurface( nurbss );
333f220fa62Smrg	else
334f220fa62Smrg	    nurbss->used = 0;
335f220fa62Smrg    }
336f220fa62Smrg
337f220fa62Smrg    if( currentSurface->save == 0 ) do_freebgnsurface( currentSurface );
338f220fa62Smrg}
339f220fa62Smrg
340f220fa62Smrgvoid
341f220fa62SmrgNurbsTessellator::do_freecurveall( O_curve *curve )
342f220fa62Smrg{
343f220fa62Smrg    assert( curve->curvetype != ct_none );
344f220fa62Smrg
345f220fa62Smrg    if( curve->curvetype == ct_nurbscurve ) {
346f220fa62Smrg	O_nurbscurve *ncurve, *next_ncurve;
347f220fa62Smrg	for( ncurve=curve->curve.o_nurbscurve; ncurve; ncurve=next_ncurve ) {
348f220fa62Smrg	    next_ncurve = ncurve->next;
349f220fa62Smrg	    if( ncurve->save == 0 )
350f220fa62Smrg		do_freenurbscurve( ncurve );
351f220fa62Smrg	    else
352f220fa62Smrg		ncurve->used = 0;
353f220fa62Smrg	}
354f220fa62Smrg    } else {
355f220fa62Smrg	O_pwlcurve *pcurve, *next_pcurve;
356f220fa62Smrg	for( pcurve=curve->curve.o_pwlcurve; pcurve; pcurve=next_pcurve ) {
357f220fa62Smrg	    next_pcurve = pcurve->next;
358f220fa62Smrg	    if( pcurve->save == 0 )
359f220fa62Smrg		do_freepwlcurve( pcurve );
360f220fa62Smrg	    else
361f220fa62Smrg		pcurve->used = 0;
362f220fa62Smrg	}
363f220fa62Smrg    }
364f220fa62Smrg    if( curve->save == 0 )
365f220fa62Smrg        do_freebgncurve( curve );
366f220fa62Smrg}
367f220fa62Smrg
368f220fa62Smrg
369f220fa62Smrg/*-----------------------------------------------------------------------------
370f220fa62Smrg * do_freebgntrim - free the space allocated for a trim loop
371f220fa62Smrg *
372f220fa62Smrg * Client:
373f220fa62Smrg *-----------------------------------------------------------------------------
374f220fa62Smrg */
375f220fa62Smrgvoid
376f220fa62SmrgNurbsTessellator::do_freebgntrim( O_trim *o_trim )
377f220fa62Smrg{
378f220fa62Smrg    o_trim->deleteMe( o_trimPool );
379f220fa62Smrg}
380f220fa62Smrg
381f220fa62Smrg
382f220fa62Smrg/*-----------------------------------------------------------------------------
383f220fa62Smrg * do_bgntrim - link in a trim loop to the current trimmed surface description
384f220fa62Smrg *
385f220fa62Smrg * Client: bgntrim()
386f220fa62Smrg *-----------------------------------------------------------------------------
387f220fa62Smrg */
388f220fa62Smrgvoid
389f220fa62SmrgNurbsTessellator::do_bgntrim( O_trim *o_trim )
390f220fa62Smrg{
391f220fa62Smrg
392f220fa62Smrg    if( ! inSurface ) {
393f220fa62Smrg	do_nurbserror( 15 );
394f220fa62Smrg	bgnsurface( 0 );
395f220fa62Smrg	inSurface = 2;
396f220fa62Smrg    }
397f220fa62Smrg
398f220fa62Smrg    if( inTrim ) {
399f220fa62Smrg	do_nurbserror( 16 );
400f220fa62Smrg	endtrim();
401f220fa62Smrg    }
402f220fa62Smrg    inTrim = 1;
403f220fa62Smrg
404f220fa62Smrg    if( *nextTrim != o_trim ) {
405f220fa62Smrg	isTrimModified = 1;
406f220fa62Smrg        *nextTrim = o_trim;
407f220fa62Smrg    }
408f220fa62Smrg
409f220fa62Smrg    currentTrim = o_trim;
410f220fa62Smrg    nextTrim = &(o_trim->next);
411f220fa62Smrg    nextCurve = &(o_trim->o_curve);
412f220fa62Smrg}
413f220fa62Smrg
414f220fa62Smrg
415f220fa62Smrg/*-----------------------------------------------------------------------------
416f220fa62Smrg * do_endtrim - mark the end of the current trim loop
417f220fa62Smrg *
418f220fa62Smrg * Client: endtrim()
419f220fa62Smrg *-----------------------------------------------------------------------------
420f220fa62Smrg */
421f220fa62Smrgvoid
422f220fa62SmrgNurbsTessellator::do_endtrim( void )
423f220fa62Smrg{
424f220fa62Smrg    if( ! inTrim ) {
425f220fa62Smrg	do_nurbserror( 17 );
426f220fa62Smrg	return;
427f220fa62Smrg    }
428f220fa62Smrg    inTrim = 0;
429f220fa62Smrg
430f220fa62Smrg    if( currentTrim->o_curve == 0 ) {
431f220fa62Smrg	do_nurbserror( 18 );
432f220fa62Smrg	isDataValid = 0;
433f220fa62Smrg    }
434f220fa62Smrg
435f220fa62Smrg    numTrims++;
436f220fa62Smrg
437f220fa62Smrg    if( *nextCurve != 0 ) {
438f220fa62Smrg	isTrimModified = 1;
439f220fa62Smrg        *nextCurve = 0;
440f220fa62Smrg    }
441f220fa62Smrg}
442f220fa62Smrg
443f220fa62Smrg/*-----------------------------------------------------------------------------
444f220fa62Smrg * do_freepwlcurve -
445f220fa62Smrg *
446f220fa62Smrg * Client:
447f220fa62Smrg *-----------------------------------------------------------------------------
448f220fa62Smrg */
449f220fa62Smrgvoid
450f220fa62SmrgNurbsTessellator::do_freepwlcurve( O_pwlcurve *o_pwlcurve )
451f220fa62Smrg{
452f220fa62Smrg    o_pwlcurve->deleteMe( o_pwlcurvePool );
453f220fa62Smrg}
454f220fa62Smrg
455f220fa62Smrgvoid
456f220fa62SmrgNurbsTessellator::do_freebgncurve( O_curve *o_curve )
457f220fa62Smrg{
458f220fa62Smrg    o_curve->deleteMe( o_curvePool );
459f220fa62Smrg}
460f220fa62Smrg
461f220fa62Smrg/*-----------------------------------------------------------------------------
462f220fa62Smrg * do_pwlcurve - link in pwl trim loop to the current surface description
463f220fa62Smrg *
464f220fa62Smrg * Client: pwlcurve()
465f220fa62Smrg *-----------------------------------------------------------------------------
466f220fa62Smrg */
467f220fa62Smrgvoid
468f220fa62SmrgNurbsTessellator::do_pwlcurve( O_pwlcurve *o_pwlcurve )
469f220fa62Smrg{
470f220fa62Smrg    if( ! inTrim ) {
471f220fa62Smrg	do_nurbserror( 19 );
472f220fa62Smrg	if( o_pwlcurve->save == 0 )
473f220fa62Smrg	    do_freepwlcurve(o_pwlcurve );
474f220fa62Smrg	return;
475f220fa62Smrg    }
476f220fa62Smrg
477f220fa62Smrg    if( ! inCurve ) {
478f220fa62Smrg	bgncurve( 0 );
479f220fa62Smrg	inCurve = 2;
480f220fa62Smrg    }
481f220fa62Smrg
482f220fa62Smrg    if( o_pwlcurve->used ) {
483f220fa62Smrg	do_nurbserror( 20 );
484f220fa62Smrg	isDataValid = 0;
485f220fa62Smrg	return;
486f220fa62Smrg    } else
487f220fa62Smrg        o_pwlcurve->used = 1;
488f220fa62Smrg
489f220fa62Smrg    if( currentCurve->curvetype == ct_none ) {
490f220fa62Smrg        currentCurve->curvetype = ct_pwlcurve;
491f220fa62Smrg    } else if( currentCurve->curvetype != ct_pwlcurve ) {
492f220fa62Smrg	do_nurbserror( 21 );
493f220fa62Smrg	isDataValid = 0;
494f220fa62Smrg	return;
495f220fa62Smrg    }
496f220fa62Smrg
497f220fa62Smrg    if( *nextPwlcurve != o_pwlcurve ) {
498f220fa62Smrg	isCurveModified = 1;
499f220fa62Smrg        *nextPwlcurve = o_pwlcurve;
500f220fa62Smrg    }
501f220fa62Smrg    nextPwlcurve = &(o_pwlcurve->next);
502f220fa62Smrg
503f220fa62Smrg    if( o_pwlcurve->owner != currentCurve ) {
504f220fa62Smrg	isCurveModified = 1;
505f220fa62Smrg	o_pwlcurve->owner = currentCurve;
506f220fa62Smrg    }
507f220fa62Smrg
508f220fa62Smrg    if( inCurve == 2 )
509f220fa62Smrg	endcurve();
510f220fa62Smrg}
511f220fa62Smrg
512f220fa62Smrg
513f220fa62Smrg/*-----------------------------------------------------------------------------
514f220fa62Smrg * do_freenurbscurve -
515f220fa62Smrg *
516f220fa62Smrg * Client:
517f220fa62Smrg *-----------------------------------------------------------------------------
518f220fa62Smrg */
519f220fa62Smrgvoid
520f220fa62SmrgNurbsTessellator::do_freenurbscurve( O_nurbscurve *o_nurbscurve )
521f220fa62Smrg{
522f220fa62Smrg    o_nurbscurve->bezier_curves->deleteMe( quiltPool );
523f220fa62Smrg    o_nurbscurve->deleteMe( o_nurbscurvePool );
524f220fa62Smrg}
525f220fa62Smrg
526f220fa62Smrg
527f220fa62Smrg/*-----------------------------------------------------------------------------
528f220fa62Smrg * do_nurbscurve -
529f220fa62Smrg *
530f220fa62Smrg * Client: nurbscurve()
531f220fa62Smrg *-----------------------------------------------------------------------------
532f220fa62Smrg */
533f220fa62Smrgvoid
534f220fa62SmrgNurbsTessellator::do_nurbscurve( O_nurbscurve *o_nurbscurve )
535f220fa62Smrg{
536f220fa62Smrg    if ( ! inCurve ) {
537f220fa62Smrg	bgncurve( 0 );
538f220fa62Smrg	inCurve = 2;
539f220fa62Smrg    }
540f220fa62Smrg
541f220fa62Smrg    if( o_nurbscurve->used ) {
542f220fa62Smrg	/* error - curve was already called in current surface */
543f220fa62Smrg	do_nurbserror( 23 );
544f220fa62Smrg	isDataValid = 0;
545f220fa62Smrg	return;
546f220fa62Smrg    } else
547f220fa62Smrg        o_nurbscurve->used = 1;
548f220fa62Smrg
549f220fa62Smrg    if( currentCurve->curvetype == ct_none ) {
550f220fa62Smrg        currentCurve->curvetype = ct_nurbscurve;
551f220fa62Smrg    } else if( currentCurve->curvetype != ct_nurbscurve ) {
552f220fa62Smrg	do_nurbserror( 24 );
553f220fa62Smrg	isDataValid = 0;
554f220fa62Smrg	return;
555f220fa62Smrg    }
556f220fa62Smrg
557f220fa62Smrg    if( *nextNurbscurve != o_nurbscurve ) {
558f220fa62Smrg	isCurveModified = 1;
559f220fa62Smrg	*nextNurbscurve = o_nurbscurve;
560f220fa62Smrg    }
561f220fa62Smrg
562f220fa62Smrg    nextNurbscurve = &(o_nurbscurve->next);
563f220fa62Smrg
564f220fa62Smrg    if( o_nurbscurve->owner != currentCurve ) {
565f220fa62Smrg	isCurveModified = 1;
566f220fa62Smrg	o_nurbscurve->owner = currentCurve;
567f220fa62Smrg    }
568f220fa62Smrg
569f220fa62Smrg    if( o_nurbscurve->owner == 0 )
570f220fa62Smrg	isCurveModified = 1;
571f220fa62Smrg
572f220fa62Smrg    if( inCurve == 2 )
573f220fa62Smrg        endcurve();
574f220fa62Smrg}
575f220fa62Smrg
576f220fa62Smrg
577f220fa62Smrg/*-----------------------------------------------------------------------------
578f220fa62Smrg * do_freenurbssurface -
579f220fa62Smrg *
580f220fa62Smrg * Client:
581f220fa62Smrg *-----------------------------------------------------------------------------
582f220fa62Smrg */
583f220fa62Smrg
584f220fa62Smrgvoid
585f220fa62SmrgNurbsTessellator::do_freenurbssurface( O_nurbssurface *o_nurbssurface )
586f220fa62Smrg{
587f220fa62Smrg    o_nurbssurface->bezier_patches->deleteMe( quiltPool );
588f220fa62Smrg    o_nurbssurface->deleteMe( o_nurbssurfacePool );
589f220fa62Smrg}
590f220fa62Smrg
591f220fa62Smrg/*-----------------------------------------------------------------------------
592f220fa62Smrg * do_nurbssurface -
593f220fa62Smrg *
594f220fa62Smrg * Client: nurbssurface()
595f220fa62Smrg *-----------------------------------------------------------------------------
596f220fa62Smrg */
597f220fa62Smrgvoid
598f220fa62SmrgNurbsTessellator::do_nurbssurface( O_nurbssurface *o_nurbssurface )
599f220fa62Smrg{
600f220fa62Smrg    if( ! inSurface ) {
601f220fa62Smrg	bgnsurface( 0 );
602f220fa62Smrg	inSurface = 2;
603f220fa62Smrg    }
604f220fa62Smrg
605f220fa62Smrg    if( o_nurbssurface->used ) {
606f220fa62Smrg	/* error - surface was already called in current block */
607f220fa62Smrg	do_nurbserror( 25 );
608f220fa62Smrg	isDataValid = 0;
609f220fa62Smrg	return;
610f220fa62Smrg    } else
611f220fa62Smrg        o_nurbssurface->used = 1;
612f220fa62Smrg
613f220fa62Smrg    if( *nextNurbssurface != o_nurbssurface ) {
614f220fa62Smrg	isSurfaceModified = 1;
615f220fa62Smrg        *nextNurbssurface  = o_nurbssurface;
616f220fa62Smrg    }
617f220fa62Smrg
618f220fa62Smrg    if( o_nurbssurface->owner != currentSurface ) {
619f220fa62Smrg	isSurfaceModified = 1;
620f220fa62Smrg	o_nurbssurface->owner = currentSurface;
621f220fa62Smrg    }
622f220fa62Smrg    nextNurbssurface = &(o_nurbssurface->next);
623f220fa62Smrg
624f220fa62Smrg    if( inSurface == 2  )
625f220fa62Smrg	endsurface();
626f220fa62Smrg}
627f220fa62Smrg
628f220fa62Smrg
629f220fa62Smrg/*-----------------------------------------------------------------------------
630f220fa62Smrg * do_freenurbsproperty
631f220fa62Smrg *
632f220fa62Smrg *-----------------------------------------------------------------------------
633f220fa62Smrg */
634f220fa62Smrg
635f220fa62Smrgvoid
636f220fa62SmrgNurbsTessellator::do_freenurbsproperty( Property *prop )
637f220fa62Smrg{
638f220fa62Smrg    prop->deleteMe( propertyPool );
639f220fa62Smrg}
640f220fa62Smrg
641f220fa62Smrg
642f220fa62Smrg/*-----------------------------------------------------------------------------
643f220fa62Smrg * do_setnurbsproperty -
644f220fa62Smrg *
645f220fa62Smrg *-----------------------------------------------------------------------------
646f220fa62Smrg */
647f220fa62Smrg
648f220fa62Smrgvoid
649f220fa62SmrgNurbsTessellator::do_setnurbsproperty( Property *prop )
650f220fa62Smrg{
651f220fa62Smrg    renderhints.setProperty( prop->tag, prop->value );
652f220fa62Smrg    if( prop->save == 0 )
653f220fa62Smrg	do_freenurbsproperty( prop );
654f220fa62Smrg}
655f220fa62Smrg
656f220fa62Smrgvoid
657f220fa62SmrgNurbsTessellator::do_setnurbsproperty2( Property *prop )
658f220fa62Smrg{
659f220fa62Smrg    Mapdesc *mapdesc = maplist.find( prop->type );
660f220fa62Smrg
661f220fa62Smrg    mapdesc->setProperty( prop->tag, prop->value );
662f220fa62Smrg    if( prop->save == 0 )
663f220fa62Smrg	do_freenurbsproperty( prop );
664f220fa62Smrg}
665f220fa62Smrg
666f220fa62Smrgvoid
667f220fa62SmrgNurbsTessellator::errorHandler( int )
668f220fa62Smrg{
669f220fa62Smrg}
670f220fa62Smrg
671f220fa62Smrgvoid
672f220fa62SmrgNurbsTessellator::do_nurbserror( int msg )
673f220fa62Smrg{
674f220fa62Smrg    errorHandler( msg );
675f220fa62Smrg}
676f220fa62Smrg
677f220fa62Smrgint
678f220fa62SmrgNurbsTessellator::do_check_knots( Knotvector *knots, const char *msg )
679f220fa62Smrg{
680f220fa62Smrg    int status = knots->validate();
681f220fa62Smrg    if( status ) {
682f220fa62Smrg	do_nurbserror( status );
683f220fa62Smrg        if( renderhints.errorchecking != N_NOMSG ) knots->show( msg );
684f220fa62Smrg    }
685f220fa62Smrg    return status;
686f220fa62Smrg}
687f220fa62Smrg
688f220fa62Smrg
689f220fa62Smrg
690f220fa62Smrg
691f220fa62Smrg
692