From f88602394d7cc340cc850622308ce1cbbff332a5 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 11 Jul 2000 14:11:04 +0000 Subject: reverted to old tessellator (GLU 1.1) --- src/glu/mesa/nurbsutl.c | 2215 +++++++++++++++++++++++------------------------ 1 file changed, 1061 insertions(+), 1154 deletions(-) (limited to 'src/glu/mesa/nurbsutl.c') diff --git a/src/glu/mesa/nurbsutl.c b/src/glu/mesa/nurbsutl.c index f0f166cb64..b28825858e 100644 --- a/src/glu/mesa/nurbsutl.c +++ b/src/glu/mesa/nurbsutl.c @@ -1,9 +1,9 @@ -/* $Id: nurbsutl.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */ +/* $Id: nurbsutl.c,v 1.2 2000/07/11 14:11:04 brianp Exp $ */ /* * Mesa 3-D graphics library - * Version: 2.4 - * Copyright (C) 1995-1997 Brian Paul + * Version: 3.3 + * Copyright (C) 1995-2000 Brian Paul * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -21,38 +21,6 @@ */ -/* - * $Log: nurbsutl.c,v $ - * Revision 1.1 1999/08/19 00:55:42 jtg - * Initial revision - * - * Revision 1.8 1999/06/08 00:44:51 brianp - * OpenStep updates (pete@ohm.york.ac.uk) - * - * Revision 1.7 1998/07/26 02:07:59 brianp - * updated for Windows compilation per Ted Jump - * - * Revision 1.6 1997/10/29 02:02:20 brianp - * various MS Windows compiler changes (David Bucciarelli, v20 3dfx driver) - * - * Revision 1.5 1997/07/24 01:28:44 brianp - * changed precompiled header symbol from PCH to PC_HEADER - * - * Revision 1.4 1997/05/28 02:29:38 brianp - * added support for precompiled headers (PCH), inserted APIENTRY keyword - * - * Revision 1.3 1997/05/27 03:19:54 brianp - * minor clean-up - * - * Revision 1.2 1997/05/27 03:00:16 brianp - * incorporated Bogdan's new NURBS code - * - * Revision 1.1 1996/09/27 01:19:39 brianp - * Initial revision - * - */ - - /* * NURBS implementation written by Bogdan Sikorski (bogdan@cira.it) * See README2 for more info. @@ -69,562 +37,516 @@ #endif -GLenum -test_knot(GLint nknots, GLfloat *knot, GLint order) +GLenum test_knot(GLint nknots, GLfloat * knot, GLint order) { - GLsizei i; - GLint knot_mult; - GLfloat tmp_knot; - - tmp_knot=knot[0]; - knot_mult=1; - for(i=1;i EPSILON) - { - if(knot_mult>order) - return GLU_NURBS_ERROR5; - knot_mult=1; - tmp_knot=knot[i]; - } - else - ++knot_mult; - } - return GLU_NO_ERROR; + GLsizei i; + GLint knot_mult; + GLfloat tmp_knot; + + tmp_knot = knot[0]; + knot_mult = 1; + for (i = 1; i < nknots; i++) { + if (knot[i] < tmp_knot) + return GLU_NURBS_ERROR4; + if (fabs(tmp_knot - knot[i]) > EPSILON) { + if (knot_mult > order) + return GLU_NURBS_ERROR5; + knot_mult = 1; + tmp_knot = knot[i]; + } + else + ++knot_mult; + } + return GLU_NO_ERROR; } static int /* qsort function */ #if defined(WIN32) && !defined(OPENSTEP) -__cdecl + __cdecl #endif knot_sort(const void *a, const void *b) { - GLfloat x,y; - - x=*((GLfloat *)a); - y=*((GLfloat *)b); - if(fabs(x-y) < EPSILON) - return 0; - if(x > y) - return 1; - return -1; + GLfloat x, y; + + x = *((GLfloat *) a); + y = *((GLfloat *) b); + if (fabs(x - y) < EPSILON) + return 0; + if (x > y) + return 1; + return -1; } /* insert into dest knot all values within the valid range from src knot */ /* that do not appear in dest */ void -collect_unified_knot(knot_str_type *dest, knot_str_type *src, - GLfloat maximal_min_knot, GLfloat minimal_max_knot) +collect_unified_knot(knot_str_type * dest, knot_str_type * src, + GLfloat maximal_min_knot, GLfloat minimal_max_knot) { - GLfloat *src_knot,*dest_knot; - GLint src_t_min,src_t_max,dest_t_min,dest_t_max; - GLint src_nknots,dest_nknots; - GLint i,j,k,new_cnt; - GLboolean not_found_flag; - - src_knot=src->unified_knot; - dest_knot=dest->unified_knot; - src_t_min=src->t_min; - src_t_max=src->t_max; - dest_t_min=dest->t_min; - dest_t_max=dest->t_max; - src_nknots=src->unified_nknots; - dest_nknots=dest->unified_nknots; - - k=new_cnt=dest_nknots; - for(i=src_t_min;i<=src_t_max;i++) - if(src_knot[i] - maximal_min_knot > -EPSILON && - src_knot[i] - minimal_max_knot < EPSILON) - { - not_found_flag=GL_TRUE; - for(j=dest_t_min;j<=dest_t_max;j++) - if(fabs(dest_knot[j]-src_knot[i]) < EPSILON) - { - not_found_flag=GL_FALSE; - break; - } - if(not_found_flag) - { - /* knot from src is not in dest - add this knot to dest */ - dest_knot[k++]=src_knot[i]; - ++new_cnt; - ++(dest->t_max); /* the valid range widens */ - ++(dest->delta_nknots); /* increment the extra knot value counter */ - } - } - dest->unified_nknots=new_cnt; - qsort((void *)dest_knot,(size_t)new_cnt,(size_t)sizeof(GLfloat), - &knot_sort); + GLfloat *src_knot, *dest_knot; + GLint src_t_min, src_t_max, dest_t_min, dest_t_max; + GLint src_nknots, dest_nknots; + GLint i, j, k, new_cnt; + GLboolean not_found_flag; + + src_knot = src->unified_knot; + dest_knot = dest->unified_knot; + src_t_min = src->t_min; + src_t_max = src->t_max; + dest_t_min = dest->t_min; + dest_t_max = dest->t_max; + src_nknots = src->unified_nknots; + dest_nknots = dest->unified_nknots; + + k = new_cnt = dest_nknots; + for (i = src_t_min; i <= src_t_max; i++) + if (src_knot[i] - maximal_min_knot > -EPSILON && + src_knot[i] - minimal_max_knot < EPSILON) { + not_found_flag = GL_TRUE; + for (j = dest_t_min; j <= dest_t_max; j++) + if (fabs(dest_knot[j] - src_knot[i]) < EPSILON) { + not_found_flag = GL_FALSE; + break; + } + if (not_found_flag) { + /* knot from src is not in dest - add this knot to dest */ + dest_knot[k++] = src_knot[i]; + ++new_cnt; + ++(dest->t_max); /* the valid range widens */ + ++(dest->delta_nknots); /* increment the extra knot value counter */ + } + } + dest->unified_nknots = new_cnt; + qsort((void *) dest_knot, (size_t) new_cnt, (size_t) sizeof(GLfloat), + &knot_sort); } /* basing on the new common knot range for all attributes set */ /* t_min and t_max values for each knot - they will be used later on */ /* by explode_knot() and calc_new_ctrl_pts */ static void -set_new_t_min_t_max(knot_str_type *geom_knot, knot_str_type *color_knot, - knot_str_type *normal_knot, knot_str_type *texture_knot, - GLfloat maximal_min_knot, GLfloat minimal_max_knot) +set_new_t_min_t_max(knot_str_type * geom_knot, knot_str_type * color_knot, + knot_str_type * normal_knot, knot_str_type * texture_knot, + GLfloat maximal_min_knot, GLfloat minimal_max_knot) { - GLuint t_min,t_max,cnt; - - if(minimal_max_knot-maximal_min_knot < EPSILON) - { - /* knot common range empty */ - geom_knot->t_min=geom_knot->t_max=0; - color_knot->t_min=color_knot->t_max=0; - normal_knot->t_min=normal_knot->t_max=0; - texture_knot->t_min=texture_knot->t_max=0; - } - else - { - if(geom_knot->unified_knot!=NULL) - { - cnt=geom_knot->unified_nknots; - for(t_min=0;t_minunified_knot)[t_min] - maximal_min_knot) < - EPSILON) - break; - for(t_max=cnt-1;t_max;t_max--) - if(fabs((geom_knot->unified_knot)[t_max] - minimal_max_knot) < - EPSILON) - break; - } - else - if(geom_knot->nknots) - { - cnt=geom_knot->nknots; - for(t_min=0;t_minknot)[t_min] - maximal_min_knot) < EPSILON) - break; - for(t_max=cnt-1;t_max;t_max--) - if(fabs((geom_knot->knot)[t_max] - minimal_max_knot) < EPSILON) - break; - } - geom_knot->t_min=t_min; - geom_knot->t_max=t_max; - if(color_knot->unified_knot!=NULL) - { - cnt=color_knot->unified_nknots; - for(t_min=0;t_minunified_knot)[t_min] - maximal_min_knot) < - EPSILON) - break; - for(t_max=cnt-1;t_max;t_max--) - if(fabs((color_knot->unified_knot)[t_max] - minimal_max_knot) < - EPSILON) - break; - color_knot->t_min=t_min; - color_knot->t_max=t_max; - } - if(normal_knot->unified_knot!=NULL) - { - cnt=normal_knot->unified_nknots; - for(t_min=0;t_minunified_knot)[t_min] - maximal_min_knot) < - EPSILON) - break; - for(t_max=cnt-1;t_max;t_max--) - if(fabs((normal_knot->unified_knot)[t_max] - minimal_max_knot) < - EPSILON) - break; - normal_knot->t_min=t_min; - normal_knot->t_max=t_max; - } - if(texture_knot->unified_knot!=NULL) - { - cnt=texture_knot->unified_nknots; - for(t_min=0;t_minunified_knot)[t_min] - maximal_min_knot) - < EPSILON) - break; - for(t_max=cnt-1;t_max;t_max--) - if(fabs((texture_knot->unified_knot)[t_max] - minimal_max_knot) - < EPSILON) - break; - texture_knot->t_min=t_min; - texture_knot->t_max=t_max; - } - } + GLuint t_min, t_max, cnt; + + if (minimal_max_knot - maximal_min_knot < EPSILON) { + /* knot common range empty */ + geom_knot->t_min = geom_knot->t_max = 0; + color_knot->t_min = color_knot->t_max = 0; + normal_knot->t_min = normal_knot->t_max = 0; + texture_knot->t_min = texture_knot->t_max = 0; + } + else { + if (geom_knot->unified_knot != NULL) { + cnt = geom_knot->unified_nknots; + for (t_min = 0; t_min < cnt; t_min++) + if (fabs((geom_knot->unified_knot)[t_min] - maximal_min_knot) < + EPSILON) break; + for (t_max = cnt - 1; t_max; t_max--) + if (fabs((geom_knot->unified_knot)[t_max] - minimal_max_knot) < + EPSILON) break; + } + else if (geom_knot->nknots) { + cnt = geom_knot->nknots; + for (t_min = 0; t_min < cnt; t_min++) + if (fabs((geom_knot->knot)[t_min] - maximal_min_knot) < EPSILON) + break; + for (t_max = cnt - 1; t_max; t_max--) + if (fabs((geom_knot->knot)[t_max] - minimal_max_knot) < EPSILON) + break; + } + geom_knot->t_min = t_min; + geom_knot->t_max = t_max; + if (color_knot->unified_knot != NULL) { + cnt = color_knot->unified_nknots; + for (t_min = 0; t_min < cnt; t_min++) + if (fabs((color_knot->unified_knot)[t_min] - maximal_min_knot) < + EPSILON) break; + for (t_max = cnt - 1; t_max; t_max--) + if (fabs((color_knot->unified_knot)[t_max] - minimal_max_knot) < + EPSILON) break; + color_knot->t_min = t_min; + color_knot->t_max = t_max; + } + if (normal_knot->unified_knot != NULL) { + cnt = normal_knot->unified_nknots; + for (t_min = 0; t_min < cnt; t_min++) + if (fabs((normal_knot->unified_knot)[t_min] - maximal_min_knot) < + EPSILON) break; + for (t_max = cnt - 1; t_max; t_max--) + if (fabs((normal_knot->unified_knot)[t_max] - minimal_max_knot) < + EPSILON) break; + normal_knot->t_min = t_min; + normal_knot->t_max = t_max; + } + if (texture_knot->unified_knot != NULL) { + cnt = texture_knot->unified_nknots; + for (t_min = 0; t_min < cnt; t_min++) + if (fabs((texture_knot->unified_knot)[t_min] - maximal_min_knot) + < EPSILON) + break; + for (t_max = cnt - 1; t_max; t_max--) + if (fabs((texture_knot->unified_knot)[t_max] - minimal_max_knot) + < EPSILON) + break; + texture_knot->t_min = t_min; + texture_knot->t_max = t_max; + } + } } /* modify all knot valid ranges in such a way that all have the same */ /* range, common to all knots */ /* do this by knot insertion */ GLenum -select_knot_working_range(GLUnurbsObj *nobj,knot_str_type *geom_knot, - knot_str_type *color_knot, knot_str_type *normal_knot, - knot_str_type *texture_knot) +select_knot_working_range(GLUnurbsObj * nobj, knot_str_type * geom_knot, + knot_str_type * color_knot, + knot_str_type * normal_knot, + knot_str_type * texture_knot) { - GLint max_nknots; - GLfloat maximal_min_knot,minimal_max_knot; - GLint i; - - /* find the maximum modified knot length */ - max_nknots=geom_knot->nknots; - if(color_knot->unified_knot) - max_nknots+=color_knot->nknots; - if(normal_knot->unified_knot) - max_nknots+=normal_knot->nknots; - if(texture_knot->unified_knot) - max_nknots+=texture_knot->nknots; - maximal_min_knot=(geom_knot->knot)[geom_knot->t_min]; - minimal_max_knot=(geom_knot->knot)[geom_knot->t_max]; - /* any attirb data ? */ - if(max_nknots!=geom_knot->nknots) - { - /* allocate space for the unified knots */ - if((geom_knot->unified_knot= - (GLfloat *)malloc(sizeof(GLfloat)*max_nknots))==NULL) - { - call_user_error(nobj,GLU_OUT_OF_MEMORY); - return GLU_ERROR; - } - /* copy the original knot to the unified one */ - geom_knot->unified_nknots=geom_knot->nknots; - for(i=0;inknots;i++) - (geom_knot->unified_knot)[i]=(geom_knot->knot)[i]; - if(color_knot->unified_knot) - { - if((color_knot->knot)[color_knot->t_min] - maximal_min_knot > - EPSILON) - maximal_min_knot=(color_knot->knot)[color_knot->t_min]; - if(minimal_max_knot - (color_knot->knot)[color_knot->t_max] > - EPSILON) - minimal_max_knot=(color_knot->knot)[color_knot->t_max]; - if((color_knot->unified_knot= - (GLfloat *)malloc(sizeof(GLfloat)*max_nknots))==NULL) - { - free(geom_knot->unified_knot); - call_user_error(nobj,GLU_OUT_OF_MEMORY); - return GLU_ERROR; - } - /* copy the original knot to the unified one */ - color_knot->unified_nknots=color_knot->nknots; - for(i=0;inknots;i++) - (color_knot->unified_knot)[i]=(color_knot->knot)[i]; - } - if(normal_knot->unified_knot) - { - if((normal_knot->knot)[normal_knot->t_min] - maximal_min_knot > - EPSILON) - maximal_min_knot=(normal_knot->knot)[normal_knot->t_min]; - if(minimal_max_knot - (normal_knot->knot)[normal_knot->t_max] > - EPSILON) - minimal_max_knot=(normal_knot->knot)[normal_knot->t_max]; - if((normal_knot->unified_knot= - (GLfloat *)malloc(sizeof(GLfloat)*max_nknots))==NULL) - { - free(geom_knot->unified_knot); - free(color_knot->unified_knot); - call_user_error(nobj,GLU_OUT_OF_MEMORY); - return GLU_ERROR; - } - /* copy the original knot to the unified one */ - normal_knot->unified_nknots=normal_knot->nknots; - for(i=0;inknots;i++) - (normal_knot->unified_knot)[i]=(normal_knot->knot)[i]; - } - if(texture_knot->unified_knot) - { - if((texture_knot->knot)[texture_knot->t_min] - maximal_min_knot > - EPSILON) - maximal_min_knot=(texture_knot->knot)[texture_knot->t_min]; - if(minimal_max_knot - (texture_knot->knot)[texture_knot->t_max] > - EPSILON) - minimal_max_knot=(texture_knot->knot)[texture_knot->t_max]; - if((texture_knot->unified_knot= - (GLfloat *)malloc(sizeof(GLfloat)*max_nknots))==NULL) - { - free(geom_knot->unified_knot); - free(color_knot->unified_knot); - free(normal_knot->unified_knot); - call_user_error(nobj,GLU_OUT_OF_MEMORY); - return GLU_ERROR; - } - /* copy the original knot to the unified one */ - texture_knot->unified_nknots=texture_knot->nknots; - for(i=0;inknots;i++) - (texture_knot->unified_knot)[i]=(texture_knot->knot)[i]; - } - /* work on the geometry knot with all additional knot values */ - /* appearing in attirbutive knots */ - if(minimal_max_knot-maximal_min_knot < EPSILON) - { - /* empty working range */ - geom_knot->unified_nknots=0; - color_knot->unified_nknots=0; - normal_knot->unified_nknots=0; - texture_knot->unified_nknots=0; - } - else - { - if(color_knot->unified_knot) - collect_unified_knot(geom_knot,color_knot,maximal_min_knot, - minimal_max_knot); - if(normal_knot->unified_knot) - collect_unified_knot(geom_knot,normal_knot,maximal_min_knot, - minimal_max_knot); - if(texture_knot->unified_knot) - collect_unified_knot(geom_knot,texture_knot,maximal_min_knot, - minimal_max_knot); - /* since we have now built the "unified" geometry knot */ - /* add same knot values to all attributive knots */ - if(color_knot->unified_knot) - collect_unified_knot(color_knot,geom_knot,maximal_min_knot, - minimal_max_knot); - if(normal_knot->unified_knot) - collect_unified_knot(normal_knot,geom_knot,maximal_min_knot, - minimal_max_knot); - if(texture_knot->unified_knot) - collect_unified_knot(texture_knot,geom_knot,maximal_min_knot, - minimal_max_knot); - } - } - set_new_t_min_t_max(geom_knot,color_knot,normal_knot,texture_knot, - maximal_min_knot,minimal_max_knot); - return GLU_NO_ERROR; + GLint max_nknots; + GLfloat maximal_min_knot, minimal_max_knot; + GLint i; + + /* find the maximum modified knot length */ + max_nknots = geom_knot->nknots; + if (color_knot->unified_knot) + max_nknots += color_knot->nknots; + if (normal_knot->unified_knot) + max_nknots += normal_knot->nknots; + if (texture_knot->unified_knot) + max_nknots += texture_knot->nknots; + maximal_min_knot = (geom_knot->knot)[geom_knot->t_min]; + minimal_max_knot = (geom_knot->knot)[geom_knot->t_max]; + /* any attirb data ? */ + if (max_nknots != geom_knot->nknots) { + /* allocate space for the unified knots */ + if ((geom_knot->unified_knot = + (GLfloat *) malloc(sizeof(GLfloat) * max_nknots)) == NULL) { + call_user_error(nobj, GLU_OUT_OF_MEMORY); + return GLU_ERROR; + } + /* copy the original knot to the unified one */ + geom_knot->unified_nknots = geom_knot->nknots; + for (i = 0; i < geom_knot->nknots; i++) + (geom_knot->unified_knot)[i] = (geom_knot->knot)[i]; + if (color_knot->unified_knot) { + if ((color_knot->knot)[color_knot->t_min] - maximal_min_knot > + EPSILON) + maximal_min_knot = (color_knot->knot)[color_knot->t_min]; + if (minimal_max_knot - (color_knot->knot)[color_knot->t_max] > + EPSILON) + minimal_max_knot = (color_knot->knot)[color_knot->t_max]; + if ((color_knot->unified_knot = + (GLfloat *) malloc(sizeof(GLfloat) * max_nknots)) == NULL) { + free(geom_knot->unified_knot); + call_user_error(nobj, GLU_OUT_OF_MEMORY); + return GLU_ERROR; + } + /* copy the original knot to the unified one */ + color_knot->unified_nknots = color_knot->nknots; + for (i = 0; i < color_knot->nknots; i++) + (color_knot->unified_knot)[i] = (color_knot->knot)[i]; + } + if (normal_knot->unified_knot) { + if ((normal_knot->knot)[normal_knot->t_min] - maximal_min_knot > + EPSILON) + maximal_min_knot = (normal_knot->knot)[normal_knot->t_min]; + if (minimal_max_knot - (normal_knot->knot)[normal_knot->t_max] > + EPSILON) + minimal_max_knot = (normal_knot->knot)[normal_knot->t_max]; + if ((normal_knot->unified_knot = + (GLfloat *) malloc(sizeof(GLfloat) * max_nknots)) == NULL) { + free(geom_knot->unified_knot); + free(color_knot->unified_knot); + call_user_error(nobj, GLU_OUT_OF_MEMORY); + return GLU_ERROR; + } + /* copy the original knot to the unified one */ + normal_knot->unified_nknots = normal_knot->nknots; + for (i = 0; i < normal_knot->nknots; i++) + (normal_knot->unified_knot)[i] = (normal_knot->knot)[i]; + } + if (texture_knot->unified_knot) { + if ((texture_knot->knot)[texture_knot->t_min] - maximal_min_knot > + EPSILON) + maximal_min_knot = (texture_knot->knot)[texture_knot->t_min]; + if (minimal_max_knot - (texture_knot->knot)[texture_knot->t_max] > + EPSILON) + minimal_max_knot = (texture_knot->knot)[texture_knot->t_max]; + if ((texture_knot->unified_knot = + (GLfloat *) malloc(sizeof(GLfloat) * max_nknots)) == NULL) { + free(geom_knot->unified_knot); + free(color_knot->unified_knot); + free(normal_knot->unified_knot); + call_user_error(nobj, GLU_OUT_OF_MEMORY); + return GLU_ERROR; + } + /* copy the original knot to the unified one */ + texture_knot->unified_nknots = texture_knot->nknots; + for (i = 0; i < texture_knot->nknots; i++) + (texture_knot->unified_knot)[i] = (texture_knot->knot)[i]; + } + /* work on the geometry knot with all additional knot values */ + /* appearing in attirbutive knots */ + if (minimal_max_knot - maximal_min_knot < EPSILON) { + /* empty working range */ + geom_knot->unified_nknots = 0; + color_knot->unified_nknots = 0; + normal_knot->unified_nknots = 0; + texture_knot->unified_nknots = 0; + } + else { + if (color_knot->unified_knot) + collect_unified_knot(geom_knot, color_knot, maximal_min_knot, + minimal_max_knot); + if (normal_knot->unified_knot) + collect_unified_knot(geom_knot, normal_knot, maximal_min_knot, + minimal_max_knot); + if (texture_knot->unified_knot) + collect_unified_knot(geom_knot, texture_knot, maximal_min_knot, + minimal_max_knot); + /* since we have now built the "unified" geometry knot */ + /* add same knot values to all attributive knots */ + if (color_knot->unified_knot) + collect_unified_knot(color_knot, geom_knot, maximal_min_knot, + minimal_max_knot); + if (normal_knot->unified_knot) + collect_unified_knot(normal_knot, geom_knot, maximal_min_knot, + minimal_max_knot); + if (texture_knot->unified_knot) + collect_unified_knot(texture_knot, geom_knot, maximal_min_knot, + minimal_max_knot); + } + } + set_new_t_min_t_max(geom_knot, color_knot, normal_knot, texture_knot, + maximal_min_knot, minimal_max_knot); + return GLU_NO_ERROR; } void -free_unified_knots(knot_str_type *geom_knot, knot_str_type *color_knot, - knot_str_type *normal_knot, knot_str_type *texture_knot) +free_unified_knots(knot_str_type * geom_knot, knot_str_type * color_knot, + knot_str_type * normal_knot, knot_str_type * texture_knot) { - if(geom_knot->unified_knot) - free(geom_knot->unified_knot); - if(color_knot->unified_knot) - free(color_knot->unified_knot); - if(normal_knot->unified_knot) - free(normal_knot->unified_knot); - if(texture_knot->unified_knot) - free(texture_knot->unified_knot); + if (geom_knot->unified_knot) + free(geom_knot->unified_knot); + if (color_knot->unified_knot) + free(color_knot->unified_knot); + if (normal_knot->unified_knot) + free(normal_knot->unified_knot); + if (texture_knot->unified_knot) + free(texture_knot->unified_knot); } -GLenum -explode_knot(knot_str_type *the_knot) +GLenum explode_knot(knot_str_type * the_knot) { - GLfloat *knot,*new_knot; - GLint nknots,n_new_knots=0; - GLint t_min,t_max; - GLint ord; - GLsizei i,j,k; - GLfloat tmp_float; - - if(the_knot->unified_knot) - { - knot=the_knot->unified_knot; - nknots=the_knot->unified_nknots; - } - else - { - knot=the_knot->knot; - nknots=the_knot->nknots; - } - ord=the_knot->order; - t_min=the_knot->t_min; - t_max=the_knot->t_max; - - for(i=t_min;i<=t_max;) - { - tmp_float=knot[i]; - for(j=0;jEPSILON) - break; - n_new_knots+=ord-j; - i+=j; - } - /* alloc space for new_knot */ - if((new_knot=(GLfloat *)malloc(sizeof(GLfloat)*(nknots+n_new_knots)))==NULL) - { - return GLU_OUT_OF_MEMORY; - } - /* fill in new knot */ - for(j=0;jnew_knot=new_knot; - the_knot->delta_nknots+=n_new_knots; - the_knot->t_max+=n_new_knots; - return GLU_NO_ERROR; + GLfloat *knot, *new_knot; + GLint nknots, n_new_knots = 0; + GLint t_min, t_max; + GLint ord; + GLsizei i, j, k; + GLfloat tmp_float; + + if (the_knot->unified_knot) { + knot = the_knot->unified_knot; + nknots = the_knot->unified_nknots; + } + else { + knot = the_knot->knot; + nknots = the_knot->nknots; + } + ord = the_knot->order; + t_min = the_knot->t_min; + t_max = the_knot->t_max; + + for (i = t_min; i <= t_max;) { + tmp_float = knot[i]; + for (j = 0; j < ord && (i + j) <= t_max; j++) + if (fabs(tmp_float - knot[i + j]) > EPSILON) + break; + n_new_knots += ord - j; + i += j; + } + /* alloc space for new_knot */ + if ( + (new_knot = + (GLfloat *) malloc(sizeof(GLfloat) * (nknots + n_new_knots))) == NULL) { + return GLU_OUT_OF_MEMORY; + } + /* fill in new knot */ + for (j = 0; j < t_min; j++) + new_knot[j] = knot[j]; + for (i = j; i <= t_max; i++) { + tmp_float = knot[i]; + for (k = 0; k < ord; k++) { + new_knot[j++] = knot[i]; + if (tmp_float == knot[i + 1]) + i++; + } + } + for (i = t_max + 1; i < (int) nknots; i++) + new_knot[j++] = knot[i]; + /* fill in the knot structure */ + the_knot->new_knot = new_knot; + the_knot->delta_nknots += n_new_knots; + the_knot->t_max += n_new_knots; + return GLU_NO_ERROR; } -GLenum -calc_alphas(knot_str_type *the_knot) +GLenum calc_alphas(knot_str_type * the_knot) { - GLfloat tmp_float; - int i,j,k,m,n; - int order; - GLfloat *alpha,*alpha_new,*tmp_alpha; - GLfloat denom; - GLfloat *knot,*new_knot; - - - knot=the_knot->knot; - order=the_knot->order; - new_knot=the_knot->new_knot; - n=the_knot->nknots-the_knot->order; - m=n+the_knot->delta_nknots; - if((alpha=(GLfloat *)malloc(sizeof(GLfloat)*n*m))==NULL) - { - return GLU_OUT_OF_MEMORY; - } - if((alpha_new=(GLfloat *)malloc(sizeof(GLfloat)*n*m))==NULL) - { - free(alpha); - return GLU_OUT_OF_MEMORY; - } - for(j=0;jEPSILON) - tmp_float+=(knot[i+k+1]-new_knot[j+k])/denom* - alpha[(i+1)+j*n]; - alpha_new[i+j*n]=tmp_float; - } - tmp_alpha=alpha_new; - alpha_new=alpha; - alpha=tmp_alpha; - } - the_knot->alpha=alpha; - free(alpha_new); - return GLU_NO_ERROR; + GLfloat tmp_float; + int i, j, k, m, n; + int order; + GLfloat *alpha, *alpha_new, *tmp_alpha; + GLfloat denom; + GLfloat *knot, *new_knot; + + + knot = the_knot->knot; + order = the_knot->order; + new_knot = the_knot->new_knot; + n = the_knot->nknots - the_knot->order; + m = n + the_knot->delta_nknots; + if ((alpha = (GLfloat *) malloc(sizeof(GLfloat) * n * m)) == NULL) { + return GLU_OUT_OF_MEMORY; + } + if ((alpha_new = (GLfloat *) malloc(sizeof(GLfloat) * n * m)) == NULL) { + free(alpha); + return GLU_OUT_OF_MEMORY; + } + for (j = 0; j < m; j++) { + for (i = 0; i < n; i++) { + if ((knot[i] <= new_knot[j]) && (new_knot[j] < knot[i + 1])) + tmp_float = 1.0; + else + tmp_float = 0.0; + alpha[i + j * n] = tmp_float; + } + } + for (k = 1; k < order; k++) { + for (j = 0; j < m; j++) + for (i = 0; i < n; i++) { + denom = knot[i + k] - knot[i]; + if (fabs(denom) < EPSILON) + tmp_float = 0.0; + else + tmp_float = (new_knot[j + k] - knot[i]) / denom * + alpha[i + j * n]; + denom = knot[i + k + 1] - knot[i + 1]; + if (fabs(denom) > EPSILON) + tmp_float += (knot[i + k + 1] - new_knot[j + k]) / denom * + alpha[(i + 1) + j * n]; + alpha_new[i + j * n] = tmp_float; + } + tmp_alpha = alpha_new; + alpha_new = alpha; + alpha = tmp_alpha; + } + the_knot->alpha = alpha; + free(alpha_new); + return GLU_NO_ERROR; } GLenum -calc_new_ctrl_pts(GLfloat *ctrl,GLint stride,knot_str_type *the_knot, - GLint dim,GLfloat **new_ctrl,GLint *ncontrol) +calc_new_ctrl_pts(GLfloat * ctrl, GLint stride, knot_str_type * the_knot, + GLint dim, GLfloat ** new_ctrl, GLint * ncontrol) { - GLsizei i,j,k,l,m,n; - GLsizei index1,index2; - GLfloat *alpha; - GLfloat *new_knot; - - new_knot=the_knot->new_knot; - n=the_knot->nknots-the_knot->order; - alpha=the_knot->alpha; - - m=the_knot->t_max+1-the_knot->t_min-the_knot->order; - k=the_knot->t_min; - /* allocate space for new control points */ - if((*new_ctrl=(GLfloat *)malloc(sizeof(GLfloat)*dim*m))==NULL) - { - return GLU_OUT_OF_MEMORY; - } - for(j=0;jnew_knot; + n = the_knot->nknots - the_knot->order; + alpha = the_knot->alpha; + + m = the_knot->t_max + 1 - the_knot->t_min - the_knot->order; + k = the_knot->t_min; + /* allocate space for new control points */ + if ((*new_ctrl = (GLfloat *) malloc(sizeof(GLfloat) * dim * m)) == NULL) { + return GLU_OUT_OF_MEMORY; + } + for (j = 0; j < m; j++) { + for (l = 0; l < dim; l++) + (*new_ctrl)[j * dim + l] = 0.0; + for (i = 0; i < n; i++) { + index1 = i + (j + k) * n; + index2 = i * stride; + for (l = 0; l < dim; l++) + (*new_ctrl)[j * dim + l] += alpha[index1] * ctrl[index2 + l]; + } + } + *ncontrol = (GLint) m; + return GLU_NO_ERROR; } static GLint -calc_factor(GLfloat *pts,GLint order,GLint indx,GLint stride,GLfloat tolerance, - GLint dim) +calc_factor(GLfloat * pts, GLint order, GLint indx, GLint stride, + GLfloat tolerance, GLint dim) { - GLdouble model[16],proj[16]; - GLint viewport[4]; - GLdouble x,y,z,w,winx1,winy1,winz,winx2,winy2; - GLint i; - GLdouble len,dx,dy; - - glGetDoublev(GL_MODELVIEW_MATRIX,model); - glGetDoublev(GL_PROJECTION_MATRIX,proj); - glGetIntegerv(GL_VIEWPORT,viewport); - if(dim==4) - { - w=(GLdouble)pts[indx+3]; - x=(GLdouble)pts[indx]/w; - y=(GLdouble)pts[indx+1]/w; - z=(GLdouble)pts[indx+2]/w; - gluProject(x,y,z,model,proj,viewport,&winx1,&winy1,&winz); - len=0.0; - for(i=1;i= 2) - { - bincoeff = order-1; - s = 1.0-t; - - for(k=0; k constant curve */ - { - for(k=0; k= 2) { + bincoeff = order - 1; + s = 1.0 - t; + + for (k = 0; k < dim; k++) + out[k] = s * cp[k] + bincoeff * t * cp[offset + k]; + + for (i = 2, cp += 2 * offset, powert = t * t; i < order; + i++, powert *= t, cp += offset) { + bincoeff *= order - i; + bincoeff /= i; + + for (k = 0; k < dim; k++) + out[k] = s * out[k] + bincoeff * powert * cp[k]; + } + } + else { /* order=1 -> constant curve */ + + for (k = 0; k < dim; k++) + out[k] = cp[k]; + } } static GLint -calc_parametric_factor(GLfloat *pts,GLint order,GLint indx,GLint stride, - GLfloat tolerance,GLint dim) +calc_parametric_factor(GLfloat * pts, GLint order, GLint indx, GLint stride, + GLfloat tolerance, GLint dim) { - GLdouble model[16],proj[16]; - GLint viewport[4]; - GLdouble x,y,z,w,x1,y1,z1,x2,y2,z2,x3,y3,z3; - GLint i; - GLint P; - GLfloat bez_pt[4]; - GLdouble len=0.0,tmp,z_med; - - P = 2*(order+2); - glGetDoublev(GL_MODELVIEW_MATRIX,model); - glGetDoublev(GL_PROJECTION_MATRIX,proj); - glGetIntegerv(GL_VIEWPORT,viewport); - z_med = (viewport[2] + viewport[3]) * 0.5; - switch(dim) - { - case 4: - for(i=1;i */ - x = x2-x1; - y = y2-y1; - z = z2-z1; - tmp = sqrt(x*x+y*y+z*z); - x /= tmp; - y /= tmp; - z /= tmp; - tmp = x3*x+y3*y+z3*z-x1*x-y1*y-z1*z; - x = x1+x*tmp-x3; - y = y1+y*tmp-y3; - z = z1+z*tmp-z3; - tmp = sqrt(x*x+y*y+z*z); - if(tmp > len) - len = tmp; - } - break; - case 3: - for(i=1;i */ - x = x2-x1; - y = y2-y1; - z = z2-z1; - tmp = sqrt(x*x+y*y+z*z); - x /= tmp; - y /= tmp; - z /= tmp; - tmp = x3*x+y3*y+z3*z-x1*x-y1*y-z1*z; - x = x1+x*tmp-x3; - y = y1+y*tmp-y3; - z = z1+z*tmp-z3; - tmp = sqrt(x*x+y*y+z*z); - if(tmp > len) - len = tmp; - } - break; - case 2: - for(i=1;i */ - x = x2-x1; - y = y2-y1; - z = z2-z1; - tmp = sqrt(x*x+y*y+z*z); - x /= tmp; - y /= tmp; - z /= tmp; - tmp = x3*x+y3*y+z3*z-x1*x-y1*y-z1*z; - x = x1+x*tmp-x3; - y = y1+y*tmp-y3; - z = z1+z*tmp-z3; - tmp = sqrt(x*x+y*y+z*z); - if(tmp > len) - len = tmp; - } - break; - - } - if(len < tolerance) - return (order); - else - return (GLint)(sqrt(len/tolerance)*(order+2)+1); + GLdouble model[16], proj[16]; + GLint viewport[4]; + GLdouble x, y, z, w, x1, y1, z1, x2, y2, z2, x3, y3, z3; + GLint i; + GLint P; + GLfloat bez_pt[4]; + GLdouble len = 0.0, tmp, z_med; + + P = 2 * (order + 2); + glGetDoublev(GL_MODELVIEW_MATRIX, model); + glGetDoublev(GL_PROJECTION_MATRIX, proj); + glGetIntegerv(GL_VIEWPORT, viewport); + z_med = (viewport[2] + viewport[3]) * 0.5; + switch (dim) { + case 4: + for (i = 1; i < P; i++) { + bezier_curve(pts + indx, bez_pt, (GLfloat) i / (GLfloat) P, 4, + order, stride); + w = (GLdouble) bez_pt[3]; + x = (GLdouble) bez_pt[0] / w; + y = (GLdouble) bez_pt[1] / w; + z = (GLdouble) bez_pt[2] / w; + gluProject(x, y, z, model, proj, viewport, &x3, &y3, &z3); + z3 *= z_med; + bezier_curve(pts + indx, bez_pt, (GLfloat) (i - 1) / (GLfloat) P, 4, + order, stride); + w = (GLdouble) bez_pt[3]; + x = (GLdouble) bez_pt[0] / w; + y = (GLdouble) bez_pt[1] / w; + z = (GLdouble) bez_pt[2] / w; + gluProject(x, y, z, model, proj, viewport, &x1, &y1, &z1); + z1 *= z_med; + bezier_curve(pts + indx, bez_pt, (GLfloat) (i + 1) / (GLfloat) P, 4, + order, stride); + w = (GLdouble) bez_pt[3]; + x = (GLdouble) bez_pt[0] / w; + y = (GLdouble) bez_pt[1] / w; + z = (GLdouble) bez_pt[2] / w; + gluProject(x, y, z, model, proj, viewport, &x2, &y2, &z2); + z2 *= z_med; + /* calc distance between point (x3,y3,z3) and line segment */ + /* */ + x = x2 - x1; + y = y2 - y1; + z = z2 - z1; + tmp = sqrt(x * x + y * y + z * z); + x /= tmp; + y /= tmp; + z /= tmp; + tmp = x3 * x + y3 * y + z3 * z - x1 * x - y1 * y - z1 * z; + x = x1 + x * tmp - x3; + y = y1 + y * tmp - y3; + z = z1 + z * tmp - z3; + tmp = sqrt(x * x + y * y + z * z); + if (tmp > len) + len = tmp; + } + break; + case 3: + for (i = 1; i < P; i++) { + bezier_curve(pts + indx, bez_pt, (GLfloat) i / (GLfloat) P, 3, + order, stride); + x = (GLdouble) bez_pt[0]; + y = (GLdouble) bez_pt[1]; + z = (GLdouble) bez_pt[2]; + gluProject(x, y, z, model, proj, viewport, &x3, &y3, &z3); + z3 *= z_med; + bezier_curve(pts + indx, bez_pt, (GLfloat) (i - 1) / (GLfloat) P, 3, + order, stride); + x = (GLdouble) bez_pt[0]; + y = (GLdouble) bez_pt[1]; + z = (GLdouble) bez_pt[2]; + gluProject(x, y, z, model, proj, viewport, &x1, &y1, &z1); + z1 *= z_med; + bezier_curve(pts + indx, bez_pt, (GLfloat) (i + 1) / (GLfloat) P, 3, + order, stride); + x = (GLdouble) bez_pt[0]; + y = (GLdouble) bez_pt[1]; + z = (GLdouble) bez_pt[2]; + gluProject(x, y, z, model, proj, viewport, &x2, &y2, &z2); + z2 *= z_med; + /* calc distance between point (x3,y3,z3) and line segment */ + /* */ + x = x2 - x1; + y = y2 - y1; + z = z2 - z1; + tmp = sqrt(x * x + y * y + z * z); + x /= tmp; + y /= tmp; + z /= tmp; + tmp = x3 * x + y3 * y + z3 * z - x1 * x - y1 * y - z1 * z; + x = x1 + x * tmp - x3; + y = y1 + y * tmp - y3; + z = z1 + z * tmp - z3; + tmp = sqrt(x * x + y * y + z * z); + if (tmp > len) + len = tmp; + } + break; + case 2: + for (i = 1; i < P; i++) { + bezier_curve(pts + indx, bez_pt, (GLfloat) i / (GLfloat) P, 2, + order, stride); + x = (GLdouble) bez_pt[0]; + y = (GLdouble) bez_pt[1]; + z = 0.0; + gluProject(x, y, z, model, proj, viewport, &x3, &y3, &z3); + z3 *= z_med; + bezier_curve(pts + indx, bez_pt, (GLfloat) (i - 1) / (GLfloat) P, 2, + order, stride); + x = (GLdouble) bez_pt[0]; + y = (GLdouble) bez_pt[1]; + z = 0.0; + gluProject(x, y, z, model, proj, viewport, &x1, &y1, &z1); + z1 *= z_med; + bezier_curve(pts + indx, bez_pt, (GLfloat) (i + 1) / (GLfloat) P, 2, + order, stride); + x = (GLdouble) bez_pt[0]; + y = (GLdouble) bez_pt[1]; + z = 0.0; + gluProject(x, y, z, model, proj, viewport, &x2, &y2, &z2); + z2 *= z_med; + /* calc distance between point (x3,y3,z3) and line segment */ + /* */ + x = x2 - x1; + y = y2 - y1; + z = z2 - z1; + tmp = sqrt(x * x + y * y + z * z); + x /= tmp; + y /= tmp; + z /= tmp; + tmp = x3 * x + y3 * y + z3 * z - x1 * x - y1 * y - z1 * z; + x = x1 + x * tmp - x3; + y = y1 + y * tmp - y3; + z = z1 + z * tmp - z3; + tmp = sqrt(x * x + y * y + z * z); + if (tmp > len) + len = tmp; + } + break; + + } + if (len < tolerance) + return (order); + else + return (GLint) (sqrt(len / tolerance) * (order + 2) + 1); } static GLenum -calc_sampling_3D(new_ctrl_type *new_ctrl, GLfloat tolerance, GLint dim, - GLint uorder, GLint vorder, GLint **ufactors, GLint **vfactors) +calc_sampling_3D(new_ctrl_type * new_ctrl, GLfloat tolerance, GLint dim, + GLint uorder, GLint vorder, GLint ** ufactors, + GLint ** vfactors) { - GLfloat *ctrl; - GLint tmp_factor1,tmp_factor2; - GLint ufactor_cnt,vfactor_cnt; - GLint offset1,offset2,offset3; - GLint i,j; - - ufactor_cnt=new_ctrl->s_bezier_cnt; - vfactor_cnt=new_ctrl->t_bezier_cnt; - if((*ufactors=(GLint *)malloc(sizeof(GLint)*ufactor_cnt*3)) - ==NULL) - { - return GLU_OUT_OF_MEMORY; - } - if((*vfactors=(GLint *)malloc(sizeof(GLint)*vfactor_cnt*3)) - ==NULL) - { - free(*ufactors); - return GLU_OUT_OF_MEMORY; - } - ctrl=new_ctrl->geom_ctrl; - offset1=new_ctrl->geom_t_stride*vorder; - offset2=new_ctrl->geom_s_stride*uorder; - for(j=0;jtmp_factor1) - tmp_factor1=tmp_factor2; - } - /* last time for the opposite edge */ - *(*vfactors+j*3+2)=tmp_factor2=calc_factor(ctrl,vorder, - j*offset1+i*offset2-new_ctrl->geom_s_stride, - dim,tolerance,dim); - if(tmp_factor2>tmp_factor1) - *(*vfactors+j*3)=tmp_factor2; - else - *(*vfactors+j*3)=tmp_factor1; - } - offset3=new_ctrl->geom_s_stride; - offset2=new_ctrl->geom_s_stride*uorder; - for(j=0;jtmp_factor1) - tmp_factor1=tmp_factor2; - } - /* last time for the opposite edge */ - *(*ufactors+j*3+2)=tmp_factor2=calc_factor(ctrl,uorder, - j*offset2+i*offset1-new_ctrl->geom_t_stride, - offset3,tolerance,dim); - if(tmp_factor2>tmp_factor1) - *(*ufactors+j*3)=tmp_factor2; - else - *(*ufactors+j*3)=tmp_factor1; - } - return GL_NO_ERROR; + GLfloat *ctrl; + GLint tmp_factor1, tmp_factor2; + GLint ufactor_cnt, vfactor_cnt; + GLint offset1, offset2, offset3; + GLint i, j; + + ufactor_cnt = new_ctrl->s_bezier_cnt; + vfactor_cnt = new_ctrl->t_bezier_cnt; + if ((*ufactors = (GLint *) malloc(sizeof(GLint) * ufactor_cnt * 3)) + == NULL) { + return GLU_OUT_OF_MEMORY; + } + if ((*vfactors = (GLint *) malloc(sizeof(GLint) * vfactor_cnt * 3)) + == NULL) { + free(*ufactors); + return GLU_OUT_OF_MEMORY; + } + ctrl = new_ctrl->geom_ctrl; + offset1 = new_ctrl->geom_t_stride * vorder; + offset2 = new_ctrl->geom_s_stride * uorder; + for (j = 0; j < vfactor_cnt; j++) { + *(*vfactors + j * 3 + 1) = tmp_factor1 = calc_factor(ctrl, vorder, + j * offset1, dim, + tolerance, dim); + /* loop ufactor_cnt-1 times */ + for (i = 1; i < ufactor_cnt; i++) { + tmp_factor2 = calc_factor(ctrl, vorder, + j * offset1 + i * offset2, dim, tolerance, + dim); + if (tmp_factor2 > tmp_factor1) + tmp_factor1 = tmp_factor2; + } + /* last time for the opposite edge */ + *(*vfactors + j * 3 + 2) = tmp_factor2 = calc_factor(ctrl, vorder, + j * offset1 + + i * offset2 - + new_ctrl-> + geom_s_stride, dim, + tolerance, dim); + if (tmp_factor2 > tmp_factor1) + *(*vfactors + j * 3) = tmp_factor2; + else + *(*vfactors + j * 3) = tmp_factor1; + } + offset3 = new_ctrl->geom_s_stride; + offset2 = new_ctrl->geom_s_stride * uorder; + for (j = 0; j < ufactor_cnt; j++) { + *(*ufactors + j * 3 + 1) = tmp_factor1 = calc_factor(ctrl, uorder, + j * offset2, + offset3, tolerance, + dim); + /* loop vfactor_cnt-1 times */ + for (i = 1; i < vfactor_cnt; i++) { + tmp_factor2 = calc_factor(ctrl, uorder, + j * offset2 + i * offset1, offset3, + tolerance, dim); + if (tmp_factor2 > tmp_factor1) + tmp_factor1 = tmp_factor2; + } + /* last time for the opposite edge */ + *(*ufactors + j * 3 + 2) = tmp_factor2 = calc_factor(ctrl, uorder, + j * offset2 + + i * offset1 - + new_ctrl-> + geom_t_stride, + offset3, tolerance, + dim); + if (tmp_factor2 > tmp_factor1) + *(*ufactors + j * 3) = tmp_factor2; + else + *(*ufactors + j * 3) = tmp_factor1; + } + return GL_NO_ERROR; } static GLenum -calc_sampling_param_3D(new_ctrl_type *new_ctrl, GLfloat tolerance, GLint dim, - GLint uorder, GLint vorder, GLint **ufactors, GLint **vfactors) +calc_sampling_param_3D(new_ctrl_type * new_ctrl, GLfloat tolerance, GLint dim, + GLint uorder, GLint vorder, GLint ** ufactors, + GLint ** vfactors) { - GLfloat *ctrl; - GLint tmp_factor1,tmp_factor2; - GLint ufactor_cnt,vfactor_cnt; - GLint offset1,offset2,offset3; - GLint i,j; - - ufactor_cnt=new_ctrl->s_bezier_cnt; - vfactor_cnt=new_ctrl->t_bezier_cnt; - if((*ufactors=(GLint *)malloc(sizeof(GLint)*ufactor_cnt*3)) - ==NULL) - { - return GLU_OUT_OF_MEMORY; - } - if((*vfactors=(GLint *)malloc(sizeof(GLint)*vfactor_cnt*3)) - ==NULL) - { - free(*ufactors); - return GLU_OUT_OF_MEMORY; - } - ctrl=new_ctrl->geom_ctrl; - offset1=new_ctrl->geom_t_stride*vorder; - offset2=new_ctrl->geom_s_stride*uorder; - for(j=0;jtmp_factor1) - tmp_factor1=tmp_factor2; - } - /* last time for the opposite edge */ - *(*vfactors+j*3+2)=tmp_factor2=calc_parametric_factor(ctrl,vorder, - j*offset1+i*offset2-new_ctrl->geom_s_stride, - dim,tolerance,dim); - if(tmp_factor2>tmp_factor1) - *(*vfactors+j*3)=tmp_factor2; - else - *(*vfactors+j*3)=tmp_factor1; - } - offset3=new_ctrl->geom_s_stride; - offset2=new_ctrl->geom_s_stride*uorder; - for(j=0;jtmp_factor1) - tmp_factor1=tmp_factor2; - } - /* last time for the opposite edge */ - *(*ufactors+j*3+2)=tmp_factor2=calc_parametric_factor(ctrl,uorder, - j*offset2+i*offset1-new_ctrl->geom_t_stride, - offset3,tolerance,dim); - if(tmp_factor2>tmp_factor1) - *(*ufactors+j*3)=tmp_factor2; - else - *(*ufactors+j*3)=tmp_factor1; - } - return GL_NO_ERROR; + GLfloat *ctrl; + GLint tmp_factor1, tmp_factor2; + GLint ufactor_cnt, vfactor_cnt; + GLint offset1, offset2, offset3; + GLint i, j; + + ufactor_cnt = new_ctrl->s_bezier_cnt; + vfactor_cnt = new_ctrl->t_bezier_cnt; + if ((*ufactors = (GLint *) malloc(sizeof(GLint) * ufactor_cnt * 3)) + == NULL) { + return GLU_OUT_OF_MEMORY; + } + if ((*vfactors = (GLint *) malloc(sizeof(GLint) * vfactor_cnt * 3)) + == NULL) { + free(*ufactors); + return GLU_OUT_OF_MEMORY; + } + ctrl = new_ctrl->geom_ctrl; + offset1 = new_ctrl->geom_t_stride * vorder; + offset2 = new_ctrl->geom_s_stride * uorder; + for (j = 0; j < vfactor_cnt; j++) { + *(*vfactors + j * 3 + 1) = tmp_factor1 = + calc_parametric_factor(ctrl, vorder, j * offset1, dim, tolerance, + dim); + /* loop ufactor_cnt-1 times */ + for (i = 1; i < ufactor_cnt; i++) { + tmp_factor2 = calc_parametric_factor(ctrl, vorder, + j * offset1 + i * offset2, dim, + tolerance, dim); + if (tmp_factor2 > tmp_factor1) + tmp_factor1 = tmp_factor2; + } + /* last time for the opposite edge */ + *(*vfactors + j * 3 + 2) = tmp_factor2 = + calc_parametric_factor(ctrl, vorder, + j * offset1 + i * offset2 - + new_ctrl->geom_s_stride, dim, tolerance, dim); + if (tmp_factor2 > tmp_factor1) + *(*vfactors + j * 3) = tmp_factor2; + else + *(*vfactors + j * 3) = tmp_factor1; + } + offset3 = new_ctrl->geom_s_stride; + offset2 = new_ctrl->geom_s_stride * uorder; + for (j = 0; j < ufactor_cnt; j++) { + *(*ufactors + j * 3 + 1) = tmp_factor1 = + calc_parametric_factor(ctrl, uorder, j * offset2, offset3, tolerance, + dim); + /* loop vfactor_cnt-1 times */ + for (i = 1; i < vfactor_cnt; i++) { + tmp_factor2 = calc_parametric_factor(ctrl, uorder, + j * offset2 + i * offset1, + offset3, tolerance, dim); + if (tmp_factor2 > tmp_factor1) + tmp_factor1 = tmp_factor2; + } + /* last time for the opposite edge */ + *(*ufactors + j * 3 + 2) = tmp_factor2 = + calc_parametric_factor(ctrl, uorder, + j * offset2 + i * offset1 - + new_ctrl->geom_t_stride, offset3, tolerance, + dim); + if (tmp_factor2 > tmp_factor1) + *(*ufactors + j * 3) = tmp_factor2; + else + *(*ufactors + j * 3) = tmp_factor1; + } + return GL_NO_ERROR; } static GLenum -calc_sampling_2D(GLfloat *ctrl, GLint cnt, GLint order, - GLfloat tolerance, GLint dim, GLint **factors) +calc_sampling_2D(GLfloat * ctrl, GLint cnt, GLint order, + GLfloat tolerance, GLint dim, GLint ** factors) { - GLint factor_cnt; - GLint tmp_factor; - GLint offset; - GLint i; - - factor_cnt=cnt/order; - if((*factors=(GLint *)malloc(sizeof(GLint)*factor_cnt))==NULL) - { - return GLU_OUT_OF_MEMORY; - } - offset=order*dim; - for(i=0;iauto_load_matrix==GL_FALSE) - { - GLint i; - GLfloat m[4]; - - glPushAttrib( (GLbitfield) (GL_VIEWPORT_BIT | GL_TRANSFORM_BIT)); - for(i=0;i<4;i++) - m[i]=nobj->sampling_matrices.viewport[i]; - glViewport(m[0],m[1],m[2],m[3]); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadMatrixf(nobj->sampling_matrices.proj); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadMatrixf(nobj->sampling_matrices.model); - } + if (nobj->auto_load_matrix == GL_FALSE) { + GLint i; + GLfloat m[4]; + + glPushAttrib((GLbitfield) (GL_VIEWPORT_BIT | GL_TRANSFORM_BIT)); + for (i = 0; i < 4; i++) + m[i] = nobj->sampling_matrices.viewport[i]; + glViewport(m[0], m[1], m[2], m[3]); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadMatrixf(nobj->sampling_matrices.proj); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadMatrixf(nobj->sampling_matrices.model); + } } static void -revert_sampling_and_culling( GLUnurbsObj *nobj ) +revert_sampling_and_culling(GLUnurbsObj * nobj) { - if(nobj->auto_load_matrix==GL_FALSE) - { - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glPopAttrib(); - } + if (nobj->auto_load_matrix == GL_FALSE) { + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + } } GLenum -glu_do_sampling_3D( GLUnurbsObj *nobj, new_ctrl_type *new_ctrl, - GLint **sfactors, GLint **tfactors) +glu_do_sampling_3D(GLUnurbsObj * nobj, new_ctrl_type * new_ctrl, + GLint ** sfactors, GLint ** tfactors) { - GLint dim; - GLenum err; - - *sfactors=NULL; - *tfactors=NULL; - dim=nobj->surface.geom.dim; - set_sampling_and_culling(nobj); - if((err=calc_sampling_3D(new_ctrl,nobj->sampling_tolerance,dim, - nobj->surface.geom.sorder,nobj->surface.geom.torder, - sfactors,tfactors))==GLU_ERROR) - { - revert_sampling_and_culling(nobj); - call_user_error(nobj,err); - return GLU_ERROR; - } - revert_sampling_and_culling(nobj); - return GLU_NO_ERROR; + GLint dim; + GLenum err; + + *sfactors = NULL; + *tfactors = NULL; + dim = nobj->surface.geom.dim; + set_sampling_and_culling(nobj); + if ((err = calc_sampling_3D(new_ctrl, nobj->sampling_tolerance, dim, + nobj->surface.geom.sorder, + nobj->surface.geom.torder, sfactors, + tfactors)) == GLU_ERROR) { + revert_sampling_and_culling(nobj); + call_user_error(nobj, err); + return GLU_ERROR; + } + revert_sampling_and_culling(nobj); + return GLU_NO_ERROR; } GLenum -glu_do_sampling_uv( GLUnurbsObj *nobj, new_ctrl_type *new_ctrl, - GLint **sfactors, GLint **tfactors) +glu_do_sampling_uv(GLUnurbsObj * nobj, new_ctrl_type * new_ctrl, + GLint ** sfactors, GLint ** tfactors) { - GLint s_cnt, t_cnt, i; - GLint u_steps, v_steps; - - s_cnt = new_ctrl->s_bezier_cnt; - t_cnt = new_ctrl->t_bezier_cnt; - *sfactors=NULL; - *tfactors=NULL; - if((*sfactors=(GLint *)malloc(sizeof(GLint)*s_cnt*3)) - ==NULL) - { - return GLU_OUT_OF_MEMORY; - } - if((*tfactors=(GLint *)malloc(sizeof(GLint)*t_cnt*3)) - ==NULL) - { - free(*sfactors); - return GLU_OUT_OF_MEMORY; - } - u_steps = nobj->u_step; - v_steps = nobj->v_step; - for(i=0; is_bezier_cnt; + t_cnt = new_ctrl->t_bezier_cnt; + *sfactors = NULL; + *tfactors = NULL; + if ((*sfactors = (GLint *) malloc(sizeof(GLint) * s_cnt * 3)) + == NULL) { + return GLU_OUT_OF_MEMORY; + } + if ((*tfactors = (GLint *) malloc(sizeof(GLint) * t_cnt * 3)) + == NULL) { + free(*sfactors); + return GLU_OUT_OF_MEMORY; + } + u_steps = nobj->u_step; + v_steps = nobj->v_step; + for (i = 0; i < s_cnt; i++) { + *(*sfactors + i * 3) = u_steps; + *(*sfactors + i * 3 + 1) = u_steps; + *(*sfactors + i * 3 + 2) = u_steps; + } + for (i = 0; i < t_cnt; i++) { + *(*tfactors + i * 3) = v_steps; + *(*tfactors + i * 3 + 1) = v_steps; + *(*tfactors + i * 3 + 2) = v_steps; + } + return GLU_NO_ERROR; } -GLenum -glu_do_sampling_param_3D( GLUnurbsObj *nobj, new_ctrl_type *new_ctrl, - GLint **sfactors, GLint **tfactors) -{ - GLint dim; - GLenum err; - - *sfactors=NULL; - *tfactors=NULL; - dim=nobj->surface.geom.dim; - set_sampling_and_culling(nobj); - if((err=calc_sampling_param_3D(new_ctrl,nobj->parametric_tolerance,dim, - nobj->surface.geom.sorder,nobj->surface.geom.torder, - sfactors,tfactors))==GLU_ERROR) - { - revert_sampling_and_culling(nobj); - call_user_error(nobj,err); - return GLU_ERROR; - } - revert_sampling_and_culling(nobj); - return GLU_NO_ERROR; -} GLenum -glu_do_sampling_2D( GLUnurbsObj *nobj, GLfloat *ctrl, GLint cnt, GLint order, - GLint dim, GLint **factors) +glu_do_sampling_param_3D(GLUnurbsObj * nobj, new_ctrl_type * new_ctrl, + GLint ** sfactors, GLint ** tfactors) { - GLenum err; - - set_sampling_and_culling(nobj); - err=calc_sampling_2D(ctrl,cnt,order,nobj->sampling_tolerance,dim, - factors); - revert_sampling_and_culling(nobj); - return err; + GLint dim; + GLenum err; + + *sfactors = NULL; + *tfactors = NULL; + dim = nobj->surface.geom.dim; + set_sampling_and_culling(nobj); + if ( + (err = + calc_sampling_param_3D(new_ctrl, nobj->parametric_tolerance, dim, + nobj->surface.geom.sorder, + nobj->surface.geom.torder, sfactors, + tfactors)) == GLU_ERROR) { + revert_sampling_and_culling(nobj); + call_user_error(nobj, err); + return GLU_ERROR; + } + revert_sampling_and_culling(nobj); + return GLU_NO_ERROR; } -GLenum -glu_do_sampling_u( GLUnurbsObj *nobj, GLfloat *ctrl, GLint cnt, GLint order, - GLint dim, GLint **factors) +static GLenum +glu_do_sampling_2D(GLUnurbsObj * nobj, GLfloat * ctrl, GLint cnt, GLint order, + GLint dim, GLint ** factors) { - GLint i; - GLint u_steps; + GLenum err; - cnt /= order; - if((*factors=(GLint *)malloc(sizeof(GLint)*cnt)) - ==NULL) - { - return GLU_OUT_OF_MEMORY; - } - u_steps = nobj->u_step; - for(i=0; isampling_tolerance, dim, + factors); + revert_sampling_and_culling(nobj); + return err; } -GLenum -glu_do_sampling_param_2D( GLUnurbsObj *nobj, GLfloat *ctrl, GLint cnt, - GLint order, GLint dim, GLint **factors) + +static GLenum +glu_do_sampling_u(GLUnurbsObj * nobj, GLfloat * ctrl, GLint cnt, GLint order, + GLint dim, GLint ** factors) { - GLint i; - GLint u_steps; - GLfloat tolerance; + GLint i; + GLint u_steps; + + cnt /= order; + if ((*factors = (GLint *) malloc(sizeof(GLint) * cnt)) + == NULL) { + return GLU_OUT_OF_MEMORY; + } + u_steps = nobj->u_step; + for (i = 0; i < cnt; i++) + (*factors)[i] = u_steps; + return GLU_NO_ERROR; +} - set_sampling_and_culling(nobj); - tolerance = nobj->parametric_tolerance; - cnt /= order; - if((*factors=(GLint *)malloc(sizeof(GLint)*cnt)) - ==NULL) - { - revert_sampling_and_culling(nobj); - return GLU_OUT_OF_MEMORY; - } - u_steps = nobj->u_step; - for(i=0; iparametric_tolerance; + cnt /= order; + if ((*factors = (GLint *) malloc(sizeof(GLint) * cnt)) + == NULL) { + revert_sampling_and_culling(nobj); + return GLU_OUT_OF_MEMORY; + } + u_steps = nobj->u_step; + for (i = 0; i < cnt; i++) { + (*factors)[i] = calc_parametric_factor(ctrl, order, 0, + dim, tolerance, dim); + + } + revert_sampling_and_culling(nobj); + return GLU_NO_ERROR; } GLenum -glu_do_sampling_crv( GLUnurbsObj *nobj, GLfloat *ctrl, GLint cnt, GLint order, - GLint dim, GLint **factors) +glu_do_sampling_crv(GLUnurbsObj * nobj, GLfloat * ctrl, GLint cnt, + GLint order, GLint dim, GLint ** factors) { - GLenum err; - - *factors=NULL; - switch(nobj->sampling_method) - { - case GLU_PATH_LENGTH: - if((err=glu_do_sampling_2D(nobj,ctrl,cnt,order,dim,factors))!= - GLU_NO_ERROR) - { - call_user_error(nobj,err); - return GLU_ERROR; - } - break; - case GLU_DOMAIN_DISTANCE: - if((err=glu_do_sampling_u(nobj,ctrl,cnt,order,dim,factors))!= - GLU_NO_ERROR) - { - call_user_error(nobj,err); - return GLU_ERROR; - } - break; - case GLU_PARAMETRIC_ERROR: - if((err=glu_do_sampling_param_2D(nobj,ctrl,cnt,order,dim,factors))!= - GLU_NO_ERROR) - { - call_user_error(nobj,err); - return GLU_ERROR; - } - break; - default: - abort(); - } - - return GLU_NO_ERROR; + GLenum err; + + *factors = NULL; + switch (nobj->sampling_method) { + case GLU_PATH_LENGTH: + if ((err = glu_do_sampling_2D(nobj, ctrl, cnt, order, dim, factors)) != + GLU_NO_ERROR) { + call_user_error(nobj, err); + return GLU_ERROR; + } + break; + case GLU_DOMAIN_DISTANCE: + if ((err = glu_do_sampling_u(nobj, ctrl, cnt, order, dim, factors)) != + GLU_NO_ERROR) { + call_user_error(nobj, err); + return GLU_ERROR; + } + break; + case GLU_PARAMETRIC_ERROR: + if ( + (err = + glu_do_sampling_param_2D(nobj, ctrl, cnt, order, dim, + factors)) != GLU_NO_ERROR) { + call_user_error(nobj, err); + return GLU_ERROR; + } + break; + default: + abort(); + } + + return GLU_NO_ERROR; } /* TODO - i don't like this culling - this one just tests if at least one */ @@ -1215,68 +1133,62 @@ glu_do_sampling_crv( GLUnurbsObj *nobj, GLfloat *ctrl, GLint cnt, GLint order, /* should be included in the fnctions for efficiency reasons */ static GLboolean -point_in_viewport(GLfloat *pt, GLint dim) +point_in_viewport(GLfloat * pt, GLint dim) { - GLdouble model[16],proj[16]; - GLint viewport[4]; - GLdouble x,y,z,w,winx,winy,winz; - - glGetDoublev(GL_MODELVIEW_MATRIX,model); - glGetDoublev(GL_PROJECTION_MATRIX,proj); - glGetIntegerv(GL_VIEWPORT,viewport); - if(dim==3) - { - x=(GLdouble)pt[0]; - y=(GLdouble)pt[1]; - z=(GLdouble)pt[2]; - gluProject(x,y,z,model,proj,viewport,&winx,&winy,&winz); - } - else - { - w=(GLdouble)pt[3]; - x=(GLdouble)pt[0]/w; - y=(GLdouble)pt[1]/w; - z=(GLdouble)pt[2]/w; - gluProject(x,y,z,model,proj,viewport,&winx,&winy,&winz); - } - if((GLint)winx >= viewport[0] && (GLint)winx < viewport[2] && - (GLint)winy >= viewport[1] && (GLint)winy < viewport[3]) - return GL_TRUE; - return GL_FALSE; + GLdouble model[16], proj[16]; + GLint viewport[4]; + GLdouble x, y, z, w, winx, winy, winz; + + glGetDoublev(GL_MODELVIEW_MATRIX, model); + glGetDoublev(GL_PROJECTION_MATRIX, proj); + glGetIntegerv(GL_VIEWPORT, viewport); + if (dim == 3) { + x = (GLdouble) pt[0]; + y = (GLdouble) pt[1]; + z = (GLdouble) pt[2]; + gluProject(x, y, z, model, proj, viewport, &winx, &winy, &winz); + } + else { + w = (GLdouble) pt[3]; + x = (GLdouble) pt[0] / w; + y = (GLdouble) pt[1] / w; + z = (GLdouble) pt[2] / w; + gluProject(x, y, z, model, proj, viewport, &winx, &winy, &winz); + } + if ((GLint) winx >= viewport[0] && (GLint) winx < viewport[2] && + (GLint) winy >= viewport[1] && (GLint) winy < viewport[3]) + return GL_TRUE; + return GL_FALSE; } GLboolean -fine_culling_test_3D(GLUnurbsObj *nobj,GLfloat *pts,GLint s_cnt,GLint t_cnt, - GLint s_stride,GLint t_stride, GLint dim) +fine_culling_test_3D(GLUnurbsObj * nobj, GLfloat * pts, GLint s_cnt, + GLint t_cnt, GLint s_stride, GLint t_stride, GLint dim) { - GLint i,j; - - if(nobj->culling==GL_FALSE) - return GL_FALSE; - set_sampling_and_culling(nobj); - - if(dim==3) - { - for(i=0;iculling == GL_FALSE) + return GL_FALSE; + set_sampling_and_culling(nobj); + + if (dim == 3) { + for (i = 0; i < s_cnt; i++) + for (j = 0; j < t_cnt; j++) + if (point_in_viewport(pts + i * s_stride + j * t_stride, dim)) { + revert_sampling_and_culling(nobj); + return GL_FALSE; + } + } + else { + for (i = 0; i < s_cnt; i++) + for (j = 0; j < t_cnt; j++) + if (point_in_viewport(pts + i * s_stride + j * t_stride, dim)) { + revert_sampling_and_culling(nobj); + return GL_FALSE; + } + } + revert_sampling_and_culling(nobj); + return GL_TRUE; } /*GLboolean @@ -1336,35 +1248,31 @@ fine_culling_test_3D(GLUnurbsObj *nobj,GLfloat *pts,GLint s_cnt,GLint t_cnt, }*/ GLboolean -fine_culling_test_2D(GLUnurbsObj *nobj,GLfloat *pts,GLint cnt, - GLint stride, GLint dim) +fine_culling_test_2D(GLUnurbsObj * nobj, GLfloat * pts, GLint cnt, + GLint stride, GLint dim) { - GLint i; - - if(nobj->culling==GL_FALSE) - return GL_FALSE; - set_sampling_and_culling(nobj); - - if(dim==3) - { - for(i=0;iculling == GL_FALSE) + return GL_FALSE; + set_sampling_and_culling(nobj); + + if (dim == 3) { + for (i = 0; i < cnt; i++) + if (point_in_viewport(pts + i * stride, dim)) { + revert_sampling_and_culling(nobj); + return GL_FALSE; + } + } + else { + for (i = 0; i < cnt; i++) + if (point_in_viewport(pts + i * stride, dim)) { + revert_sampling_and_culling(nobj); + return GL_FALSE; + } + } + revert_sampling_and_culling(nobj); + return GL_TRUE; } /*GLboolean @@ -1400,4 +1308,3 @@ fine_culling_test_2D(GLUnurbsObj *nobj,GLfloat *pts,GLint cnt, revert_sampling_and_culling(nobj); return (GLboolean)(visible_cnt==0); }*/ - -- cgit v1.2.3