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