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