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