~ubuntu-branches/ubuntu/jaunty/mesa/jaunty

« back to all changes in this revision

Viewing changes to src/glu/mesa/nurbssrf.c

  • Committer: Bazaar Package Importer
  • Author(s): Timo Aaltonen
  • Date: 2009-01-31 12:38:44 UTC
  • mfrom: (1.2.15 upstream) (3.1.4 experimental)
  • Revision ID: james.westby@ubuntu.com-20090131123844-ncib2eu1l01b1et0
Tags: 7.3-1ubuntu1
* Merge with Debian experimental.
* Drop 102_remove_flip.diff, included in 7.3..

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
 
/*
3
 
 * Mesa 3-D graphics library
4
 
 * Version:  3.3
5
 
 * Copyright (C) 1995-2000  Brian Paul
6
 
 *
7
 
 * This library is free software; you can redistribute it and/or
8
 
 * modify it under the terms of the GNU Library General Public
9
 
 * License as published by the Free Software Foundation; either
10
 
 * version 2 of the License, or (at your option) any later version.
11
 
 *
12
 
 * This library is distributed in the hope that it will be useful,
13
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 
 * Library General Public License for more details.
16
 
 *
17
 
 * You should have received a copy of the GNU Library General Public
18
 
 * License along with this library; if not, write to the Free
19
 
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
 
 */
21
 
 
22
 
 
23
 
/*
24
 
 * NURBS implementation written by Bogdan Sikorski (bogdan@cira.it)
25
 
 * See README2 for more info.
26
 
 */
27
 
 
28
 
 
29
 
#ifdef PC_HEADER
30
 
#include "all.h"
31
 
#else
32
 
#include <math.h>
33
 
#include <stdlib.h>
34
 
#include <string.h>
35
 
#include "gluP.h"
36
 
#include "nurbs.h"
37
 
#endif
38
 
 
39
 
 
40
 
static int
41
 
get_surface_dim(GLenum type)
42
 
{
43
 
   switch (type) {
44
 
   case GL_MAP2_VERTEX_3:
45
 
      return 3;
46
 
   case GL_MAP2_VERTEX_4:
47
 
      return 4;
48
 
   case GL_MAP2_INDEX:
49
 
      return 1;
50
 
   case GL_MAP2_COLOR_4:
51
 
      return 4;
52
 
   case GL_MAP2_NORMAL:
53
 
      return 3;
54
 
   case GL_MAP2_TEXTURE_COORD_1:
55
 
      return 1;
56
 
   case GL_MAP2_TEXTURE_COORD_2:
57
 
      return 2;
58
 
   case GL_MAP2_TEXTURE_COORD_3:
59
 
      return 3;
60
 
   case GL_MAP2_TEXTURE_COORD_4:
61
 
      return 4;
62
 
   default:
63
 
      abort();                  /* TODO: is this OK? */
64
 
   }
65
 
   return 0;                    /*never get here */
66
 
}
67
 
 
68
 
static GLenum
69
 
test_nurbs_surface(GLUnurbsObj * nobj, surface_attribs * attrib)
70
 
{
71
 
   GLenum err;
72
 
   GLint tmp_int;
73
 
 
74
 
   if (attrib->sorder < 0 || attrib->torder < 0) {
75
 
      call_user_error(nobj, GLU_INVALID_VALUE);
76
 
      return GLU_ERROR;
77
 
   }
78
 
   glGetIntegerv(GL_MAX_EVAL_ORDER, &tmp_int);
79
 
   if (attrib->sorder > tmp_int || attrib->sorder < 2) {
80
 
      call_user_error(nobj, GLU_NURBS_ERROR1);
81
 
      return GLU_ERROR;
82
 
   }
83
 
   if (attrib->torder > tmp_int || attrib->torder < 2) {
84
 
      call_user_error(nobj, GLU_NURBS_ERROR1);
85
 
      return GLU_ERROR;
86
 
   }
87
 
   if (attrib->sknot_count < attrib->sorder + 2) {
88
 
      call_user_error(nobj, GLU_NURBS_ERROR2);
89
 
      return GLU_ERROR;
90
 
   }
91
 
   if (attrib->tknot_count < attrib->torder + 2) {
92
 
      call_user_error(nobj, GLU_NURBS_ERROR2);
93
 
      return GLU_ERROR;
94
 
   }
95
 
   if (attrib->s_stride < 0 || attrib->t_stride < 0) {
96
 
      call_user_error(nobj, GLU_NURBS_ERROR34);
97
 
      return GLU_ERROR;
98
 
   }
99
 
   if (attrib->sknot == NULL || attrib->tknot == NULL
100
 
       || attrib->ctrlarray == NULL) {
101
 
      call_user_error(nobj, GLU_NURBS_ERROR36);
102
 
      return GLU_ERROR;
103
 
   }
104
 
   if ((err = test_knot(attrib->tknot_count, attrib->tknot, attrib->torder))
105
 
       != GLU_NO_ERROR) {
106
 
      call_user_error(nobj, err);
107
 
      return GLU_ERROR;
108
 
   }
109
 
   if ((err = test_knot(attrib->sknot_count, attrib->sknot, attrib->sorder))
110
 
       != GLU_NO_ERROR) {
111
 
      call_user_error(nobj, err);
112
 
      return GLU_ERROR;
113
 
   }
114
 
   return GLU_NO_ERROR;
115
 
}
116
 
 
117
 
static GLenum
118
 
test_nurbs_surfaces(GLUnurbsObj * nobj)
119
 
{
120
 
   /* test the geometric data */
121
 
   if (test_nurbs_surface(nobj, &(nobj->surface.geom)) != GLU_NO_ERROR)
122
 
      return GLU_ERROR;
123
 
   /* now test the attributive data */
124
 
   /* color */
125
 
   if (nobj->surface.color.type != GLU_INVALID_ENUM)
126
 
      if (test_nurbs_surface(nobj, &(nobj->surface.color)) != GLU_NO_ERROR)
127
 
         return GLU_ERROR;
128
 
   /* normal */
129
 
   if (nobj->surface.normal.type != GLU_INVALID_ENUM)
130
 
      if (test_nurbs_surface(nobj, &(nobj->surface.normal)) != GLU_NO_ERROR)
131
 
         return GLU_ERROR;
132
 
   /* texture */
133
 
   if (nobj->surface.texture.type != GLU_INVALID_ENUM)
134
 
      if (test_nurbs_surface(nobj, &(nobj->surface.texture)) != GLU_NO_ERROR)
135
 
         return GLU_ERROR;
136
 
   return GLU_NO_ERROR;
137
 
}
138
 
 
139
 
static GLenum
140
 
convert_surf(knot_str_type * s_knot, knot_str_type * t_knot,
141
 
             surface_attribs * attrib, GLfloat ** new_ctrl,
142
 
             GLint * s_n_ctrl, GLint * t_n_ctrl)
143
 
{
144
 
   GLfloat **tmp_ctrl;
145
 
   GLfloat *ctrl_offset;
146
 
   GLint tmp_n_control;
147
 
   GLint i, j, t_cnt, s_cnt;
148
 
   GLint tmp_stride;
149
 
   GLint dim;
150
 
   GLenum err;
151
 
 
152
 
   /* valid range is empty? */
153
 
   if ((s_knot->unified_knot != NULL && s_knot->unified_nknots == 0) ||
154
 
       (t_knot->unified_knot != NULL && t_knot->unified_nknots == 0)) {
155
 
      if (s_knot->unified_knot) {
156
 
         free(s_knot->unified_knot);
157
 
         s_knot->unified_knot = NULL;
158
 
      }
159
 
      if (t_knot->unified_knot) {
160
 
         free(t_knot->unified_knot);
161
 
         t_knot->unified_knot = NULL;
162
 
      }
163
 
      *s_n_ctrl = 0;
164
 
      *t_n_ctrl = 0;
165
 
      return GLU_NO_ERROR;
166
 
   }
167
 
   t_cnt = attrib->tknot_count - attrib->torder;
168
 
   s_cnt = attrib->sknot_count - attrib->sorder;
169
 
   if ((tmp_ctrl = (GLfloat **) malloc(sizeof(GLfloat *) * t_cnt)) == NULL)
170
 
      return GLU_OUT_OF_MEMORY;
171
 
   if ((err = explode_knot(s_knot)) != GLU_NO_ERROR) {
172
 
      free(tmp_ctrl);
173
 
      if (s_knot->unified_knot) {
174
 
         free(s_knot->unified_knot);
175
 
         s_knot->unified_knot = NULL;
176
 
      }
177
 
      return err;
178
 
   }
179
 
   if (s_knot->unified_knot) {
180
 
      free(s_knot->unified_knot);
181
 
      s_knot->unified_knot = NULL;
182
 
   }
183
 
   if ((err = calc_alphas(s_knot)) != GLU_NO_ERROR) {
184
 
      free(tmp_ctrl);
185
 
      free(s_knot->new_knot);
186
 
      return err;
187
 
   }
188
 
   free(s_knot->new_knot);
189
 
   ctrl_offset = attrib->ctrlarray;
190
 
   dim = attrib->dim;
191
 
   for (i = 0; i < t_cnt; i++) {
192
 
      if ((err = calc_new_ctrl_pts(ctrl_offset, attrib->s_stride, s_knot,
193
 
                                   dim, &(tmp_ctrl[i]),
194
 
                                   &tmp_n_control)) != GLU_NO_ERROR) {
195
 
         for (--i; i <= 0; i--)
196
 
            free(tmp_ctrl[i]);
197
 
         free(tmp_ctrl);
198
 
         free(s_knot->alpha);
199
 
         return err;
200
 
      }
201
 
      ctrl_offset += attrib->t_stride;
202
 
   }
203
 
   free(s_knot->alpha);
204
 
   tmp_stride = dim * tmp_n_control;
205
 
   if ((*new_ctrl = (GLfloat *) malloc(sizeof(GLfloat) * tmp_stride * t_cnt))
206
 
       == NULL) {
207
 
      for (i = 0; i < t_cnt; i++)
208
 
         free(tmp_ctrl[i]);
209
 
      free(tmp_ctrl);
210
 
      return GLU_OUT_OF_MEMORY;
211
 
   }
212
 
   for (i = 0; i < tmp_n_control; i++)
213
 
      for (j = 0; j < t_cnt; j++)
214
 
         MEMCPY(*new_ctrl + j * dim + i * dim * t_cnt, tmp_ctrl[j] + dim * i,
215
 
                sizeof(GLfloat) * dim);
216
 
   for (i = 0; i < t_cnt; i++)
217
 
      free(tmp_ctrl[i]);
218
 
   free(tmp_ctrl);
219
 
   *s_n_ctrl = tmp_n_control;
220
 
 
221
 
   if ((tmp_ctrl = (GLfloat **) malloc(sizeof(GLfloat *) * (*s_n_ctrl))) ==
222
 
       NULL) {
223
 
      return GLU_OUT_OF_MEMORY;
224
 
   }
225
 
   if ((err = explode_knot(t_knot)) != GLU_NO_ERROR) {
226
 
      free(tmp_ctrl);
227
 
      if (t_knot->unified_knot) {
228
 
         free(t_knot->unified_knot);
229
 
         t_knot->unified_knot = NULL;
230
 
      }
231
 
      return err;
232
 
   }
233
 
   if (t_knot->unified_knot) {
234
 
      free(t_knot->unified_knot);
235
 
      t_knot->unified_knot = NULL;
236
 
   }
237
 
   if ((err = calc_alphas(t_knot)) != GLU_NO_ERROR) {
238
 
      free(tmp_ctrl);
239
 
      free(t_knot->new_knot);
240
 
      return err;
241
 
   }
242
 
   free(t_knot->new_knot);
243
 
   ctrl_offset = *new_ctrl;
244
 
   for (i = 0; i < (*s_n_ctrl); i++) {
245
 
      if ((err = calc_new_ctrl_pts(ctrl_offset, dim, t_knot,
246
 
                                   dim, &(tmp_ctrl[i]),
247
 
                                   &tmp_n_control)) != GLU_NO_ERROR) {
248
 
         for (--i; i <= 0; i--)
249
 
            free(tmp_ctrl[i]);
250
 
         free(tmp_ctrl);
251
 
         free(t_knot->alpha);
252
 
         return err;
253
 
      }
254
 
      ctrl_offset += dim * t_cnt;
255
 
   }
256
 
   free(t_knot->alpha);
257
 
   free(*new_ctrl);
258
 
   tmp_stride = dim * tmp_n_control;
259
 
   if (
260
 
       (*new_ctrl =
261
 
        (GLfloat *) malloc(sizeof(GLfloat) * tmp_stride * (*s_n_ctrl))) ==
262
 
       NULL) {
263
 
      for (i = 0; i < (*s_n_ctrl); i++)
264
 
         free(tmp_ctrl[i]);
265
 
      free(tmp_ctrl);
266
 
      return GLU_OUT_OF_MEMORY;
267
 
   }
268
 
   for (i = 0; i < (*s_n_ctrl); i++) {
269
 
      MEMCPY(*new_ctrl + i * tmp_stride, tmp_ctrl[i],
270
 
             sizeof(GLfloat) * tmp_stride);
271
 
      free(tmp_ctrl[i]);
272
 
   }
273
 
   free(tmp_ctrl);
274
 
   *t_n_ctrl = tmp_n_control;
275
 
   return GLU_NO_ERROR;
276
 
}
277
 
 
278
 
/* prepare the knot information structures */
279
 
static GLenum
280
 
fill_knot_structures(GLUnurbsObj * nobj,
281
 
                     knot_str_type * geom_s_knot, knot_str_type * geom_t_knot,
282
 
                     knot_str_type * color_s_knot,
283
 
                     knot_str_type * color_t_knot,
284
 
                     knot_str_type * normal_s_knot,
285
 
                     knot_str_type * normal_t_knot,
286
 
                     knot_str_type * texture_s_knot,
287
 
                     knot_str_type * texture_t_knot)
288
 
{
289
 
   GLint order;
290
 
   GLfloat *knot;
291
 
   GLint nknots;
292
 
   GLint t_min, t_max;
293
 
 
294
 
   geom_s_knot->unified_knot = NULL;
295
 
   knot = geom_s_knot->knot = nobj->surface.geom.sknot;
296
 
   nknots = geom_s_knot->nknots = nobj->surface.geom.sknot_count;
297
 
   order = geom_s_knot->order = nobj->surface.geom.sorder;
298
 
   geom_s_knot->delta_nknots = 0;
299
 
   t_min = geom_s_knot->t_min = order - 1;
300
 
   t_max = geom_s_knot->t_max = nknots - order;
301
 
   if (fabs(knot[t_min] - knot[t_max]) < EPSILON) {
302
 
      call_user_error(nobj, GLU_NURBS_ERROR3);
303
 
      return GLU_ERROR;
304
 
   }
305
 
   if (fabs(knot[0] - knot[t_min]) < EPSILON) {
306
 
      /* knot open at beggining */
307
 
      geom_s_knot->open_at_begin = GL_TRUE;
308
 
   }
309
 
   else
310
 
      geom_s_knot->open_at_begin = GL_FALSE;
311
 
   if (fabs(knot[t_max] - knot[nknots - 1]) < EPSILON) {
312
 
      /* knot open at end */
313
 
      geom_s_knot->open_at_end = GL_TRUE;
314
 
   }
315
 
   else
316
 
      geom_s_knot->open_at_end = GL_FALSE;
317
 
   geom_t_knot->unified_knot = NULL;
318
 
   knot = geom_t_knot->knot = nobj->surface.geom.tknot;
319
 
   nknots = geom_t_knot->nknots = nobj->surface.geom.tknot_count;
320
 
   order = geom_t_knot->order = nobj->surface.geom.torder;
321
 
   geom_t_knot->delta_nknots = 0;
322
 
   t_min = geom_t_knot->t_min = order - 1;
323
 
   t_max = geom_t_knot->t_max = nknots - order;
324
 
   if (fabs(knot[t_min] - knot[t_max]) < EPSILON) {
325
 
      call_user_error(nobj, GLU_NURBS_ERROR3);
326
 
      return GLU_ERROR;
327
 
   }
328
 
   if (fabs(knot[0] - knot[t_min]) < EPSILON) {
329
 
      /* knot open at beggining */
330
 
      geom_t_knot->open_at_begin = GL_TRUE;
331
 
   }
332
 
   else
333
 
      geom_t_knot->open_at_begin = GL_FALSE;
334
 
   if (fabs(knot[t_max] - knot[nknots - 1]) < EPSILON) {
335
 
      /* knot open at end */
336
 
      geom_t_knot->open_at_end = GL_TRUE;
337
 
   }
338
 
   else
339
 
      geom_t_knot->open_at_end = GL_FALSE;
340
 
 
341
 
   if (nobj->surface.color.type != GLU_INVALID_ENUM) {
342
 
      color_s_knot->unified_knot = (GLfloat *) 1;
343
 
      knot = color_s_knot->knot = nobj->surface.color.sknot;
344
 
      nknots = color_s_knot->nknots = nobj->surface.color.sknot_count;
345
 
      order = color_s_knot->order = nobj->surface.color.sorder;
346
 
      color_s_knot->delta_nknots = 0;
347
 
      t_min = color_s_knot->t_min = order - 1;
348
 
      t_max = color_s_knot->t_max = nknots - order;
349
 
      if (fabs(knot[t_min] - knot[t_max]) < EPSILON) {
350
 
         call_user_error(nobj, GLU_NURBS_ERROR3);
351
 
         return GLU_ERROR;
352
 
      }
353
 
      if (fabs(knot[0] - knot[t_min]) < EPSILON) {
354
 
         /* knot open at beggining */
355
 
         color_s_knot->open_at_begin = GL_TRUE;
356
 
      }
357
 
      else
358
 
         color_s_knot->open_at_begin = GL_FALSE;
359
 
      if (fabs(knot[t_max] - knot[nknots - 1]) < EPSILON) {
360
 
         /* knot open at end */
361
 
         color_s_knot->open_at_end = GL_TRUE;
362
 
      }
363
 
      else
364
 
         color_s_knot->open_at_end = GL_FALSE;
365
 
      color_t_knot->unified_knot = (GLfloat *) 1;
366
 
      knot = color_t_knot->knot = nobj->surface.color.tknot;
367
 
      nknots = color_t_knot->nknots = nobj->surface.color.tknot_count;
368
 
      order = color_t_knot->order = nobj->surface.color.torder;
369
 
      color_t_knot->delta_nknots = 0;
370
 
      t_min = color_t_knot->t_min = order - 1;
371
 
      t_max = color_t_knot->t_max = nknots - order;
372
 
      if (fabs(knot[t_min] - knot[t_max]) < EPSILON) {
373
 
         call_user_error(nobj, GLU_NURBS_ERROR3);
374
 
         return GLU_ERROR;
375
 
      }
376
 
      if (fabs(knot[0] - knot[t_min]) < EPSILON) {
377
 
         /* knot open at beggining */
378
 
         color_t_knot->open_at_begin = GL_TRUE;
379
 
      }
380
 
      else
381
 
         color_t_knot->open_at_begin = GL_FALSE;
382
 
      if (fabs(knot[t_max] - knot[nknots - 1]) < EPSILON) {
383
 
         /* knot open at end */
384
 
         color_t_knot->open_at_end = GL_TRUE;
385
 
      }
386
 
      else
387
 
         color_t_knot->open_at_end = GL_FALSE;
388
 
   }
389
 
   else {
390
 
      color_s_knot->unified_knot = NULL;
391
 
      color_t_knot->unified_knot = NULL;
392
 
   }
393
 
 
394
 
   if (nobj->surface.normal.type != GLU_INVALID_ENUM) {
395
 
      normal_s_knot->unified_knot = (GLfloat *) 1;
396
 
      knot = normal_s_knot->knot = nobj->surface.normal.sknot;
397
 
      nknots = normal_s_knot->nknots = nobj->surface.normal.sknot_count;
398
 
      order = normal_s_knot->order = nobj->surface.normal.sorder;
399
 
      normal_s_knot->delta_nknots = 0;
400
 
      t_min = normal_s_knot->t_min = order - 1;
401
 
      t_max = normal_s_knot->t_max = nknots - order;
402
 
      if (fabs(knot[t_min] - knot[t_max]) < EPSILON) {
403
 
         call_user_error(nobj, GLU_NURBS_ERROR3);
404
 
         return GLU_ERROR;
405
 
      }
406
 
      if (fabs(knot[0] - knot[t_min]) < EPSILON) {
407
 
         /* knot open at beggining */
408
 
         normal_s_knot->open_at_begin = GL_TRUE;
409
 
      }
410
 
      else
411
 
         normal_s_knot->open_at_begin = GL_FALSE;
412
 
      if (fabs(knot[t_max] - knot[nknots - 1]) < EPSILON) {
413
 
         /* knot open at end */
414
 
         normal_s_knot->open_at_end = GL_TRUE;
415
 
      }
416
 
      else
417
 
         normal_s_knot->open_at_end = GL_FALSE;
418
 
      normal_t_knot->unified_knot = (GLfloat *) 1;
419
 
      knot = normal_t_knot->knot = nobj->surface.normal.tknot;
420
 
      nknots = normal_t_knot->nknots = nobj->surface.normal.tknot_count;
421
 
      order = normal_t_knot->order = nobj->surface.normal.torder;
422
 
      normal_t_knot->delta_nknots = 0;
423
 
      t_min = normal_t_knot->t_min = order - 1;
424
 
      t_max = normal_t_knot->t_max = nknots - order;
425
 
      if (fabs(knot[t_min] - knot[t_max]) < EPSILON) {
426
 
         call_user_error(nobj, GLU_NURBS_ERROR3);
427
 
         return GLU_ERROR;
428
 
      }
429
 
      if (fabs(knot[0] - knot[t_min]) < EPSILON) {
430
 
         /* knot open at beggining */
431
 
         normal_t_knot->open_at_begin = GL_TRUE;
432
 
      }
433
 
      else
434
 
         normal_t_knot->open_at_begin = GL_FALSE;
435
 
      if (fabs(knot[t_max] - knot[nknots - 1]) < EPSILON) {
436
 
         /* knot open at end */
437
 
         normal_t_knot->open_at_end = GL_TRUE;
438
 
      }
439
 
      else
440
 
         normal_t_knot->open_at_end = GL_FALSE;
441
 
   }
442
 
   else {
443
 
      normal_s_knot->unified_knot = NULL;
444
 
      normal_t_knot->unified_knot = NULL;
445
 
   }
446
 
 
447
 
   if (nobj->surface.texture.type != GLU_INVALID_ENUM) {
448
 
      texture_s_knot->unified_knot = (GLfloat *) 1;
449
 
      knot = texture_s_knot->knot = nobj->surface.texture.sknot;
450
 
      nknots = texture_s_knot->nknots = nobj->surface.texture.sknot_count;
451
 
      order = texture_s_knot->order = nobj->surface.texture.sorder;
452
 
      texture_s_knot->delta_nknots = 0;
453
 
      t_min = texture_s_knot->t_min = order - 1;
454
 
      t_max = texture_s_knot->t_max = nknots - order;
455
 
      if (fabs(knot[t_min] - knot[t_max]) < EPSILON) {
456
 
         call_user_error(nobj, GLU_NURBS_ERROR3);
457
 
         return GLU_ERROR;
458
 
      }
459
 
      if (fabs(knot[0] - knot[t_min]) < EPSILON) {
460
 
         /* knot open at beggining */
461
 
         texture_s_knot->open_at_begin = GL_TRUE;
462
 
      }
463
 
      else
464
 
         texture_s_knot->open_at_begin = GL_FALSE;
465
 
      if (fabs(knot[t_max] - knot[nknots - 1]) < EPSILON) {
466
 
         /* knot open at end */
467
 
         texture_s_knot->open_at_end = GL_TRUE;
468
 
      }
469
 
      else
470
 
         texture_s_knot->open_at_end = GL_FALSE;
471
 
      texture_t_knot->unified_knot = (GLfloat *) 1;
472
 
      knot = texture_t_knot->knot = nobj->surface.texture.tknot;
473
 
      nknots = texture_t_knot->nknots = nobj->surface.texture.tknot_count;
474
 
      order = texture_t_knot->order = nobj->surface.texture.torder;
475
 
      texture_t_knot->delta_nknots = 0;
476
 
      t_min = texture_t_knot->t_min = order - 1;
477
 
      t_max = texture_t_knot->t_max = nknots - order;
478
 
      if (fabs(knot[t_min] - knot[t_max]) < EPSILON) {
479
 
         call_user_error(nobj, GLU_NURBS_ERROR3);
480
 
         return GLU_ERROR;
481
 
      }
482
 
      if (fabs(knot[0] - knot[t_min]) < EPSILON) {
483
 
         /* knot open at beggining */
484
 
         texture_t_knot->open_at_begin = GL_TRUE;
485
 
      }
486
 
      else
487
 
         texture_t_knot->open_at_begin = GL_FALSE;
488
 
      if (fabs(knot[t_max] - knot[nknots - 1]) < EPSILON) {
489
 
         /* knot open at end */
490
 
         texture_t_knot->open_at_end = GL_TRUE;
491
 
      }
492
 
      else
493
 
         texture_t_knot->open_at_end = GL_FALSE;
494
 
   }
495
 
   else {
496
 
      texture_s_knot->unified_knot = NULL;
497
 
      texture_t_knot->unified_knot = NULL;
498
 
   }
499
 
   return GLU_NO_ERROR;
500
 
}
501
 
 
502
 
 
503
 
static void
504
 
free_new_ctrl(new_ctrl_type * p)
505
 
{
506
 
   if (p->geom_ctrl)
507
 
      free(p->geom_ctrl);
508
 
   if (p->geom_offsets)
509
 
      free(p->geom_offsets);
510
 
   if (p->color_ctrl) {
511
 
      free(p->color_ctrl);
512
 
      if (p->color_offsets)
513
 
         free(p->color_offsets);
514
 
   }
515
 
   if (p->normal_ctrl) {
516
 
      free(p->normal_ctrl);
517
 
      if (p->normal_offsets)
518
 
         free(p->normal_offsets);
519
 
   }
520
 
   if (p->texture_ctrl) {
521
 
      free(p->texture_ctrl);
522
 
      if (p->texture_offsets)
523
 
         free(p->texture_offsets);
524
 
   }
525
 
}
526
 
 
527
 
/* convert surfaces - geometry and possible attribute ones into equivalent */
528
 
/* sequence of adjacent Bezier patches */
529
 
static GLenum
530
 
convert_surfs(GLUnurbsObj * nobj, new_ctrl_type * new_ctrl)
531
 
{
532
 
   knot_str_type geom_s_knot, color_s_knot, normal_s_knot, texture_s_knot;
533
 
   knot_str_type geom_t_knot, color_t_knot, normal_t_knot, texture_t_knot;
534
 
   GLenum err;
535
 
 
536
 
   if ((err = fill_knot_structures(nobj, &geom_s_knot, &geom_t_knot,
537
 
                                   &color_s_knot, &color_t_knot,
538
 
                                   &normal_s_knot, &normal_t_knot,
539
 
                                   &texture_s_knot,
540
 
                                   &texture_t_knot)) != GLU_NO_ERROR) {
541
 
      return err;
542
 
   }
543
 
   /* unify knots - all knots should have the same working range */
544
 
   if ((err = select_knot_working_range(nobj, &geom_s_knot, &color_s_knot,
545
 
                                        &normal_s_knot,
546
 
                                        &texture_s_knot)) != GLU_NO_ERROR) {
547
 
      call_user_error(nobj, err);
548
 
      return err;
549
 
   }
550
 
   if ((err = select_knot_working_range(nobj, &geom_t_knot, &color_t_knot,
551
 
                                        &normal_t_knot,
552
 
                                        &texture_t_knot)) != GLU_NO_ERROR) {
553
 
      free_unified_knots(&geom_s_knot, &color_s_knot, &normal_s_knot,
554
 
                         &texture_s_knot);
555
 
      call_user_error(nobj, err);
556
 
      return err;
557
 
   }
558
 
 
559
 
   /* convert the geometry surface */
560
 
   nobj->surface.geom.dim = get_surface_dim(nobj->surface.geom.type);
561
 
   if ((err = convert_surf(&geom_s_knot, &geom_t_knot, &(nobj->surface.geom),
562
 
                           &(new_ctrl->geom_ctrl), &(new_ctrl->geom_s_pt_cnt),
563
 
                           &(new_ctrl->geom_t_pt_cnt))) != GLU_NO_ERROR) {
564
 
      free_unified_knots(&geom_s_knot, &color_s_knot, &normal_s_knot,
565
 
                         &texture_s_knot);
566
 
      free_unified_knots(&geom_t_knot, &color_t_knot, &normal_t_knot,
567
 
                         &texture_t_knot);
568
 
      call_user_error(nobj, err);
569
 
      return err;
570
 
   }
571
 
   /* if additional attributive surfaces are given convert them as well */
572
 
   if (color_s_knot.unified_knot) {
573
 
      nobj->surface.color.dim = get_surface_dim(nobj->surface.color.type);
574
 
      if (
575
 
          (err =
576
 
           convert_surf(&color_s_knot, &color_t_knot, &(nobj->surface.color),
577
 
                        &(new_ctrl->color_ctrl), &(new_ctrl->color_s_pt_cnt),
578
 
                        &(new_ctrl->color_t_pt_cnt))) != GLU_NO_ERROR) {
579
 
         free_unified_knots(&color_s_knot, &color_s_knot, &normal_s_knot,
580
 
                            &texture_s_knot);
581
 
         free_unified_knots(&color_t_knot, &color_t_knot, &normal_t_knot,
582
 
                            &texture_t_knot);
583
 
         free_new_ctrl(new_ctrl);
584
 
         call_user_error(nobj, err);
585
 
         return err;
586
 
      }
587
 
   }
588
 
   if (normal_s_knot.unified_knot) {
589
 
      nobj->surface.normal.dim = get_surface_dim(nobj->surface.normal.type);
590
 
      if ((err = convert_surf(&normal_s_knot, &normal_t_knot,
591
 
                              &(nobj->surface.normal),
592
 
                              &(new_ctrl->normal_ctrl),
593
 
                              &(new_ctrl->normal_s_pt_cnt),
594
 
                              &(new_ctrl->normal_t_pt_cnt))) !=
595
 
          GLU_NO_ERROR) {
596
 
         free_unified_knots(&normal_s_knot, &normal_s_knot, &normal_s_knot,
597
 
                            &texture_s_knot);
598
 
         free_unified_knots(&normal_t_knot, &normal_t_knot, &normal_t_knot,
599
 
                            &texture_t_knot);
600
 
         free_new_ctrl(new_ctrl);
601
 
         call_user_error(nobj, err);
602
 
         return err;
603
 
      }
604
 
   }
605
 
   if (texture_s_knot.unified_knot) {
606
 
      nobj->surface.texture.dim = get_surface_dim(nobj->surface.texture.type);
607
 
      if ((err = convert_surf(&texture_s_knot, &texture_t_knot,
608
 
                              &(nobj->surface.texture),
609
 
                              &(new_ctrl->texture_ctrl),
610
 
                              &(new_ctrl->texture_s_pt_cnt),
611
 
                              &(new_ctrl->texture_t_pt_cnt))) !=
612
 
          GLU_NO_ERROR) {
613
 
         free_unified_knots(&texture_s_knot, &texture_s_knot, &texture_s_knot,
614
 
                            &texture_s_knot);
615
 
         free_unified_knots(&texture_t_knot, &texture_t_knot, &texture_t_knot,
616
 
                            &texture_t_knot);
617
 
         free_new_ctrl(new_ctrl);
618
 
         call_user_error(nobj, err);
619
 
         return err;
620
 
      }
621
 
   }
622
 
   return GLU_NO_ERROR;
623
 
}
624
 
 
625
 
/* tesselate the "boundary" Bezier edge strips */
626
 
static void
627
 
tesselate_strip_t_line(GLint top_start, GLint top_end, GLint top_z,
628
 
                       GLint bottom_start, GLint bottom_end, GLint bottom_z,
629
 
                       GLint bottom_domain)
630
 
{
631
 
   GLint top_cnt, bottom_cnt, tri_cnt, k;
632
 
   GLint direction;
633
 
 
634
 
   top_cnt = top_end - top_start;
635
 
   direction = (top_cnt >= 0 ? 1 : -1);
636
 
   bottom_cnt = bottom_end - bottom_start;
637
 
   glBegin(GL_LINES);
638
 
   while (top_cnt) {
639
 
      if (bottom_cnt)
640
 
         tri_cnt = top_cnt / bottom_cnt;
641
 
      else
642
 
         tri_cnt = abs(top_cnt);
643
 
      for (k = 0; k <= tri_cnt; k++, top_start += direction) {
644
 
         glEvalCoord2f((GLfloat) bottom_z / bottom_domain,
645
 
                       (GLfloat) bottom_start / bottom_domain);
646
 
         glEvalPoint2(top_z, top_start);
647
 
      }
648
 
      if (bottom_cnt) {
649
 
         glEvalCoord2f((GLfloat) bottom_z / bottom_domain,
650
 
                       (GLfloat) bottom_start / bottom_domain);
651
 
         bottom_start += direction;
652
 
         top_start -= direction;
653
 
         glEvalCoord2f((GLfloat) bottom_z / bottom_domain,
654
 
                       (GLfloat) bottom_start / bottom_domain);
655
 
         glEvalCoord2f((GLfloat) bottom_z / bottom_domain,
656
 
                       (GLfloat) bottom_start / bottom_domain);
657
 
         glEvalPoint2(top_z, top_start);
658
 
      }
659
 
      top_cnt -= direction * tri_cnt;
660
 
      bottom_cnt -= direction;
661
 
   }
662
 
   glEnd();
663
 
}
664
 
 
665
 
 
666
 
static void
667
 
tesselate_strip_t_fill(GLint top_start, GLint top_end, GLint top_z,
668
 
                       GLint bottom_start, GLint bottom_end, GLint bottom_z,
669
 
                       GLint bottom_domain)
670
 
{
671
 
   GLint top_cnt, bottom_cnt, tri_cnt, k;
672
 
   GLint direction;
673
 
 
674
 
   top_cnt = top_end - top_start;
675
 
   direction = (top_cnt >= 0 ? 1 : -1);
676
 
   bottom_cnt = bottom_end - bottom_start;
677
 
   while (top_cnt) {
678
 
      if (bottom_cnt)
679
 
         tri_cnt = top_cnt / bottom_cnt;
680
 
      else
681
 
         tri_cnt = abs(top_cnt);
682
 
      glBegin(GL_TRIANGLE_FAN);
683
 
      glEvalCoord2f((GLfloat) bottom_z / bottom_domain,
684
 
                    (GLfloat) bottom_start / bottom_domain);
685
 
      for (k = 0; k <= tri_cnt; k++, top_start += direction)
686
 
         glEvalPoint2(top_z, top_start);
687
 
      if (bottom_cnt) {
688
 
         bottom_start += direction;
689
 
         top_start -= direction;
690
 
         glEvalCoord2f((GLfloat) bottom_z / bottom_domain,
691
 
                       (GLfloat) bottom_start / bottom_domain);
692
 
      }
693
 
      glEnd();
694
 
      top_cnt -= direction * tri_cnt;
695
 
      bottom_cnt -= direction;
696
 
   }
697
 
}
698
 
 
699
 
 
700
 
static void
701
 
tesselate_strip_t(GLenum display_mode, GLint top_start, GLint top_end,
702
 
                  GLint top_z, GLint bottom_start, GLint bottom_end,
703
 
                  GLint bottom_z, GLint bottom_domain)
704
 
{
705
 
   if (display_mode == GL_FILL)
706
 
      tesselate_strip_t_fill(top_start, top_end, top_z, bottom_start,
707
 
                             bottom_end, bottom_z, bottom_domain);
708
 
   else
709
 
      tesselate_strip_t_line(top_start, top_end, top_z, bottom_start,
710
 
                             bottom_end, bottom_z, bottom_domain);
711
 
}
712
 
 
713
 
 
714
 
static void
715
 
tesselate_strip_s_fill(GLint top_start, GLint top_end, GLint top_z,
716
 
                       GLint bottom_start, GLint bottom_end, GLint bottom_z,
717
 
                       GLfloat bottom_domain)
718
 
{
719
 
   GLint top_cnt, bottom_cnt, tri_cnt, k;
720
 
   GLint direction;
721
 
 
722
 
   top_cnt = top_end - top_start;
723
 
   direction = (top_cnt >= 0 ? 1 : -1);
724
 
   bottom_cnt = bottom_end - bottom_start;
725
 
   while (top_cnt) {
726
 
      if (bottom_cnt)
727
 
         tri_cnt = top_cnt / bottom_cnt;
728
 
      else
729
 
         tri_cnt = abs(top_cnt);
730
 
      glBegin(GL_TRIANGLE_FAN);
731
 
      glEvalCoord2f((GLfloat) bottom_start / bottom_domain,
732
 
                    (GLfloat) bottom_z / bottom_domain);
733
 
      for (k = 0; k <= tri_cnt; k++, top_start += direction)
734
 
         glEvalPoint2(top_start, top_z);
735
 
      if (bottom_cnt) {
736
 
         bottom_start += direction;
737
 
         top_start -= direction;
738
 
         glEvalCoord2f((GLfloat) bottom_start / bottom_domain,
739
 
                       (GLfloat) bottom_z / bottom_domain);
740
 
      }
741
 
      glEnd();
742
 
      top_cnt -= direction * tri_cnt;
743
 
      bottom_cnt -= direction;
744
 
   }
745
 
}
746
 
 
747
 
 
748
 
static void
749
 
tesselate_strip_s_line(GLint top_start, GLint top_end, GLint top_z,
750
 
                       GLint bottom_start, GLint bottom_end, GLint bottom_z,
751
 
                       GLfloat bottom_domain)
752
 
{
753
 
   GLint top_cnt, bottom_cnt, tri_cnt, k;
754
 
   GLint direction;
755
 
 
756
 
   top_cnt = top_end - top_start;
757
 
   direction = (top_cnt >= 0 ? 1 : -1);
758
 
   bottom_cnt = bottom_end - bottom_start;
759
 
   glBegin(GL_LINES);
760
 
   while (top_cnt) {
761
 
      if (bottom_cnt)
762
 
         tri_cnt = top_cnt / bottom_cnt;
763
 
      else
764
 
         tri_cnt = abs(top_cnt);
765
 
      for (k = 0; k <= tri_cnt; k++, top_start += direction) {
766
 
         glEvalCoord2f((GLfloat) bottom_start / bottom_domain,
767
 
                       (GLfloat) bottom_z / bottom_domain);
768
 
         glEvalPoint2(top_start, top_z);
769
 
      }
770
 
      if (bottom_cnt) {
771
 
         glEvalCoord2f((GLfloat) bottom_start / bottom_domain,
772
 
                       (GLfloat) bottom_z / bottom_domain);
773
 
         bottom_start += direction;
774
 
         top_start -= direction;
775
 
         glEvalCoord2f((GLfloat) bottom_start / bottom_domain,
776
 
                       (GLfloat) bottom_z / bottom_domain);
777
 
         glEvalPoint2(top_start, top_z);
778
 
         glEvalCoord2f((GLfloat) bottom_start / bottom_domain,
779
 
                       (GLfloat) bottom_z / bottom_domain);
780
 
      }
781
 
      top_cnt -= direction * tri_cnt;
782
 
      bottom_cnt -= direction;
783
 
   }
784
 
   glEnd();
785
 
}
786
 
 
787
 
 
788
 
static void
789
 
tesselate_strip_s(GLenum display_mode, GLint top_start, GLint top_end,
790
 
                  GLint top_z, GLint bottom_start, GLint bottom_end,
791
 
                  GLint bottom_z, GLfloat bottom_domain)
792
 
{
793
 
   if (display_mode == GL_FILL)
794
 
      tesselate_strip_s_fill(top_start, top_end, top_z, bottom_start,
795
 
                             bottom_end, bottom_z, bottom_domain);
796
 
   else
797
 
      tesselate_strip_s_line(top_start, top_end, top_z, bottom_start,
798
 
                             bottom_end, bottom_z, bottom_domain);
799
 
}
800
 
 
801
 
static void
802
 
tesselate_bottom_left_corner(GLenum display_mode, GLfloat s_1, GLfloat t_1)
803
 
{
804
 
   if (display_mode == GL_FILL) {
805
 
      glBegin(GL_TRIANGLE_FAN);
806
 
      glEvalPoint2(1, 1);
807
 
      glEvalCoord2f(s_1, 0.0);
808
 
      glEvalCoord2f(0.0, 0.0);
809
 
      glEvalCoord2f(0.0, t_1);
810
 
   }
811
 
   else {
812
 
      glBegin(GL_LINES);
813
 
      glEvalCoord2f(0.0, 0.0);
814
 
      glEvalCoord2f(0.0, t_1);
815
 
      glEvalCoord2f(0.0, 0.0);
816
 
      glEvalPoint2(1, 1);
817
 
      glEvalCoord2f(0.0, 0.0);
818
 
      glEvalCoord2f(s_1, 0.0);
819
 
   }
820
 
   glEnd();
821
 
}
822
 
 
823
 
static void
824
 
tesselate_bottom_right_corner(GLenum display_mode, GLint v_top,
825
 
                              GLint v_bottom, GLfloat s_1, GLfloat t_1)
826
 
{
827
 
   if (display_mode == GL_FILL) {
828
 
      glBegin(GL_TRIANGLE_FAN);
829
 
      glEvalPoint2(1, v_top);
830
 
      glEvalCoord2f(0.0, v_bottom * t_1);
831
 
      glEvalCoord2f(0.0, (v_bottom + 1) * t_1);
832
 
      glEvalCoord2f(s_1, (v_bottom + 1) * t_1);
833
 
   }
834
 
   else {
835
 
      glBegin(GL_LINES);
836
 
      glEvalCoord2f(0.0, (v_bottom + 1) * t_1);
837
 
      glEvalPoint2(1, v_top);
838
 
      glEvalCoord2f(0.0, (v_bottom + 1) * t_1);
839
 
      glEvalCoord2f(0.0, v_bottom * t_1);
840
 
      glEvalCoord2f(0.0, (v_bottom + 1) * t_1);
841
 
      glEvalCoord2f(s_1, (v_bottom + 1) * t_1);
842
 
   }
843
 
   glEnd();
844
 
}
845
 
 
846
 
static void
847
 
tesselate_top_left_corner(GLenum display_mode, GLint u_right, GLint u_left,
848
 
                          GLfloat s_1, GLfloat t_1)
849
 
{
850
 
   if (display_mode == GL_FILL) {
851
 
      glBegin(GL_TRIANGLE_FAN);
852
 
      glEvalPoint2(u_right, 1);
853
 
      glEvalCoord2f((u_left + 1) * s_1, t_1);
854
 
      glEvalCoord2f((u_left + 1) * s_1, 0.0);
855
 
      glEvalCoord2f(u_left * s_1, 0.0);
856
 
   }
857
 
   else {
858
 
      glBegin(GL_LINES);
859
 
      glEvalCoord2f((u_left + 1) * s_1, 0.0);
860
 
      glEvalPoint2(u_right, 1);
861
 
      glEvalCoord2f((u_left + 1) * s_1, 0.0);
862
 
      glEvalCoord2f(u_left * s_1, 0.0);
863
 
      glEvalCoord2f((u_left + 1) * s_1, 0.0);
864
 
      glEvalCoord2f((u_left + 1) * s_1, t_1);
865
 
   }
866
 
   glEnd();
867
 
}
868
 
 
869
 
static void
870
 
tesselate_top_right_corner(GLenum display_mode, GLint u_left, GLint v_bottom,
871
 
                           GLint u_right, GLint v_top, GLfloat s_1,
872
 
                           GLfloat t_1)
873
 
{
874
 
   if (display_mode == GL_FILL) {
875
 
      glBegin(GL_TRIANGLE_FAN);
876
 
      glEvalPoint2(u_left, v_bottom);
877
 
      glEvalCoord2f((u_right - 1) * s_1, v_top * t_1);
878
 
      glEvalCoord2f(u_right * s_1, v_top * t_1);
879
 
      glEvalCoord2f(u_right * s_1, (v_top - 1) * t_1);
880
 
   }
881
 
   else {
882
 
      glBegin(GL_LINES);
883
 
      glEvalCoord2f(u_right * s_1, v_top * t_1);
884
 
      glEvalPoint2(u_left, v_bottom);
885
 
      glEvalCoord2f(u_right * s_1, v_top * t_1);
886
 
      glEvalCoord2f(u_right * s_1, (v_top - 1) * t_1);
887
 
      glEvalCoord2f(u_right * s_1, v_top * t_1);
888
 
      glEvalCoord2f((u_right - 1) * s_1, v_top * t_1);
889
 
   }
890
 
   glEnd();
891
 
}
892
 
 
893
 
/* do mesh mapping of Bezier */
894
 
static void
895
 
nurbs_map_bezier(GLenum display_mode, GLint * sfactors, GLint * tfactors,
896
 
                 GLint s_bezier_cnt, GLint t_bezier_cnt, GLint s, GLint t)
897
 
{
898
 
   GLint top, bottom, right, left;
899
 
 
900
 
 
901
 
   if (s == 0) {
902
 
      top = *(tfactors + t * 3);
903
 
      bottom = *(tfactors + t * 3 + 1);
904
 
   }
905
 
   else if (s == s_bezier_cnt - 1) {
906
 
      top = *(tfactors + t * 3 + 2);
907
 
      bottom = *(tfactors + t * 3);
908
 
   }
909
 
   else {
910
 
      top = bottom = *(tfactors + t * 3);
911
 
   }
912
 
   if (t == 0) {
913
 
      left = *(sfactors + s * 3 + 1);
914
 
      right = *(sfactors + s * 3);
915
 
   }
916
 
   else if (t == t_bezier_cnt - 1) {
917
 
      left = *(sfactors + s * 3);
918
 
      right = *(sfactors + s * 3 + 2);
919
 
   }
920
 
   else {
921
 
      left = right = *(sfactors + s * 3);
922
 
   }
923
 
 
924
 
   if (top > bottom) {
925
 
      if (left < right) {
926
 
         glMapGrid2f(right, 0.0, 1.0, top, 0.0, 1.0);
927
 
         glEvalMesh2(display_mode, 1, right, 1, top);
928
 
         tesselate_strip_s(display_mode, 1, right, 1, 1, left, 0,
929
 
                           (GLfloat) left);
930
 
         tesselate_bottom_left_corner(display_mode, (GLfloat) (1.0 / left),
931
 
                                      (GLfloat) (1.0 / bottom));
932
 
/*                      tesselate_strip_t(display_mode,1,top,1,1,bottom,0,(GLfloat)bottom);*/
933
 
         tesselate_strip_t(display_mode, top, 1, 1, bottom, 1, 0,
934
 
                           (GLfloat) bottom);
935
 
      }
936
 
      else if (left == right) {
937
 
         glMapGrid2f(right, 0.0, 1.0, top, 0.0, 1.0);
938
 
         glEvalMesh2(display_mode, 1, right, 0, top);
939
 
/*                      tesselate_strip_t(display_mode,0,top,1,0,bottom,0,(GLfloat)bottom);*/
940
 
         tesselate_strip_t(display_mode, top, 0, 1, bottom, 0, 0,
941
 
                           (GLfloat) bottom);
942
 
      }
943
 
      else {
944
 
         glMapGrid2f(left, 0.0, 1.0, top, 0.0, 1.0);
945
 
         glEvalMesh2(display_mode, 1, left, 0, top - 1);
946
 
/*                      tesselate_strip_t(display_mode,0,top-1,1,0,bottom-1,0,
947
 
                                (GLfloat)bottom);*/
948
 
         tesselate_strip_t(display_mode, top - 1, 0, 1, bottom - 1, 0, 0,
949
 
                           (GLfloat) bottom);
950
 
         tesselate_bottom_right_corner(display_mode, top - 1, bottom - 1,
951
 
                                       (GLfloat) (1.0 / right),
952
 
                                       (GLfloat) (1.0 / bottom));
953
 
/*                      tesselate_strip_s(display_mode,1,left,top-1,1,right,right,
954
 
                                (GLfloat)right);*/
955
 
         tesselate_strip_s(display_mode, left, 1, top - 1, right, 1, right,
956
 
                           (GLfloat) right);
957
 
      }
958
 
   }
959
 
   else if (top == bottom) {
960
 
      if (left < right) {
961
 
         glMapGrid2f(right, 0.0, 1.0, top, 0.0, 1.0);
962
 
         glEvalMesh2(display_mode, 0, right, 1, top);
963
 
         tesselate_strip_s(display_mode, 0, right, 1, 0, left, 0,
964
 
                           (GLfloat) left);
965
 
      }
966
 
      else if (left == right) {
967
 
         glMapGrid2f(right, 0.0, 1.0, top, 0.0, 1.0);
968
 
         glEvalMesh2(display_mode, 0, right, 0, top);
969
 
      }
970
 
      else {
971
 
         glMapGrid2f(left, 0.0, 1.0, top, 0.0, 1.0);
972
 
         glEvalMesh2(display_mode, 0, left, 0, top - 1);
973
 
/*                      tesselate_strip_s(display_mode,0,left,top-1,0,right,right,
974
 
                                (GLfloat)right);*/
975
 
         tesselate_strip_s(display_mode, left, 0, top - 1, right, 0, right,
976
 
                           (GLfloat) right);
977
 
      }
978
 
   }
979
 
   else {
980
 
      if (left < right) {
981
 
         glMapGrid2f(right, 0.0, 1.0, bottom, 0.0, 1.0);
982
 
         glEvalMesh2(display_mode, 0, right - 1, 1, bottom);
983
 
         tesselate_strip_s(display_mode, 0, right - 1, 1, 0, left - 1, 0,
984
 
                           (GLfloat) left);
985
 
         tesselate_top_left_corner(display_mode, right - 1, left - 1,
986
 
                                   (GLfloat) (1.0 / left),
987
 
                                   (GLfloat) (1.0 / top));
988
 
         tesselate_strip_t(display_mode, 1, bottom, right - 1, 1, top, top,
989
 
                           (GLfloat) top);
990
 
      }
991
 
      else if (left == right) {
992
 
         glMapGrid2f(right, 0.0, 1.0, bottom, 0.0, 1.0);
993
 
         glEvalMesh2(display_mode, 0, right - 1, 0, bottom);
994
 
         tesselate_strip_t(display_mode, 0, bottom, right - 1, 0, top, top,
995
 
                           (GLfloat) top);
996
 
      }
997
 
      else {
998
 
         glMapGrid2f(left, 0.0, 1.0, bottom, 0.0, 1.0);
999
 
         glEvalMesh2(display_mode, 0, left - 1, 0, bottom - 1);
1000
 
         tesselate_strip_t(display_mode, 0, bottom - 1, left - 1, 0, top - 1,
1001
 
                           top, (GLfloat) top);
1002
 
         tesselate_top_right_corner(display_mode, left - 1, bottom - 1, right,
1003
 
                                    top, (GLfloat) (1.0 / right),
1004
 
                                    (GLfloat) (1.0 / top));
1005
 
/*                      tesselate_strip_s(display_mode,0,left-1,bottom-1,0,right-1,right,
1006
 
                                (GLfloat)right);*/
1007
 
         tesselate_strip_s(display_mode, left - 1, 0, bottom - 1, right - 1,
1008
 
                           0, right, (GLfloat) right);
1009
 
      }
1010
 
   }
1011
 
}
1012
 
 
1013
 
/* draw NURBS surface in OUTLINE POLYGON mode */
1014
 
static void
1015
 
draw_polygon_mode(GLenum display_mode, GLUnurbsObj * nobj,
1016
 
                  new_ctrl_type * new_ctrl, GLint * sfactors,
1017
 
                  GLint * tfactors)
1018
 
{
1019
 
   GLsizei offset;
1020
 
   GLint t_bezier_cnt, s_bezier_cnt;
1021
 
   GLboolean do_color, do_normal, do_texture;
1022
 
   GLint i, j;
1023
 
 
1024
 
   t_bezier_cnt = new_ctrl->t_bezier_cnt;
1025
 
   s_bezier_cnt = new_ctrl->s_bezier_cnt;
1026
 
   glEnable(nobj->surface.geom.type);
1027
 
   if (new_ctrl->color_ctrl) {
1028
 
      glEnable(nobj->surface.color.type);
1029
 
      do_color = GL_TRUE;
1030
 
   }
1031
 
   else
1032
 
      do_color = GL_FALSE;
1033
 
   if (new_ctrl->normal_ctrl) {
1034
 
      glEnable(nobj->surface.normal.type);
1035
 
      do_normal = GL_TRUE;
1036
 
   }
1037
 
   else
1038
 
      do_normal = GL_FALSE;
1039
 
   if (new_ctrl->texture_ctrl) {
1040
 
      glEnable(nobj->surface.texture.type);
1041
 
      do_texture = GL_TRUE;
1042
 
   }
1043
 
   else
1044
 
      do_texture = GL_FALSE;
1045
 
   for (j = 0; j < s_bezier_cnt; j++) {
1046
 
      for (i = 0; i < t_bezier_cnt; i++) {
1047
 
         offset = j * t_bezier_cnt + i;
1048
 
         if (fine_culling_test_3D(nobj, *(new_ctrl->geom_offsets + offset),
1049
 
                                  nobj->surface.geom.sorder,
1050
 
                                  nobj->surface.geom.torder,
1051
 
                                  new_ctrl->geom_s_stride,
1052
 
                                  new_ctrl->geom_t_stride,
1053
 
                                  nobj->surface.geom.dim)) continue;
1054
 
         glMap2f(nobj->surface.geom.type, 0.0, 1.0, new_ctrl->geom_s_stride,
1055
 
                 nobj->surface.geom.sorder, 0.0, 1.0, new_ctrl->geom_t_stride,
1056
 
                 nobj->surface.geom.torder,
1057
 
                 *(new_ctrl->geom_offsets + offset));
1058
 
         if (do_color) {
1059
 
            glMap2f(nobj->surface.color.type, 0.0, 1.0,
1060
 
                    new_ctrl->color_s_stride, nobj->surface.color.sorder,
1061
 
                    0.0, 1.0, new_ctrl->color_t_stride,
1062
 
                    nobj->surface.color.torder,
1063
 
                    *(new_ctrl->color_offsets + offset));
1064
 
         }
1065
 
         if (do_normal) {
1066
 
            glMap2f(nobj->surface.normal.type, 0.0, 1.0,
1067
 
                    new_ctrl->normal_s_stride, nobj->surface.normal.sorder,
1068
 
                    0.0, 1.0, new_ctrl->normal_t_stride,
1069
 
                    nobj->surface.normal.torder,
1070
 
                    *(new_ctrl->normal_offsets + offset));
1071
 
         }
1072
 
         if (do_texture) {
1073
 
            glMap2f(nobj->surface.texture.type, 0.0, 1.0,
1074
 
                    new_ctrl->texture_s_stride, nobj->surface.texture.sorder,
1075
 
                    0.0, 1.0, new_ctrl->texture_t_stride,
1076
 
                    nobj->surface.texture.torder,
1077
 
                    *(new_ctrl->texture_offsets + offset));
1078
 
         }
1079
 
/*                      glMapGrid2f(sfactors[j*3+0],0.0,1.0,tfactors[i*3+0],0.0,1.0);
1080
 
                        glEvalMesh2(display_mode,0,sfactors[j*3+0],0,tfactors[i*3+0]);*/
1081
 
         nurbs_map_bezier(display_mode, sfactors, tfactors, s_bezier_cnt,
1082
 
                          t_bezier_cnt, j, i);
1083
 
      }
1084
 
   }
1085
 
}
1086
 
 
1087
 
 
1088
 
 
1089
 
/* draw NURBS surface in OUTLINE POLYGON mode */
1090
 
#if 0
1091
 
static void
1092
 
draw_patch_mode(GLenum display_mode, GLUnurbsObj * nobj,
1093
 
                new_ctrl_type * new_ctrl, GLint * sfactors, GLint * tfactors)
1094
 
{
1095
 
   GLsizei offset;
1096
 
   GLint t_bezier_cnt, s_bezier_cnt;
1097
 
   GLboolean do_color, do_normal, do_texture;
1098
 
   GLint i, j;
1099
 
 
1100
 
   t_bezier_cnt = new_ctrl->t_bezier_cnt;
1101
 
   s_bezier_cnt = new_ctrl->s_bezier_cnt;
1102
 
   glEnable(nobj->surface.geom.type);
1103
 
   if (new_ctrl->color_ctrl) {
1104
 
      glEnable(nobj->surface.color.type);
1105
 
      do_color = GL_TRUE;
1106
 
   }
1107
 
   else
1108
 
      do_color = GL_FALSE;
1109
 
   if (new_ctrl->normal_ctrl) {
1110
 
      glEnable(nobj->surface.normal.type);
1111
 
      do_normal = GL_TRUE;
1112
 
   }
1113
 
   else
1114
 
      do_normal = GL_FALSE;
1115
 
   if (new_ctrl->texture_ctrl) {
1116
 
      glEnable(nobj->surface.texture.type);
1117
 
      do_texture = GL_TRUE;
1118
 
   }
1119
 
   else
1120
 
      do_texture = GL_FALSE;
1121
 
   for (j = 0; j < s_bezier_cnt; j++) {
1122
 
      for (i = 0; i < t_bezier_cnt; i++) {
1123
 
         offset = j * t_bezier_cnt + i;
1124
 
         if (fine_culling_test_3D(nobj, *(new_ctrl->geom_offsets + offset),
1125
 
                                  nobj->surface.geom.sorder,
1126
 
                                  nobj->surface.geom.torder,
1127
 
                                  new_ctrl->geom_s_stride,
1128
 
                                  new_ctrl->geom_t_stride,
1129
 
                                  nobj->surface.geom.dim)) continue;
1130
 
         glMap2f(nobj->surface.geom.type, 0.0, 1.0, new_ctrl->geom_s_stride,
1131
 
                 nobj->surface.geom.sorder, 0.0, 1.0, new_ctrl->geom_t_stride,
1132
 
                 nobj->surface.geom.torder,
1133
 
                 *(new_ctrl->geom_offsets + offset));
1134
 
         if (do_color) {
1135
 
            glMap2f(nobj->surface.color.type, 0.0, 1.0,
1136
 
                    new_ctrl->color_s_stride, nobj->surface.color.sorder,
1137
 
                    0.0, 1.0, new_ctrl->color_t_stride,
1138
 
                    nobj->surface.color.torder,
1139
 
                    *(new_ctrl->color_offsets + offset));
1140
 
         }
1141
 
         if (do_normal) {
1142
 
            glMap2f(nobj->surface.normal.type, 0.0, 1.0,
1143
 
                    new_ctrl->normal_s_stride, nobj->surface.normal.sorder,
1144
 
                    0.0, 1.0, new_ctrl->normal_t_stride,
1145
 
                    nobj->surface.normal.torder,
1146
 
                    *(new_ctrl->normal_offsets + offset));
1147
 
         }
1148
 
         if (do_texture) {
1149
 
            glMap2f(nobj->surface.texture.type, 0.0, 1.0,
1150
 
                    new_ctrl->texture_s_stride, nobj->surface.texture.sorder,
1151
 
                    0.0, 1.0, new_ctrl->texture_t_stride,
1152
 
                    nobj->surface.texture.torder,
1153
 
                    *(new_ctrl->texture_offsets + offset));
1154
 
         }
1155
 
         nurbs_map_bezier(display_mode, sfactors, tfactors, s_bezier_cnt,
1156
 
                          t_bezier_cnt, i, j);
1157
 
/*                      glMapGrid2f(sfactors[j],0.0,1.0,tfactors[i],0.0,1.0);
1158
 
                        glEvalMesh2(display_mode,0,sfactors[j],0,tfactors[i]);*/
1159
 
      }
1160
 
   }
1161
 
}
1162
 
#endif
1163
 
 
1164
 
 
1165
 
 
1166
 
static void
1167
 
init_new_ctrl(new_ctrl_type * p)
1168
 
{
1169
 
   p->geom_ctrl = p->color_ctrl = p->normal_ctrl = p->texture_ctrl = NULL;
1170
 
   p->geom_offsets = p->color_offsets = p->normal_offsets =
1171
 
      p->texture_offsets = NULL;
1172
 
   p->s_bezier_cnt = p->t_bezier_cnt = 0;
1173
 
}
1174
 
 
1175
 
 
1176
 
static GLenum
1177
 
augment_new_ctrl(GLUnurbsObj * nobj, new_ctrl_type * p)
1178
 
{
1179
 
   GLsizei offset_size;
1180
 
   GLint i, j;
1181
 
 
1182
 
   p->s_bezier_cnt = (p->geom_s_pt_cnt) / (nobj->surface.geom.sorder);
1183
 
   p->t_bezier_cnt = (p->geom_t_pt_cnt) / (nobj->surface.geom.torder);
1184
 
   offset_size = (p->s_bezier_cnt) * (p->t_bezier_cnt);
1185
 
   p->geom_t_stride = nobj->surface.geom.dim;
1186
 
   p->geom_s_stride = (p->geom_t_pt_cnt) * (nobj->surface.geom.dim);
1187
 
   p->color_t_stride = nobj->surface.color.dim;
1188
 
   p->color_s_stride = (p->color_t_pt_cnt) * (nobj->surface.color.dim);
1189
 
   p->normal_t_stride = nobj->surface.normal.dim;
1190
 
   p->normal_s_stride = (p->normal_t_pt_cnt) * (nobj->surface.normal.dim);
1191
 
   p->texture_t_stride = nobj->surface.texture.dim;
1192
 
   p->texture_s_stride = (p->texture_t_pt_cnt) * (nobj->surface.texture.dim);
1193
 
   if (
1194
 
       (p->geom_offsets =
1195
 
        (GLfloat **) malloc(sizeof(GLfloat *) * offset_size)) == NULL) {
1196
 
      call_user_error(nobj, GLU_OUT_OF_MEMORY);
1197
 
      return GLU_ERROR;
1198
 
   }
1199
 
   if (p->color_ctrl)
1200
 
      if (
1201
 
          (p->color_offsets =
1202
 
           (GLfloat **) malloc(sizeof(GLfloat *) * offset_size)) == NULL) {
1203
 
         free_new_ctrl(p);
1204
 
         call_user_error(nobj, GLU_OUT_OF_MEMORY);
1205
 
         return GLU_ERROR;
1206
 
      }
1207
 
   if (p->normal_ctrl)
1208
 
      if (
1209
 
          (p->normal_offsets =
1210
 
           (GLfloat **) malloc(sizeof(GLfloat *) * offset_size)) == NULL) {
1211
 
         free_new_ctrl(p);
1212
 
         call_user_error(nobj, GLU_OUT_OF_MEMORY);
1213
 
         return GLU_ERROR;
1214
 
      }
1215
 
   if (p->texture_ctrl)
1216
 
      if (
1217
 
          (p->texture_offsets =
1218
 
           (GLfloat **) malloc(sizeof(GLfloat *) * offset_size)) == NULL) {
1219
 
         free_new_ctrl(p);
1220
 
         call_user_error(nobj, GLU_OUT_OF_MEMORY);
1221
 
         return GLU_ERROR;
1222
 
      }
1223
 
   for (i = 0; i < p->s_bezier_cnt; i++)
1224
 
      for (j = 0; j < p->t_bezier_cnt; j++)
1225
 
         *(p->geom_offsets + i * (p->t_bezier_cnt) + j) =
1226
 
            p->geom_ctrl + i * (nobj->surface.geom.sorder) *
1227
 
            (nobj->surface.geom.dim) * (p->geom_t_pt_cnt) +
1228
 
            j * (nobj->surface.geom.dim) * (nobj->surface.geom.torder);
1229
 
   if (p->color_ctrl)
1230
 
      for (i = 0; i < p->s_bezier_cnt; i++)
1231
 
         for (j = 0; j < p->t_bezier_cnt; j++)
1232
 
            *(p->color_offsets + i * (p->t_bezier_cnt) + j) =
1233
 
               p->color_ctrl + i * (nobj->surface.color.sorder) *
1234
 
               (nobj->surface.color.dim) * (p->color_t_pt_cnt) +
1235
 
               j * (nobj->surface.color.dim) * (nobj->surface.color.torder);
1236
 
   if (p->normal_ctrl)
1237
 
      for (i = 0; i < p->s_bezier_cnt; i++)
1238
 
         for (j = 0; j < p->t_bezier_cnt; j++)
1239
 
            *(p->normal_offsets + i * (p->t_bezier_cnt) + j) =
1240
 
               p->normal_ctrl + i * (nobj->surface.normal.sorder) *
1241
 
               (nobj->surface.normal.dim) * (p->normal_t_pt_cnt) +
1242
 
               j * (nobj->surface.normal.dim) * (nobj->surface.normal.torder);
1243
 
   if (p->texture_ctrl)
1244
 
      for (i = 0; i < p->s_bezier_cnt; i++)
1245
 
         for (j = 0; j < p->t_bezier_cnt; j++)
1246
 
            *(p->texture_offsets + i * (p->t_bezier_cnt) + j) =
1247
 
               p->texture_ctrl + i * (nobj->surface.texture.sorder) *
1248
 
               (nobj->surface.texture.dim) * (p->texture_t_pt_cnt) +
1249
 
               j * (nobj->surface.texture.dim) *
1250
 
               (nobj->surface.texture.torder);
1251
 
   return GLU_NO_ERROR;
1252
 
}
1253
 
 
1254
 
/* main NURBS surface procedure */
1255
 
void
1256
 
do_nurbs_surface(GLUnurbsObj * nobj)
1257
 
{
1258
 
   GLint *sfactors, *tfactors;
1259
 
   new_ctrl_type new_ctrl;
1260
 
 
1261
 
   /* test user supplied data */
1262
 
   if (test_nurbs_surfaces(nobj) != GLU_NO_ERROR)
1263
 
      return;
1264
 
 
1265
 
   init_new_ctrl(&new_ctrl);
1266
 
 
1267
 
   if (convert_surfs(nobj, &new_ctrl) != GLU_NO_ERROR)
1268
 
      return;
1269
 
   if (augment_new_ctrl(nobj, &new_ctrl) != GLU_NO_ERROR)
1270
 
      return;
1271
 
   switch (nobj->sampling_method) {
1272
 
   case GLU_PATH_LENGTH:
1273
 
      if (glu_do_sampling_3D(nobj, &new_ctrl, &sfactors, &tfactors) !=
1274
 
          GLU_NO_ERROR) {
1275
 
         free_new_ctrl(&new_ctrl);
1276
 
         return;
1277
 
      }
1278
 
      break;
1279
 
   case GLU_DOMAIN_DISTANCE:
1280
 
      if (glu_do_sampling_uv(nobj, &new_ctrl, &sfactors, &tfactors) !=
1281
 
          GLU_NO_ERROR) {
1282
 
         free_new_ctrl(&new_ctrl);
1283
 
         return;
1284
 
      }
1285
 
      break;
1286
 
   case GLU_PARAMETRIC_ERROR:
1287
 
      if (glu_do_sampling_param_3D(nobj, &new_ctrl, &sfactors, &tfactors) !=
1288
 
          GLU_NO_ERROR) {
1289
 
         free_new_ctrl(&new_ctrl);
1290
 
         return;
1291
 
      }
1292
 
      break;
1293
 
   default:
1294
 
      abort();
1295
 
   }
1296
 
   glFrontFace(GL_CW);
1297
 
   switch (nobj->display_mode) {
1298
 
   case GLU_FILL:
1299
 
/*                      if(polygon_trimming(nobj,&new_ctrl,sfactors,tfactors)==GLU_NO_ERROR)*/
1300
 
      draw_polygon_mode(GL_FILL, nobj, &new_ctrl, sfactors, tfactors);
1301
 
      break;
1302
 
   case GLU_OUTLINE_POLYGON:
1303
 
      /* TODO - missing trimming handeling */
1304
 
/* just for now - no OUTLINE_PATCH mode 
1305
 
                        draw_patch_mode(GL_LINE,nobj,&new_ctrl,sfactors,tfactors);
1306
 
                        break; */
1307
 
   case GLU_OUTLINE_PATCH:
1308
 
/*                      if(polygon_trimming(nobj,&new_ctrl,sfactors,tfactors)==GLU_NO_ERROR)*/
1309
 
      draw_polygon_mode(GL_LINE, nobj, &new_ctrl, sfactors, tfactors);
1310
 
      break;
1311
 
   default:
1312
 
      abort();                  /* TODO: is this OK? */
1313
 
   }
1314
 
   free(sfactors);
1315
 
   free(tfactors);
1316
 
   free_new_ctrl(&new_ctrl);
1317
 
}