| 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 |
|
|---|
| 49 | static int isDegenerate(float A[2], float B[2], float C[2]);
|
|---|
| 50 |
|
|---|
| 51 | void 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 |
|
|---|
| 69 | void bezierPatchMeshListDelDeg(bezierPatchMesh* list)
|
|---|
| 70 | {
|
|---|
| 71 | bezierPatchMesh* temp;
|
|---|
| 72 | for(temp=list; temp != NULL; temp = temp->next)
|
|---|
| 73 | {
|
|---|
| 74 | bezierPatchMeshDelDeg(temp);
|
|---|
| 75 | }
|
|---|
| 76 | }
|
|---|
| 77 |
|
|---|
| 78 | void bezierPatchMeshListDelete(bezierPatchMesh *list)
|
|---|
| 79 | {
|
|---|
| 80 | if(list == NULL) return;
|
|---|
| 81 | bezierPatchMeshListDelete(list->next);
|
|---|
| 82 | bezierPatchMeshDelete(list);
|
|---|
| 83 | }
|
|---|
| 84 |
|
|---|
| 85 |
|
|---|
| 86 |
|
|---|
| 87 |
|
|---|
| 88 | bezierPatchMesh* 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 | */
|
|---|
| 103 | bezierPatchMesh *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 |
|
|---|
| 156 | bezierPatchMesh *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 |
|
|---|
| 187 | void 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 | */
|
|---|
| 227 | void 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 | */
|
|---|
| 249 | void bezierPatchMeshBeginStrip(bezierPatchMesh *bpm, GLenum type)
|
|---|
| 250 | {
|
|---|
| 251 | bpm->counter = 0;
|
|---|
| 252 | bpm->type = type;
|
|---|
| 253 | }
|
|---|
| 254 |
|
|---|
| 255 | /*signal the end of the current strip*/
|
|---|
| 256 | void 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) */
|
|---|
| 294 | void 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 |
|
|---|
| 330 | void 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*/
|
|---|
| 351 | bezierPatchMesh* bezierPatchMeshListInsert(bezierPatchMesh* list, bezierPatchMesh* bpm)
|
|---|
| 352 | {
|
|---|
| 353 | bpm->next=list;
|
|---|
| 354 | return bpm;
|
|---|
| 355 | }
|
|---|
| 356 |
|
|---|
| 357 | /*print all the patches*/
|
|---|
| 358 | void bezierPatchMeshListPrint(bezierPatchMesh* list)
|
|---|
| 359 | {
|
|---|
| 360 | bezierPatchMesh *temp;
|
|---|
| 361 | for(temp = list; temp != NULL; temp = temp->next)
|
|---|
| 362 | {
|
|---|
| 363 | bezierPatchMeshPrint(temp);
|
|---|
| 364 | }
|
|---|
| 365 | }
|
|---|
| 366 |
|
|---|
| 367 | int 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 |
|
|---|
| 378 | int 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 |
|
|---|
| 389 | int 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 |
|
|---|
| 400 | int 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*/
|
|---|
| 431 | void 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 | */
|
|---|
| 483 | void 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 |
|
|---|
| 519 | void bezierPatchMeshListEval(bezierPatchMesh* list)
|
|---|
| 520 | {
|
|---|
| 521 | bezierPatchMesh* temp;
|
|---|
| 522 | for(temp = list; temp != NULL; temp = temp->next)
|
|---|
| 523 | {
|
|---|
| 524 | bezierPatchMeshEval(temp);
|
|---|
| 525 | }
|
|---|
| 526 | }
|
|---|
| 527 |
|
|---|
| 528 | void 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 |
|
|---|
| 546 | void bezierPatchMeshListDraw(bezierPatchMesh* list)
|
|---|
| 547 | {
|
|---|
| 548 | bezierPatchMesh* temp;
|
|---|
| 549 | for(temp = list; temp != NULL; temp = temp->next)
|
|---|
| 550 | {
|
|---|
| 551 | bezierPatchMeshDraw(temp);
|
|---|
| 552 | }
|
|---|
| 553 | }
|
|---|
| 554 |
|
|---|
| 555 | void 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 |
|
|---|
| 601 | static 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 |
|
|---|