source: trunk/src/opengl/glu/nurbs/interface/bezierPatchMesh.cpp

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

* empty log message *

File size: 17.3 KB
Line 
1/* $Id: bezierPatchMesh.cpp,v 1.1 2000-02-09 08:49:00 jeroen Exp $ */
2/*
3** License Applicability. Except to the extent portions of this file are
4** made subject to an alternative license as permitted in the SGI Free
5** Software License B, Version 1.0 (the "License"), the contents of this
6** file are subject only to the provisions of the License. You may not use
7** this file except in compliance with the License. You may obtain a copy
8** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
9** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
10**
11** http://oss.sgi.com/projects/FreeB
12**
13** Note that, as provided in the License, the Software is distributed on an
14** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
15** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
16** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
17** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
18**
19** Original Code. The Original Code is: OpenGL Sample Implementation,
20** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
21** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
22** Copyright in any portions created by third parties is as indicated
23** elsewhere herein. All Rights Reserved.
24**
25** Additional Notice Provisions: The application programming interfaces
26** established by SGI in conjunction with the Original Code are The
27** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
28** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
29** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
30** Window System(R) (Version 1.3), released October 19, 1998. This software
31** was created using the OpenGL(R) version 1.2.1 Sample Implementation
32** published by SGI, but has not been independently verified as being
33** compliant with the OpenGL(R) version 1.2.1 Specification.
34**
35** $Date: 2000-02-09 08:49:00 $ $Revision: 1.1 $
36*/
37/*
38** $Header: /home/ktk/tmp/odin/2007/netlabs.cvs/odin32/src/opengl/glu/nurbs/interface/bezierPatchMesh.cpp,v 1.1 2000-02-09 08:49:00 jeroen Exp $
39*/
40
41#include "gluos.h"
42#include <stdlib.h>
43#include <stdio.h>
44#include <assert.h>
45#include "gl.h"
46#include "bezierEval.h"
47#include "bezierPatchMesh.h"
48
49static int isDegenerate(float A[2], float B[2], float C[2]);
50
51void drawStrips(float *vertex_array, float *normal_array, int *length_array, GLenum *type_array, int num_strips)
52{
53 int i,j,k;
54 k=0;
55 /*k is the index of the first component of the current vertex*/
56 for(i=0; i<num_strips; i++)
57 {
58 glBegin(type_array[i]);
59 for(j=0; j<length_array[i]; j++)
60 {
61 glNormal3fv(normal_array+k);
62 glVertex3fv(vertex_array+k);
63 k += 3;
64 }
65 glEnd();
66 }
67}
68
69void bezierPatchMeshListDelDeg(bezierPatchMesh* list)
70{
71 bezierPatchMesh* temp;
72 for(temp=list; temp != NULL; temp = temp->next)
73 {
74 bezierPatchMeshDelDeg(temp);
75 }
76}
77
78void bezierPatchMeshListDelete(bezierPatchMesh *list)
79{
80 if(list == NULL) return;
81 bezierPatchMeshListDelete(list->next);
82 bezierPatchMeshDelete(list);
83}
84
85
86
87
88bezierPatchMesh* bezierPatchMeshListReverse(bezierPatchMesh* list)
89{
90 bezierPatchMesh* ret=NULL;
91 bezierPatchMesh* temp;
92 bezierPatchMesh* nextone;
93 for(temp = list; temp != NULL; temp = nextone)
94 {
95 nextone = temp->next;
96 ret=bezierPatchMeshListInsert(ret, temp);
97 }
98 return ret;
99}
100
101/*maptype is either GL_MAP2_VERTEX_3 or GL_MAP2_VERTEX_4
102 */
103bezierPatchMesh *bezierPatchMeshMake(int maptype, float umin, float umax, int ustride, int uorder, float vmin, float vmax, int vstride, int vorder, float *ctlpoints, int size_UVarray, int size_length_array)
104{
105 int i,j,k;
106 int dimension;
107 int the_ustride;
108 int the_vstride;
109
110 bezierPatchMesh *ret = (bezierPatchMesh*) malloc(sizeof(bezierPatchMesh));
111 assert(ret);
112
113 ret->bpatch = NULL;
114 ret->bpatch_normal = NULL;
115 ret->bpatch_color = NULL;
116 ret->bpatch_texcoord = NULL;
117
118 if(maptype == GL_MAP2_VERTEX_3) dimension = 3;
119 else if (maptype==GL_MAP2_VERTEX_4) dimension = 4;
120 else {
121 fprintf(stderr, "error in inMap2f, maptype=%i is wrong, maptype,map is invalid\n");
122 return NULL;
123 }
124
125 ret->bpatch = bezierPatchMake(umin, vmin, umax, vmax, uorder, vorder, dimension);
126 /*copy the control points there*/
127 the_ustride = vorder * dimension;
128 the_vstride = dimension;
129 for(i=0; i<uorder; i++)
130 for(j=0; j<vorder; j++)
131 for(k=0; k<dimension; k++)
132 ret->bpatch->ctlpoints[i * the_ustride + j*the_vstride+k] = ctlpoints[i*ustride+j*vstride+k];
133
134
135 ret->size_UVarray = size_UVarray;
136 ret->size_length_array = size_length_array;
137 ret->UVarray = (float*) malloc(sizeof(float) * size_UVarray);
138 assert(ret->UVarray);
139 ret->length_array = (int *)malloc(sizeof(int) * size_length_array);
140 assert(ret->length_array);
141 ret->type_array = (GLenum *)malloc(sizeof(GLenum) * size_length_array);
142 assert(ret->type_array);
143
144 ret->index_UVarray = 0;
145 ret->index_length_array = 0;
146
147 ret->vertex_array = NULL;
148 ret->normal_array = NULL;
149 ret->color_array = NULL;
150 ret->texcoord_array = NULL;
151
152 ret->next = NULL;
153 return ret;
154}
155
156bezierPatchMesh *bezierPatchMeshMake2(int size_UVarray, int size_length_array)
157{
158 bezierPatchMesh *ret = (bezierPatchMesh*) malloc(sizeof(bezierPatchMesh));
159 assert(ret);
160
161 ret->bpatch = NULL;
162 ret->bpatch_normal = NULL;
163 ret->bpatch_color = NULL;
164 ret->bpatch_texcoord = NULL;
165
166 ret->size_UVarray = size_UVarray;
167 ret->size_length_array = size_length_array;
168 ret->UVarray = (float*) malloc(sizeof(float) * size_UVarray);
169 assert(ret->UVarray);
170 ret->length_array = (int *)malloc(sizeof(int) * size_length_array);
171 assert(ret->length_array);
172 ret->type_array = (GLenum *)malloc(sizeof(GLenum) * size_length_array);
173 assert(ret->type_array);
174
175 ret->index_UVarray = 0;
176 ret->index_length_array = 0;
177
178 ret->vertex_array = NULL;
179 ret->normal_array = NULL;
180 ret->color_array = NULL;
181 ret->texcoord_array = NULL;
182
183 ret->next = NULL;
184 return ret;
185}
186
187void bezierPatchMeshPutPatch(bezierPatchMesh *bpm, int maptype, float umin, float umax, int ustride, int uorder, float vmin, float vmax, int vstride, int vorder, float *ctlpoints)
188{
189 switch(maptype){
190 case GL_MAP2_VERTEX_3:
191 bpm->bpatch = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 3, ustride, vstride, ctlpoints);
192 break;
193 case GL_MAP2_VERTEX_4:
194 bpm->bpatch = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 4,ustride, vstride, ctlpoints );
195 break;
196 case GL_MAP2_NORMAL:
197 bpm->bpatch_normal = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 3, ustride, vstride, ctlpoints);
198 break;
199 case GL_MAP2_INDEX:
200 bpm->bpatch_color = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 1, ustride, vstride, ctlpoints);
201 break;
202 case GL_MAP2_COLOR_4:
203 bpm->bpatch_color = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 4, ustride, vstride, ctlpoints);
204 break;
205 case GL_MAP2_TEXTURE_COORD_1:
206 bpm->bpatch_texcoord = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 1, ustride, vstride, ctlpoints);
207 break;
208 case GL_MAP2_TEXTURE_COORD_2:
209 bpm->bpatch_texcoord = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 2, ustride, vstride, ctlpoints);
210 break;
211 case GL_MAP2_TEXTURE_COORD_3:
212 bpm->bpatch_texcoord = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 3, ustride, vstride, ctlpoints);
213 break;
214 case GL_MAP2_TEXTURE_COORD_4:
215 bpm->bpatch_texcoord = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 4, ustride, vstride, ctlpoints);
216 break;
217 default:
218 fprintf(stderr, "error in bezierPatchMeshPutPatch, maptype=%i is wrong, maptype,map is invalid\n");
219 }
220}
221
222
223/*delete everything including the arrays. So if you want to output the
224 *pointers of the arrays, you should not use this function to deallocate space.
225 *you should dealocate manually
226 */
227void bezierPatchMeshDelete(bezierPatchMesh *bpm)
228{
229 if(bpm->bpatch != NULL)
230 bezierPatchDelete(bpm->bpatch);
231 if(bpm->bpatch_normal != NULL)
232 bezierPatchDelete(bpm->bpatch_normal);
233 if(bpm->bpatch_color != NULL)
234 bezierPatchDelete(bpm->bpatch_color);
235 if(bpm->bpatch_texcoord != NULL)
236 bezierPatchDelete(bpm->bpatch_texcoord);
237
238 free(bpm->UVarray);
239 free(bpm->length_array);
240 free(bpm->vertex_array);
241 free(bpm->normal_array);
242 free(bpm->type_array);
243 free(bpm);
244}
245
246/*begin a strip
247 *type is the primitive type:
248 */
249void bezierPatchMeshBeginStrip(bezierPatchMesh *bpm, GLenum type)
250{
251 bpm->counter = 0;
252 bpm->type = type;
253}
254
255/*signal the end of the current strip*/
256void bezierPatchMeshEndStrip(bezierPatchMesh *bpm)
257{
258 int i;
259
260 /*if there are no vertices in this strip, then nothing needs to be done*/
261 if(bpm->counter == 0) return;
262
263 /*if the length_array is full, it should be expanded*/
264 if(bpm->index_length_array >= bpm->size_length_array)
265 {
266 int *temp = (int*) malloc(sizeof(int) * (bpm->size_length_array*2 + 1));
267 assert(temp);
268 GLenum *temp_type = (GLenum*) malloc(sizeof(GLenum) * (bpm->size_length_array*2 + 1));
269 assert(temp_type);
270 /*update the size*/
271 bpm->size_length_array = bpm->size_length_array*2 + 1;
272
273 /*copy*/
274 for(i=0; i<bpm->index_length_array; i++)
275 {
276 temp[i] = bpm->length_array[i];
277 temp_type[i] = bpm->type_array[i];
278 }
279
280 /*deallocate old array*/
281 free(bpm->length_array);
282 free(bpm->type_array);
283
284 /*point to the new array which is twice as bigger*/
285 bpm->length_array = temp;
286 bpm->type_array = temp_type;
287 }
288 bpm->type_array[bpm->index_length_array] = bpm->type;
289 bpm->length_array[bpm->index_length_array++] = bpm->counter;
290
291}
292
293/*insert (u,v) */
294void bezierPatchMeshInsertUV(bezierPatchMesh *bpm, float u, float v)
295{
296 int i;
297 /*if the UVarray is full, it should be expanded*/
298 if(bpm->index_UVarray+1 >= bpm->size_UVarray)
299 {
300 float *temp = (float*) malloc(sizeof(float) * (bpm->size_UVarray * 2 + 2));
301 assert(temp);
302
303 /*update the size*/
304 bpm->size_UVarray = bpm->size_UVarray*2 + 2;
305
306 /*copy*/
307 for(i=0; i<bpm->index_UVarray; i++)
308 {
309 temp[i] = bpm->UVarray[i];
310 }
311
312 /*deallocate old array*/
313 free(bpm->UVarray);
314
315 /*pointing to the new arrays*/
316 bpm->UVarray = temp;
317 }
318 /*insert the new UV*/
319 bpm->UVarray[bpm->index_UVarray] = u;
320 bpm->index_UVarray++;
321 bpm->UVarray[bpm->index_UVarray] = v;
322 bpm->index_UVarray++;
323
324 /*update counter: one more vertex*/
325 bpm->counter++;
326
327
328}
329
330void bezierPatchMeshPrint(bezierPatchMesh *bpm)
331{
332 int i;
333 printf("the bezier patch is\n");
334 bezierPatchPrint(bpm->bpatch);
335 printf("index_length_array= %i\n", bpm->index_length_array);
336 printf("size_length_array =%i\n", bpm->size_length_array);
337 printf("index_UVarray =%i\n", bpm->index_UVarray);
338 printf("size_UVarray =%i\n", bpm->size_UVarray);
339 printf("UVarray is\n");
340 for(i=0; i<bpm->index_UVarray; i++)
341 printf("%f ", bpm->UVarray[i]);
342
343 printf("length_array is\n");
344 for(i=0; i<bpm->index_length_array; i++)
345 printf("%i ", bpm->length_array[i]);
346 printf("\n");
347
348}
349
350/*insert a new patch in front of the current linked list and return the new list*/
351bezierPatchMesh* bezierPatchMeshListInsert(bezierPatchMesh* list, bezierPatchMesh* bpm)
352{
353 bpm->next=list;
354 return bpm;
355}
356
357/*print all the patches*/
358void bezierPatchMeshListPrint(bezierPatchMesh* list)
359{
360 bezierPatchMesh *temp;
361 for(temp = list; temp != NULL; temp = temp->next)
362 {
363 bezierPatchMeshPrint(temp);
364 }
365}
366
367int bezierPatchMeshListTotalStrips(bezierPatchMesh* list)
368{
369 int sum=0;
370 bezierPatchMesh *temp;
371 for(temp=list; temp != NULL; temp = temp->next)
372 {
373 sum += temp->index_length_array;
374 }
375 return sum;
376}
377
378int bezierPatchMeshListTotalVert(bezierPatchMesh* list)
379{
380 int sum=0;
381 bezierPatchMesh *temp;
382 for(temp=list; temp != NULL; temp = temp->next)
383 {
384 sum += temp->index_UVarray;
385 }
386 return sum/2;
387}
388
389int bezierPatchMeshListNumTriangles(bezierPatchMesh* list)
390{
391 int sum=0;
392 bezierPatchMesh* temp;
393 for(temp=list; temp != NULL; temp = temp->next)
394 {
395 sum += bezierPatchMeshNumTriangles(temp);
396 }
397 return sum;
398}
399
400int bezierPatchMeshNumTriangles(bezierPatchMesh* bpm)
401{
402 int i;
403 int sum=0;
404 for(i=0; i<bpm->index_length_array; i++)
405 {
406 switch(bpm->type_array[i])
407 {
408 case GL_TRIANGLES:
409 sum += bpm->length_array[i]/3;
410 break;
411 case GL_TRIANGLE_FAN:
412 if(bpm->length_array[i] > 2)
413 sum += bpm->length_array[i]-2;
414 break;
415 case GL_TRIANGLE_STRIP:
416 if(bpm->length_array[i] > 2)
417 sum += bpm->length_array[i]-2;
418 break;
419 case GL_QUAD_STRIP:
420 if(bpm->length_array[i]>2)
421 sum += (bpm->length_array[i]-2);
422 break;
423 default:
424 fprintf(stderr,"error in bezierPatchMeshListNumTriangles, type invalid\n");
425 }
426 }
427 return sum;
428}
429
430/*delete degenerate triangles*/
431void bezierPatchMeshDelDeg(bezierPatchMesh* bpm)
432{
433 if(bpm == NULL) return;
434 int i,j,k;
435 int *new_length_array;
436 GLenum *new_type_array;
437 int index_new_length_array;
438 float *new_UVarray;
439 int index_new_UVarray;
440
441 new_length_array = (int*)malloc(sizeof(int) * bpm->index_length_array);
442 assert(new_length_array);
443 new_type_array = (GLenum*)malloc(sizeof(GLenum) * bpm->index_length_array);
444 assert(new_length_array);
445 new_UVarray = (float*) malloc(sizeof(float) * bpm->index_UVarray);
446 assert(new_UVarray);
447
448 index_new_length_array = 0;
449 index_new_UVarray=0;
450 k=0;
451 for(i=0; i<bpm->index_length_array; i++){
452
453 /*(if not degenerate, we have to copy*/
454 if( (bpm->length_array[i] != 3) || (!isDegenerate(bpm->UVarray+k, bpm->UVarray+k+2, bpm->UVarray+k+4)))
455 {
456 for(j=0; j<2* bpm->length_array[i]; j++)
457 new_UVarray[index_new_UVarray++] = bpm->UVarray[k++];
458
459 new_length_array[index_new_length_array] = bpm->length_array[i];
460 new_type_array[index_new_length_array] = bpm->type_array[i];
461 index_new_length_array++;
462 }
463 else
464 {
465 k += 6;
466 }
467 }
468 free(bpm->UVarray);
469 free(bpm->length_array);
470 free(bpm->type_array);
471 bpm->UVarray=new_UVarray;
472 bpm->length_array=new_length_array;
473 bpm->type_array=new_type_array;
474 bpm->index_UVarray = index_new_UVarray;
475 bpm->index_length_array = index_new_length_array;
476
477}
478
479/*(u,v) to XYZ
480 *the xyz and normals are stored in vertex_array,
481 *and normal_array. the spaces of both are allocated here
482 */
483void bezierPatchMeshEval(bezierPatchMesh* bpm)
484{
485 int i,j,k,l;
486 float u,v;
487 float u0 = bpm->bpatch->umin;
488 float u1 = bpm->bpatch->umax;
489 int uorder = bpm->bpatch->uorder;
490 float v0 = bpm->bpatch->vmin;
491 float v1 = bpm->bpatch->vmax;
492 int vorder = bpm->bpatch->vorder;
493 int dimension = bpm->bpatch->dimension;
494 int ustride = dimension * vorder;
495 int vstride = dimension;
496 float *ctlpoints = bpm->bpatch->ctlpoints;
497
498 bpm->vertex_array = (float*) malloc(sizeof(float)* (bpm->index_UVarray/2) * 3);
499 assert(bpm->vertex_array);
500 bpm->normal_array = (float*) malloc(sizeof(float)* (bpm->index_UVarray/2) * 3);
501 assert(bpm->normal_array);
502
503 k=0;
504 l=0;
505 for(i=0; i<bpm->index_length_array; i++)
506 {
507 for(j=0; j<bpm->length_array[i]; j++)
508 {
509 u = bpm->UVarray[k];
510 v = bpm->UVarray[k+1];
511 bezierSurfEval(u0,u1,uorder, v0, v1, vorder, dimension, ctlpoints, ustride, vstride, u,v, bpm->vertex_array+l);
512 bezierSurfEvalNormal(u0,u1,uorder, v0, v1, vorder, dimension, ctlpoints, ustride, vstride, u,v, bpm->normal_array+l);
513 k += 2;
514 l += 3;
515 }
516 }
517}
518
519void bezierPatchMeshListEval(bezierPatchMesh* list)
520{
521 bezierPatchMesh* temp;
522 for(temp = list; temp != NULL; temp = temp->next)
523 {
524 bezierPatchMeshEval(temp);
525 }
526}
527
528void bezierPatchMeshDraw(bezierPatchMesh* bpm)
529{
530 int i,j,k;
531 k=0;
532 /*k is the index of the first component of the current vertex*/
533 for(i=0; i<bpm->index_length_array; i++)
534 {
535 glBegin(bpm->type_array[i]);
536 for(j=0; j<bpm->length_array[i]; j++)
537 {
538 glNormal3fv(bpm->normal_array+k);
539 glVertex3fv(bpm->vertex_array+k);
540 k+= 3;
541 }
542 glEnd();
543 }
544}
545
546void bezierPatchMeshListDraw(bezierPatchMesh* list)
547{
548 bezierPatchMesh* temp;
549 for(temp = list; temp != NULL; temp = temp->next)
550 {
551 bezierPatchMeshDraw(temp);
552 }
553}
554
555void bezierPatchMeshListCollect(bezierPatchMesh* list, float **vertex_array, float **normal_array, int **length_array, GLenum **type_array, int *num_strips)
556{
557 int i,j,k,l;
558 bezierPatchMesh *temp;
559 int total_num_vertices = bezierPatchMeshListTotalVert(list);
560 (*vertex_array) = (float *) malloc(sizeof(float) * total_num_vertices*3);
561 assert(*vertex_array);
562 (*normal_array) = (float *) malloc(sizeof(float) * total_num_vertices*3);
563 assert(*normal_array);
564
565 *num_strips = bezierPatchMeshListTotalStrips(list);
566
567 *length_array = (int*) malloc(sizeof(int) * (*num_strips));
568 assert(*length_array);
569
570 *type_array = (GLenum*) malloc(sizeof(GLenum) * (*num_strips));
571 assert(*type_array);
572
573 k=0;
574 l=0;
575 for(temp = list; temp != NULL; temp = temp->next)
576 {
577 int x=0;
578 for(i=0; i<temp->index_length_array; i++)
579 {
580 for(j=0; j<temp->length_array[i]; j++)
581 {
582 (*vertex_array)[k] = temp->vertex_array[x];
583 (*vertex_array)[k+1] = temp->vertex_array[x+1];
584 (*vertex_array)[k+2] = temp->vertex_array[x+2];
585
586 (*normal_array)[k] = temp->normal_array[x];
587 (*normal_array)[k+1] = temp->normal_array[x+1];
588 (*normal_array)[k+2] = temp->normal_array[x+2];
589
590 x += 3;
591 k += 3;
592 }
593 (*type_array)[l] = temp->type_array[i];
594 (*length_array)[l++] = temp->length_array[i];
595 }
596 }
597}
598
599
600
601static int isDegenerate(float A[2], float B[2], float C[2])
602{
603 if( (A[0] == B[0] && A[1]==B[1]) ||
604 (A[0] == C[0] && A[1]==C[1]) ||
605 (B[0] == C[0] && B[1]==C[1])
606 )
607 return 1;
608 else
609 return 0;
610}
611
612
613
614
Note: See TracBrowser for help on using the repository browser.