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

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

* empty log message *

File size: 15.5 KB
Line 
1/* $Id: nurbsinterfac.cpp,v 1.1 2000-02-09 08:50:26 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 * nurbsinterfac.c++
38 *
39 * $Date: 2000-02-09 08:50:26 $ $Revision: 1.1 $
40 * $Header: /home/ktk/tmp/odin/2007/netlabs.cvs/odin32/src/opengl/glu/nurbs/internals/nurbsinterfac.cpp,v 1.1 2000-02-09 08:50:26 jeroen Exp $
41 */
42
43#include "glimports.h"
44#include "mystdio.h"
45#include "nurbsconsts.h"
46#include "nurbstess.h"
47#include "bufpool.h"
48#include "quilt.h"
49#include "displaylist.h"
50#include "knotvector.h"
51#include "mapdesc.h"
52
53#define THREAD( work, arg, cleanup ) \
54 if( dl ) {\
55 arg->save = 1;\
56 dl->append( (PFVS)&NurbsTessellator::work, (void *) arg, (PFVS)&NurbsTessellator::cleanup );\
57 } else {\
58 arg->save = 0;\
59 work( arg );\
60 }
61
62#define THREAD2( work ) \
63 if( dl ) {\
64 dl->append( (PFVS)&NurbsTessellator::work, 0, 0 );\
65 } else {\
66 work( );\
67 }
68
69NurbsTessellator::NurbsTessellator( BasicCurveEvaluator &c, BasicSurfaceEvaluator& e)
70 : subdivider( renderhints, backend ),
71 backend( c, e ),
72 maplist( backend ),
73 o_pwlcurvePool( sizeof( O_pwlcurve ), 32, "o_pwlcurvePool" ),
74 o_nurbscurvePool( sizeof( O_nurbscurve ), 32, "o_nurbscurvePool"),
75 o_curvePool( sizeof( O_curve ), 32, "o_curvePool" ),
76 o_trimPool( sizeof( O_trim ), 32, "o_trimPool" ),
77 o_surfacePool( sizeof( O_surface ), 1, "o_surfacePool" ),
78 o_nurbssurfacePool( sizeof( O_nurbssurface ), 4, "o_nurbssurfacePool" ),
79 propertyPool( sizeof( Property ), 32, "propertyPool" ),
80 quiltPool( sizeof( Quilt ), 32, "quiltPool" )
81{
82 dl = 0;
83 inSurface = 0;
84 inCurve = 0;
85 inTrim = 0;
86 playBack = 0;
87 jumpbuffer = newJumpbuffer();
88 subdivider.setJumpbuffer( jumpbuffer );
89}
90
91NurbsTessellator::~NurbsTessellator( void )
92{
93 if( inTrim ) {
94 do_nurbserror( 12 );
95 endtrim();
96 }
97
98 if( inSurface ) {
99 *nextNurbssurface = 0;
100 do_freeall();
101 }
102
103 if (jumpbuffer) {
104 deleteJumpbuffer(jumpbuffer);
105 jumpbuffer= 0;
106 }
107}
108
109/*-----------------------------------------------------------------------------
110 * bgnsurface - allocate and initialize an o_surface structure
111 *
112 * Client: GL user
113 *-----------------------------------------------------------------------------
114 */
115void
116NurbsTessellator::bgnsurface( long nuid )
117{
118 O_surface *o_surface = new(o_surfacePool) O_surface;
119 o_surface->nuid = nuid;
120 THREAD( do_bgnsurface, o_surface, do_freebgnsurface );
121}
122
123/*-----------------------------------------------------------------------------
124 * bgncurve - allocate an initialize an o_curve structure
125 *
126 * Client: GL user
127 *-----------------------------------------------------------------------------
128 */
129void
130NurbsTessellator::bgncurve( long nuid )
131{
132 O_curve *o_curve = new(o_curvePool) O_curve;
133 o_curve->nuid = nuid;
134 THREAD( do_bgncurve, o_curve, do_freebgncurve );
135}
136/*-----------------------------------------------------------------------------
137 * endcurve -
138 *
139 * Client:
140 *-----------------------------------------------------------------------------
141 */
142
143void
144NurbsTessellator::endcurve( void )
145{
146 THREAD2( do_endcurve );
147}
148
149/*-----------------------------------------------------------------------------
150 * endsurface - user level end of surface call
151 *
152 * Client: GL user
153 *-----------------------------------------------------------------------------
154 */
155void
156NurbsTessellator::endsurface( void )
157{
158 THREAD2( do_endsurface );
159}
160
161
162/*-----------------------------------------------------------------------------
163 * bgntrim - allocate and initialize a new trim loop structure (o_trim )
164 *
165 * Client: GL user
166 *-----------------------------------------------------------------------------
167 */
168void
169NurbsTessellator::bgntrim( void )
170{
171 O_trim *o_trim = new(o_trimPool) O_trim;
172 THREAD( do_bgntrim, o_trim, do_freebgntrim );
173}
174
175/*-----------------------------------------------------------------------------
176 * endtrim -
177 *
178 * Client: GL user
179 *-----------------------------------------------------------------------------
180 */
181void
182NurbsTessellator::endtrim( void )
183{
184 THREAD2( do_endtrim );
185}
186
187
188/*-----------------------------------------------------------------------------
189 * pwlcurve -
190 *
191 * count - number of points on curve
192 * array - array of points on curve
193 * byte_stride - distance between points in bytes
194 * type - valid data flag
195 *
196 * Client: Gl user
197 *-----------------------------------------------------------------------------
198 */
199void
200NurbsTessellator::pwlcurve( long count, INREAL array[], long byte_stride, long type )
201{
202 Mapdesc *mapdesc = maplist.locate( type );
203
204 if( mapdesc == 0 ) {
205 do_nurbserror( 35 );
206 isDataValid = 0;
207 return;
208 }
209
210 if ( (type != N_P2D) && (type != N_P2DR) ) {
211 do_nurbserror( 22 );
212 isDataValid = 0;
213 return;
214 }
215 if( count < 0 ) {
216 do_nurbserror( 33 );
217 isDataValid = 0;
218 return;
219 }
220 if( byte_stride < 0 ) {
221 do_nurbserror( 34 );
222 isDataValid = 0;
223 return;
224 }
225
226#ifdef NOTDEF
227 if( mapdesc->isRational() ) {
228 INREAL *p = array;
229 INREAL x = p[0]; INREAL y = p[1]; INREAL w = p[2];
230 p = (INREAL *) (((char *) p) + byte_stride);
231 for( long i = 1; i != count; i++ ) {
232 if( p[0] == x && p[1] == y && p[2] == w ) break;
233 x = p[0]; y = p[1]; w = p[2];
234 p = (INREAL *) (((char *) p) + byte_stride);
235 }
236 if( i != count ) {
237 do_nurbserror( 37 );
238 dprintf( "point %d (%f,%f)\n", i, x, y );
239 isDataValid = 0;
240 return;
241 }
242 } else {
243 INREAL *p = array;
244 INREAL x = p[0]; INREAL y = p[1];
245 p = (INREAL *) (((char *) p) + byte_stride);
246 for( long i = 1; i != count; i++ ) {
247 if( p[0] == x && p[1] == y ) break;
248 x = p[0]; y = p[1];
249 p = (INREAL *) (((char *) p) + byte_stride);
250 }
251 if( i != count ) {
252 do_nurbserror( 37 );
253 dprintf( "point %d (%f,%f)\n", i, x, y );
254 isDataValid = 0;
255 return;
256 }
257 }
258#endif
259
260 O_pwlcurve *o_pwlcurve = new(o_pwlcurvePool) O_pwlcurve( type, count, array, byte_stride, extTrimVertexPool.get((int)count) );
261 THREAD( do_pwlcurve, o_pwlcurve, do_freepwlcurve );
262}
263
264
265/*-----------------------------------------------------------------------------
266 * nurbscurve -
267 *
268 * Client: GL user
269 *-----------------------------------------------------------------------------
270 */
271void
272NurbsTessellator::nurbscurve(
273 long nknots, /* number of p knots */
274 INREAL knot[], /* nondecreasing knot values in p */
275 long byte_stride, /* distance in bytes between control points */
276 INREAL ctlarray[], /* pointer to first control point */
277 long order, /* order of spline */
278 long type ) /* description of range space */
279{
280
281 Mapdesc *mapdesc = maplist.locate( type );
282
283 if( mapdesc == 0 ) {
284 do_nurbserror( 35 );
285 isDataValid = 0;
286 return;
287 }
288
289 if( ctlarray == 0 ) {
290 do_nurbserror( 36 );
291 isDataValid = 0;
292 return;
293 }
294
295 if( byte_stride < 0 ) {
296 do_nurbserror( 34 );
297 isDataValid = 0;
298 return;
299 }
300
301 Knotvector knots;
302
303 knots.init( nknots, byte_stride, order, knot );
304 if( do_check_knots( &knots, "curve" ) ) return;
305
306 O_nurbscurve *o_nurbscurve = new(o_nurbscurvePool) O_nurbscurve(type);
307 o_nurbscurve->bezier_curves = new(quiltPool) Quilt(mapdesc);
308 o_nurbscurve->bezier_curves->toBezier( knots,ctlarray, mapdesc->getNcoords() );
309
310 THREAD( do_nurbscurve, o_nurbscurve, do_freenurbscurve );
311}
312
313
314/*-----------------------------------------------------------------------------
315 * nurbssurface -
316 *
317 * Client: User routine
318 *-----------------------------------------------------------------------------
319 */
320void
321NurbsTessellator::nurbssurface(
322 long sknot_count, /* number of s knots */
323 INREAL sknot[], /* nondecreasing knot values in s */
324 long tknot_count, /* number of t knots */
325 INREAL tknot[], /* nondecreasing knot values in t */
326 long s_byte_stride, /* s step size in memory bytes */
327 long t_byte_stride, /* t step size in memory bytes */
328 INREAL ctlarray[], /* pointer to first control point */
329 long sorder, /* order of the spline in s parameter */
330 long torder, /* order of the spline in t parameter */
331 long type) /* description of range space */
332{
333 Mapdesc *mapdesc = maplist.locate( type );
334
335 if( mapdesc == 0 ) {
336 do_nurbserror( 35 );
337 isDataValid = 0;
338 return;
339 }
340
341 if( s_byte_stride < 0 ) {
342 do_nurbserror( 34 );
343 isDataValid = 0;
344 return;
345 }
346
347 if( t_byte_stride < 0 ) {
348 do_nurbserror( 34 );
349 isDataValid = 0;
350 return;
351 }
352
353 Knotvector sknotvector, tknotvector;
354
355 sknotvector.init( sknot_count, s_byte_stride, sorder, sknot );
356 if( do_check_knots( &sknotvector, "surface" ) ) return;
357
358 tknotvector.init( tknot_count, t_byte_stride, torder, tknot );
359 if( do_check_knots( &tknotvector, "surface" ) ) return;
360
361 O_nurbssurface *o_nurbssurface = new(o_nurbssurfacePool) O_nurbssurface(type);
362 o_nurbssurface->bezier_patches = new(quiltPool) Quilt(mapdesc);
363
364 o_nurbssurface->bezier_patches->toBezier( sknotvector, tknotvector,
365 ctlarray, mapdesc->getNcoords() );
366 THREAD( do_nurbssurface, o_nurbssurface, do_freenurbssurface );
367}
368
369
370/*-----------------------------------------------------------------------------
371 * setnurbsproperty -
372 *
373 *-----------------------------------------------------------------------------
374 */
375void
376NurbsTessellator::setnurbsproperty( long tag, INREAL value )
377{
378 if( ! renderhints.isProperty( tag ) ) {
379 do_nurbserror( 26 );
380 } else {
381 Property *prop = new(propertyPool) Property( tag, value );
382 THREAD( do_setnurbsproperty, prop, do_freenurbsproperty );
383 }
384}
385
386/*-----------------------------------------------------------------------------
387 * setnurbsproperty -
388 *
389 *-----------------------------------------------------------------------------
390 */
391void
392NurbsTessellator::setnurbsproperty( long type, long tag, INREAL value )
393{
394 Mapdesc *mapdesc = maplist.locate( type );
395
396 if( mapdesc == 0 ) {
397 do_nurbserror( 35 );
398 return;
399 }
400
401 if( ! mapdesc->isProperty( tag ) ) {
402 do_nurbserror( 26 );
403 return;
404 }
405
406 Property *prop = new(propertyPool) Property( type, tag, value );
407 THREAD( do_setnurbsproperty2, prop, do_freenurbsproperty );
408}
409
410
411/*-----------------------------------------------------------------------------
412 * getnurbsproperty -
413 *
414 *-----------------------------------------------------------------------------
415 */
416
417void
418NurbsTessellator::getnurbsproperty( long tag, INREAL *value )
419{
420 if( renderhints.isProperty( tag ) ) {
421 *value = renderhints.getProperty( tag );
422 } else {
423 do_nurbserror( 26 );
424 }
425}
426
427/*-----------------------------------------------------------------------------
428 * getnurbsproperty -
429 *
430 *-----------------------------------------------------------------------------
431 */
432
433void
434NurbsTessellator::getnurbsproperty( long type, long tag, INREAL *value )
435{
436 Mapdesc *mapdesc = maplist.locate( type );
437
438 if( mapdesc == 0 )
439 do_nurbserror( 35 );
440
441 if( mapdesc->isProperty( tag ) ) {
442 *value = mapdesc->getProperty( tag );
443 } else {
444 do_nurbserror( 26 );
445 }
446}
447
448/*--------------------------------------------------------------------------
449 * setnurbsproperty - accept a user supplied matrix as culling or sampling mat
450 *--------------------------------------------------------------------------
451 */
452
453void
454NurbsTessellator::setnurbsproperty( long type, long purpose, INREAL *mat )
455{
456 // XXX - cannot be put in display list
457 Mapdesc *mapdesc = maplist.locate( type );
458
459 if( mapdesc == 0 ) {
460 do_nurbserror( 35 );
461 isDataValid = 0;
462 } else if( purpose == N_BBOXSIZE ) {
463 mapdesc->setBboxsize( mat );
464 } else {
465#ifndef NDEBUG
466 dprintf( "ERRORRORRORR!!!\n");
467#endif
468 }
469}
470
471/*--------------------------------------------------------------------------
472 * setnurbsproperty - accept a user supplied matrix as culling or sampling mat
473 *--------------------------------------------------------------------------
474 */
475
476void
477NurbsTessellator::setnurbsproperty( long type, long purpose, INREAL *mat,
478 long rstride, long cstride )
479{
480 // XXX - cannot be put in display list
481 Mapdesc *mapdesc = maplist.locate( type );
482
483 if( mapdesc == 0 ) {
484 do_nurbserror( 35 );
485 isDataValid = 0;
486 } else if( purpose == N_CULLINGMATRIX ) {
487 mapdesc->setCmat( mat, rstride, cstride );
488 } else if( purpose == N_SAMPLINGMATRIX ) {
489 mapdesc->setSmat( mat, rstride, cstride );
490 } else if( purpose == N_BBOXMATRIX ) {
491 mapdesc->setBmat( mat, rstride, cstride );
492 } else {
493#ifndef NDEBUG
494 dprintf( "ERRORRORRORR!!!\n");
495#endif
496 }
497}
498
499void
500NurbsTessellator::redefineMaps( void )
501{
502 maplist.initialize();
503}
504
505void
506NurbsTessellator::defineMap( long type, long rational, long ncoords )
507{
508 maplist.define( type, (int) rational, (int) ncoords );
509}
510
511void
512NurbsTessellator::discardRecording( void *_dl )
513{
514 delete (DisplayList *) _dl;
515}
516
517void *
518NurbsTessellator::beginRecording( void )
519{
520 dl = new DisplayList( this );
521 return (void *) dl;
522}
523
524void
525NurbsTessellator::endRecording( void )
526{
527 dl->endList();
528 dl = 0;
529}
530
531void
532NurbsTessellator::playRecording( void *_dl )
533{
534 playBack = 1;
535 bgnrender();
536 ((DisplayList *)_dl)->play();
537 endrender();
538 playBack = 0;
539}
540
Note: See TracBrowser for help on using the repository browser.