diff options
author | marha <marha@users.sourceforge.net> | 2009-10-09 06:31:44 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2009-10-09 06:31:44 +0000 |
commit | 06456f5db88b434c3634ede42bdbfdce78fc4249 (patch) | |
tree | 97f5174e2d3da40faee7f2ad8858233da3d0166e /mesalib/src/glu/sgi/libnurbs | |
parent | 7b230a3fe2d6c83488d9eec43067fe8ba8ac081b (diff) | |
parent | a0c4815433ccd57322f4f7703ca35e9ccfa59250 (diff) | |
download | vcxsrv-06456f5db88b434c3634ede42bdbfdce78fc4249.tar.gz vcxsrv-06456f5db88b434c3634ede42bdbfdce78fc4249.tar.bz2 vcxsrv-06456f5db88b434c3634ede42bdbfdce78fc4249.zip |
svn merge ^/branches/released . --username marha
Diffstat (limited to 'mesalib/src/glu/sgi/libnurbs')
158 files changed, 39452 insertions, 0 deletions
diff --git a/mesalib/src/glu/sgi/libnurbs/interface/bezierEval.cc b/mesalib/src/glu/sgi/libnurbs/interface/bezierEval.cc new file mode 100644 index 000000000..b414f535f --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/interface/bezierEval.cc @@ -0,0 +1,260 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <assert.h> +#include <math.h> +#include "bezierEval.h" + +#ifdef __WATCOMC__ +#pragma warning 14 10 +#endif + +#define TOLERANCE 0.0001 + +#ifndef MAX_ORDER +#define MAX_ORDER 16 +#endif + +#ifndef MAX_DIMENSION +#define MAX_DIMENSION 4 +#endif + +static void normalize(float vec[3]); +static void crossProduct(float x[3], float y[3], float ret[3]); +#if 0 // UNUSED +static void bezierCurveEvalfast(float u0, float u1, int order, float *ctlpoints, int stride, int dimension, float u, float retpoint[]); +#endif + +static float binomialCoefficients[8][8] = { + {1,0,0,0,0,0,0,0}, + {1,1,0,0,0,0,0,0}, + {1,2,1,0,0,0,0,0}, + {1,3,3,1,0,0,0,0}, + {1,4,6,4,1,0,0,0}, + {1,5,10,10,5,1,0,0}, + {1,6,15,20,15,6,1,0}, + {1,7,21,35,35,21,7,1} +}; + +void bezierCurveEval(float u0, float u1, int order, float *ctlpoints, int stride, int dimension, float u, float retpoint[]) +{ + float uprime = (u-u0)/(u1-u0); + float *ctlptr = ctlpoints; + float oneMinusX = 1.0f-uprime; + float XPower = 1.0f; + + int i,k; + for(k=0; k<dimension; k++) + retpoint[k] = (*(ctlptr + k)); + + for(i=1; i<order; i++){ + ctlptr += stride; + XPower *= uprime; + for(k=0; k<dimension; k++) { + retpoint[k] = retpoint[k]*oneMinusX + ctlptr[k]* binomialCoefficients[order-1][i] * XPower; + } + } +} + + +#if 0 // UNUSED +/*order = degree +1 >=1. + */ +void bezierCurveEvalfast(float u0, float u1, int order, float *ctlpoints, int stride, int dimension, float u, float retpoint[]) +{ + float uprime = (u-u0)/(u1-u0); + float buf[MAX_ORDER][MAX_ORDER][MAX_DIMENSION]; + float* ctlptr = ctlpoints; + int r, i,j; + for(i=0; i<order; i++) { + for(j=0; j<dimension; j++) + buf[0][i][j] = ctlptr[j]; + ctlptr += stride; + } + for(r=1; r<order; r++){ + for(i=0; i<order-r; i++) { + for(j=0; j<dimension; j++) + buf[r][i][j] = (1-uprime)*buf[r-1][i][j] + uprime*buf[r-1][i+1][j]; + } + } + + for(j=0; j<dimension; j++) + retpoint[j] = buf[order-1][0][j]; +} +#endif + + +/*order = degree +1 >=1. + */ +void bezierCurveEvalDer(float u0, float u1, int order, float *ctlpoints, int stride, int dimension, float u, float retDer[]) +{ + int i,k; + float width = u1-u0; + float *ctlptr = ctlpoints; + + float buf[MAX_ORDER][MAX_DIMENSION]; + if(order == 1){ + for(k=0; k<dimension; k++) + retDer[k]=0; + } + for(i=0; i<order-1; i++){ + for(k=0; k<dimension; k++) { + buf[i][k] = (ctlptr[stride+k] - ctlptr[k])*(order-1)/width; + } + ctlptr += stride; + } + + bezierCurveEval(u0, u1, order-1, (float*) buf, MAX_DIMENSION, dimension, u, retDer); +} + +void bezierCurveEvalDerGen(int der, float u0, float u1, int order, float *ctlpoints, int stride, int dimension, float u, float retDer[]) +{ + int i,k,r; + float *ctlptr = ctlpoints; + float width=u1-u0; + float buf[MAX_ORDER][MAX_ORDER][MAX_DIMENSION]; + if(der<0) der=0; + for(i=0; i<order; i++){ + for(k=0; k<dimension; k++){ + buf[0][i][k] = ctlptr[k]; + } + ctlptr += stride; + } + + + for(r=1; r<=der; r++){ + for(i=0; i<order-r; i++){ + for(k=0; k<dimension; k++){ + buf[r][i][k] = (buf[r-1][i+1][k] - buf[r-1][i][k])*(order-r)/width; + } + } + } + + bezierCurveEval(u0, u1, order-der, (float *) (buf[der]), MAX_DIMENSION, dimension, u, retDer); +} + +/*the Bezier bivarite polynomial is: + * sum[i:0,uorder-1][j:0,vorder-1] { ctlpoints[i*ustride+j*vstride] * B(i)*B(j) + * where B(i) and B(j) are basis functions + */ +void bezierSurfEvalDerGen(int uder, int vder, float u0, float u1, int uorder, float v0, float v1, int vorder, int dimension, float *ctlpoints, int ustride, int vstride, float u, float v, float ret[]) +{ + int i; + float newPoints[MAX_ORDER][MAX_DIMENSION]; + + for(i=0; i<uorder; i++){ + + bezierCurveEvalDerGen(vder, v0, v1, vorder, ctlpoints+ustride*i, vstride, dimension, v, newPoints[i]); + + } + + bezierCurveEvalDerGen(uder, u0, u1, uorder, (float *) newPoints, MAX_DIMENSION, dimension, u, ret); +} + + +/*division by w is performed*/ +void bezierSurfEval(float u0, float u1, int uorder, float v0, float v1, int vorder, int dimension, float *ctlpoints, int ustride, int vstride, float u, float v, float ret[]) +{ + bezierSurfEvalDerGen(0, 0, u0, u1, uorder, v0, v1, vorder, dimension, ctlpoints, ustride, vstride, u, v, ret); + if(dimension == 4) /*homogeneous*/{ + ret[0] /= ret[3]; + ret[1] /= ret[3]; + ret[2] /= ret[3]; + } +} + +void bezierSurfEvalNormal(float u0, float u1, int uorder, float v0, float v1, int vorder, int dimension, float *ctlpoints, int ustride, int vstride, float u, float v, float retNormal[]) +{ + float partialU[4]; + float partialV[4]; + assert(dimension>=3 && dimension <=4); + bezierSurfEvalDerGen(1,0, u0, u1, uorder, v0, v1, vorder, dimension, ctlpoints, ustride, vstride, u, v, partialU); + bezierSurfEvalDerGen(0,1, u0, u1, uorder, v0, v1, vorder, dimension, ctlpoints, ustride, vstride, u, v, partialV); + + if(dimension == 3){/*inhomogeneous*/ + crossProduct(partialU, partialV, retNormal); + + normalize(retNormal); + + return; + } + else { /*homogeneous*/ + float val[4]; /*the point coordinates (without derivative)*/ + float newPartialU[MAX_DIMENSION]; + float newPartialV[MAX_DIMENSION]; + int i; + bezierSurfEvalDerGen(0,0, u0, u1, uorder, v0, v1, vorder, dimension, ctlpoints, ustride, vstride, u, v, val); + + for(i=0; i<=2; i++){ + newPartialU[i] = partialU[i] * val[3] - val[i] * partialU[3]; + newPartialV[i] = partialV[i] * val[3] - val[i] * partialV[3]; + } + crossProduct(newPartialU, newPartialV, retNormal); + normalize(retNormal); + } +} + +/*if size is 0, then nothing is done*/ +static void normalize(float vec[3]) +{ + float size = (float)sqrt(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]); + + if(size < TOLERANCE) + { +#ifdef DEBUG + fprintf(stderr, "Warning: in oglBSpline.c normal is 0\n"); +#endif + return; + } + else { + vec[0] = vec[0]/size; + vec[1] = vec[1]/size; + vec[2] = vec[2]/size; + } +} + + +static void crossProduct(float x[3], float y[3], float ret[3]) +{ + ret[0] = x[1]*y[2] - y[1]*x[2]; + ret[1] = x[2]*y[0] - y[2]*x[0]; + ret[2] = x[0]*y[1] - y[0]*x[1]; + +} + diff --git a/mesalib/src/glu/sgi/libnurbs/interface/bezierEval.h b/mesalib/src/glu/sgi/libnurbs/interface/bezierEval.h new file mode 100644 index 000000000..93e8c69d1 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/interface/bezierEval.h @@ -0,0 +1,48 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ +/* +*/ + +#ifndef _BEZIEREVAL_H +#define _BEZIEREVAL_H + +void bezierCurveEval(float u0, float u1, int order, float *ctlpoints, int stride, int dimension, float u, float retpoint[]); +void bezierCurveEvalDer(float u0, float u1, int order, float *ctlpoints, int stride, int dimension, float u, float retDer[]); +void bezierCurveEvalDerGen(int der, float u0, float u1, int order, float *ctlpoints, int stride, int dimension, float u, float retDer[]); + + +void bezierSurfEvalDerGen(int uder, int vder, float u0, float u1, int uorder, float v0, float v1, int vorder, int dimension, float *ctlpoints, int ustride, int vstride, float u, float v, float ret[]); + +void bezierSurfEval(float u0, float u1, int uorder, float v0, float v1, int vorder, int dimension, float *ctlpoints, int ustride, int vstride, float u, float v, float ret[]); + +void bezierSurfEvalNormal(float u0, float u1, int uorder, float v0, float v1, int vorder, int dimension, float *ctlpoints, int ustride, int vstride, float u, float v, float retNormal[]); + + +#endif diff --git a/mesalib/src/glu/sgi/libnurbs/interface/bezierPatch.cc b/mesalib/src/glu/sgi/libnurbs/interface/bezierPatch.cc new file mode 100644 index 000000000..dbab3a1a2 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/interface/bezierPatch.cc @@ -0,0 +1,206 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include "gluos.h" +#include <stdlib.h> +#include <stdio.h> +#include <assert.h> +#include <GL/glu.h> /*for drawing bzier patch*/ +#include "bezierPatch.h" +#include "bezierEval.h" + +/* + *allocate an instance of bezierPatch. The control points are unknown. But + *the space of this array is allocated with size of + * uorder*vorder*dimension + * + */ +bezierPatch* bezierPatchMake(float umin, float vmin, float umax, float vmax, int uorder, int vorder, int dimension) +{ + bezierPatch* ret = (bezierPatch*) malloc(sizeof(bezierPatch)); + assert(ret); + ret->umin = umin; + ret->vmin = vmin; + ret->umax = umax; + ret->vmax = vmax; + ret->uorder = uorder; + ret->vorder = vorder; + ret->dimension = dimension; + ret->ctlpoints = (float*) malloc(sizeof(float) * dimension * uorder * vorder); + assert(ret->ctlpoints); + + ret->next = NULL; + + return ret; +} + +bezierPatch* bezierPatchMake2(float umin, float vmin, float umax, float vmax, int uorder, int vorder, int dimension, int ustride, int vstride, float* ctlpoints) +{ + bezierPatch* ret = (bezierPatch*) malloc(sizeof(bezierPatch)); + assert(ret); + ret->umin = umin; + ret->vmin = vmin; + ret->umax = umax; + ret->vmax = vmax; + ret->uorder = uorder; + ret->vorder = vorder; + ret->dimension = dimension; + ret->ctlpoints = (float*) malloc(sizeof(float) * dimension * uorder * vorder); + assert(ret->ctlpoints); + + /*copy the control points there*/ + int the_ustride = vorder * dimension; + int the_vstride = dimension; + for(int i=0; i<uorder; i++) + for(int j=0; j<vorder; j++) + for(int k=0; k<dimension; k++) + ret->ctlpoints[i * the_ustride + j*the_vstride+k] = ctlpoints[i*ustride+j*vstride+k]; + + ret->next = NULL; + + return ret; +} + +/* + *deallocate the space as allocated by Make + */ +void bezierPatchDelete(bezierPatch *b) +{ + free(b->ctlpoints); + free(b); +} + +/*delete the whole linked list + */ +void bezierPatchDeleteList(bezierPatch *b) +{ + bezierPatch *temp; + while (b != NULL) { + temp = b; + b = b->next; + bezierPatchDelete(temp); + } +} + +bezierPatch* bezierPatchInsert(bezierPatch *list, bezierPatch *b) +{ + b->next = list; + return b; +} + +/*print the data stored in this patch*/ +void bezierPatchPrint(bezierPatch *b) +{ + printf("bezierPatch:\n"); + printf("umin,umax=(%f,%f), (vmin, vmax)=(%f,%f)\n", b->umin, b->umax, b->vmin, b->vmax); + printf("uorder=%i, vorder=%i\n", b->uorder, b->vorder); + printf("idmension = %i\n", b->dimension); +} + +/*print the whole list*/ +void bezierPatchPrintList(bezierPatch *list) +{ + bezierPatch* temp; + for(temp=list; temp != NULL; temp = temp->next) + bezierPatchPrint(temp); +} + +void bezierPatchEval(bezierPatch *b, float u, float v, float ret[]) +{ + if( u >= b->umin && u<= b->umax + && v >= b->vmin && v<= b->vmax) + { + + bezierSurfEval(b->umin, b->umax, b->uorder, b->vmin, b->vmax, b->vorder, b->dimension, b->ctlpoints, b->dimension * b->vorder, b->dimension, u, v, ret); + + } + else if(b->next != NULL) + bezierPatchEval(b->next, u,v, ret); + else + bezierSurfEval(b->umin, b->umax, b->uorder, b->vmin, b->vmax, b->vorder, b->dimension, b->ctlpoints, b->dimension * b->vorder, b->dimension, u, v, ret); +} + +/*the returned normal is normlized + */ +void bezierPatchEvalNormal(bezierPatch *b, float u, float v, float ret[]) +{ + bezierSurfEvalNormal(b->umin, b->umax, b->uorder, b->vmin, b->vmax, b->vorder, b->dimension, b->ctlpoints, b->dimension * b->vorder, b->dimension, u, v, ret); + + if( u >= b->umin && u<= b->umax + && v >= b->vmin && v<= b->vmax) + { + bezierSurfEvalNormal(b->umin, b->umax, b->uorder, b->vmin, b->vmax, b->vorder, b->dimension, b->ctlpoints, b->dimension * b->vorder, b->dimension, u, v, ret); + } + else if(b->next != NULL) + bezierPatchEvalNormal(b->next, u,v, ret); + else + bezierSurfEvalNormal(b->umin, b->umax, b->uorder, b->vmin, b->vmax, b->vorder, b->dimension, b->ctlpoints, b->dimension * b->vorder, b->dimension, u, v, ret); + +} + +void bezierPatchDraw(bezierPatch *bpatch, int u_reso, int v_reso) +{ + if(bpatch->dimension == 3) + glMap2f(GL_MAP2_VERTEX_3, bpatch->umin, bpatch->umax, 3*bpatch->vorder, bpatch->uorder, bpatch->vmin, bpatch->vmax,3, bpatch->vorder, (GLfloat*) bpatch->ctlpoints); + else + glMap2f(GL_MAP2_VERTEX_4, bpatch->umin, bpatch->umax, 4*bpatch->vorder, bpatch->uorder, bpatch->vmin, bpatch->vmax,3, bpatch->vorder, (GLfloat*) bpatch->ctlpoints); + + glMapGrid2f(u_reso, bpatch->umin, bpatch->umax, + v_reso, bpatch->vmin, bpatch->vmax); + glEvalMesh2(GL_LINE, 0, u_reso, 0, v_reso); +} + +void bezierPatchListDraw(bezierPatch *list, int u_reso, int v_reso) +{ + bezierPatch *temp; +glEnable(GL_LIGHTING); +glEnable(GL_LIGHT0); +glEnable(GL_MAP2_VERTEX_3); +glEnable(GL_AUTO_NORMAL); +glEnable(GL_NORMALIZE); +glColor3f(1,0,0); +#ifdef DEBUG +printf("mapmap\n"); +#endif + + + for(temp = list; temp != NULL; temp = temp->next) + bezierPatchDraw(temp, u_reso, v_reso); +} + + + diff --git a/mesalib/src/glu/sgi/libnurbs/interface/bezierPatch.h b/mesalib/src/glu/sgi/libnurbs/interface/bezierPatch.h new file mode 100644 index 000000000..981183afa --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/interface/bezierPatch.h @@ -0,0 +1,104 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ +/* +*/ + +#ifndef _BEZIERPATCH_H +#define _BEZIERPATCH_H + +typedef struct bezierPatch{ + float umin, vmin, umax, vmax; + int uorder; /*order= degree + 1*/ + int vorder; + + /* + *the control points are stored in a one dimensional array. + *the surface is defined as: + * s(u,v) = sum_{i,j} P(i,j) * B_i(u) * B_j(v). + *where P(i,j) are the control points, B_i(.) are Bezier + *basis functions. + *Each control point can have dimension 3 or 4: (x,y,z,w). + *The components of P(i,j) are stored in a one dimensional + *array: + * ctlpoints[] + *in the order of: + * P[0,0], P[0,1], ..., P[0,vorder-1], + * P[1,0], P[1,1], ..., P[1,vorder-1], + * ... + * P[uorder-1,0], P[uorder-1,1], ..., P[uorder-1,vorder-1]. + */ + int dimension; + float* ctlpoints; + + /* + *in case we have to manage multiple bezierPatches. + */ + struct bezierPatch *next; + +} bezierPatch; + +#ifdef __cplusplus +extern "C" { +#endif + +bezierPatch* bezierPatchMake(float umin, float vmin, float umax, float vmax, int urder, int vorder, int dimension); + +bezierPatch* bezierPatchMake2(float umin, float vmin, float umax, float vmax, int urder, int vorder, int dimension, int ustride, int vstride, float *ctlpoints); + + +bezierPatch* bezierPatchInsert(bezierPatch *list, bezierPatch *b); + +void bezierPatchDelete(bezierPatch *b); + +void bezierPatchDeleteList(bezierPatch *b); + +void bezierPatchPrint(bezierPatch *b); + +void bezierPatchPrintList(bezierPatch *list); + +void bezierPatchEval(bezierPatch *b, float u, float v, float ret[]); + +void bezierPatchEvalNormal(bezierPatch *b, float u, float v, float retNormal[]); + +void bezierPatchEval(bezierPatch *b, float u, float v, float ret[]); + +void bezierPatchEvalNormal(bezierPatch *b, float u, float v, float ret[]); + + +void bezierPatchDraw(bezierPatch *bpatch, int u_reso, int v_reso); + +void bezierPatchListDraw(bezierPatch *list, int u_reso, int v_reso); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/mesalib/src/glu/sgi/libnurbs/interface/bezierPatchMesh.cc b/mesalib/src/glu/sgi/libnurbs/interface/bezierPatchMesh.cc new file mode 100644 index 000000000..ac7ff84fc --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/interface/bezierPatchMesh.cc @@ -0,0 +1,610 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include "gluos.h" +#include <stdlib.h> +#include <stdio.h> +#include <assert.h> +#include <GL/gl.h> +#include "bezierEval.h" +#include "bezierPatchMesh.h" + +static int isDegenerate(float A[2], float B[2], float C[2]); + +void drawStrips(float *vertex_array, float *normal_array, int *length_array, GLenum *type_array, int num_strips) +{ + int i,j,k; + k=0; + /*k is the index of the first component of the current vertex*/ + for(i=0; i<num_strips; i++) + { + glBegin(type_array[i]); + for(j=0; j<length_array[i]; j++) + { + glNormal3fv(normal_array+k); + glVertex3fv(vertex_array+k); + k += 3; + } + glEnd(); + } +} + +void bezierPatchMeshListDelDeg(bezierPatchMesh* list) +{ + bezierPatchMesh* temp; + for(temp=list; temp != NULL; temp = temp->next) + { + bezierPatchMeshDelDeg(temp); + } +} + +void bezierPatchMeshListDelete(bezierPatchMesh *list) +{ + if(list == NULL) return; + bezierPatchMeshListDelete(list->next); + bezierPatchMeshDelete(list); +} + + + + +bezierPatchMesh* bezierPatchMeshListReverse(bezierPatchMesh* list) +{ + bezierPatchMesh* ret=NULL; + bezierPatchMesh* temp; + bezierPatchMesh* nextone; + for(temp = list; temp != NULL; temp = nextone) + { + nextone = temp->next; + ret=bezierPatchMeshListInsert(ret, temp); + } + return ret; +} + +/*maptype is either GL_MAP2_VERTEX_3 or GL_MAP2_VERTEX_4 + */ +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) +{ + int i,j,k; + int dimension; + int the_ustride; + int the_vstride; + + if(maptype == GL_MAP2_VERTEX_3) dimension = 3; + else if (maptype==GL_MAP2_VERTEX_4) dimension = 4; + else { + fprintf(stderr, "error in inMap2f, maptype=%i is wrong, maptype,map is invalid\n", maptype); + return NULL; + } + + bezierPatchMesh *ret = (bezierPatchMesh*) malloc(sizeof(bezierPatchMesh)); + assert(ret); + + ret->bpatch_normal = NULL; + ret->bpatch_color = NULL; + ret->bpatch_texcoord = NULL; + ret->bpatch = bezierPatchMake(umin, vmin, umax, vmax, uorder, vorder, dimension); + + /*copy the control points there*/ + the_ustride = vorder * dimension; + the_vstride = dimension; + for(i=0; i<uorder; i++) + for(j=0; j<vorder; j++) + for(k=0; k<dimension; k++) + ret->bpatch->ctlpoints[i * the_ustride + j*the_vstride+k] = ctlpoints[i*ustride+j*vstride+k]; + + + ret->size_UVarray = size_UVarray; + ret->size_length_array = size_length_array; + ret->UVarray = (float*) malloc(sizeof(float) * size_UVarray); + assert(ret->UVarray); + ret->length_array = (int *)malloc(sizeof(int) * size_length_array); + assert(ret->length_array); + ret->type_array = (GLenum *)malloc(sizeof(GLenum) * size_length_array); + assert(ret->type_array); + + ret->index_UVarray = 0; + ret->index_length_array = 0; + + ret->vertex_array = NULL; + ret->normal_array = NULL; + ret->color_array = NULL; + ret->texcoord_array = NULL; + + ret->next = NULL; + return ret; +} + +bezierPatchMesh *bezierPatchMeshMake2(int size_UVarray, int size_length_array) +{ + bezierPatchMesh *ret = (bezierPatchMesh*) malloc(sizeof(bezierPatchMesh)); + assert(ret); + + ret->bpatch = NULL; + ret->bpatch_normal = NULL; + ret->bpatch_color = NULL; + ret->bpatch_texcoord = NULL; + + ret->size_UVarray = size_UVarray; + ret->size_length_array = size_length_array; + ret->UVarray = (float*) malloc(sizeof(float) * size_UVarray); + assert(ret->UVarray); + ret->length_array = (int *)malloc(sizeof(int) * size_length_array); + assert(ret->length_array); + ret->type_array = (GLenum *)malloc(sizeof(GLenum) * size_length_array); + assert(ret->type_array); + + ret->index_UVarray = 0; + ret->index_length_array = 0; + + ret->vertex_array = NULL; + ret->normal_array = NULL; + ret->color_array = NULL; + ret->texcoord_array = NULL; + + ret->next = NULL; + return ret; +} + +void bezierPatchMeshPutPatch(bezierPatchMesh *bpm, int maptype, float umin, float umax, int ustride, int uorder, float vmin, float vmax, int vstride, int vorder, float *ctlpoints) +{ + switch(maptype){ + case GL_MAP2_VERTEX_3: + bpm->bpatch = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 3, ustride, vstride, ctlpoints); + break; + case GL_MAP2_VERTEX_4: + bpm->bpatch = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 4,ustride, vstride, ctlpoints ); + break; + case GL_MAP2_NORMAL: + bpm->bpatch_normal = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 3, ustride, vstride, ctlpoints); + break; + case GL_MAP2_INDEX: + bpm->bpatch_color = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 1, ustride, vstride, ctlpoints); + break; + case GL_MAP2_COLOR_4: + bpm->bpatch_color = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 4, ustride, vstride, ctlpoints); + break; + case GL_MAP2_TEXTURE_COORD_1: + bpm->bpatch_texcoord = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 1, ustride, vstride, ctlpoints); + break; + case GL_MAP2_TEXTURE_COORD_2: + bpm->bpatch_texcoord = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 2, ustride, vstride, ctlpoints); + break; + case GL_MAP2_TEXTURE_COORD_3: + bpm->bpatch_texcoord = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 3, ustride, vstride, ctlpoints); + break; + case GL_MAP2_TEXTURE_COORD_4: + bpm->bpatch_texcoord = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 4, ustride, vstride, ctlpoints); + break; + default: + fprintf(stderr, "error in bezierPatchMeshPutPatch, maptype=%i is wrong, maptype,map is invalid\n", maptype); + } +} + + +/*delete everything including the arrays. So if you want to output the + *pointers of the arrays, you should not use this function to deallocate space. + *you should dealocate manually + */ +void bezierPatchMeshDelete(bezierPatchMesh *bpm) +{ + if(bpm->bpatch != NULL) + bezierPatchDelete(bpm->bpatch); + if(bpm->bpatch_normal != NULL) + bezierPatchDelete(bpm->bpatch_normal); + if(bpm->bpatch_color != NULL) + bezierPatchDelete(bpm->bpatch_color); + if(bpm->bpatch_texcoord != NULL) + bezierPatchDelete(bpm->bpatch_texcoord); + + free(bpm->UVarray); + free(bpm->length_array); + free(bpm->vertex_array); + free(bpm->normal_array); + free(bpm->type_array); + free(bpm); +} + +/*begin a strip + *type is the primitive type: + */ +void bezierPatchMeshBeginStrip(bezierPatchMesh *bpm, GLenum type) +{ + bpm->counter = 0; + bpm->type = type; +} + +/*signal the end of the current strip*/ +void bezierPatchMeshEndStrip(bezierPatchMesh *bpm) +{ + int i; + + /*if there are no vertices in this strip, then nothing needs to be done*/ + if(bpm->counter == 0) return; + + /*if the length_array is full, it should be expanded*/ + if(bpm->index_length_array >= bpm->size_length_array) + { + int *temp = (int*) malloc(sizeof(int) * (bpm->size_length_array*2 + 1)); + assert(temp); + GLenum *temp_type = (GLenum*) malloc(sizeof(GLenum) * (bpm->size_length_array*2 + 1)); + assert(temp_type); + /*update the size*/ + bpm->size_length_array = bpm->size_length_array*2 + 1; + + /*copy*/ + for(i=0; i<bpm->index_length_array; i++) + { + temp[i] = bpm->length_array[i]; + temp_type[i] = bpm->type_array[i]; + } + + /*deallocate old array*/ + free(bpm->length_array); + free(bpm->type_array); + + /*point to the new array which is twice as bigger*/ + bpm->length_array = temp; + bpm->type_array = temp_type; + } + bpm->type_array[bpm->index_length_array] = bpm->type; + bpm->length_array[bpm->index_length_array++] = bpm->counter; + +} + +/*insert (u,v) */ +void bezierPatchMeshInsertUV(bezierPatchMesh *bpm, float u, float v) +{ + int i; + /*if the UVarray is full, it should be expanded*/ + if(bpm->index_UVarray+1 >= bpm->size_UVarray) + { + float *temp = (float*) malloc(sizeof(float) * (bpm->size_UVarray * 2 + 2)); + assert(temp); + + /*update the size*/ + bpm->size_UVarray = bpm->size_UVarray*2 + 2; + + /*copy*/ + for(i=0; i<bpm->index_UVarray; i++) + { + temp[i] = bpm->UVarray[i]; + } + + /*deallocate old array*/ + free(bpm->UVarray); + + /*pointing to the new arrays*/ + bpm->UVarray = temp; + } + /*insert the new UV*/ + bpm->UVarray[bpm->index_UVarray] = u; + bpm->index_UVarray++; + bpm->UVarray[bpm->index_UVarray] = v; + bpm->index_UVarray++; + + /*update counter: one more vertex*/ + bpm->counter++; + + +} + +void bezierPatchMeshPrint(bezierPatchMesh *bpm) +{ + int i; + printf("the bezier patch is\n"); + bezierPatchPrint(bpm->bpatch); + printf("index_length_array= %i\n", bpm->index_length_array); + printf("size_length_array =%i\n", bpm->size_length_array); + printf("index_UVarray =%i\n", bpm->index_UVarray); + printf("size_UVarray =%i\n", bpm->size_UVarray); + printf("UVarray is\n"); + for(i=0; i<bpm->index_UVarray; i++) + printf("%f ", bpm->UVarray[i]); + + printf("length_array is\n"); + for(i=0; i<bpm->index_length_array; i++) + printf("%i ", bpm->length_array[i]); + printf("\n"); + +} + +/*insert a new patch in front of the current linked list and return the new list*/ +bezierPatchMesh* bezierPatchMeshListInsert(bezierPatchMesh* list, bezierPatchMesh* bpm) +{ + bpm->next=list; + return bpm; +} + +/*print all the patches*/ +void bezierPatchMeshListPrint(bezierPatchMesh* list) +{ + bezierPatchMesh *temp; + for(temp = list; temp != NULL; temp = temp->next) + { + bezierPatchMeshPrint(temp); + } +} + +int bezierPatchMeshListTotalStrips(bezierPatchMesh* list) +{ + int sum=0; + bezierPatchMesh *temp; + for(temp=list; temp != NULL; temp = temp->next) + { + sum += temp->index_length_array; + } + return sum; +} + +int bezierPatchMeshListTotalVert(bezierPatchMesh* list) +{ + int sum=0; + bezierPatchMesh *temp; + for(temp=list; temp != NULL; temp = temp->next) + { + sum += temp->index_UVarray; + } + return sum/2; +} + +int bezierPatchMeshListNumTriangles(bezierPatchMesh* list) +{ + int sum=0; + bezierPatchMesh* temp; + for(temp=list; temp != NULL; temp = temp->next) + { + sum += bezierPatchMeshNumTriangles(temp); + } + return sum; +} + +int bezierPatchMeshNumTriangles(bezierPatchMesh* bpm) +{ + int i; + int sum=0; + for(i=0; i<bpm->index_length_array; i++) + { + switch(bpm->type_array[i]) + { + case GL_TRIANGLES: + sum += bpm->length_array[i]/3; + break; + case GL_TRIANGLE_FAN: + if(bpm->length_array[i] > 2) + sum += bpm->length_array[i]-2; + break; + case GL_TRIANGLE_STRIP: + if(bpm->length_array[i] > 2) + sum += bpm->length_array[i]-2; + break; + case GL_QUAD_STRIP: + if(bpm->length_array[i]>2) + sum += (bpm->length_array[i]-2); + break; + default: + fprintf(stderr,"error in bezierPatchMeshListNumTriangles, type invalid\n"); + } + } + return sum; +} + +/*delete degenerate triangles*/ +void bezierPatchMeshDelDeg(bezierPatchMesh* bpm) +{ + if(bpm == NULL) return; + int i,j,k; + int *new_length_array; + GLenum *new_type_array; + int index_new_length_array; + float *new_UVarray; + int index_new_UVarray; + + new_length_array = (int*)malloc(sizeof(int) * bpm->index_length_array); + assert(new_length_array); + new_type_array = (GLenum*)malloc(sizeof(GLenum) * bpm->index_length_array); + assert(new_length_array); + new_UVarray = (float*) malloc(sizeof(float) * bpm->index_UVarray); + assert(new_UVarray); + + index_new_length_array = 0; + index_new_UVarray=0; + k=0; + for(i=0; i<bpm->index_length_array; i++){ + + /*(if not degenerate, we have to copy*/ + if( (bpm->length_array[i] != 3) || (!isDegenerate(bpm->UVarray+k, bpm->UVarray+k+2, bpm->UVarray+k+4))) + { + for(j=0; j<2* bpm->length_array[i]; j++) + new_UVarray[index_new_UVarray++] = bpm->UVarray[k++]; + + new_length_array[index_new_length_array] = bpm->length_array[i]; + new_type_array[index_new_length_array] = bpm->type_array[i]; + index_new_length_array++; + } + else + { + k += 6; + } + } + free(bpm->UVarray); + free(bpm->length_array); + free(bpm->type_array); + bpm->UVarray=new_UVarray; + bpm->length_array=new_length_array; + bpm->type_array=new_type_array; + bpm->index_UVarray = index_new_UVarray; + bpm->index_length_array = index_new_length_array; + +} + +/*(u,v) to XYZ + *the xyz and normals are stored in vertex_array, + *and normal_array. the spaces of both are allocated here + */ +void bezierPatchMeshEval(bezierPatchMesh* bpm) +{ + int i,j,k,l; + float u,v; + float u0 = bpm->bpatch->umin; + float u1 = bpm->bpatch->umax; + int uorder = bpm->bpatch->uorder; + float v0 = bpm->bpatch->vmin; + float v1 = bpm->bpatch->vmax; + int vorder = bpm->bpatch->vorder; + int dimension = bpm->bpatch->dimension; + int ustride = dimension * vorder; + int vstride = dimension; + float *ctlpoints = bpm->bpatch->ctlpoints; + + bpm->vertex_array = (float*) malloc(sizeof(float)* (bpm->index_UVarray/2) * 3); + assert(bpm->vertex_array); + bpm->normal_array = (float*) malloc(sizeof(float)* (bpm->index_UVarray/2) * 3); + assert(bpm->normal_array); + + k=0; + l=0; + for(i=0; i<bpm->index_length_array; i++) + { + for(j=0; j<bpm->length_array[i]; j++) + { + u = bpm->UVarray[k]; + v = bpm->UVarray[k+1]; + bezierSurfEval(u0,u1,uorder, v0, v1, vorder, dimension, ctlpoints, ustride, vstride, u,v, bpm->vertex_array+l); + bezierSurfEvalNormal(u0,u1,uorder, v0, v1, vorder, dimension, ctlpoints, ustride, vstride, u,v, bpm->normal_array+l); + k += 2; + l += 3; + } + } +} + +void bezierPatchMeshListEval(bezierPatchMesh* list) +{ + bezierPatchMesh* temp; + for(temp = list; temp != NULL; temp = temp->next) + { + bezierPatchMeshEval(temp); + } +} + +void bezierPatchMeshDraw(bezierPatchMesh* bpm) +{ + int i,j,k; + k=0; + /*k is the index of the first component of the current vertex*/ + for(i=0; i<bpm->index_length_array; i++) + { + glBegin(bpm->type_array[i]); + for(j=0; j<bpm->length_array[i]; j++) + { + glNormal3fv(bpm->normal_array+k); + glVertex3fv(bpm->vertex_array+k); + k+= 3; + } + glEnd(); + } +} + +void bezierPatchMeshListDraw(bezierPatchMesh* list) +{ + bezierPatchMesh* temp; + for(temp = list; temp != NULL; temp = temp->next) + { + bezierPatchMeshDraw(temp); + } +} + +void bezierPatchMeshListCollect(bezierPatchMesh* list, float **vertex_array, float **normal_array, int **length_array, GLenum **type_array, int *num_strips) +{ + int i,j,k,l; + bezierPatchMesh *temp; + int total_num_vertices = bezierPatchMeshListTotalVert(list); + (*vertex_array) = (float *) malloc(sizeof(float) * total_num_vertices*3); + assert(*vertex_array); + (*normal_array) = (float *) malloc(sizeof(float) * total_num_vertices*3); + assert(*normal_array); + + *num_strips = bezierPatchMeshListTotalStrips(list); + + *length_array = (int*) malloc(sizeof(int) * (*num_strips)); + assert(*length_array); + + *type_array = (GLenum*) malloc(sizeof(GLenum) * (*num_strips)); + assert(*type_array); + + k=0; + l=0; + for(temp = list; temp != NULL; temp = temp->next) + { + int x=0; + for(i=0; i<temp->index_length_array; i++) + { + for(j=0; j<temp->length_array[i]; j++) + { + (*vertex_array)[k] = temp->vertex_array[x]; + (*vertex_array)[k+1] = temp->vertex_array[x+1]; + (*vertex_array)[k+2] = temp->vertex_array[x+2]; + + (*normal_array)[k] = temp->normal_array[x]; + (*normal_array)[k+1] = temp->normal_array[x+1]; + (*normal_array)[k+2] = temp->normal_array[x+2]; + + x += 3; + k += 3; + } + (*type_array)[l] = temp->type_array[i]; + (*length_array)[l++] = temp->length_array[i]; + } + } +} + + + +static int isDegenerate(float A[2], float B[2], float C[2]) +{ + if( (A[0] == B[0] && A[1]==B[1]) || + (A[0] == C[0] && A[1]==C[1]) || + (B[0] == C[0] && B[1]==C[1]) + ) + return 1; + else + return 0; +} + + + + diff --git a/mesalib/src/glu/sgi/libnurbs/interface/bezierPatchMesh.h b/mesalib/src/glu/sgi/libnurbs/interface/bezierPatchMesh.h new file mode 100644 index 000000000..449329665 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/interface/bezierPatchMesh.h @@ -0,0 +1,120 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ +/* +*/ + +#ifndef _BEZIERPATCHMESH_H +#define _BEZIERPATCHMESH_H + +#include "bezierPatch.h" + +typedef struct bezierPatchMesh{ + bezierPatch *bpatch; /*vertex*/ + bezierPatch *bpatch_normal; + bezierPatch *bpatch_texcoord; /*s,t,r,q*/ + bezierPatch *bpatch_color; /*RGBA*/ + + float *UVarray; /*all UV components of all vertices of all strips*/ + int *length_array; /*[i] is the number of vertices in the ith strip*/ + GLenum *type_array; /*[i] is the type of the ith primitive*/ + + /*to support dynamic insertion*/ + int size_UVarray; + int index_UVarray; + int size_length_array; + int index_length_array; + + int counter; /*track the current strip size*/ + GLenum type; /*track the current type: 0: GL_TRIANGLES, 1: GL_TRIANGLE_STRIP*/ + + /*we eventually want to evaluate from (u,v) to (x,y,z) and draw them*/ + float *vertex_array; /*each vertex contains three components*/ + float *normal_array; /*each normal contains three components*/ + float *color_array; + float *texcoord_array; + + /*in case we need a linked list*/ + struct bezierPatchMesh *next; +} bezierPatchMesh; + +#ifdef __cplusplus +extern "C" { +#endif + + + +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); + +/*initilize patches to be null*/ +bezierPatchMesh *bezierPatchMeshMake2(int size_UVarray, int size_length_array); + +void bezierPatchMeshPutPatch(bezierPatchMesh *bpm, int maptype, float umin, float umax, int ustride, int uorder, float vmin, float vmax, int vstride, int vorder, float *ctlpoints); + +void bezierPatchMeshDelete(bezierPatchMesh *bpm); + +void bezierPatchMeshBeginStrip(bezierPatchMesh *bpm, GLenum type); + +void bezierPatchMeshEndStrip(bezierPatchMesh *bpm); + +void bezierPatchMeshInsertUV(bezierPatchMesh *bpm, float u, float v); + +void bezierPatchMeshPrint(bezierPatchMesh *bpm); + +bezierPatchMesh* bezierPatchMeshListInsert(bezierPatchMesh* list, bezierPatchMesh* bpm); + +void bezierPatchMeshListPrint(bezierPatchMesh* list); + +int bezierPatchMeshListTotalStrips(bezierPatchMesh* list); + +int bezierPatchMeshListTotalVert(bezierPatchMesh* list); +int bezierPatchMeshNumTriangles(bezierPatchMesh* bpm); +int bezierPatchMeshListNumTriangles(bezierPatchMesh* list); + +void bezierPatchMeshDelDeg(bezierPatchMesh* bpm); + + +void bezierPatchMeshEval(bezierPatchMesh* bpm); + +void bezierPatchMeshDraw(bezierPatchMesh* bpm); + +void bezierPatchMeshListDraw(bezierPatchMesh* list); +void bezierPatchMeshListEval(bezierPatchMesh* list); +void bezierPatchMeshListCollect(bezierPatchMesh* list, float **vertex_array, float **normal_array, int **length_array, GLenum **type_array, int *num_strips); + +void bezierPatchMeshListDelDeg(bezierPatchMesh* list); +void bezierPatchMeshListDelete(bezierPatchMesh *list); +bezierPatchMesh* bezierPatchMeshListReverse(bezierPatchMesh* list); +void drawStrips(float *vertex_array, float *normal_array, int *length_array, GLenum *type_array, int num_strips); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mesalib/src/glu/sgi/libnurbs/interface/glcurveval.cc b/mesalib/src/glu/sgi/libnurbs/interface/glcurveval.cc new file mode 100644 index 000000000..b6591dba0 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/interface/glcurveval.cc @@ -0,0 +1,402 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * glcurveval.c++ + * + */ + +/* Polynomial Evaluator Interface */ + +#include "gluos.h" +#include "glimports.h" +#include "glrenderer.h" +#include "glcurveval.h" +#include "nurbsconsts.h" + +OpenGLCurveEvaluator::OpenGLCurveEvaluator(void) +{ + //no default callback functions + beginCallBackN = NULL; + endCallBackN = NULL; + vertexCallBackN = NULL; + normalCallBackN = NULL; + colorCallBackN = NULL; + texcoordCallBackN = NULL; + beginCallBackData = NULL; + endCallBackData = NULL; + vertexCallBackData = NULL; + normalCallBackData = NULL; + colorCallBackData = NULL; + texcoordCallBackData = NULL; + + userData = NULL; + + vertex_flag = 0; + normal_flag = 0; + color_flag = 0; + texcoord_flag = 0; + + em_vertex.uprime = -1.0; + em_normal.uprime = -1.0; + em_color.uprime = -1.0; + em_texcoord.uprime = -1.0; + output_triangles = 0; // don't output triangles by default +} + +OpenGLCurveEvaluator::~OpenGLCurveEvaluator(void) +{ +} + +/* added nonsense to avoid the warning messages at compile time */ +void +OpenGLCurveEvaluator::addMap(CurveMap *m) +{ + m = m; +} + +void +OpenGLCurveEvaluator::range1f(long type, REAL *from, REAL *to) +{ + type = type; + from = from; + to = to; +} + +void +OpenGLCurveEvaluator::domain1f(REAL ulo, REAL uhi) +{ + ulo = ulo; + uhi = uhi; +} + +void +OpenGLCurveEvaluator::bgnline(void) +{ + if(output_triangles) + beginCallBack(GL_LINE_STRIP, userData); + else + glBegin((GLenum) GL_LINE_STRIP); +} + +void +OpenGLCurveEvaluator::endline(void) +{ + if(output_triangles) + endCallBack(userData); + else + glEnd(); +} + +/*--------------------------------------------------------------------------- + * disable - turn off a curve map + *--------------------------------------------------------------------------- + */ +void +OpenGLCurveEvaluator::disable(long type) +{ + glDisable((GLenum) type); +} + +/*--------------------------------------------------------------------------- + * enable - turn on a curve map + *--------------------------------------------------------------------------- + */ +void +OpenGLCurveEvaluator::enable(long type) +{ + glEnable((GLenum) type); +} + +/*------------------------------------------------------------------------- + * mapgrid1f - define a lattice of points with origin and offset + *------------------------------------------------------------------------- + */ +void +OpenGLCurveEvaluator::mapgrid1f(long nu, REAL u0, REAL u1) +{ + if(output_triangles) + { + global_grid_u0 = u0; + global_grid_u1 = u1; + global_grid_nu = (int) nu; + } + else + glMapGrid1f((GLint) nu, (GLfloat) u0, (GLfloat) u1); +} + +/*------------------------------------------------------------------------- + * bgnmap1 - preamble to curve definition and evaluations + *------------------------------------------------------------------------- + */ +void +OpenGLCurveEvaluator::bgnmap1f(long) +{ + if(output_triangles) + { + //initialized so that no maps are set initially + vertex_flag = 0; + normal_flag = 0; + color_flag = 0; + texcoord_flag = 0; + //no need to worry about gl states when doing callback + } + else + glPushAttrib((GLbitfield) GL_EVAL_BIT); +} + +/*------------------------------------------------------------------------- + * endmap1 - postamble to a curve map + *------------------------------------------------------------------------- + */ +void +OpenGLCurveEvaluator::endmap1f(void) +{ + if(output_triangles) + { + + } + else + glPopAttrib(); +} + +/*------------------------------------------------------------------------- + * map1f - pass a desription of a curve map + *------------------------------------------------------------------------- + */ +void +OpenGLCurveEvaluator::map1f( + long type, /* map type */ + REAL ulo, /* lower parametric bound */ + REAL uhi, /* upper parametric bound */ + long stride, /* distance to next point in REALS */ + long order, /* parametric order */ + REAL *pts /* control points */ +) +{ + if(output_triangles) + { + int dimension = 0; + int which = 0; + switch(type){ + case GL_MAP1_VERTEX_3: + which = 0; + dimension = 3; + break; + case GL_MAP1_VERTEX_4: + which=0; + dimension = 4; + break; + case GL_MAP1_INDEX: + which=2; + dimension = 1; + break; + case GL_MAP1_COLOR_4: + which=2; + dimension = 4; + break; + case GL_MAP1_NORMAL: + which=1; + dimension = 3; + break; + case GL_MAP1_TEXTURE_COORD_1: + which=3; + dimension = 1; + break; + case GL_MAP1_TEXTURE_COORD_2: + which=3; + dimension = 2; + break; + + case GL_MAP1_TEXTURE_COORD_3: + which=3; + dimension = 3; + break; + case GL_MAP1_TEXTURE_COORD_4: + which=3; + dimension = 4; + break; + } + inMap1f(which, dimension, ulo, uhi, stride, order, pts); + } + else + glMap1f((GLenum) type, (GLfloat) ulo, (GLfloat) uhi, (GLint) stride, + (GLint) order, (const GLfloat *) pts); +} + +/*------------------------------------------------------------------------- + * mapmesh1f - evaluate a mesh of points on lattice + *------------------------------------------------------------------------- + */ +void OpenGLCurveEvaluator::mapmesh1f(long style, long from, long to) +{ + if(output_triangles) + { + inMapMesh1f((int) from, (int) to); + } + else + { + switch(style) { + default: + case N_MESHFILL: + case N_MESHLINE: + glEvalMesh1((GLenum) GL_LINE, (GLint) from, (GLint) to); + break; + case N_MESHPOINT: + glEvalMesh1((GLenum) GL_POINT, (GLint) from, (GLint) to); + break; + } + } +} + +/*------------------------------------------------------------------------- + * evalpoint1i - evaluate a point on a curve + *------------------------------------------------------------------------- + */ +void OpenGLCurveEvaluator::evalpoint1i(long i) +{ + glEvalPoint1((GLint) i); +} + +/*------------------------------------------------------------------------- + * evalcoord1f - evaluate a point on a curve + *------------------------------------------------------------------------- + */ +void OpenGLCurveEvaluator::evalcoord1f(long, REAL u) +{ + glEvalCoord1f((GLfloat) u); +} + +void +#ifdef _WIN32 +OpenGLCurveEvaluator::putCallBack(GLenum which, void (GLAPIENTRY *fn)()) +#else +OpenGLCurveEvaluator::putCallBack(GLenum which, _GLUfuncptr fn) +#endif +{ + switch(which) + { + case GLU_NURBS_BEGIN: + beginCallBackN = (void (GLAPIENTRY *) (GLenum)) fn; + break; + case GLU_NURBS_END: + endCallBackN = (void (GLAPIENTRY *) (void)) fn; + break; + case GLU_NURBS_VERTEX: + vertexCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn; + break; + case GLU_NURBS_NORMAL: + normalCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn; + break; + case GLU_NURBS_COLOR: + colorCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn; + break; + case GLU_NURBS_TEXTURE_COORD: + texcoordCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn; + break; + case GLU_NURBS_BEGIN_DATA: + beginCallBackData = (void (GLAPIENTRY *) (GLenum, void*)) fn; + break; + case GLU_NURBS_END_DATA: + endCallBackData = (void (GLAPIENTRY *) (void*)) fn; + break; + case GLU_NURBS_VERTEX_DATA: + vertexCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn; + break; + case GLU_NURBS_NORMAL_DATA: + normalCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn; + break; + case GLU_NURBS_COLOR_DATA: + colorCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn; + break; + case GLU_NURBS_TEXTURE_COORD_DATA: + texcoordCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn; + break; + } +} + +void +OpenGLCurveEvaluator::beginCallBack(GLenum which, void *data) +{ + if(beginCallBackData) + beginCallBackData(which, data); + else if(beginCallBackN) + beginCallBackN(which); +} + +void +OpenGLCurveEvaluator::endCallBack(void *data) +{ + if(endCallBackData) + endCallBackData(data); + else if(endCallBackN) + endCallBackN(); +} + +void +OpenGLCurveEvaluator::vertexCallBack(const GLfloat *vert, void* data) +{ + if(vertexCallBackData) + vertexCallBackData(vert, data); + else if(vertexCallBackN) + vertexCallBackN(vert); +} + + +void +OpenGLCurveEvaluator::normalCallBack(const GLfloat *normal, void* data) +{ + if(normalCallBackData) + normalCallBackData(normal, data); + else if(normalCallBackN) + normalCallBackN(normal); +} + +void +OpenGLCurveEvaluator::colorCallBack(const GLfloat *color, void* data) +{ + if(colorCallBackData) + colorCallBackData(color, data); + else if(colorCallBackN) + colorCallBackN(color); +} + +void +OpenGLCurveEvaluator::texcoordCallBack(const GLfloat *texcoord, void* data) +{ + if(texcoordCallBackData) + texcoordCallBackData(texcoord, data); + else if(texcoordCallBackN) + texcoordCallBackN(texcoord); +} diff --git a/mesalib/src/glu/sgi/libnurbs/interface/glcurveval.h b/mesalib/src/glu/sgi/libnurbs/interface/glcurveval.h new file mode 100644 index 000000000..8fa493034 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/interface/glcurveval.h @@ -0,0 +1,157 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * glcurveval.h + * + */ + +#ifndef __gluglcurveval_h_ +#define __gluglcurveval_h_ + +#include "gluos.h" +#include <GL/gl.h> +#include <GL/glu.h> +#include "basiccrveval.h" + +class CurveMap; + +/*for internal evaluator callback stuff*/ +#ifndef IN_MAX_BEZIER_ORDER +#define IN_MAX_BEZIER_ORDER 40 /*XXX should be bigger than machine order*/ +#endif + +#ifndef IN_MAX_DIMENSION +#define IN_MAX_DIMENSION 4 +#endif + +typedef struct curveEvalMachine{ + REAL uprime; //cached previously evaluated uprime + int k; //the dimension + REAL u1; + REAL u2; + int ustride; + int uorder; + REAL ctlpoints[IN_MAX_BEZIER_ORDER*IN_MAX_DIMENSION]; + REAL ucoeff[IN_MAX_BEZIER_ORDER];//cache the polynomial values +} curveEvalMachine; + +class OpenGLCurveEvaluator : public BasicCurveEvaluator { +public: + OpenGLCurveEvaluator(void); + virtual ~OpenGLCurveEvaluator(void); + void range1f(long, REAL *, REAL *); + void domain1f(REAL, REAL); + void addMap(CurveMap *); + + void enable(long); + void disable(long); + void bgnmap1f(long); + void map1f(long, REAL, REAL, long, long, REAL *); + void mapgrid1f(long, REAL, REAL); + void mapmesh1f(long, long, long); + void evalpoint1i(long); + void evalcoord1f(long, REAL); + void endmap1f(void); + + void bgnline(void); + void endline(void); + + void put_vertices_call_back(int flag) + { + output_triangles = flag; + } +#ifdef _WIN32 + void putCallBack(GLenum which, void (GLAPIENTRY *fn)() ); +#else + void putCallBack(GLenum which, _GLUfuncptr fn ); +#endif + void set_callback_userData(void *data) + { + userData = data; + } + +/*------------------begin for curveEvalMachine------------*/ +curveEvalMachine em_vertex; +curveEvalMachine em_normal; +curveEvalMachine em_color; +curveEvalMachine em_texcoord; +int vertex_flag; //whether there is a vertex map or not +int normal_flag; //whether there is a normal map or not +int color_flag; //whether there is a color map or not +int texcoord_flag; //whether there is a texture map or not + +REAL global_grid_u0; +REAL global_grid_u1; +int global_grid_nu; + +void inMap1f(int which, //0: vert, 1: norm, 2: color, 3: tex + int dimension, + REAL ulower, + REAL uupper, + int ustride, + int uorder, + REAL *ctlpoints); + +void inPreEvaluate(int order, REAL vprime, REAL *coeff); +void inDoDomain1(curveEvalMachine *em, REAL u, REAL *retPoint); +void inDoEvalCoord1(REAL u); +void inMapMesh1f(int umin, int umax); + +void (GLAPIENTRY *beginCallBackN) (GLenum type); +void (GLAPIENTRY *endCallBackN) (void); +void (GLAPIENTRY *vertexCallBackN) (const GLfloat *vert); +void (GLAPIENTRY *normalCallBackN) (const GLfloat *normal); +void (GLAPIENTRY *colorCallBackN) (const GLfloat *color); +void (GLAPIENTRY *texcoordCallBackN) (const GLfloat *texcoord); + +void (GLAPIENTRY *beginCallBackData) (GLenum type, void* data); +void (GLAPIENTRY *endCallBackData) (void* data); +void (GLAPIENTRY *vertexCallBackData) (const GLfloat *vert, void* data); +void (GLAPIENTRY *normalCallBackData) (const GLfloat *normal, void* data); +void (GLAPIENTRY *colorCallBackData) (const GLfloat *color, void* data); +void (GLAPIENTRY *texcoordCallBackData) (const GLfloat *texcoord, void* data); + +void* userData; //the opaque pointer for Data callback functions +void beginCallBack(GLenum type, void* data); +void endCallBack(void* data); +void vertexCallBack(const GLfloat *vert, void *data); +void normalCallBack(const GLfloat *normal, void* data); +void colorCallBack(const GLfloat *color, void* data); +void texcoordCallBack(const GLfloat *texcoord, void* data); + + +/*------------------end for curveEvalMachine------------*/ + +private: + int output_triangles; //true 1; false 0 +}; + +#endif /* __gluglcurveval_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/interface/glimports.h b/mesalib/src/glu/sgi/libnurbs/interface/glimports.h new file mode 100644 index 000000000..6e69feb40 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/interface/glimports.h @@ -0,0 +1,42 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * glimports.h + * + */ + +#ifndef __gluimports_h_ +#define __gluimports_h_ + +#include "mystdlib.h" +#include "mystdio.h" + +#endif /* __gluimports_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/interface/glinterface.cc b/mesalib/src/glu/sgi/libnurbs/interface/glinterface.cc new file mode 100644 index 000000000..ba64bcd2d --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/interface/glinterface.cc @@ -0,0 +1,469 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include "gluos.h" +#include <GL/gl.h> +#include <GL/glu.h> +#include <stdio.h> +#include "glimports.h" +#include "glrenderer.h" +#include "nurbsconsts.h" + +//#define DOWN_LOAD_NURBS +#ifdef DOWN_LOAD_NURBS + +#include "oglTrimNurbs.h" +static int surfcount = 0; +static oglTrimNurbs* otn = NULL; +nurbSurf* tempNurb = NULL; +oglTrimLoops* tempTrim = NULL; +#endif + + +//for LOD +extern "C" {void glu_LOD_eval_list(GLUnurbs *nurb, int level);} + +void glu_LOD_eval_list(GLUnurbs *nurb, int level) +{ + nurb->LOD_eval_list(level); +} + +GLUnurbs * GLAPIENTRY +gluNewNurbsRenderer(void) +{ + GLUnurbs *t; + + t = new GLUnurbs(); + return t; +} + +void GLAPIENTRY +gluDeleteNurbsRenderer(GLUnurbs *r) +{ + delete r; +} + +extern "C" +void GLAPIENTRY + +gluDeleteNurbsTessellatorEXT(GLUnurbsObj *r) +{ + delete r; +} + +void GLAPIENTRY +gluBeginSurface(GLUnurbs *r) +{ +#ifdef DOWN_LOAD_NURBS +surfcount++; +tempTrim = OTL_make(10,10); +#endif + r->bgnsurface(0); +} + +void GLAPIENTRY +gluBeginCurve(GLUnurbs *r) +{ + r->bgncurve(0); +} + +void GLAPIENTRY +gluEndCurve(GLUnurbs *r) +{ + r->endcurve(); +} + +void GLAPIENTRY +gluEndSurface(GLUnurbs *r) +{ +#ifdef DOWN_LOAD_NURBS +if(surfcount == 1) + otn = OTN_make(1); +OTN_insert(otn, tempNurb, tempTrim); +if(surfcount >= 1) +{ +#ifdef DEBUG +printf("write file\n"); +#endif +OTN_write(otn, "out.otn"); + +} +#endif + + r->endsurface(); +} + +void GLAPIENTRY +gluBeginTrim(GLUnurbs *r) +{ +#ifdef DOWN_LOAD_NURBS +OTL_bgnTrim(tempTrim); +#endif + + r->bgntrim(); +} + +void GLAPIENTRY +gluEndTrim(GLUnurbs *r) +{ +#ifdef DOWN_LOAD_NURBS +OTL_endTrim(tempTrim); +#endif + r->endtrim(); +} + +void GLAPIENTRY +gluPwlCurve(GLUnurbs *r, GLint count, INREAL array[], + GLint stride, GLenum type) +{ +#ifdef DOWN_LOAD_NURBS +OTL_pwlCurve(tempTrim, count, array, stride, type); +#endif + + int realType; + switch(type) { + case GLU_MAP1_TRIM_2: + realType = N_P2D; + break; + case GLU_MAP1_TRIM_3: + realType = N_P2DR; + break; + default: + realType = type; + break; + } + r->pwlcurve(count, array, sizeof(INREAL) * stride, realType); +} + +void GLAPIENTRY +gluNurbsCurve(GLUnurbs *r, GLint nknots, INREAL knot[], GLint stride, + INREAL ctlarray[], GLint order, GLenum type) +{ +#ifdef DOWN_LOAD_NURBS +OTL_nurbsCurve(tempTrim, nknots, knot, stride, ctlarray, order, type); +#endif + + int realType; + + switch(type) { + case GLU_MAP1_TRIM_2: + realType = N_P2D; + break; + case GLU_MAP1_TRIM_3: + realType = N_P2DR; + break; + default: + realType = type; + break; + } + + r->nurbscurve(nknots, knot, sizeof(INREAL) * stride, ctlarray, order, + realType); +} + +void GLAPIENTRY +gluNurbsSurface(GLUnurbs *r, GLint sknot_count, GLfloat *sknot, + GLint tknot_count, GLfloat *tknot, + GLint s_stride, GLint t_stride, + GLfloat *ctlarray, GLint sorder, GLint torder, + GLenum type) +{ +#ifdef DOWN_LOAD_NURBS + { + int dimension; + switch(type){ + case GL_MAP2_VERTEX_3: + dimension = 3; + break; + case GL_MAP2_VERTEX_4: + dimension = 4; + break; + default: + fprintf(stderr, "error in glinterface.c++, type no implemented\n"); + exit(1); + } +tempNurb = nurbSurfMake(sknot_count, sknot, + tknot_count, tknot, + sorder, torder, + dimension, + ctlarray, + s_stride, t_stride); + + } +#endif + + r->nurbssurface(sknot_count, sknot, tknot_count, tknot, + sizeof(INREAL) * s_stride, sizeof(INREAL) * t_stride, + ctlarray, sorder, torder, type); +} + +void GLAPIENTRY +gluLoadSamplingMatrices(GLUnurbs *r, const GLfloat modelMatrix[16], + const GLfloat projMatrix[16], + const GLint viewport[4]) +{ + r->useGLMatrices(modelMatrix, projMatrix, viewport); +} + +void GLAPIENTRY +gluNurbsProperty(GLUnurbs *r, GLenum property, GLfloat value) +{ + GLfloat nurbsValue; + + switch (property) { + case GLU_AUTO_LOAD_MATRIX: + r->setautoloadmode(value); + return; + + case GLU_CULLING: + if (value != 0.0) { + nurbsValue = N_CULLINGON; + } else { + nurbsValue = N_NOCULLING; + } + r->setnurbsproperty(GL_MAP2_VERTEX_3, N_CULLING, nurbsValue); + r->setnurbsproperty(GL_MAP2_VERTEX_4, N_CULLING, nurbsValue); + r->setnurbsproperty(GL_MAP1_VERTEX_3, N_CULLING, nurbsValue); + r->setnurbsproperty(GL_MAP1_VERTEX_4, N_CULLING, nurbsValue); + return; + + case GLU_SAMPLING_METHOD: + if (value == GLU_PATH_LENGTH) { + nurbsValue = N_PATHLENGTH; + } else if (value == GLU_PARAMETRIC_ERROR) { + nurbsValue = N_PARAMETRICDISTANCE; + } else if (value == GLU_DOMAIN_DISTANCE) { + nurbsValue = N_DOMAINDISTANCE; + r->set_is_domain_distance_sampling(1); //optimzing untrimmed case + + } else if (value == GLU_OBJECT_PARAMETRIC_ERROR) { + nurbsValue = N_OBJECTSPACE_PARA; + r->setautoloadmode( 0.0 ); + r->setSamplingMatrixIdentity(); + } else if (value == GLU_OBJECT_PATH_LENGTH) { + nurbsValue = N_OBJECTSPACE_PATH; + r->setautoloadmode( 0.0 ); + r->setSamplingMatrixIdentity(); + } else { + r->postError(GLU_INVALID_VALUE); + return; + } + + r->setnurbsproperty(GL_MAP2_VERTEX_3, N_SAMPLINGMETHOD, nurbsValue); + r->setnurbsproperty(GL_MAP2_VERTEX_4, N_SAMPLINGMETHOD, nurbsValue); + r->setnurbsproperty(GL_MAP1_VERTEX_3, N_SAMPLINGMETHOD, nurbsValue); + r->setnurbsproperty(GL_MAP1_VERTEX_4, N_SAMPLINGMETHOD, nurbsValue); + return; + + case GLU_SAMPLING_TOLERANCE: + r->setnurbsproperty(GL_MAP2_VERTEX_3, N_PIXEL_TOLERANCE, value); + r->setnurbsproperty(GL_MAP2_VERTEX_4, N_PIXEL_TOLERANCE, value); + r->setnurbsproperty(GL_MAP1_VERTEX_3, N_PIXEL_TOLERANCE, value); + r->setnurbsproperty(GL_MAP1_VERTEX_4, N_PIXEL_TOLERANCE, value); + return; + + case GLU_PARAMETRIC_TOLERANCE: + r->setnurbsproperty(GL_MAP2_VERTEX_3, N_ERROR_TOLERANCE, value); + r->setnurbsproperty(GL_MAP2_VERTEX_4, N_ERROR_TOLERANCE, value); + r->setnurbsproperty(GL_MAP1_VERTEX_3, N_ERROR_TOLERANCE, value); + r->setnurbsproperty(GL_MAP1_VERTEX_4, N_ERROR_TOLERANCE, value); + return; + + + case GLU_DISPLAY_MODE: + + if (value == GLU_FILL) { + nurbsValue = N_FILL; + } else if (value == GLU_OUTLINE_POLYGON) { + nurbsValue = N_OUTLINE_POLY; + } else if (value == GLU_OUTLINE_PATCH) { + nurbsValue = N_OUTLINE_PATCH; + } else { + r->postError(GLU_INVALID_VALUE); + return; + } + r->setnurbsproperty(N_DISPLAY, nurbsValue); + + break; + + case GLU_U_STEP: + r->setnurbsproperty(GL_MAP1_VERTEX_3, N_S_STEPS, value); + r->setnurbsproperty(GL_MAP1_VERTEX_4, N_S_STEPS, value); + r->setnurbsproperty(GL_MAP2_VERTEX_3, N_S_STEPS, value); + r->setnurbsproperty(GL_MAP2_VERTEX_4, N_S_STEPS, value); + + //added for optimizing untrimmed case + r->set_domain_distance_u_rate(value); + break; + + case GLU_V_STEP: + r->setnurbsproperty(GL_MAP1_VERTEX_3, N_T_STEPS, value); + r->setnurbsproperty(GL_MAP1_VERTEX_4, N_T_STEPS, value); + r->setnurbsproperty(GL_MAP2_VERTEX_3, N_T_STEPS, value); + r->setnurbsproperty(GL_MAP2_VERTEX_4, N_T_STEPS, value); + + //added for optimizing untrimmed case + r->set_domain_distance_v_rate(value); + break; + + case GLU_NURBS_MODE: + if(value == GLU_NURBS_RENDERER) + r->put_callbackFlag(0); + else if(value == GLU_NURBS_TESSELLATOR) + r->put_callbackFlag(1); + else + r->postError(GLU_INVALID_ENUM); + break; + + default: + r->postError(GLU_INVALID_ENUM); + return; + } +} + +void GLAPIENTRY +gluGetNurbsProperty(GLUnurbs *r, GLenum property, GLfloat *value) +{ + GLfloat nurbsValue; + + switch(property) { + case GLU_AUTO_LOAD_MATRIX: + if (r->getautoloadmode()) { + *value = GL_TRUE; + } else { + *value = GL_FALSE; + } + break; + case GLU_CULLING: + r->getnurbsproperty(GL_MAP2_VERTEX_3, N_CULLING, &nurbsValue); + if (nurbsValue == N_CULLINGON) { + *value = GL_TRUE; + } else { + *value = GL_FALSE; + } + break; + case GLU_SAMPLING_METHOD: + r->getnurbsproperty(GL_MAP2_VERTEX_3, N_SAMPLINGMETHOD, value); + if(*value == N_PATHLENGTH) + *value = GLU_PATH_LENGTH; + else if(*value == N_PARAMETRICDISTANCE) + *value = GLU_PARAMETRIC_ERROR; + else if(*value == N_DOMAINDISTANCE) + *value = GLU_DOMAIN_DISTANCE; + else if(*value == N_OBJECTSPACE_PATH) + *value = GLU_OBJECT_PATH_LENGTH; + else if(*value == N_OBJECTSPACE_PARA) + *value = GLU_OBJECT_PARAMETRIC_ERROR; + break; + case GLU_SAMPLING_TOLERANCE: + r->getnurbsproperty(GL_MAP2_VERTEX_3, N_PIXEL_TOLERANCE, value); + break; + case GLU_PARAMETRIC_TOLERANCE: + r->getnurbsproperty(GL_MAP2_VERTEX_3, N_ERROR_TOLERANCE, value); + break; + + case GLU_U_STEP: + r->getnurbsproperty(GL_MAP2_VERTEX_3, N_S_STEPS, value); + break; + case GLU_V_STEP: + r->getnurbsproperty(GL_MAP2_VERTEX_3, N_T_STEPS, value); + break; + case GLU_DISPLAY_MODE: + r->getnurbsproperty(N_DISPLAY, &nurbsValue); + if (nurbsValue == N_FILL) { + *value = GLU_FILL; + } else if (nurbsValue == N_OUTLINE_POLY) { + *value = GLU_OUTLINE_POLYGON; + } else { + *value = GLU_OUTLINE_PATCH; + } + break; + + case GLU_NURBS_MODE: + if(r->is_callback()) + *value = GLU_NURBS_TESSELLATOR; + else + *value = GLU_NURBS_RENDERER; + break; + + default: + r->postError(GLU_INVALID_ENUM); + return; + } +} + +extern "C" void GLAPIENTRY +gluNurbsCallback(GLUnurbs *r, GLenum which, _GLUfuncptr fn ) +{ + switch (which) { + case GLU_NURBS_BEGIN: + case GLU_NURBS_END: + case GLU_NURBS_VERTEX: + case GLU_NURBS_NORMAL: + case GLU_NURBS_TEXTURE_COORD: + case GLU_NURBS_COLOR: + case GLU_NURBS_BEGIN_DATA: + case GLU_NURBS_END_DATA: + case GLU_NURBS_VERTEX_DATA: + case GLU_NURBS_NORMAL_DATA: + case GLU_NURBS_TEXTURE_COORD_DATA: + case GLU_NURBS_COLOR_DATA: + r->putSurfCallBack(which, fn); + break; + + case GLU_NURBS_ERROR: + r->errorCallback = (void (APIENTRY *)( GLenum e )) fn; + break; + default: + r->postError(GLU_INVALID_ENUM); + return; + } +} + +extern "C" +void GLAPIENTRY +gluNurbsCallbackDataEXT(GLUnurbs* r, void* userData) +{ + r->setNurbsCallbackData(userData); +} + +extern "C" +void GLAPIENTRY +gluNurbsCallbackData(GLUnurbs* r, void* userData) +{ + gluNurbsCallbackDataEXT(r,userData); +} diff --git a/mesalib/src/glu/sgi/libnurbs/interface/glrenderer.cc b/mesalib/src/glu/sgi/libnurbs/interface/glrenderer.cc new file mode 100644 index 000000000..17123fbc6 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/interface/glrenderer.cc @@ -0,0 +1,301 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include "gluos.h" +#include "glimports.h" +#include "glrenderer.h" + +GLUnurbs::GLUnurbs() + : NurbsTessellator(curveEvaluator, surfaceEvaluator) +{ + redefineMaps(); + defineMap(GL_MAP2_NORMAL, 0, 3); + defineMap(GL_MAP1_NORMAL, 0, 3); + defineMap(GL_MAP2_TEXTURE_COORD_1, 0, 1); + defineMap(GL_MAP1_TEXTURE_COORD_1, 0, 1); + defineMap(GL_MAP2_TEXTURE_COORD_2, 0, 2); + defineMap(GL_MAP1_TEXTURE_COORD_2, 0, 2); + defineMap(GL_MAP2_TEXTURE_COORD_3, 0, 3); + defineMap(GL_MAP1_TEXTURE_COORD_3, 0, 3); + defineMap(GL_MAP2_TEXTURE_COORD_4, 1, 4); + defineMap(GL_MAP1_TEXTURE_COORD_4, 1, 4); + defineMap(GL_MAP2_VERTEX_4, 1, 4); + defineMap(GL_MAP1_VERTEX_4, 1, 4); + defineMap(GL_MAP2_VERTEX_3, 0, 3); + defineMap(GL_MAP1_VERTEX_3, 0, 3); + defineMap(GL_MAP2_COLOR_4, 0, 4); + defineMap(GL_MAP1_COLOR_4, 0, 4); + defineMap(GL_MAP2_INDEX, 0, 1); + defineMap(GL_MAP1_INDEX, 0, 1); + + setnurbsproperty(GL_MAP1_VERTEX_3, N_SAMPLINGMETHOD, (float) N_PATHLENGTH); + setnurbsproperty(GL_MAP1_VERTEX_4, N_SAMPLINGMETHOD, (float) N_PATHLENGTH); + setnurbsproperty(GL_MAP2_VERTEX_3, N_SAMPLINGMETHOD, (float) N_PATHLENGTH); + setnurbsproperty(GL_MAP2_VERTEX_4, N_SAMPLINGMETHOD, (float) N_PATHLENGTH); + + setnurbsproperty(GL_MAP1_VERTEX_3, N_PIXEL_TOLERANCE, (float) 50.0); + setnurbsproperty(GL_MAP1_VERTEX_4, N_PIXEL_TOLERANCE, (float) 50.0); + setnurbsproperty(GL_MAP2_VERTEX_3, N_PIXEL_TOLERANCE, (float) 50.0); + setnurbsproperty(GL_MAP2_VERTEX_4, N_PIXEL_TOLERANCE, (float) 50.0); + + setnurbsproperty(GL_MAP1_VERTEX_3, N_ERROR_TOLERANCE, (float) 0.50); + setnurbsproperty(GL_MAP1_VERTEX_4, N_ERROR_TOLERANCE, (float) 0.50); + setnurbsproperty(GL_MAP2_VERTEX_3, N_ERROR_TOLERANCE, (float) 0.50); + setnurbsproperty(GL_MAP2_VERTEX_4, N_ERROR_TOLERANCE, (float) 0.50); + + setnurbsproperty(GL_MAP1_VERTEX_3, N_S_STEPS, (float) 100.0); + setnurbsproperty(GL_MAP1_VERTEX_4, N_S_STEPS, (float) 100.0); + setnurbsproperty(GL_MAP2_VERTEX_3, N_S_STEPS, (float) 100.0); + setnurbsproperty(GL_MAP2_VERTEX_4, N_S_STEPS, (float) 100.0); + + //added for optimizing untrimmed case + set_domain_distance_u_rate(100.0); + + setnurbsproperty(GL_MAP1_VERTEX_3, N_T_STEPS, (float) 100.0); + setnurbsproperty(GL_MAP1_VERTEX_4, N_T_STEPS, (float) 100.0); + setnurbsproperty(GL_MAP2_VERTEX_3, N_T_STEPS, (float) 100.0); + setnurbsproperty(GL_MAP2_VERTEX_4, N_T_STEPS, (float) 100.0); + + //added for optimizing untrimmed case + set_domain_distance_v_rate(100.0); + set_is_domain_distance_sampling(0); //since the default is path_length + + //default autoloadmode is true + autoloadmode = 1; + + //default callbackFlag is 0 + callbackFlag = 0; + + errorCallback = NULL; +} + +void +GLUnurbs::bgnrender(void) +{ + if (autoloadmode) { + loadGLMatrices(); + } +} + +void +GLUnurbs::endrender(void) +{ +} + +void +GLUnurbs::errorHandler(int i) +{ + int gluError; + + gluError = i + (GLU_NURBS_ERROR1 - 1); + postError( gluError ); +} + +void +GLUnurbs::loadGLMatrices(void) +{ + GLfloat vmat[4][4]; + GLint viewport[4]; + + grabGLMatrix((GLfloat (*)[4]) vmat); + loadCullingMatrix((GLfloat (*)[4]) vmat); + ::glGetIntegerv((GLenum) GL_VIEWPORT, (GLint *) viewport); + loadSamplingMatrix((const GLfloat (*)[4]) vmat, (const GLint *) viewport); +} + +void +GLUnurbs::useGLMatrices(const GLfloat modelMatrix[16], + const GLfloat projMatrix[16], + const GLint viewport[4]) +{ + GLfloat vmat[4][4]; + + multmatrix4d(vmat, (const GLfloat (*)[4]) modelMatrix, + (const GLfloat (*)[4]) projMatrix); + loadCullingMatrix((GLfloat (*)[4]) vmat); + loadSamplingMatrix((const GLfloat (*)[4]) vmat, (const GLint *) viewport); +} + +/*-------------------------------------------------------------------------- + * grabGLMatrix + *-------------------------------------------------------------------------- + */ + +void +GLUnurbs::grabGLMatrix(GLfloat vmat[4][4]) +{ + GLfloat m1[4][4], m2[4][4]; + + ::glGetFloatv((GLenum) GL_MODELVIEW_MATRIX, (GLfloat *) &(m1[0][0])); + ::glGetFloatv((GLenum) GL_PROJECTION_MATRIX, (GLfloat *) &(m2[0][0])); + multmatrix4d((GLfloat (*)[4]) vmat, + (const GLfloat (*)[4]) m1, (const GLfloat (*)[4]) m2); +} + +//for object space tesselation: view independent +void +GLUnurbs::setSamplingMatrixIdentity( void ) +{ + INREAL smat[4][4] = { + {1,0,0,0}, + {0,1,0,0}, + {0,0,1,0}, + {0,0,0,1} + }; + const long rstride = sizeof(smat[0]) / sizeof(smat[0][0]); + const long cstride = 1; + + setnurbsproperty(GL_MAP1_VERTEX_3, N_SAMPLINGMATRIX, &smat[0][0], rstride, + cstride); + setnurbsproperty(GL_MAP1_VERTEX_4, N_SAMPLINGMATRIX, &smat[0][0], rstride, + cstride); + setnurbsproperty(GL_MAP2_VERTEX_3, N_SAMPLINGMATRIX, &smat[0][0], rstride, + cstride); + setnurbsproperty(GL_MAP2_VERTEX_4, N_SAMPLINGMATRIX, &smat[0][0], rstride, + cstride); +} + + +void +GLUnurbs::loadSamplingMatrix(const GLfloat vmat[4][4], + const GLint viewport[4]) +{ + + /* rescale the mapping to correspond to pixels in x/y */ + REAL xsize = 0.5 * (REAL) (viewport[2]); + REAL ysize = 0.5 * (REAL) (viewport[3]); + + INREAL smat[4][4]; + smat[0][0] = vmat[0][0] * xsize; + smat[1][0] = vmat[1][0] * xsize; + smat[2][0] = vmat[2][0] * xsize; + smat[3][0] = vmat[3][0] * xsize; + + smat[0][1] = vmat[0][1] * ysize; + smat[1][1] = vmat[1][1] * ysize; + smat[2][1] = vmat[2][1] * ysize; + smat[3][1] = vmat[3][1] * ysize; + + smat[0][2] = 0.0; + smat[1][2] = 0.0; + smat[2][2] = 0.0; + smat[3][2] = 0.0; + + smat[0][3] = vmat[0][3]; + smat[1][3] = vmat[1][3]; + smat[2][3] = vmat[2][3]; + smat[3][3] = vmat[3][3]; + + const long rstride = sizeof(smat[0]) / sizeof(smat[0][0]); + const long cstride = 1; + + setnurbsproperty(GL_MAP1_VERTEX_3, N_SAMPLINGMATRIX, &smat[0][0], rstride, + cstride); + setnurbsproperty(GL_MAP1_VERTEX_4, N_SAMPLINGMATRIX, &smat[0][0], rstride, + cstride); + setnurbsproperty(GL_MAP2_VERTEX_3, N_SAMPLINGMATRIX, &smat[0][0], rstride, + cstride); + setnurbsproperty(GL_MAP2_VERTEX_4, N_SAMPLINGMATRIX, &smat[0][0], rstride, + cstride); +} + +void +GLUnurbs::loadCullingMatrix(GLfloat vmat[4][4]) +{ + INREAL cmat[4][4]; + + cmat[0][0] = vmat[0][0]; + cmat[0][1] = vmat[0][1]; + cmat[0][2] = vmat[0][2]; + cmat[0][3] = vmat[0][3]; + + cmat[1][0] = vmat[1][0]; + cmat[1][1] = vmat[1][1]; + cmat[1][2] = vmat[1][2]; + cmat[1][3] = vmat[1][3]; + + cmat[2][0] = vmat[2][0]; + cmat[2][1] = vmat[2][1]; + cmat[2][2] = vmat[2][2]; + cmat[2][3] = vmat[2][3]; + + cmat[3][0] = vmat[3][0]; + cmat[3][1] = vmat[3][1]; + cmat[3][2] = vmat[3][2]; + cmat[3][3] = vmat[3][3]; + + const long rstride = sizeof(cmat[0]) / sizeof(cmat[0][0]); + const long cstride = 1; + + setnurbsproperty(GL_MAP2_VERTEX_3, N_CULLINGMATRIX, &cmat[0][0], rstride, + cstride); + setnurbsproperty(GL_MAP2_VERTEX_4, N_CULLINGMATRIX, &cmat[0][0], rstride, + cstride); + //added for curves by zl + setnurbsproperty(GL_MAP1_VERTEX_3, N_CULLINGMATRIX, &cmat[0][0], rstride, + cstride); + setnurbsproperty(GL_MAP1_VERTEX_4, N_CULLINGMATRIX, &cmat[0][0], rstride, + cstride); +} + +/*--------------------------------------------------------------------- + * A = B * MAT ; transform a 4d vector through a 4x4 matrix + *--------------------------------------------------------------------- + */ +void +GLUnurbs::transform4d(GLfloat A[4], GLfloat B[4], GLfloat mat[4][4]) +{ + + A[0] = B[0]*mat[0][0] + B[1]*mat[1][0] + B[2]*mat[2][0] + B[3]*mat[3][0]; + A[1] = B[0]*mat[0][1] + B[1]*mat[1][1] + B[2]*mat[2][1] + B[3]*mat[3][1]; + A[2] = B[0]*mat[0][2] + B[1]*mat[1][2] + B[2]*mat[2][2] + B[3]*mat[3][2]; + A[3] = B[0]*mat[0][3] + B[1]*mat[1][3] + B[2]*mat[2][3] + B[3]*mat[3][3]; +} + +/*--------------------------------------------------------------------- + * new = [left][right] ; multiply two matrices together + *--------------------------------------------------------------------- + */ +void +GLUnurbs::multmatrix4d (GLfloat n[4][4], const GLfloat left[4][4], + const GLfloat right[4][4]) +{ + transform4d ((GLfloat *) n[0],(GLfloat *) left[0],(GLfloat (*)[4]) right); + transform4d ((GLfloat *) n[1],(GLfloat *) left[1],(GLfloat (*)[4]) right); + transform4d ((GLfloat *) n[2],(GLfloat *) left[2],(GLfloat (*)[4]) right); + transform4d ((GLfloat *) n[3],(GLfloat *) left[3],(GLfloat (*)[4]) right); +} diff --git a/mesalib/src/glu/sgi/libnurbs/interface/glrenderer.h b/mesalib/src/glu/sgi/libnurbs/interface/glrenderer.h new file mode 100644 index 000000000..3b72d44d1 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/interface/glrenderer.h @@ -0,0 +1,146 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * glrenderer.h + * + */ + +#ifndef __gluglrenderer_h_ +#define __gluglrenderer_h_ + +#include <GL/gl.h> +#include <GL/glu.h> +#include "nurbstess.h" +#include "glsurfeval.h" +#include "glcurveval.h" + +extern "C" { + typedef void (APIENTRY *errorCallbackType)( GLenum ); +} + +class GLUnurbs : public NurbsTessellator { + +public: + GLUnurbs( void ); + void loadGLMatrices( void ); + void useGLMatrices( const GLfloat modelMatrix[16], + const GLfloat projMatrix[16], + const GLint viewport[4] ); + void setSamplingMatrixIdentity( void ); + + void errorHandler( int ); + void bgnrender( void ); + void endrender( void ); + void setautoloadmode( INREAL value ) + { + + if (value) autoloadmode = GL_TRUE; + else autoloadmode = GL_FALSE; + + } + GLboolean getautoloadmode( void ) { return autoloadmode; } + + errorCallbackType errorCallback; + void postError( int which ) + { if (errorCallback) (errorCallback)( (GLenum)which ); } +#ifdef _WIN32 + void putSurfCallBack(GLenum which, void (GLAPIENTRY *fn)() ) +#else + void putSurfCallBack(GLenum which, _GLUfuncptr fn ) +#endif + { + curveEvaluator.putCallBack(which, fn); + surfaceEvaluator.putCallBack(which, fn); + } + + int get_vertices_call_back() + { + return surfaceEvaluator.get_vertices_call_back(); + } + + void put_vertices_call_back(int flag) + { + surfaceEvaluator.put_vertices_call_back(flag); + } + + int get_callback_auto_normal() + { + return surfaceEvaluator.get_callback_auto_normal(); + } + + void put_callback_auto_normal(int flag) + { + surfaceEvaluator.put_callback_auto_normal(flag); + } + + void setNurbsCallbackData(void* userData) + { + curveEvaluator.set_callback_userData(userData); + surfaceEvaluator.set_callback_userData(userData); + } + + + //for LOD + void LOD_eval_list(int level) + { + surfaceEvaluator.LOD_eval_list(level); + } + + //NEWCALLBACK + int is_callback() + { + return callbackFlag; + } + void put_callbackFlag(int flag) + { + callbackFlag = flag; + surfaceEvaluator.put_vertices_call_back(flag); + curveEvaluator.put_vertices_call_back(flag); + } + +private: + GLboolean autoloadmode; + OpenGLSurfaceEvaluator surfaceEvaluator; + OpenGLCurveEvaluator curveEvaluator; + + void loadSamplingMatrix( const GLfloat vmat[4][4], + const GLint viewport[4] ); + void loadCullingMatrix( GLfloat vmat[4][4] ); + static void grabGLMatrix( GLfloat vmat[4][4] ); + static void transform4d( GLfloat A[4], GLfloat B[4], + GLfloat mat[4][4] ); + static void multmatrix4d( GLfloat n[4][4], const GLfloat left[4][4], + const GLfloat right[4][4] ); + + int callbackFlag; +}; + +#endif /* __gluglrenderer_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/interface/glsurfeval.cc b/mesalib/src/glu/sgi/libnurbs/interface/glsurfeval.cc new file mode 100644 index 000000000..b5bfab1e2 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/interface/glsurfeval.cc @@ -0,0 +1,1293 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * glsurfeval.c++ + * + */ + +/* Polynomial Evaluator Interface */ +#include "gluos.h" +#include <stdio.h> +#include "glimports.h" +#include "glrenderer.h" +#include "glsurfeval.h" +#include "nurbsconsts.h" +#include "bezierPatchMesh.h" + + +//extern int surfcount; +//int surfcount=0; + +/*#define USE_INTERNAL_EVAL*/ //use internal evaluator + +/*whether do evaluation or not*/ +/*#define NO_EVALUATION*/ + +//#define USE_LOD //for LOD test, have to turn on USE_LOD in insurfeval.c++ too + +/*for statistics*/ +//#define STATISTICS +#ifdef STATISTICS +static int STAT_num_of_triangles=0; +static int STAT_num_of_eval_vertices=0; +static int STAT_num_of_quad_strips=0; +#endif + +/*for output triangles*/ +/*#define OUTPUT_TRIANGLES*/ + + +/*#define FOR_CHRIS*/ +#ifdef FOR_CHRIS +extern "C" { void evalUStripExt(int n_upper, REAL v_upper, REAL* upper_val, + int n_lower, REAL v_lower, REAL* lower_val);} + +extern "C" { void evalVStripExt(int n_left, REAL u_left, REAL* left_val, + int n_right, REAL u_right, REAL* right_val); + } +#endif + + +/**************begin for LOD_eval_list***********/ +void OpenGLSurfaceEvaluator::LOD_eval_list(int level) +{ + if(level == 0) + LOD_eval_level = 1; + else if(level == 1) + LOD_eval_level = 2; + else if(level == 2) + LOD_eval_level = 4; + else + LOD_eval_level = 8; + + inBPMListEvalEM(global_bpm); +} + + +OpenGLSurfaceEvaluator::OpenGLSurfaceEvaluator() +{ + int i; + + for (i=0; i<VERTEX_CACHE_SIZE; i++) { + vertexCache[i] = new StoredVertex; + } + tmeshing = 0; + which = 0; + vcount = 0; + + global_uorder = 0; + global_vorder = 0; + global_uprime = -1.0; + global_vprime = -1.0; + global_vprime_BV = -1.0; + global_uprime_BU = -1.0; + global_uorder_BU = 0; + global_vorder_BU = 0; + global_uorder_BV = 0; + global_vorder_BV = 0; + global_baseData = NULL; + + global_bpm = NULL; + output_triangles = 0; //don't output triangles by default + + //no default callback functions + beginCallBackN = NULL; + endCallBackN = NULL; + vertexCallBackN = NULL; + normalCallBackN = NULL; + colorCallBackN = NULL; + texcoordCallBackN = NULL; + beginCallBackData = NULL; + endCallBackData = NULL; + vertexCallBackData = NULL; + normalCallBackData = NULL; + colorCallBackData = NULL; + texcoordCallBackData = NULL; + + userData = NULL; + + auto_normal_flag = 0; + callback_auto_normal = 0; //default of GLU_CALLBACK_AUTO_NORMAL is 0 + vertex_flag = 0; + normal_flag = 0; + color_flag = 0; + texcoord_flag = 0; + + em_vertex.uprime = -1.0; + em_vertex.vprime = -1.0; + em_normal.uprime = -1.0; + em_normal.vprime = -1.0; + em_color.uprime = -1.0; + em_color.vprime = -1.0; + em_texcoord.uprime = -1.0; + em_texcoord.vprime = -1.0; + +#ifdef USE_LOD + LOD_eval_level = 1; +#endif +} + +OpenGLSurfaceEvaluator::~OpenGLSurfaceEvaluator() +{ + for (int ii= 0; ii< VERTEX_CACHE_SIZE; ii++) { + delete vertexCache[ii]; + vertexCache[ii]= 0; + } +} + +/*--------------------------------------------------------------------------- + * disable - turn off a map + *--------------------------------------------------------------------------- + */ +void +OpenGLSurfaceEvaluator::disable(long type) +{ + glDisable((GLenum) type); +} + +/*--------------------------------------------------------------------------- + * enable - turn on a map + *--------------------------------------------------------------------------- + */ +void +OpenGLSurfaceEvaluator::enable(long type) +{ + glEnable((GLenum) type); +} + +/*------------------------------------------------------------------------- + * mapgrid2f - define a lattice of points with origin and offset + *------------------------------------------------------------------------- + */ +void +OpenGLSurfaceEvaluator::mapgrid2f(long nu, REAL u0, REAL u1, long nv, REAL v0, REAL v1) +{ +#ifdef USE_INTERNAL_EVAL + inMapGrid2f((int) nu, (REAL) u0, (REAL) u1, (int) nv, + (REAL) v0, (REAL) v1); +#else + + if(output_triangles) + { + global_grid_u0 = u0; + global_grid_u1 = u1; + global_grid_nu = nu; + global_grid_v0 = v0; + global_grid_v1 = v1; + global_grid_nv = nv; + } + else + glMapGrid2d((GLint) nu, (GLdouble) u0, (GLdouble) u1, (GLint) nv, + (GLdouble) v0, (GLdouble) v1); + +#endif +} + +void +OpenGLSurfaceEvaluator::polymode(long style) +{ + if(! output_triangles) + { + switch(style) { + default: + case N_MESHFILL: + + glPolygonMode((GLenum) GL_FRONT_AND_BACK, (GLenum) GL_FILL); + break; + case N_MESHLINE: + glPolygonMode((GLenum) GL_FRONT_AND_BACK, (GLenum) GL_LINE); + break; + case N_MESHPOINT: + glPolygonMode((GLenum) GL_FRONT_AND_BACK, (GLenum) GL_POINT); + break; + } + } +} + +void +OpenGLSurfaceEvaluator::bgnline(void) +{ + if(output_triangles) + bezierPatchMeshBeginStrip(global_bpm, GL_LINE_STRIP); + else + glBegin((GLenum) GL_LINE_STRIP); +} + +void +OpenGLSurfaceEvaluator::endline(void) +{ + if(output_triangles) + bezierPatchMeshEndStrip(global_bpm); + else + glEnd(); +} + +void +OpenGLSurfaceEvaluator::range2f(long type, REAL *from, REAL *to) +{ +} + +void +OpenGLSurfaceEvaluator::domain2f(REAL ulo, REAL uhi, REAL vlo, REAL vhi) +{ +} + +void +OpenGLSurfaceEvaluator::bgnclosedline(void) +{ + if(output_triangles) + bezierPatchMeshBeginStrip(global_bpm, GL_LINE_LOOP); + else + glBegin((GLenum) GL_LINE_LOOP); +} + +void +OpenGLSurfaceEvaluator::endclosedline(void) +{ + if(output_triangles) + bezierPatchMeshEndStrip(global_bpm); + else + glEnd(); +} + + + + + +void +OpenGLSurfaceEvaluator::bgntmesh(void) +{ + + tmeshing = 1; + which = 0; + vcount = 0; + + if(output_triangles) + bezierPatchMeshBeginStrip(global_bpm, GL_TRIANGLES); + else + glBegin((GLenum) GL_TRIANGLES); + +} + +void +OpenGLSurfaceEvaluator::swaptmesh(void) +{ + which = 1 - which; + +} + +void +OpenGLSurfaceEvaluator::endtmesh(void) +{ + tmeshing = 0; + + + if(output_triangles) + bezierPatchMeshEndStrip(global_bpm); + else + glEnd(); +} + +void +OpenGLSurfaceEvaluator::bgntfan(void) +{ + + if(output_triangles) + bezierPatchMeshBeginStrip(global_bpm, GL_TRIANGLE_FAN); + else + glBegin((GLenum) GL_TRIANGLE_FAN); + +} +void +OpenGLSurfaceEvaluator::endtfan(void) +{ + if(output_triangles) + bezierPatchMeshEndStrip(global_bpm); + else + glEnd(); +} + +void +OpenGLSurfaceEvaluator::evalUStrip(int n_upper, REAL v_upper, REAL* upper_val, int n_lower, REAL v_lower, REAL* lower_val) +{ +#ifdef USE_INTERNAL_EVAL + inEvalUStrip(n_upper, v_upper, upper_val, + n_lower, v_lower, lower_val); +#else + +#ifdef FOR_CHRIS + evalUStripExt(n_upper, v_upper, upper_val, + n_lower, v_lower, lower_val); + return; + +#endif + int i,j,k,l; + REAL leftMostV[2]; + + /* + *the algorithm works by scanning from left to right. + *leftMostV: the left most of the remaining verteces (on both upper and lower). + * it could an element of upperVerts or lowerVerts. + *i: upperVerts[i] is the first vertex to the right of leftMostV on upper line + *j: lowerVerts[j] is the first vertex to the right of leftMostV on lower line + */ + + /*initialize i,j,and leftMostV + */ + if(upper_val[0] <= lower_val[0]) + { + i=1; + j=0; + + leftMostV[0] = upper_val[0]; + leftMostV[1] = v_upper; + } + else + { + i=0; + j=1; + + leftMostV[0] = lower_val[0]; + leftMostV[1] = v_lower; + + } + + /*the main loop. + *the invariance is that: + *at the beginning of each loop, the meaning of i,j,and leftMostV are + *maintained + */ + while(1) + { + if(i >= n_upper) /*case1: no more in upper*/ + { + if(j<n_lower-1) /*at least two vertices in lower*/ + { + bgntfan(); + coord2f(leftMostV[0], leftMostV[1]); +// glNormal3fv(leftMostNormal); +// glVertex3fv(leftMostXYZ); + + while(j<n_lower){ + coord2f(lower_val[j], v_lower); +// glNormal3fv(lowerNormal[j]); +// glVertex3fv(lowerXYZ[j]); + j++; + + } + endtfan(); + } + break; /*exit the main loop*/ + } + else if(j>= n_lower) /*case2: no more in lower*/ + { + if(i<n_upper-1) /*at least two vertices in upper*/ + { + bgntfan(); + coord2f(leftMostV[0], leftMostV[1]); +// glNormal3fv(leftMostNormal); +// glVertex3fv(leftMostXYZ); + + for(k=n_upper-1; k>=i; k--) /*reverse order for two-side lighting*/ + { + coord2f(upper_val[k], v_upper); +// glNormal3fv(upperNormal[k]); +// glVertex3fv(upperXYZ[k]); + } + + endtfan(); + } + break; /*exit the main loop*/ + } + else /* case3: neither is empty, plus the leftMostV, there is at least one triangle to output*/ + { + if(upper_val[i] <= lower_val[j]) + { + bgntfan(); + coord2f(lower_val[j], v_lower); +// glNormal3fv(lowerNormal[j]); +// glVertex3fv(lowerXYZ[j]); + + /*find the last k>=i such that + *upperverts[k][0] <= lowerverts[j][0] + */ + k=i; + + while(k<n_upper) + { + if(upper_val[k] > lower_val[j]) + break; + k++; + + } + k--; + + + for(l=k; l>=i; l--)/*the reverse is for two-side lighting*/ + { + coord2f(upper_val[l], v_upper); +// glNormal3fv(upperNormal[l]); +// glVertex3fv(upperXYZ[l]); + + } + coord2f(leftMostV[0], leftMostV[1]); +// glNormal3fv(leftMostNormal); +// glVertex3fv(leftMostXYZ); + + endtfan(); + + /*update i and leftMostV for next loop + */ + i = k+1; + + leftMostV[0] = upper_val[k]; + leftMostV[1] = v_upper; +// leftMostNormal = upperNormal[k]; +// leftMostXYZ = upperXYZ[k]; + } + else /*upperVerts[i][0] > lowerVerts[j][0]*/ + { + bgntfan(); + coord2f(upper_val[i], v_upper); +// glNormal3fv(upperNormal[i]); +// glVertex3fv(upperXYZ[i]); + + coord2f(leftMostV[0], leftMostV[1]); +// glNormal3fv(leftMostNormal); +// glVertex3fv(leftMostXYZ); + + + /*find the last k>=j such that + *lowerverts[k][0] < upperverts[i][0] + */ + k=j; + while(k< n_lower) + { + if(lower_val[k] >= upper_val[i]) + break; + coord2f(lower_val[k], v_lower); +// glNormal3fv(lowerNormal[k]); +// glVertex3fv(lowerXYZ[k]); + + k++; + } + endtfan(); + + /*update j and leftMostV for next loop + */ + j=k; + leftMostV[0] = lower_val[j-1]; + leftMostV[1] = v_lower; + +// leftMostNormal = lowerNormal[j-1]; +// leftMostXYZ = lowerXYZ[j-1]; + } + } + } + //clean up +// free(upperXYZ); +// free(lowerXYZ); +// free(upperNormal); +// free(lowerNormal); +#endif + +} + + +void +OpenGLSurfaceEvaluator::evalVStrip(int n_left, REAL u_left, REAL* left_val, int n_right, REAL u_right, REAL* right_val) +{ +#ifdef USE_INTERNAL_EVAL + inEvalVStrip(n_left, u_left, left_val, + n_right, u_right, right_val); +#else + +#ifdef FOR_CHRIS + evalVStripExt(n_left, u_left, left_val, + n_right, u_right, right_val); + return; + +#endif + + int i,j,k,l; + REAL botMostV[2]; + /* + *the algorithm works by scanning from bot to top. + *botMostV: the bot most of the remaining verteces (on both left and right). + * it could an element of leftVerts or rightVerts. + *i: leftVerts[i] is the first vertex to the top of botMostV on left line + *j: rightVerts[j] is the first vertex to the top of botMostV on rightline + */ + + /*initialize i,j,and botMostV + */ + if(left_val[0] <= right_val[0]) + { + i=1; + j=0; + + botMostV[0] = u_left; + botMostV[1] = left_val[0]; + } + else + { + i=0; + j=1; + + botMostV[0] = u_right; + botMostV[1] = right_val[0]; + } + + /*the main loop. + *the invariance is that: + *at the beginning of each loop, the meaning of i,j,and botMostV are + *maintained + */ + while(1) + { + if(i >= n_left) /*case1: no more in left*/ + { + if(j<n_right-1) /*at least two vertices in right*/ + { + bgntfan(); + coord2f(botMostV[0], botMostV[1]); + while(j<n_right){ + coord2f(u_right, right_val[j]); +// glNormal3fv(rightNormal[j]); +// glVertex3fv(rightXYZ[j]); + j++; + + } + endtfan(); + } + break; /*exit the main loop*/ + } + else if(j>= n_right) /*case2: no more in right*/ + { + if(i<n_left-1) /*at least two vertices in left*/ + { + bgntfan(); + coord2f(botMostV[0], botMostV[1]); +// glNormal3fv(botMostNormal); +// glVertex3fv(botMostXYZ); + + for(k=n_left-1; k>=i; k--) /*reverse order for two-side lighting*/ + { + coord2f(u_left, left_val[k]); +// glNormal3fv(leftNormal[k]); +// glVertex3fv(leftXYZ[k]); + } + + endtfan(); + } + break; /*exit the main loop*/ + } + else /* case3: neither is empty, plus the botMostV, there is at least one triangle to output*/ + { + if(left_val[i] <= right_val[j]) + { + bgntfan(); + coord2f(u_right, right_val[j]); +// glNormal3fv(rightNormal[j]); +// glVertex3fv(rightXYZ[j]); + + /*find the last k>=i such that + *leftverts[k][0] <= rightverts[j][0] + */ + k=i; + + while(k<n_left) + { + if(left_val[k] > right_val[j]) + break; + k++; + + } + k--; + + + for(l=k; l>=i; l--)/*the reverse is for two-side lighting*/ + { + coord2f(u_left, left_val[l]); +// glNormal3fv(leftNormal[l]); +// glVertex3fv(leftXYZ[l]); + + } + coord2f(botMostV[0], botMostV[1]); +// glNormal3fv(botMostNormal); +// glVertex3fv(botMostXYZ); + + endtfan(); + + /*update i and botMostV for next loop + */ + i = k+1; + + botMostV[0] = u_left; + botMostV[1] = left_val[k]; +// botMostNormal = leftNormal[k]; +// botMostXYZ = leftXYZ[k]; + } + else /*left_val[i] > right_val[j])*/ + { + bgntfan(); + coord2f(u_left, left_val[i]); +// glNormal3fv(leftNormal[i]); +// glVertex3fv(leftXYZ[i]); + + coord2f(botMostV[0], botMostV[1]); +// glNormal3fv(botMostNormal); +// glVertex3fv(botMostXYZ); + + + /*find the last k>=j such that + *rightverts[k][0] < leftverts[i][0] + */ + k=j; + while(k< n_right) + { + if(right_val[k] >= left_val[i]) + break; + coord2f(u_right, right_val[k]); +// glNormal3fv(rightNormal[k]); +// glVertex3fv(rightXYZ[k]); + + k++; + } + endtfan(); + + /*update j and botMostV for next loop + */ + j=k; + botMostV[0] = u_right; + botMostV[1] = right_val[j-1]; + +// botMostNormal = rightNormal[j-1]; +// botMostXYZ = rightXYZ[j-1]; + } + } + } + //clean up +// free(leftXYZ); +// free(leftNormal); +// free(rightXYZ); +// free(rightNormal); +#endif +} + + +void +OpenGLSurfaceEvaluator::bgnqstrip(void) +{ + if(output_triangles) + bezierPatchMeshBeginStrip(global_bpm, GL_QUAD_STRIP); + else + glBegin((GLenum) GL_QUAD_STRIP); + +#ifdef STATISTICS + STAT_num_of_quad_strips++; +#endif +} + +void +OpenGLSurfaceEvaluator::endqstrip(void) +{ + if(output_triangles) + bezierPatchMeshEndStrip(global_bpm); + else + glEnd(); + +} + +/*------------------------------------------------------------------------- + * bgnmap2f - preamble to surface definition and evaluations + *------------------------------------------------------------------------- + */ +void +OpenGLSurfaceEvaluator::bgnmap2f(long) +{ + if(output_triangles) + { + /*deallocate the space which may has been + *allocated by global_bpm previously + */ + if(global_bpm != NULL) { + bezierPatchMeshListDelete(global_bpm); + global_bpm = NULL; + } + + + /* + auto_normal_flag = 1; //always output normal in callback mode. + //we could have used the following code, + //but Inspector doesn't have gl context + //before it calls tessellator. + //this way is temporary. + */ + //NEWCALLBACK + //if one of the two normal callback functions are set, + //then set + if(normalCallBackN != NULL || + normalCallBackData != NULL) + auto_normal_flag = 1; + else + auto_normal_flag = 0; + + //initialize so that no maps initially + vertex_flag = 0; + normal_flag = 0; + color_flag = 0; + texcoord_flag = 0; + + /* + if(glIsEnabled(GL_AUTO_NORMAL) == GL_TRUE) + auto_normal_flag = 1; + else if (callback_auto_normal == 1) + auto_normal_flag = 1; + else + auto_normal_flag = 0; + */ + glPushAttrib((GLbitfield) GL_EVAL_BIT); + + } + else + { + glPushAttrib((GLbitfield) GL_EVAL_BIT); + + /*to avoid side effect, we restor the opengl state for GL_POLYGON_MODE + */ + glGetIntegerv(GL_POLYGON_MODE, gl_polygon_mode); + } + +} + +/*------------------------------------------------------------------------- + * endmap2f - postamble to a map + *------------------------------------------------------------------------- + */ +void +OpenGLSurfaceEvaluator::endmap2f(void) +{ + + if(output_triangles) + { + //bezierPatchMeshListDelDeg(global_bpm); + + // bezierPatchMeshListEval(global_bpm); + + //surfcount++; + //printf("surfcount=%i\n", surfcount); + //if(surfcount == 8) exit(0); + + inBPMListEvalEM(global_bpm); + + + +/* + global_bpm = bezierPatchMeshListReverse(global_bpm); + { + float *vertex_array; + float *normal_array; + int *length_array; + int *type_array; + int num_strips; + bezierPatchMeshListCollect(global_bpm, &vertex_array, &normal_array, &length_array, &type_array, &num_strips); + drawStrips(vertex_array, normal_array, length_array, type_array, num_strips); + free(vertex_array); + free(normal_array); + free(length_array); + free(type_array); + } +*/ + + //bezierPatchMeshListPrint(global_bpm); + //bezierPatchMeshListDraw(global_bpm); + +// printf("num triangles=%i\n", bezierPatchMeshListNumTriangles(global_bpm)); + +#ifdef USE_LOD +#else + bezierPatchMeshListDelete(global_bpm); + global_bpm = NULL; +#endif + glPopAttrib(); + } +else + { +#ifndef USE_LOD + glPopAttrib(); +#endif + +#ifdef STATISTICS + fprintf(stderr, "num_vertices=%i,num_triangles=%i,num_quads_strips=%i\n", STAT_num_of_eval_vertices,STAT_num_of_triangles,STAT_num_of_quad_strips); +#endif + + /*to restore the gl_polygon_mode + */ +#ifndef USE_LOD + glPolygonMode( GL_FRONT, (GLenum) gl_polygon_mode[0]); + glPolygonMode( GL_BACK, (GLenum) gl_polygon_mode[1]); +#endif +} + +} + +/*------------------------------------------------------------------------- + * map2f - pass a desription of a surface map + *------------------------------------------------------------------------- + */ +void +OpenGLSurfaceEvaluator::map2f( + long _type, + REAL _ulower, /* u lower domain coord */ + REAL _uupper, /* u upper domain coord */ + long _ustride, /* interpoint distance */ + long _uorder, /* parametric order */ + REAL _vlower, /* v lower domain coord */ + REAL _vupper, /* v upper domain coord */ + long _vstride, /* interpoint distance */ + long _vorder, /* parametric order */ + REAL *pts) /* control points */ +{ +#ifdef USE_INTERNAL_EVAL + inMap2f((int) _type, (REAL) _ulower, (REAL) _uupper, + (int) _ustride, (int) _uorder, (REAL) _vlower, + (REAL) _vupper, (int) _vstride, (int) _vorder, + (REAL *) pts); +#else + + + + if(output_triangles) + { + if(global_bpm == NULL) + global_bpm = bezierPatchMeshMake2(10,10); + if( + (global_bpm->bpatch == NULL && + (_type == GL_MAP2_VERTEX_3 || _type == GL_MAP2_VERTEX_4)) + || + (global_bpm->bpatch_normal == NULL && + (_type == GL_MAP2_NORMAL)) + || + (global_bpm->bpatch_color == NULL && + (_type == GL_MAP2_INDEX || _type == GL_MAP2_COLOR_4)) + || + (global_bpm->bpatch_texcoord == NULL && + (_type == GL_MAP2_TEXTURE_COORD_1 || + _type == GL_MAP2_TEXTURE_COORD_2 || + _type == GL_MAP2_TEXTURE_COORD_3 || + _type == GL_MAP2_TEXTURE_COORD_4 ) + )) + { + bezierPatchMeshPutPatch(global_bpm, (int) _type, _ulower, _uupper,(int) _ustride,(int) _uorder,_vlower, _vupper, (int) _vstride, (int) _vorder, pts); + } + else /*new surface patch (with multiple maps) starts*/ + { + bezierPatchMesh *temp = bezierPatchMeshMake2(10,10); + bezierPatchMeshPutPatch(temp, (int) _type, _ulower, _uupper,(int) _ustride,(int) _uorder,_vlower, _vupper, (int) _vstride, (int) _vorder, pts); + global_bpm = bezierPatchMeshListInsert(global_bpm, temp); + + /* + global_bpm = bezierPatchMeshListInsert(global_bpm, + bezierPatchMeshMake( + (int) _type, _ulower, _uupper,(int) _ustride, (int) _uorder, _vlower, _vupper, (int) _vstride, (int) _vorder, pts, 10, 10)); + */ + } + } + else /*not output triangles*/ + { + glMap2f((GLenum) _type, (GLfloat) _ulower, (GLfloat) _uupper, + (GLint) _ustride, (GLint) _uorder, (GLfloat) _vlower, + (GLfloat) _vupper, (GLint) _vstride, (GLint) _vorder, + (const GLfloat *) pts); + } + +#endif +} + + +/*------------------------------------------------------------------------- + * mapmesh2f - evaluate a mesh of points on lattice + *------------------------------------------------------------------------- + */ +void +OpenGLSurfaceEvaluator::mapmesh2f(long style, long umin, long umax, long vmin, long vmax) +{ +#ifdef NO_EVALUATION +return; +#endif + +#ifdef USE_INTERNAL_EVAL + inEvalMesh2((int)umin, (int)vmin, (int)umax, (int)vmax); +#else + + + +if(output_triangles) +{ +#ifdef USE_LOD + bezierPatchMeshBeginStrip(global_bpm, GL_POLYGON); + bezierPatchMeshInsertUV(global_bpm, global_grid_u0, global_grid_v0); + bezierPatchMeshInsertUV(global_bpm, global_grid_u1, global_grid_v1); + bezierPatchMeshInsertUV(global_bpm, (REAL)global_grid_nu, (REAL)global_grid_nv); + bezierPatchMeshInsertUV(global_bpm, (REAL)umin, (REAL)vmin); + bezierPatchMeshInsertUV(global_bpm, (REAL)umax, (REAL)vmax); + bezierPatchMeshEndStrip(global_bpm); + +#else + + REAL du, dv; + long i,j; + if(global_grid_nu == 0 || global_grid_nv == 0) + return; /*no points need to be output*/ + du = (global_grid_u1 - global_grid_u0) / (REAL)global_grid_nu; + dv = (global_grid_v1 - global_grid_v0) / (REAL)global_grid_nv; + + if(global_grid_nu >= global_grid_nv){ + + for(i=umin; i<umax; i++){ + REAL u1 = (i==global_grid_nu)? global_grid_u1:(global_grid_u0 + i*du); + REAL u2 = ((i+1) == global_grid_nu)? global_grid_u1: (global_grid_u0+(i+1)*du); + + bgnqstrip(); + for(j=vmax; j>=vmin; j--){ + REAL v1 = (j == global_grid_nv)? global_grid_v1: (global_grid_v0 +j*dv); + + coord2f(u1, v1); + coord2f(u2, v1); + } + endqstrip(); + } + } + else{ + + for(i=vmin; i<vmax; i++){ + REAL v1 = (i==global_grid_nv)? global_grid_v1:(global_grid_v0 + i*dv); + REAL v2 = ((i+1) == global_grid_nv)? global_grid_v1: (global_grid_v0+(i+1)*dv); + + bgnqstrip(); + for(j=umax; j>=umin; j--){ + REAL u1 = (j == global_grid_nu)? global_grid_u1: (global_grid_u0 +j*du); + coord2f(u1, v2); + coord2f(u1, v1); + } + endqstrip(); + } + } +#endif +} +else +{ + switch(style) { + default: + case N_MESHFILL: + glEvalMesh2((GLenum) GL_FILL, (GLint) umin, (GLint) umax, + (GLint) vmin, (GLint) vmax); + break; + case N_MESHLINE: + glEvalMesh2((GLenum) GL_LINE, (GLint) umin, (GLint) umax, + (GLint) vmin, (GLint) vmax); + break; + case N_MESHPOINT: + glEvalMesh2((GLenum) GL_POINT, (GLint) umin, (GLint) umax, + (GLint) vmin, (GLint) vmax); + break; + } + } + +#endif + +#ifdef STATISTICS + STAT_num_of_quad_strips += (umax-umin)*(vmax-vmin); +#endif +} + +/*------------------------------------------------------------------------- + * evalcoord2f - evaluate a point on a surface + *------------------------------------------------------------------------- + */ +void +OpenGLSurfaceEvaluator::evalcoord2f(long, REAL u, REAL v) +{ + + +#ifdef NO_EVALUATION +return; +#endif + + + newtmeshvert(u, v); +} + +/*------------------------------------------------------------------------- + * evalpoint2i - evaluate a grid point + *------------------------------------------------------------------------- + */ +void +OpenGLSurfaceEvaluator::evalpoint2i(long u, long v) +{ +#ifdef NO_EVALUATION +return; +#endif + + newtmeshvert(u, v); +} + +void +OpenGLSurfaceEvaluator::point2i( long u, long v ) +{ +#ifdef NO_EVALUATION +return; +#else + +#ifdef USE_INTERNAL_EVAL + inEvalPoint2( (int)u, (int)v); +#else + + +if(output_triangles) +{ + + REAL du, dv; + REAL fu,fv; + du = (global_grid_u1 - global_grid_u0) / (REAL)global_grid_nu; + dv = (global_grid_v1 - global_grid_v0) / (REAL)global_grid_nv; + fu = (u==global_grid_nu)? global_grid_u1:(global_grid_u0 + u*du); + fv = (v == global_grid_nv)? global_grid_v1: (global_grid_v0 +v*dv); + coord2f(fu,fv); +} +else + glEvalPoint2((GLint) u, (GLint) v); + + +#endif + +#ifdef STATISTICS + STAT_num_of_eval_vertices++; +#endif + +#endif + +} + +void +OpenGLSurfaceEvaluator::coord2f( REAL u, REAL v ) +{ +#ifdef NO_EVALUATION +return; +#else + +#ifdef USE_INTERNAL_EVAL + inEvalCoord2f( u, v); +#else + + +if(output_triangles) + bezierPatchMeshInsertUV(global_bpm, u,v); +else + glEvalCoord2f((GLfloat) u, (GLfloat) v); + + +#endif + + +#ifdef STATISTICS + STAT_num_of_eval_vertices++; +#endif + +#endif +} + +void +OpenGLSurfaceEvaluator::newtmeshvert( long u, long v ) +{ +#ifdef NO_EVALUATION +return; +#else + + if (tmeshing) { + + if (vcount == 2) { + vertexCache[0]->invoke(this); + vertexCache[1]->invoke(this); + point2i( u, v); + + } else { + vcount++; + } + + vertexCache[which]->saveEvalPoint(u, v); + which = 1 - which; + } else { + point2i( u, v); + } +#endif +} + +void +OpenGLSurfaceEvaluator::newtmeshvert( REAL u, REAL v ) +{ +#ifdef NO_EVALUATION +return; +#else + if (tmeshing) { + + + if (vcount == 2) { + vertexCache[0]->invoke(this); + vertexCache[1]->invoke(this); + coord2f(u,v); + + } else { + vcount++; + } + + vertexCache[which]->saveEvalCoord(u, v); + which = 1 - which; + } else { + + coord2f( u, v); + } +#endif + +} + +#ifdef _WIN32 +void OpenGLSurfaceEvaluator::putCallBack(GLenum which, void (GLAPIENTRY *fn)() ) +#else +void OpenGLSurfaceEvaluator::putCallBack(GLenum which, _GLUfuncptr fn ) +#endif +{ + switch(which) + { + case GLU_NURBS_BEGIN: + beginCallBackN = (void (GLAPIENTRY *) (GLenum)) fn; + break; + case GLU_NURBS_END: + endCallBackN = (void (GLAPIENTRY *) (void)) fn; + break; + case GLU_NURBS_VERTEX: + vertexCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn; + break; + case GLU_NURBS_NORMAL: + normalCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn; + break; + case GLU_NURBS_COLOR: + colorCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn; + break; + case GLU_NURBS_TEXTURE_COORD: + texcoordCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn; + break; + case GLU_NURBS_BEGIN_DATA: + beginCallBackData = (void (GLAPIENTRY *) (GLenum, void*)) fn; + break; + case GLU_NURBS_END_DATA: + endCallBackData = (void (GLAPIENTRY *) (void*)) fn; + break; + case GLU_NURBS_VERTEX_DATA: + vertexCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn; + break; + case GLU_NURBS_NORMAL_DATA: + normalCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn; + break; + case GLU_NURBS_COLOR_DATA: + colorCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn; + break; + case GLU_NURBS_TEXTURE_COORD_DATA: + texcoordCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn; + break; + + } +} + + +void +OpenGLSurfaceEvaluator::beginCallBack(GLenum which, void *data) +{ + if(beginCallBackData) + beginCallBackData(which, data); + else if(beginCallBackN) + beginCallBackN(which); +} + +void +OpenGLSurfaceEvaluator::endCallBack(void *data) +{ + if(endCallBackData) + endCallBackData(data); + else if(endCallBackN) + endCallBackN(); +} + +void +OpenGLSurfaceEvaluator::vertexCallBack(const GLfloat *vert, void* data) +{ + if(vertexCallBackData) + vertexCallBackData(vert, data); + else if(vertexCallBackN) + vertexCallBackN(vert); +} + + +void +OpenGLSurfaceEvaluator::normalCallBack(const GLfloat *normal, void* data) +{ + if(normalCallBackData) + normalCallBackData(normal, data); + else if(normalCallBackN) + normalCallBackN(normal); +} + +void +OpenGLSurfaceEvaluator::colorCallBack(const GLfloat *color, void* data) +{ + if(colorCallBackData) + colorCallBackData(color, data); + else if(colorCallBackN) + colorCallBackN(color); +} + +void +OpenGLSurfaceEvaluator::texcoordCallBack(const GLfloat *texcoord, void* data) +{ + if(texcoordCallBackData) + texcoordCallBackData(texcoord, data); + else if(texcoordCallBackN) + texcoordCallBackN(texcoord); +} + + + + diff --git a/mesalib/src/glu/sgi/libnurbs/interface/glsurfeval.h b/mesalib/src/glu/sgi/libnurbs/interface/glsurfeval.h new file mode 100644 index 000000000..1567c6b09 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/interface/glsurfeval.h @@ -0,0 +1,404 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * glsurfeval.h + * + */ + +#ifndef __gluglsurfeval_h_ +#define __gluglsurfeval_h_ + +#include "basicsurfeval.h" +#include "bezierPatchMesh.h" //in case output triangles +#include <GL/gl.h> +#include <GL/glu.h> + +class SurfaceMap; +class OpenGLSurfaceEvaluator; +class StoredVertex; + +#define TYPECOORD 1 +#define TYPEPOINT 2 + +/* Cache up to 3 vertices from tmeshes */ +#define VERTEX_CACHE_SIZE 3 + +/*for internal evaluator callback stuff*/ +#ifndef IN_MAX_BEZIER_ORDER +#define IN_MAX_BEZIER_ORDER 40 /*XXX should be bigger than machine order*/ +#endif + +#ifndef IN_MAX_DIMENSION +#define IN_MAX_DIMENSION 4 +#endif + +typedef struct surfEvalMachine{ + REAL uprime;//cached previusly evaluated uprime. + REAL vprime; + int k; /*the dimension*/ + REAL u1; + REAL u2; + int ustride; + int uorder; + REAL v1; + REAL v2; + int vstride; + int vorder; + REAL ctlPoints[IN_MAX_BEZIER_ORDER*IN_MAX_BEZIER_ORDER*IN_MAX_DIMENSION]; + REAL ucoeff[IN_MAX_BEZIER_ORDER]; /*cache the polynomial values*/ + REAL vcoeff[IN_MAX_BEZIER_ORDER]; + REAL ucoeffDeriv[IN_MAX_BEZIER_ORDER]; /*cache the polynomial derivatives*/ + REAL vcoeffDeriv[IN_MAX_BEZIER_ORDER]; +} surfEvalMachine; + + + +class StoredVertex { +public: + StoredVertex() { type = 0; } + ~StoredVertex(void) {} + void saveEvalCoord(REAL x, REAL y) + {coord[0] = x; coord[1] = y; type = TYPECOORD; } + void saveEvalPoint(long x, long y) + {point[0] = x; point[1] = y; type = TYPEPOINT; } + void invoke(OpenGLSurfaceEvaluator *eval); + +private: + int type; + REAL coord[2]; + long point[2]; +}; + +class OpenGLSurfaceEvaluator : public BasicSurfaceEvaluator { +public: + OpenGLSurfaceEvaluator(); + virtual ~OpenGLSurfaceEvaluator( void ); + void polymode( long style ); + void range2f( long, REAL *, REAL * ); + void domain2f( REAL, REAL, REAL, REAL ); + void addMap( SurfaceMap * ) { } + + void enable( long ); + void disable( long ); + void bgnmap2f( long ); + void map2f( long, REAL, REAL, long, long, + REAL, REAL, long, long, REAL * ); + void mapgrid2f( long, REAL, REAL, long, REAL, REAL ); + void mapmesh2f( long, long, long, long, long ); + void evalcoord2f( long, REAL, REAL ); + void evalpoint2i( long, long ); + void endmap2f( void ); + + void bgnline( void ); + void endline( void ); + void bgnclosedline( void ); + void endclosedline( void ); + void bgntmesh( void ); + void swaptmesh( void ); + void endtmesh( void ); + void bgnqstrip( void ); + void endqstrip( void ); + + void bgntfan( void ); + void endtfan( void ); + void evalUStrip(int n_upper, REAL v_upper, REAL* upper_val, + int n_lower, REAL v_lower, REAL* lower_val); + void evalVStrip(int n_left, REAL u_left, REAL* left_val, + int n_right, REAL u_right, REAL* right_val); + + void coord2f( REAL, REAL ); + void point2i( long, long ); + + void newtmeshvert( REAL, REAL ); + void newtmeshvert( long, long ); + +#ifdef _WIN32 + void putCallBack(GLenum which, void (GLAPIENTRY *fn)() ); +#else + void putCallBack(GLenum which, _GLUfuncptr fn ); +#endif + + int get_vertices_call_back() + { + return output_triangles; + } + void put_vertices_call_back(int flag) + { + output_triangles = flag; + } + + void put_callback_auto_normal(int flag) + { + callback_auto_normal = flag; + } + + int get_callback_auto_normal() + { + return callback_auto_normal; + } + + void set_callback_userData(void* data) + { + userData = data; + } + + /**************begin for LOD_eval_list***********/ + void LOD_eval_list(int level); + + + + +private: + StoredVertex *vertexCache[VERTEX_CACHE_SIZE]; + int tmeshing; + int which; + int vcount; + + GLint gl_polygon_mode[2];/*to save and restore so that + *no side effect + */ + bezierPatchMesh *global_bpm; //for output triangles + int output_triangles; //true 1 or false 0 + + + + void (GLAPIENTRY *beginCallBackN) (GLenum type); + void (GLAPIENTRY *endCallBackN) (void); + void (GLAPIENTRY *vertexCallBackN) (const GLfloat *vert); + void (GLAPIENTRY *normalCallBackN) (const GLfloat *normal); + void (GLAPIENTRY *colorCallBackN) (const GLfloat *color); + void (GLAPIENTRY *texcoordCallBackN) (const GLfloat *texcoord); + + void (GLAPIENTRY *beginCallBackData) (GLenum type, void* data); + void (GLAPIENTRY *endCallBackData) (void* data); + void (GLAPIENTRY *vertexCallBackData) (const GLfloat *vert, void* data); + void (GLAPIENTRY *normalCallBackData) (const GLfloat *normal, void* data); + void (GLAPIENTRY *colorCallBackData) (const GLfloat *color, void* data); + void (GLAPIENTRY *texcoordCallBackData) (const GLfloat *texcoord, void* data); + + void beginCallBack (GLenum type, void* data); + void endCallBack (void* data); + void vertexCallBack (const GLfloat *vert, void* data); + void normalCallBack (const GLfloat *normal, void* data); + void colorCallBack (const GLfloat *color, void* data); + void texcoordCallBack (const GLfloat *texcoord, void* data); + + + void* userData; //the opaque pointer for Data callback functions. + + /*LOD evaluation*/ + void LOD_triangle(REAL A[2], REAL B[2], REAL C[2], + int level); + void LOD_eval(int num_vert, REAL* verts, int type, int level); + + int LOD_eval_level; //set by LOD_eval_list() + + /*************begin for internal evaluators*****************/ + + /*the following global variables are only defined in this file. + *They are used to cache the precomputed Bezier polynomial values. + *These calues may be used consecutively in which case we don't have + *recompute these values again. + */ + int global_uorder; /*store the uorder in the previous evaluation*/ + int global_vorder; /*store the vorder in the previous evaluation*/ + REAL global_uprime; + REAL global_vprime; + REAL global_vprime_BV; + REAL global_uprime_BU; + int global_uorder_BV; /*store the uorder in the previous evaluation*/ + int global_vorder_BV; /*store the vorder in the previous evaluation*/ + int global_uorder_BU; /*store the uorder in the previous evaluation*/ + int global_vorder_BU; /*store the vorder in the previous evaluation*/ + + REAL global_ucoeff[IN_MAX_BEZIER_ORDER]; /*cache the polynomial values*/ + REAL global_vcoeff[IN_MAX_BEZIER_ORDER]; + REAL global_ucoeffDeriv[IN_MAX_BEZIER_ORDER]; /*cache the polynomial derivatives*/ + REAL global_vcoeffDeriv[IN_MAX_BEZIER_ORDER]; + + REAL global_BV[IN_MAX_BEZIER_ORDER][IN_MAX_DIMENSION]; + REAL global_PBV[IN_MAX_BEZIER_ORDER][IN_MAX_DIMENSION]; + REAL global_BU[IN_MAX_BEZIER_ORDER][IN_MAX_DIMENSION]; + REAL global_PBU[IN_MAX_BEZIER_ORDER][IN_MAX_DIMENSION]; + REAL* global_baseData; + + int global_ev_k; /*the dimension*/ + REAL global_ev_u1; + REAL global_ev_u2; + int global_ev_ustride; + int global_ev_uorder; + REAL global_ev_v1; + REAL global_ev_v2; + int global_ev_vstride; + int global_ev_vorder; + REAL global_ev_ctlPoints[IN_MAX_BEZIER_ORDER*IN_MAX_BEZIER_ORDER*IN_MAX_DIMENSION]; + + REAL global_grid_u0; + REAL global_grid_u1; + int global_grid_nu; + REAL global_grid_v0; + REAL global_grid_v1; + int global_grid_nv; + +/*functions*/ + void inDoDomain2WithDerivs(int k, REAL u, REAL v, + REAL u1, REAL u2, int uorder, + REAL v1, REAL v2, int vorder, + REAL *baseData, + REAL *retPoint, REAL *retdu, REAL *retdv); + void inPreEvaluate(int order, REAL vprime, REAL *coeff); + void inPreEvaluateWithDeriv(int order, REAL vprime, REAL *coeff, REAL *coeffDeriv); + void inComputeFirstPartials(REAL *p, REAL *pu, REAL *pv); + void inComputeNormal2(REAL *pu, REAL *pv, REAL *n); + void inDoEvalCoord2(REAL u, REAL v, + REAL *retPoint, REAL *retNormal); + void inDoEvalCoord2NOGE(REAL u, REAL v, + REAL *retPoint, REAL *retNormal); + void inMap2f(int k, + REAL ulower, + REAL uupper, + int ustride, + int uorder, + REAL vlower, + REAL vupper, + int vstride, + int vorder, + REAL *ctlPoints); + + void inMapGrid2f(int nu, REAL u0, REAL u1, + int nv, REAL v0, REAL v1); + + void inEvalMesh2(int lowU, int lowV, int highU, int highV); + void inEvalPoint2(int i, int j); + void inEvalCoord2f(REAL u, REAL v); + +void inEvalULine(int n_points, REAL v, REAL* u_vals, + int stride, REAL ret_points[][3], REAL ret_normals[][3]); + +void inEvalVLine(int n_points, REAL u, REAL* v_vals, + int stride, REAL ret_points[][3], REAL ret_normals[][3]); + +void inEvalUStrip(int n_upper, REAL v_upper, REAL* upper_val, + int n_lower, REAL v_lower, REAL* lower_val + ); +void inEvalVStrip(int n_left, REAL u_left, REAL* left_val, int n_right, REAL u_right, REAL* right_val); + +void inPreEvaluateBV(int k, int uorder, int vorder, REAL vprime, REAL *baseData); +void inPreEvaluateBU(int k, int uorder, int vorder, REAL uprime, REAL *baseData); +void inPreEvaluateBV_intfac(REAL v ) + { + inPreEvaluateBV(global_ev_k, global_ev_uorder, global_ev_vorder, (v-global_ev_v1)/(global_ev_v2-global_ev_v1), global_ev_ctlPoints); + } + +void inPreEvaluateBU_intfac(REAL u) + { + inPreEvaluateBU(global_ev_k, global_ev_uorder, global_ev_vorder, (u-global_ev_u1)/(global_ev_u2-global_ev_u1), global_ev_ctlPoints); + } + +void inDoDomain2WithDerivsBV(int k, REAL u, REAL v, + REAL u1, REAL u2, int uorder, + REAL v1, REAL v2, int vorder, + REAL *baseData, + REAL *retPoint, REAL* retdu, REAL *retdv); + +void inDoDomain2WithDerivsBU(int k, REAL u, REAL v, + REAL u1, REAL u2, int uorder, + REAL v1, REAL v2, int vorder, + REAL *baseData, + REAL *retPoint, REAL* retdu, REAL *retdv); + + +void inDoEvalCoord2NOGE_BV(REAL u, REAL v, + REAL *retPoint, REAL *retNormal); + +void inDoEvalCoord2NOGE_BU(REAL u, REAL v, + REAL *retPoint, REAL *retNormal); + +void inBPMEval(bezierPatchMesh* bpm); +void inBPMListEval(bezierPatchMesh* list); + +/*-------------begin for surfEvalMachine -------------*/ +surfEvalMachine em_vertex; +surfEvalMachine em_normal; +surfEvalMachine em_color; +surfEvalMachine em_texcoord; + +int auto_normal_flag; //whether to output normla or not in callback + //determined by GL_AUTO_NORMAL and callback_auto_normal +int callback_auto_normal; //GLU_CALLBACK_AUTO_NORMAL_EXT +int vertex_flag; +int normal_flag; +int color_flag; +int texcoord_flag; + +void inMap2fEM(int which, //0:vert,1:norm,2:color,3:tex + int dimension, + REAL ulower, + REAL uupper, + int ustride, + int uorder, + REAL vlower, + REAL vupper, + int vstride, + int vorder, + REAL *ctlPoints); + +void inDoDomain2WithDerivsEM(surfEvalMachine *em, REAL u, REAL v, + REAL *retPoint, REAL *retdu, REAL *retdv); +void inDoDomain2EM(surfEvalMachine *em, REAL u, REAL v, + REAL *retPoint); + void inDoEvalCoord2EM(REAL u, REAL v); + +void inBPMEvalEM(bezierPatchMesh* bpm); +void inBPMListEvalEM(bezierPatchMesh* list); + +/*-------------end for surfEvalMachine -------------*/ + + + /*************end for internal evaluators*****************/ + +}; + +inline void StoredVertex::invoke(OpenGLSurfaceEvaluator *eval) +{ + switch(type) { + case TYPECOORD: + eval->coord2f(coord[0], coord[1]); + break; + case TYPEPOINT: + eval->point2i(point[0], point[1]); + break; + default: + break; + } +} + +#endif /* __gluglsurfeval_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/interface/incurveeval.cc b/mesalib/src/glu/sgi/libnurbs/interface/incurveeval.cc new file mode 100644 index 000000000..96ea8896a --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/interface/incurveeval.cc @@ -0,0 +1,206 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include <stdlib.h> +#include <stdio.h> + +#include "glcurveval.h" + + +/* + *compute the Bezier polynomials C[n,j](v) for all j at v with + *return values stored in coeff[], where + * C[n,j](v) = (n,j) * v^j * (1-v)^(n-j), + * j=0,1,2,...,n. + *order : n+1 + *vprime: v + *coeff : coeff[j]=C[n,j](v), this array store the returned values. + *The algorithm is a recursive scheme: + * C[0,0]=1; + * C[n,j](v) = (1-v)*C[n-1,j](v) + v*C[n-1,j-1](v), n>=1 + *This code is copied from opengl/soft/so_eval.c:PreEvaluate + */ +void OpenGLCurveEvaluator::inPreEvaluate(int order, REAL vprime, REAL *coeff) +{ + int i, j; + REAL oldval, temp; + REAL oneMinusvprime; + + /* + * Minor optimization + * Compute orders 1 and 2 outright, and set coeff[0], coeff[1] to + * their i==1 loop values to avoid the initialization and the i==1 loop. + */ + if (order == 1) { + coeff[0] = 1.0; + return; + } + + oneMinusvprime = 1-vprime; + coeff[0] = oneMinusvprime; + coeff[1] = vprime; + if (order == 2) return; + + for (i = 2; i < order; i++) { + oldval = coeff[0] * vprime; + coeff[0] = oneMinusvprime * coeff[0]; + for (j = 1; j < i; j++) { + temp = oldval; + oldval = coeff[j] * vprime; + coeff[j] = temp + oneMinusvprime * coeff[j]; + } + coeff[j] = oldval; + } +} + +void OpenGLCurveEvaluator::inMap1f(int which, //0: vert, 1: norm, 2: color, 3: tex + int k, //dimension + REAL ulower, + REAL uupper, + int ustride, + int uorder, + REAL *ctlpoints) +{ + int i,x; + curveEvalMachine *temp_em; + switch(which){ + case 0: //vertex + vertex_flag = 1; + temp_em = &em_vertex; + break; + case 1: //normal + normal_flag = 1; + temp_em = &em_normal; + break; + case 2: //color + color_flag = 1; + temp_em = &em_color; + break; + default: + texcoord_flag = 1; + temp_em = &em_texcoord; + break; + } + + REAL *data = temp_em->ctlpoints; + temp_em->uprime = -1; //initialized + temp_em->k = k; + temp_em->u1 = ulower; + temp_em->u2 = uupper; + temp_em->ustride = ustride; + temp_em->uorder = uorder; + /*copy the control points*/ + for(i=0; i<uorder; i++){ + for(x=0; x<k; x++){ + data[x] = ctlpoints[x]; + } + ctlpoints += ustride; + data += k; + } +} + +void OpenGLCurveEvaluator::inDoDomain1(curveEvalMachine *em, REAL u, REAL *retPoint) +{ + int j, row; + REAL the_uprime; + REAL *data; + + if(em->u2 == em->u1) + return; + the_uprime = (u-em->u1) / (em->u2-em->u1); + /*use already cached values if possible*/ + if(em->uprime != the_uprime){ + inPreEvaluate(em->uorder, the_uprime, em->ucoeff); + em->uprime = the_uprime; + } + + for(j=0; j<em->k; j++){ + data = em->ctlpoints+j; + retPoint[j] = 0.0; + for(row=0; row<em->uorder; row++) + { + retPoint[j] += em->ucoeff[row] * (*data); + data += em->k; + } + } +} + +void OpenGLCurveEvaluator::inDoEvalCoord1(REAL u) +{ + REAL temp_vertex[4]; + REAL temp_normal[3]; + REAL temp_color[4]; + REAL temp_texcoord[4]; + if(texcoord_flag) //there is a texture map + { + inDoDomain1(&em_texcoord, u, temp_texcoord); + texcoordCallBack(temp_texcoord, userData); + } +#ifdef DEBUG +printf("color_flag = %i\n", color_flag); +#endif + if(color_flag) //there is a color map + { + inDoDomain1(&em_color, u, temp_color); + colorCallBack(temp_color, userData); + } + if(normal_flag) //there is a normal map + { + inDoDomain1(&em_normal, u, temp_normal); + normalCallBack(temp_normal, userData); + } + if(vertex_flag) + { + inDoDomain1(&em_vertex, u, temp_vertex); + vertexCallBack(temp_vertex, userData); + } +} + +void OpenGLCurveEvaluator::inMapMesh1f(int umin, int umax) +{ + REAL du, u; + int i; + if(global_grid_nu == 0) + return; //no points to output + du = (global_grid_u1 - global_grid_u0) / (REAL) global_grid_nu; + bgnline(); + for(i=umin; i<= umax; i++){ + u = (i==global_grid_nu)? global_grid_u1: global_grid_u0 + i*du; + inDoEvalCoord1(u); + } + endline(); +} diff --git a/mesalib/src/glu/sgi/libnurbs/interface/insurfeval.cc b/mesalib/src/glu/sgi/libnurbs/interface/insurfeval.cc new file mode 100644 index 000000000..9d0c82a91 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/interface/insurfeval.cc @@ -0,0 +1,2064 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include "gluos.h" +#include <stdlib.h> +#include <stdio.h> +#include <GL/gl.h> +#include <math.h> +#include <assert.h> + +#include "glsurfeval.h" + +//extern int surfcount; + +//#define CRACK_TEST + +#define AVOID_ZERO_NORMAL + +#ifdef AVOID_ZERO_NORMAL +#define myabs(x) ((x>0)? x: (-x)) +#define MYZERO 0.000001 +#define MYDELTA 0.001 +#endif + +//#define USE_LOD +#ifdef USE_LOD +//#define LOD_EVAL_COORD(u,v) inDoEvalCoord2EM(u,v) +#define LOD_EVAL_COORD(u,v) glEvalCoord2f(u,v) + +static void LOD_interpolate(REAL A[2], REAL B[2], REAL C[2], int j, int k, int pow2_level, + REAL& u, REAL& v) +{ + REAL a,a1,b,b1; + + a = ((REAL) j) / ((REAL) pow2_level); + a1 = 1-a; + + if(j != 0) + { + b = ((REAL) k) / ((REAL)j); + b1 = 1-b; + } + REAL x,y,z; + x = a1; + if(j==0) + { + y=0; z=0; + } + else{ + y = b1*a; + z = b *a; + } + + u = x*A[0] + y*B[0] + z*C[0]; + v = x*A[1] + y*B[1] + z*C[1]; +} + +void OpenGLSurfaceEvaluator::LOD_triangle(REAL A[2], REAL B[2], REAL C[2], + int level) +{ + int k,j; + int pow2_level; + /*compute 2^level*/ + pow2_level = 1; + + for(j=0; j<level; j++) + pow2_level *= 2; + for(j=0; j<=pow2_level-1; j++) + { + REAL u,v; + +/* beginCallBack(GL_TRIANGLE_STRIP);*/ +glBegin(GL_TRIANGLE_STRIP); + LOD_interpolate(A,B,C, j+1, j+1, pow2_level, u,v); +#ifdef USE_LOD + LOD_EVAL_COORD(u,v); +// glEvalCoord2f(u,v); +#else + inDoEvalCoord2EM(u,v); +#endif + + for(k=0; k<=j; k++) + { + LOD_interpolate(A,B,C,j,j-k,pow2_level, u,v); +#ifdef USE_LOD + LOD_EVAL_COORD(u,v); +// glEvalCoord2f(u,v); +#else + inDoEvalCoord2EM(u,v); +#endif + + LOD_interpolate(A,B,C,j+1,j-k,pow2_level, u,v); + +#ifdef USE_LOD + LOD_EVAL_COORD(u,v); +// glEvalCoord2f(u,v); +#else + inDoEvalCoord2EM(u,v); +#endif + } +// endCallBack(); +glEnd(); + } +} + +void OpenGLSurfaceEvaluator::LOD_eval(int num_vert, REAL* verts, int type, + int level + ) +{ + int i,k; + switch(type){ + case GL_TRIANGLE_STRIP: + case GL_QUAD_STRIP: + for(i=2, k=4; i<=num_vert-2; i+=2, k+=4) + { + LOD_triangle(verts+k-4, verts+k-2, verts+k, + level + ); + LOD_triangle(verts+k-2, verts+k+2, verts+k, + level + ); + } + if(num_vert % 2 ==1) + { + LOD_triangle(verts+2*(num_vert-3), verts+2*(num_vert-2), verts+2*(num_vert-1), + level + ); + } + break; + case GL_TRIANGLE_FAN: + for(i=1, k=2; i<=num_vert-2; i++, k+=2) + { + LOD_triangle(verts,verts+k, verts+k+2, + level + ); + } + break; + + default: + fprintf(stderr, "typy not supported in LOD_\n"); + } +} + + +#endif //USE_LOD + +//#define GENERIC_TEST +#ifdef GENERIC_TEST +extern float xmin, xmax, ymin, ymax, zmin, zmax; /*bounding box*/ +extern int temp_signal; + +static void gTessVertexSphere(float u, float v, float temp_normal[3], float temp_vertex[3]) +{ + float r=2.0; + float Ox = 0.5*(xmin+xmax); + float Oy = 0.5*(ymin+ymax); + float Oz = 0.5*(zmin+zmax); + float nx = cos(v) * sin(u); + float ny = sin(v) * sin(u); + float nz = cos(u); + float x= Ox+r * nx; + float y= Oy+r * ny; + float z= Oz+r * nz; + + temp_normal[0] = nx; + temp_normal[1] = ny; + temp_normal[2] = nz; + temp_vertex[0] = x; + temp_vertex[1] = y; + temp_vertex[2] = z; + +// glNormal3f(nx,ny,nz); +// glVertex3f(x,y,z); +} + +static void gTessVertexCyl(float u, float v, float temp_normal[3], float temp_vertex[3]) +{ + float r=2.0; + float Ox = 0.5*(xmin+xmax); + float Oy = 0.5*(ymin+ymax); + float Oz = 0.5*(zmin+zmax); + float nx = cos(v); + float ny = sin(v); + float nz = 0; + float x= Ox+r * nx; + float y= Oy+r * ny; + float z= Oz - 2*u; + + temp_normal[0] = nx; + temp_normal[1] = ny; + temp_normal[2] = nz; + temp_vertex[0] = x; + temp_vertex[1] = y; + temp_vertex[2] = z; + +/* + glNormal3f(nx,ny,nz); + glVertex3f(x,y,z); +*/ +} + +#endif //GENERIC_TEST + +void OpenGLSurfaceEvaluator::inBPMListEval(bezierPatchMesh* list) +{ + bezierPatchMesh* temp; + for(temp = list; temp != NULL; temp = temp->next) + { + inBPMEval(temp); + } +} + +void OpenGLSurfaceEvaluator::inBPMEval(bezierPatchMesh* bpm) +{ + int i,j,k,l; + float u,v; + + int ustride = bpm->bpatch->dimension * bpm->bpatch->vorder; + int vstride = bpm->bpatch->dimension; + inMap2f( + (bpm->bpatch->dimension == 3)? GL_MAP2_VERTEX_3 : GL_MAP2_VERTEX_4, + bpm->bpatch->umin, + bpm->bpatch->umax, + ustride, + bpm->bpatch->uorder, + bpm->bpatch->vmin, + bpm->bpatch->vmax, + vstride, + bpm->bpatch->vorder, + bpm->bpatch->ctlpoints); + + bpm->vertex_array = (float*) malloc(sizeof(float)* (bpm->index_UVarray/2) * 3+1); /*in case the origional dimenion is 4, then we need 4 space to pass to evaluator.*/ + assert(bpm->vertex_array); + bpm->normal_array = (float*) malloc(sizeof(float)* (bpm->index_UVarray/2) * 3); + assert(bpm->normal_array); +#ifdef CRACK_TEST +if( global_ev_u1 ==2 && global_ev_u2 == 3 + && global_ev_v1 ==2 && global_ev_v2 == 3) +{ +REAL vertex[4]; +REAL normal[4]; +#ifdef DEBUG +printf("***number 1\n"); +#endif + +beginCallBack(GL_QUAD_STRIP, NULL); +inEvalCoord2f(3.0, 3.0); +inEvalCoord2f(2.0, 3.0); +inEvalCoord2f(3.0, 2.7); +inEvalCoord2f(2.0, 2.7); +inEvalCoord2f(3.0, 2.0); +inEvalCoord2f(2.0, 2.0); +endCallBack(NULL); + + +beginCallBack(GL_TRIANGLE_STRIP, NULL); +inEvalCoord2f(2.0, 3.0); +inEvalCoord2f(2.0, 2.0); +inEvalCoord2f(2.0, 2.7); +endCallBack(NULL); + +} + +/* +if( global_ev_u1 ==2 && global_ev_u2 == 3 + && global_ev_v1 ==1 && global_ev_v2 == 2) +{ +#ifdef DEBUG +printf("***number 2\n"); +#endif +beginCallBack(GL_QUAD_STRIP); +inEvalCoord2f(2.0, 2.0); +inEvalCoord2f(2.0, 1.0); +inEvalCoord2f(3.0, 2.0); +inEvalCoord2f(3.0, 1.0); +endCallBack(); +} +*/ +if( global_ev_u1 ==1 && global_ev_u2 == 2 + && global_ev_v1 ==2 && global_ev_v2 == 3) +{ +#ifdef DEBUG +printf("***number 3\n"); +#endif +beginCallBack(GL_QUAD_STRIP, NULL); +inEvalCoord2f(2.0, 3.0); +inEvalCoord2f(1.0, 3.0); +inEvalCoord2f(2.0, 2.3); +inEvalCoord2f(1.0, 2.3); +inEvalCoord2f(2.0, 2.0); +inEvalCoord2f(1.0, 2.0); +endCallBack(NULL); + +beginCallBack(GL_TRIANGLE_STRIP, NULL); +inEvalCoord2f(2.0, 2.3); +inEvalCoord2f(2.0, 2.0); +inEvalCoord2f(2.0, 3.0); +endCallBack(NULL); + +} +return; +#endif + + k=0; + l=0; + + for(i=0; i<bpm->index_length_array; i++) + { + beginCallBack(bpm->type_array[i], userData); + for(j=0; j<bpm->length_array[i]; j++) + { + u = bpm->UVarray[k]; + v = bpm->UVarray[k+1]; + inDoEvalCoord2NOGE(u,v, + bpm->vertex_array+l, + bpm->normal_array+l); + + normalCallBack(bpm->normal_array+l, userData); + vertexCallBack(bpm->vertex_array+l, userData); + + k += 2; + l += 3; + } + endCallBack(userData); + } +} + +void OpenGLSurfaceEvaluator::inEvalPoint2(int i, int j) +{ + REAL du, dv; + REAL point[4]; + REAL normal[3]; + REAL u,v; + du = (global_grid_u1 - global_grid_u0) / (REAL)global_grid_nu; + dv = (global_grid_v1 - global_grid_v0) / (REAL)global_grid_nv; + u = (i==global_grid_nu)? global_grid_u1:(global_grid_u0 + i*du); + v = (j == global_grid_nv)? global_grid_v1: (global_grid_v0 +j*dv); + inDoEvalCoord2(u,v,point,normal); +} + +void OpenGLSurfaceEvaluator::inEvalCoord2f(REAL u, REAL v) +{ + + REAL point[4]; + REAL normal[3]; + inDoEvalCoord2(u,v,point, normal); +} + + + +/*define a grid. store the values into the global variabls: + * global_grid_* + *These values will be used later by evaluating functions + */ +void OpenGLSurfaceEvaluator::inMapGrid2f(int nu, REAL u0, REAL u1, + int nv, REAL v0, REAL v1) +{ + global_grid_u0 = u0; + global_grid_u1 = u1; + global_grid_nu = nu; + global_grid_v0 = v0; + global_grid_v1 = v1; + global_grid_nv = nv; +} + +void OpenGLSurfaceEvaluator::inEvalMesh2(int lowU, int lowV, int highU, int highV) +{ + REAL du, dv; + int i,j; + REAL point[4]; + REAL normal[3]; + if(global_grid_nu == 0 || global_grid_nv == 0) + return; /*no points need to be output*/ + du = (global_grid_u1 - global_grid_u0) / (REAL)global_grid_nu; + dv = (global_grid_v1 - global_grid_v0) / (REAL)global_grid_nv; + + if(global_grid_nu >= global_grid_nv){ + for(i=lowU; i<highU; i++){ + REAL u1 = (i==global_grid_nu)? global_grid_u1:(global_grid_u0 + i*du); + REAL u2 = ((i+1) == global_grid_nu)? global_grid_u1: (global_grid_u0+(i+1)*du); + + bgnqstrip(); + for(j=highV; j>=lowV; j--){ + REAL v1 = (j == global_grid_nv)? global_grid_v1: (global_grid_v0 +j*dv); + + inDoEvalCoord2(u1, v1, point, normal); + inDoEvalCoord2(u2, v1, point, normal); + } + endqstrip(); + } + } + + else{ + for(i=lowV; i<highV; i++){ + REAL v1 = (i==global_grid_nv)? global_grid_v1:(global_grid_v0 + i*dv); + REAL v2 = ((i+1) == global_grid_nv)? global_grid_v1: (global_grid_v0+(i+1)*dv); + + bgnqstrip(); + for(j=highU; j>=lowU; j--){ + REAL u1 = (j == global_grid_nu)? global_grid_u1: (global_grid_u0 +j*du); + inDoEvalCoord2(u1, v2, point, normal); + inDoEvalCoord2(u1, v1, point, normal); + } + endqstrip(); + } + } + +} + +void OpenGLSurfaceEvaluator::inMap2f(int k, + REAL ulower, + REAL uupper, + int ustride, + int uorder, + REAL vlower, + REAL vupper, + int vstride, + int vorder, + REAL *ctlPoints) +{ + int i,j,x; + REAL *data = global_ev_ctlPoints; + + + + if(k == GL_MAP2_VERTEX_3) k=3; + else if (k==GL_MAP2_VERTEX_4) k =4; + else { + printf("error in inMap2f, maptype=%i is wrong, k,map is not updated\n", k); + return; + } + + global_ev_k = k; + global_ev_u1 = ulower; + global_ev_u2 = uupper; + global_ev_ustride = ustride; + global_ev_uorder = uorder; + global_ev_v1 = vlower; + global_ev_v2 = vupper; + global_ev_vstride = vstride; + global_ev_vorder = vorder; + + /*copy the contrl points from ctlPoints to global_ev_ctlPoints*/ + for (i=0; i<uorder; i++) { + for (j=0; j<vorder; j++) { + for (x=0; x<k; x++) { + data[x] = ctlPoints[x]; + } + ctlPoints += vstride; + data += k; + } + ctlPoints += ustride - vstride * vorder; + } + +} + + +/* + *given a point p with homegeneous coordiante (x,y,z,w), + *let pu(x,y,z,w) be its partial derivative vector with + *respect to u + *and pv(x,y,z,w) be its partial derivative vector with repect to v. + *This function returns the partial derivative vectors of the + *inhomegensous coordinates, i.e., + * (x/w, y/w, z/w) with respect to u and v. + */ +void OpenGLSurfaceEvaluator::inComputeFirstPartials(REAL *p, REAL *pu, REAL *pv) +{ + pu[0] = pu[0]*p[3] - pu[3]*p[0]; + pu[1] = pu[1]*p[3] - pu[3]*p[1]; + pu[2] = pu[2]*p[3] - pu[3]*p[2]; + + pv[0] = pv[0]*p[3] - pv[3]*p[0]; + pv[1] = pv[1]*p[3] - pv[3]*p[1]; + pv[2] = pv[2]*p[3] - pv[3]*p[2]; +} + +/*compute the cross product of pu and pv and normalize. + *the normal is returned in retNormal + * pu: dimension 3 + * pv: dimension 3 + * n: return normal, of dimension 3 + */ +void OpenGLSurfaceEvaluator::inComputeNormal2(REAL *pu, REAL *pv, REAL *n) +{ + REAL mag; + + n[0] = pu[1]*pv[2] - pu[2]*pv[1]; + n[1] = pu[2]*pv[0] - pu[0]*pv[2]; + n[2] = pu[0]*pv[1] - pu[1]*pv[0]; + + mag = sqrt(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]); + + if (mag > 0.0) { + n[0] /= mag; + n[1] /= mag; + n[2] /= mag; + } +} + + + +/*Compute point and normal + *see the head of inDoDomain2WithDerivs + *for the meaning of the arguments + */ +void OpenGLSurfaceEvaluator::inDoEvalCoord2(REAL u, REAL v, + REAL *retPoint, REAL *retNormal) +{ + + REAL du[4]; + REAL dv[4]; + + + assert(global_ev_k>=3 && global_ev_k <= 4); + /*compute homegeneous point and partial derivatives*/ + inDoDomain2WithDerivs(global_ev_k, u, v, global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, retPoint, du, dv); + +#ifdef AVOID_ZERO_NORMAL + + if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO) + { + + REAL tempdu[4]; + REAL tempdata[4]; + REAL u1 = global_ev_u1; + REAL u2 = global_ev_u2; + if(u-MYDELTA*(u2-u1) < u1) + u = u+ MYDELTA*(u2-u1); + else + u = u-MYDELTA*(u2-u1); + inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, tempdu, dv); + } + if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO) + { + REAL tempdv[4]; + REAL tempdata[4]; + REAL v1 = global_ev_v1; + REAL v2 = global_ev_v2; + if(v-MYDELTA*(v2-v1) < v1) + v = v+ MYDELTA*(v2-v1); + else + v = v-MYDELTA*(v2-v1); + inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, du, tempdv); + } +#endif + + + /*compute normal*/ + switch(global_ev_k){ + case 3: + inComputeNormal2(du, dv, retNormal); + + break; + case 4: + inComputeFirstPartials(retPoint, du, dv); + inComputeNormal2(du, dv, retNormal); + /*transform the homegeneous coordinate of retPoint into inhomogenous one*/ + retPoint[0] /= retPoint[3]; + retPoint[1] /= retPoint[3]; + retPoint[2] /= retPoint[3]; + break; + } + /*output this vertex*/ +/* inMeshStreamInsert(global_ms, retPoint, retNormal);*/ + + + + glNormal3fv(retNormal); + glVertex3fv(retPoint); + + + + + #ifdef DEBUG + printf("vertex(%f,%f,%f)\n", retPoint[0],retPoint[1],retPoint[2]); + #endif + + + +} + +/*Compute point and normal + *see the head of inDoDomain2WithDerivs + *for the meaning of the arguments + */ +void OpenGLSurfaceEvaluator::inDoEvalCoord2NOGE_BU(REAL u, REAL v, + REAL *retPoint, REAL *retNormal) +{ + + REAL du[4]; + REAL dv[4]; + + + assert(global_ev_k>=3 && global_ev_k <= 4); + /*compute homegeneous point and partial derivatives*/ +// inPreEvaluateBU(global_ev_k, global_ev_uorder, global_ev_vorder, (u-global_ev_u1)/(global_ev_u2-global_ev_u1), global_ev_ctlPoints); + inDoDomain2WithDerivsBU(global_ev_k, u, v, global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, retPoint, du, dv); + + +#ifdef AVOID_ZERO_NORMAL + + if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO) + { + + REAL tempdu[4]; + REAL tempdata[4]; + REAL u1 = global_ev_u1; + REAL u2 = global_ev_u2; + if(u-MYDELTA*(u2-u1) < u1) + u = u+ MYDELTA*(u2-u1); + else + u = u-MYDELTA*(u2-u1); + inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, tempdu, dv); + } + if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO) + { + REAL tempdv[4]; + REAL tempdata[4]; + REAL v1 = global_ev_v1; + REAL v2 = global_ev_v2; + if(v-MYDELTA*(v2-v1) < v1) + v = v+ MYDELTA*(v2-v1); + else + v = v-MYDELTA*(v2-v1); + inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, du, tempdv); + } +#endif + + /*compute normal*/ + switch(global_ev_k){ + case 3: + inComputeNormal2(du, dv, retNormal); + break; + case 4: + inComputeFirstPartials(retPoint, du, dv); + inComputeNormal2(du, dv, retNormal); + /*transform the homegeneous coordinate of retPoint into inhomogenous one*/ + retPoint[0] /= retPoint[3]; + retPoint[1] /= retPoint[3]; + retPoint[2] /= retPoint[3]; + break; + } +} + +/*Compute point and normal + *see the head of inDoDomain2WithDerivs + *for the meaning of the arguments + */ +void OpenGLSurfaceEvaluator::inDoEvalCoord2NOGE_BV(REAL u, REAL v, + REAL *retPoint, REAL *retNormal) +{ + + REAL du[4]; + REAL dv[4]; + + + assert(global_ev_k>=3 && global_ev_k <= 4); + /*compute homegeneous point and partial derivatives*/ +// inPreEvaluateBV(global_ev_k, global_ev_uorder, global_ev_vorder, (v-global_ev_v1)/(global_ev_v2-global_ev_v1), global_ev_ctlPoints); + + inDoDomain2WithDerivsBV(global_ev_k, u, v, global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, retPoint, du, dv); + + +#ifdef AVOID_ZERO_NORMAL + + if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO) + { + + REAL tempdu[4]; + REAL tempdata[4]; + REAL u1 = global_ev_u1; + REAL u2 = global_ev_u2; + if(u-MYDELTA*(u2-u1) < u1) + u = u+ MYDELTA*(u2-u1); + else + u = u-MYDELTA*(u2-u1); + inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, tempdu, dv); + } + if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO) + { + REAL tempdv[4]; + REAL tempdata[4]; + REAL v1 = global_ev_v1; + REAL v2 = global_ev_v2; + if(v-MYDELTA*(v2-v1) < v1) + v = v+ MYDELTA*(v2-v1); + else + v = v-MYDELTA*(v2-v1); + inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, du, tempdv); + } +#endif + + /*compute normal*/ + switch(global_ev_k){ + case 3: + inComputeNormal2(du, dv, retNormal); + break; + case 4: + inComputeFirstPartials(retPoint, du, dv); + inComputeNormal2(du, dv, retNormal); + /*transform the homegeneous coordinate of retPoint into inhomogenous one*/ + retPoint[0] /= retPoint[3]; + retPoint[1] /= retPoint[3]; + retPoint[2] /= retPoint[3]; + break; + } +} + + +/*Compute point and normal + *see the head of inDoDomain2WithDerivs + *for the meaning of the arguments + */ +void OpenGLSurfaceEvaluator::inDoEvalCoord2NOGE(REAL u, REAL v, + REAL *retPoint, REAL *retNormal) +{ + + REAL du[4]; + REAL dv[4]; + + + assert(global_ev_k>=3 && global_ev_k <= 4); + /*compute homegeneous point and partial derivatives*/ + inDoDomain2WithDerivs(global_ev_k, u, v, global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, retPoint, du, dv); + + +#ifdef AVOID_ZERO_NORMAL + + if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO) + { + + REAL tempdu[4]; + REAL tempdata[4]; + REAL u1 = global_ev_u1; + REAL u2 = global_ev_u2; + if(u-MYDELTA*(u2-u1) < u1) + u = u+ MYDELTA*(u2-u1); + else + u = u-MYDELTA*(u2-u1); + inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, tempdu, dv); + } + if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO) + { + REAL tempdv[4]; + REAL tempdata[4]; + REAL v1 = global_ev_v1; + REAL v2 = global_ev_v2; + if(v-MYDELTA*(v2-v1) < v1) + v = v+ MYDELTA*(v2-v1); + else + v = v-MYDELTA*(v2-v1); + inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, du, tempdv); + } +#endif + + /*compute normal*/ + switch(global_ev_k){ + case 3: + inComputeNormal2(du, dv, retNormal); + break; + case 4: + inComputeFirstPartials(retPoint, du, dv); + inComputeNormal2(du, dv, retNormal); + /*transform the homegeneous coordinate of retPoint into inhomogenous one*/ + retPoint[0] /= retPoint[3]; + retPoint[1] /= retPoint[3]; + retPoint[2] /= retPoint[3]; + break; + } +// glNormal3fv(retNormal); +// glVertex3fv(retPoint); +} + +void OpenGLSurfaceEvaluator::inPreEvaluateBV(int k, int uorder, int vorder, REAL vprime, REAL *baseData) +{ + int j,row,col; + REAL p, pdv; + REAL *data; + + if(global_vprime != vprime || global_vorder != vorder) { + inPreEvaluateWithDeriv(vorder, vprime, global_vcoeff, global_vcoeffDeriv); + global_vprime = vprime; + global_vorder = vorder; + } + + for(j=0; j<k; j++){ + data = baseData+j; + for(row=0; row<uorder; row++){ + p = global_vcoeff[0] * (*data); + pdv = global_vcoeffDeriv[0] * (*data); + data += k; + for(col = 1; col < vorder; col++){ + p += global_vcoeff[col] * (*data); + pdv += global_vcoeffDeriv[col] * (*data); + data += k; + } + global_BV[row][j] = p; + global_PBV[row][j] = pdv; + } + } +} + +void OpenGLSurfaceEvaluator::inPreEvaluateBU(int k, int uorder, int vorder, REAL uprime, REAL *baseData) +{ + int j,row,col; + REAL p, pdu; + REAL *data; + + if(global_uprime != uprime || global_uorder != uorder) { + inPreEvaluateWithDeriv(uorder, uprime, global_ucoeff, global_ucoeffDeriv); + global_uprime = uprime; + global_uorder = uorder; + } + + for(j=0; j<k; j++){ + data = baseData+j; + for(col=0; col<vorder; col++){ + data = baseData+j + k*col; + p = global_ucoeff[0] * (*data); + pdu = global_ucoeffDeriv[0] * (*data); + data += k*uorder; + for(row = 1; row < uorder; row++){ + p += global_ucoeff[row] * (*data); + pdu += global_ucoeffDeriv[row] * (*data); + data += k * uorder; + } + global_BU[col][j] = p; + global_PBU[col][j] = pdu; + } + } +} + +void OpenGLSurfaceEvaluator::inDoDomain2WithDerivsBU(int k, REAL u, REAL v, + REAL u1, REAL u2, int uorder, + REAL v1, REAL v2, int vorder, + REAL *baseData, + REAL *retPoint, REAL* retdu, REAL *retdv) +{ + int j, col; + + REAL vprime; + + + if((u2 == u1) || (v2 == v1)) + return; + + vprime = (v - v1) / (v2 - v1); + + + if(global_vprime != vprime || global_vorder != vorder) { + inPreEvaluateWithDeriv(vorder, vprime, global_vcoeff, global_vcoeffDeriv); + global_vprime = vprime; + global_vorder = vorder; + } + + + for(j=0; j<k; j++) + { + retPoint[j] = retdu[j] = retdv[j] = 0.0; + for (col = 0; col < vorder; col++) { + retPoint[j] += global_BU[col][j] * global_vcoeff[col]; + retdu[j] += global_PBU[col][j] * global_vcoeff[col]; + retdv[j] += global_BU[col][j] * global_vcoeffDeriv[col]; + } + } +} + +void OpenGLSurfaceEvaluator::inDoDomain2WithDerivsBV(int k, REAL u, REAL v, + REAL u1, REAL u2, int uorder, + REAL v1, REAL v2, int vorder, + REAL *baseData, + REAL *retPoint, REAL* retdu, REAL *retdv) +{ + int j, row; + REAL uprime; + + + if((u2 == u1) || (v2 == v1)) + return; + uprime = (u - u1) / (u2 - u1); + + + if(global_uprime != uprime || global_uorder != uorder) { + inPreEvaluateWithDeriv(uorder, uprime, global_ucoeff, global_ucoeffDeriv); + global_uprime = uprime; + global_uorder = uorder; + } + + + for(j=0; j<k; j++) + { + retPoint[j] = retdu[j] = retdv[j] = 0.0; + for (row = 0; row < uorder; row++) { + retPoint[j] += global_BV[row][j] * global_ucoeff[row]; + retdu[j] += global_BV[row][j] * global_ucoeffDeriv[row]; + retdv[j] += global_PBV[row][j] * global_ucoeff[row]; + } + } +} + + +/* + *given a Bezier surface, and parameter (u,v), compute the point in the object space, + *and the normal + *k: the dimension of the object space: usually 2,3,or 4. + *u,v: the paramter pair. + *u1,u2,uorder: the Bezier polynomial of u coord is defined on [u1,u2] with order uorder. + *v1,v2,vorder: the Bezier polynomial of v coord is defined on [v1,v2] with order vorder. + *baseData: contrl points. arranged as: (u,v,k). + *retPoint: the computed point (one point) with dimension k. + *retdu: the computed partial derivative with respect to u. + *retdv: the computed partial derivative with respect to v. + */ +void OpenGLSurfaceEvaluator::inDoDomain2WithDerivs(int k, REAL u, REAL v, + REAL u1, REAL u2, int uorder, + REAL v1, REAL v2, int vorder, + REAL *baseData, + REAL *retPoint, REAL *retdu, REAL *retdv) +{ + int j, row, col; + REAL uprime; + REAL vprime; + REAL p; + REAL pdv; + REAL *data; + + if((u2 == u1) || (v2 == v1)) + return; + uprime = (u - u1) / (u2 - u1); + vprime = (v - v1) / (v2 - v1); + + /* Compute coefficients for values and derivs */ + + /* Use already cached values if possible */ + if(global_uprime != uprime || global_uorder != uorder) { + inPreEvaluateWithDeriv(uorder, uprime, global_ucoeff, global_ucoeffDeriv); + global_uorder = uorder; + global_uprime = uprime; + } + if (global_vprime != vprime || + global_vorder != vorder) { + inPreEvaluateWithDeriv(vorder, vprime, global_vcoeff, global_vcoeffDeriv); + global_vorder = vorder; + global_vprime = vprime; + } + + for (j = 0; j < k; j++) { + data=baseData+j; + retPoint[j] = retdu[j] = retdv[j] = 0.0; + for (row = 0; row < uorder; row++) { + /* + ** Minor optimization. + ** The col == 0 part of the loop is extracted so we don't + ** have to initialize p and pdv to 0. + */ + p = global_vcoeff[0] * (*data); + pdv = global_vcoeffDeriv[0] * (*data); + data += k; + for (col = 1; col < vorder; col++) { + /* Incrementally build up p, pdv value */ + p += global_vcoeff[col] * (*data); + pdv += global_vcoeffDeriv[col] * (*data); + data += k; + } + /* Use p, pdv value to incrementally add up r, du, dv */ + retPoint[j] += global_ucoeff[row] * p; + retdu[j] += global_ucoeffDeriv[row] * p; + retdv[j] += global_ucoeff[row] * pdv; + } + } +} + + +/* + *compute the Bezier polynomials C[n,j](v) for all j at v with + *return values stored in coeff[], where + * C[n,j](v) = (n,j) * v^j * (1-v)^(n-j), + * j=0,1,2,...,n. + *order : n+1 + *vprime: v + *coeff : coeff[j]=C[n,j](v), this array store the returned values. + *The algorithm is a recursive scheme: + * C[0,0]=1; + * C[n,j](v) = (1-v)*C[n-1,j](v) + v*C[n-1,j-1](v), n>=1 + *This code is copied from opengl/soft/so_eval.c:PreEvaluate + */ +void OpenGLSurfaceEvaluator::inPreEvaluate(int order, REAL vprime, REAL *coeff) +{ + int i, j; + REAL oldval, temp; + REAL oneMinusvprime; + + /* + * Minor optimization + * Compute orders 1 and 2 outright, and set coeff[0], coeff[1] to + * their i==1 loop values to avoid the initialization and the i==1 loop. + */ + if (order == 1) { + coeff[0] = 1.0; + return; + } + + oneMinusvprime = 1-vprime; + coeff[0] = oneMinusvprime; + coeff[1] = vprime; + if (order == 2) return; + + for (i = 2; i < order; i++) { + oldval = coeff[0] * vprime; + coeff[0] = oneMinusvprime * coeff[0]; + for (j = 1; j < i; j++) { + temp = oldval; + oldval = coeff[j] * vprime; + coeff[j] = temp + oneMinusvprime * coeff[j]; + } + coeff[j] = oldval; + } +} + +/* + *compute the Bezier polynomials C[n,j](v) and derivatives for all j at v with + *return values stored in coeff[] and coeffDeriv[]. + *see the head of function inPreEvaluate for the definition of C[n,j](v) + *and how to compute the values. + *The algorithm to compute the derivative is: + * dC[0,0](v) = 0. + * dC[n,j](v) = n*(dC[n-1,j-1](v) - dC[n-1,j](v)). + * + *This code is copied from opengl/soft/so_eval.c:PreEvaluateWidthDeriv + */ +void OpenGLSurfaceEvaluator::inPreEvaluateWithDeriv(int order, REAL vprime, + REAL *coeff, REAL *coeffDeriv) +{ + int i, j; + REAL oldval, temp; + REAL oneMinusvprime; + + oneMinusvprime = 1-vprime; + /* + * Minor optimization + * Compute orders 1 and 2 outright, and set coeff[0], coeff[1] to + * their i==1 loop values to avoid the initialization and the i==1 loop. + */ + if (order == 1) { + coeff[0] = 1.0; + coeffDeriv[0] = 0.0; + return; + } else if (order == 2) { + coeffDeriv[0] = -1.0; + coeffDeriv[1] = 1.0; + coeff[0] = oneMinusvprime; + coeff[1] = vprime; + return; + } + coeff[0] = oneMinusvprime; + coeff[1] = vprime; + for (i = 2; i < order - 1; i++) { + oldval = coeff[0] * vprime; + coeff[0] = oneMinusvprime * coeff[0]; + for (j = 1; j < i; j++) { + temp = oldval; + oldval = coeff[j] * vprime; + coeff[j] = temp + oneMinusvprime * coeff[j]; + } + coeff[j] = oldval; + } + coeffDeriv[0] = -coeff[0]; + /* + ** Minor optimization: + ** Would make this a "for (j=1; j<order-1; j++)" loop, but it is always + ** executed at least once, so this is more efficient. + */ + j=1; + do { + coeffDeriv[j] = coeff[j-1] - coeff[j]; + j++; + } while (j < order - 1); + coeffDeriv[j] = coeff[j-1]; + + oldval = coeff[0] * vprime; + coeff[0] = oneMinusvprime * coeff[0]; + for (j = 1; j < i; j++) { + temp = oldval; + oldval = coeff[j] * vprime; + coeff[j] = temp + oneMinusvprime * coeff[j]; + } + coeff[j] = oldval; +} + +void OpenGLSurfaceEvaluator::inEvalULine(int n_points, REAL v, REAL* u_vals, + int stride, REAL ret_points[][3], REAL ret_normals[][3]) +{ + int i,k; + REAL temp[4]; +inPreEvaluateBV_intfac(v); + + for(i=0,k=0; i<n_points; i++, k += stride) + { + inDoEvalCoord2NOGE_BV(u_vals[k],v,temp, ret_normals[i]); + + ret_points[i][0] = temp[0]; + ret_points[i][1] = temp[1]; + ret_points[i][2] = temp[2]; + + } + +} + +void OpenGLSurfaceEvaluator::inEvalVLine(int n_points, REAL u, REAL* v_vals, + int stride, REAL ret_points[][3], REAL ret_normals[][3]) +{ + int i,k; + REAL temp[4]; +inPreEvaluateBU_intfac(u); + for(i=0,k=0; i<n_points; i++, k += stride) + { + inDoEvalCoord2NOGE_BU(u, v_vals[k], temp, ret_normals[i]); + ret_points[i][0] = temp[0]; + ret_points[i][1] = temp[1]; + ret_points[i][2] = temp[2]; + } +} + + +/*triangulate a strip bounded by two lines which are parallel to U-axis + *upperVerts: the verteces on the upper line + *lowerVertx: the verteces on the lower line + *n_upper >=1 + *n_lower >=1 + */ +void OpenGLSurfaceEvaluator::inEvalUStrip(int n_upper, REAL v_upper, REAL* upper_val, int n_lower, REAL v_lower, REAL* lower_val) +{ + int i,j,k,l; + REAL leftMostV[2]; + typedef REAL REAL3[3]; + + REAL3* upperXYZ = (REAL3*) malloc(sizeof(REAL3)*n_upper); + assert(upperXYZ); + REAL3* upperNormal = (REAL3*) malloc(sizeof(REAL3) * n_upper); + assert(upperNormal); + REAL3* lowerXYZ = (REAL3*) malloc(sizeof(REAL3)*n_lower); + assert(lowerXYZ); + REAL3* lowerNormal = (REAL3*) malloc(sizeof(REAL3) * n_lower); + assert(lowerNormal); + + inEvalULine(n_upper, v_upper, upper_val, 1, upperXYZ, upperNormal); + inEvalULine(n_lower, v_lower, lower_val, 1, lowerXYZ, lowerNormal); + + + + REAL* leftMostXYZ; + REAL* leftMostNormal; + + /* + *the algorithm works by scanning from left to right. + *leftMostV: the left most of the remaining verteces (on both upper and lower). + * it could an element of upperVerts or lowerVerts. + *i: upperVerts[i] is the first vertex to the right of leftMostV on upper line *j: lowerVerts[j] is the first vertex to the right of leftMostV on lower line */ + + /*initialize i,j,and leftMostV + */ + if(upper_val[0] <= lower_val[0]) + { + i=1; + j=0; + + leftMostV[0] = upper_val[0]; + leftMostV[1] = v_upper; + leftMostXYZ = upperXYZ[0]; + leftMostNormal = upperNormal[0]; + } + else + { + i=0; + j=1; + + leftMostV[0] = lower_val[0]; + leftMostV[1] = v_lower; + + leftMostXYZ = lowerXYZ[0]; + leftMostNormal = lowerNormal[0]; + } + + /*the main loop. + *the invariance is that: + *at the beginning of each loop, the meaning of i,j,and leftMostV are + *maintained + */ + while(1) + { + if(i >= n_upper) /*case1: no more in upper*/ + { + if(j<n_lower-1) /*at least two vertices in lower*/ + { + bgntfan(); + glNormal3fv(leftMostNormal); + glVertex3fv(leftMostXYZ); + + while(j<n_lower){ + glNormal3fv(lowerNormal[j]); + glVertex3fv(lowerXYZ[j]); + j++; + + } + endtfan(); + } + break; /*exit the main loop*/ + } + else if(j>= n_lower) /*case2: no more in lower*/ + { + if(i<n_upper-1) /*at least two vertices in upper*/ + { + bgntfan(); + glNormal3fv(leftMostNormal); + glVertex3fv(leftMostXYZ); + + for(k=n_upper-1; k>=i; k--) /*reverse order for two-side lighting*/ + { + glNormal3fv(upperNormal[k]); + glVertex3fv(upperXYZ[k]); + } + + endtfan(); + } + break; /*exit the main loop*/ + } + else /* case3: neither is empty, plus the leftMostV, there is at least one triangle to output*/ + { + if(upper_val[i] <= lower_val[j]) + { + bgntfan(); + + glNormal3fv(lowerNormal[j]); + glVertex3fv(lowerXYZ[j]); + + /*find the last k>=i such that + *upperverts[k][0] <= lowerverts[j][0] + */ + k=i; + + while(k<n_upper) + { + if(upper_val[k] > lower_val[j]) + break; + k++; + + } + k--; + + + for(l=k; l>=i; l--)/*the reverse is for two-side lighting*/ + { + glNormal3fv(upperNormal[l]); + glVertex3fv(upperXYZ[l]); + + } + glNormal3fv(leftMostNormal); + glVertex3fv(leftMostXYZ); + + endtfan(); + + /*update i and leftMostV for next loop + */ + i = k+1; + + leftMostV[0] = upper_val[k]; + leftMostV[1] = v_upper; + leftMostNormal = upperNormal[k]; + leftMostXYZ = upperXYZ[k]; + } + else /*upperVerts[i][0] > lowerVerts[j][0]*/ + { + bgntfan(); + glNormal3fv(upperNormal[i]); + glVertex3fv(upperXYZ[i]); + + glNormal3fv(leftMostNormal); + glVertex3fv(leftMostXYZ); + + + /*find the last k>=j such that + *lowerverts[k][0] < upperverts[i][0] + */ + k=j; + while(k< n_lower) + { + if(lower_val[k] >= upper_val[i]) + break; + glNormal3fv(lowerNormal[k]); + glVertex3fv(lowerXYZ[k]); + + k++; + } + endtfan(); + + /*update j and leftMostV for next loop + */ + j=k; + leftMostV[0] = lower_val[j-1]; + leftMostV[1] = v_lower; + + leftMostNormal = lowerNormal[j-1]; + leftMostXYZ = lowerXYZ[j-1]; + } + } + } + //clean up + free(upperXYZ); + free(lowerXYZ); + free(upperNormal); + free(lowerNormal); +} + +/*triangulate a strip bounded by two lines which are parallel to V-axis + *leftVerts: the verteces on the left line + *rightVertx: the verteces on the right line + *n_left >=1 + *n_right >=1 + */ +void OpenGLSurfaceEvaluator::inEvalVStrip(int n_left, REAL u_left, REAL* left_val, int n_right, REAL u_right, REAL* right_val) +{ + int i,j,k,l; + REAL botMostV[2]; + typedef REAL REAL3[3]; + + REAL3* leftXYZ = (REAL3*) malloc(sizeof(REAL3)*n_left); + assert(leftXYZ); + REAL3* leftNormal = (REAL3*) malloc(sizeof(REAL3) * n_left); + assert(leftNormal); + REAL3* rightXYZ = (REAL3*) malloc(sizeof(REAL3)*n_right); + assert(rightXYZ); + REAL3* rightNormal = (REAL3*) malloc(sizeof(REAL3) * n_right); + assert(rightNormal); + + inEvalVLine(n_left, u_left, left_val, 1, leftXYZ, leftNormal); + inEvalVLine(n_right, u_right, right_val, 1, rightXYZ, rightNormal); + + + + REAL* botMostXYZ; + REAL* botMostNormal; + + /* + *the algorithm works by scanning from bot to top. + *botMostV: the bot most of the remaining verteces (on both left and right). + * it could an element of leftVerts or rightVerts. + *i: leftVerts[i] is the first vertex to the top of botMostV on left line + *j: rightVerts[j] is the first vertex to the top of botMostV on rightline */ + + /*initialize i,j,and botMostV + */ + if(left_val[0] <= right_val[0]) + { + i=1; + j=0; + + botMostV[0] = u_left; + botMostV[1] = left_val[0]; + botMostXYZ = leftXYZ[0]; + botMostNormal = leftNormal[0]; + } + else + { + i=0; + j=1; + + botMostV[0] = u_right; + botMostV[1] = right_val[0]; + + botMostXYZ = rightXYZ[0]; + botMostNormal = rightNormal[0]; + } + + /*the main loop. + *the invariance is that: + *at the beginning of each loop, the meaning of i,j,and botMostV are + *maintained + */ + while(1) + { + if(i >= n_left) /*case1: no more in left*/ + { + if(j<n_right-1) /*at least two vertices in right*/ + { + bgntfan(); + glNormal3fv(botMostNormal); + glVertex3fv(botMostXYZ); + + while(j<n_right){ + glNormal3fv(rightNormal[j]); + glVertex3fv(rightXYZ[j]); + j++; + + } + endtfan(); + } + break; /*exit the main loop*/ + } + else if(j>= n_right) /*case2: no more in right*/ + { + if(i<n_left-1) /*at least two vertices in left*/ + { + bgntfan(); + glNormal3fv(botMostNormal); + glVertex3fv(botMostXYZ); + + for(k=n_left-1; k>=i; k--) /*reverse order for two-side lighting*/ + { + glNormal3fv(leftNormal[k]); + glVertex3fv(leftXYZ[k]); + } + + endtfan(); + } + break; /*exit the main loop*/ + } + else /* case3: neither is empty, plus the botMostV, there is at least one triangle to output*/ + { + if(left_val[i] <= right_val[j]) + { + bgntfan(); + + glNormal3fv(rightNormal[j]); + glVertex3fv(rightXYZ[j]); + + /*find the last k>=i such that + *leftverts[k][0] <= rightverts[j][0] + */ + k=i; + + while(k<n_left) + { + if(left_val[k] > right_val[j]) + break; + k++; + + } + k--; + + + for(l=k; l>=i; l--)/*the reverse is for two-side lighting*/ + { + glNormal3fv(leftNormal[l]); + glVertex3fv(leftXYZ[l]); + + } + glNormal3fv(botMostNormal); + glVertex3fv(botMostXYZ); + + endtfan(); + + /*update i and botMostV for next loop + */ + i = k+1; + + botMostV[0] = u_left; + botMostV[1] = left_val[k]; + botMostNormal = leftNormal[k]; + botMostXYZ = leftXYZ[k]; + } + else /*left_val[i] > right_val[j])*/ + { + bgntfan(); + glNormal3fv(leftNormal[i]); + glVertex3fv(leftXYZ[i]); + + glNormal3fv(botMostNormal); + glVertex3fv(botMostXYZ); + + + /*find the last k>=j such that + *rightverts[k][0] < leftverts[i][0] + */ + k=j; + while(k< n_right) + { + if(right_val[k] >= left_val[i]) + break; + glNormal3fv(rightNormal[k]); + glVertex3fv(rightXYZ[k]); + + k++; + } + endtfan(); + + /*update j and botMostV for next loop + */ + j=k; + botMostV[0] = u_right; + botMostV[1] = right_val[j-1]; + + botMostNormal = rightNormal[j-1]; + botMostXYZ = rightXYZ[j-1]; + } + } + } + //clean up + free(leftXYZ); + free(rightXYZ); + free(leftNormal); + free(rightNormal); +} + +/*-----------------------begin evalMachine-------------------*/ +void OpenGLSurfaceEvaluator::inMap2fEM(int which, int k, + REAL ulower, + REAL uupper, + int ustride, + int uorder, + REAL vlower, + REAL vupper, + int vstride, + int vorder, + REAL *ctlPoints) +{ + int i,j,x; + surfEvalMachine *temp_em; + switch(which){ + case 0: //vertex + vertex_flag = 1; + temp_em = &em_vertex; + break; + case 1: //normal + normal_flag = 1; + temp_em = &em_normal; + break; + case 2: //color + color_flag = 1; + temp_em = &em_color; + break; + default: + texcoord_flag = 1; + temp_em = &em_texcoord; + break; + } + + REAL *data = temp_em->ctlPoints; + + temp_em->uprime = -1;//initilized + temp_em->vprime = -1; + + temp_em->k = k; + temp_em->u1 = ulower; + temp_em->u2 = uupper; + temp_em->ustride = ustride; + temp_em->uorder = uorder; + temp_em->v1 = vlower; + temp_em->v2 = vupper; + temp_em->vstride = vstride; + temp_em->vorder = vorder; + + /*copy the contrl points from ctlPoints to global_ev_ctlPoints*/ + for (i=0; i<uorder; i++) { + for (j=0; j<vorder; j++) { + for (x=0; x<k; x++) { + data[x] = ctlPoints[x]; + } + ctlPoints += vstride; + data += k; + } + ctlPoints += ustride - vstride * vorder; + } +} + +void OpenGLSurfaceEvaluator::inDoDomain2WithDerivsEM(surfEvalMachine *em, REAL u, REAL v, + REAL *retPoint, REAL *retdu, REAL *retdv) +{ + int j, row, col; + REAL the_uprime; + REAL the_vprime; + REAL p; + REAL pdv; + REAL *data; + + if((em->u2 == em->u1) || (em->v2 == em->v1)) + return; + the_uprime = (u - em->u1) / (em->u2 - em->u1); + the_vprime = (v - em->v1) / (em->v2 - em->v1); + + /* Compute coefficients for values and derivs */ + + /* Use already cached values if possible */ + if(em->uprime != the_uprime) { + inPreEvaluateWithDeriv(em->uorder, the_uprime, em->ucoeff, em->ucoeffDeriv); + em->uprime = the_uprime; + } + if (em->vprime != the_vprime) { + inPreEvaluateWithDeriv(em->vorder, the_vprime, em->vcoeff, em->vcoeffDeriv); + em->vprime = the_vprime; + } + + for (j = 0; j < em->k; j++) { + data=em->ctlPoints+j; + retPoint[j] = retdu[j] = retdv[j] = 0.0; + for (row = 0; row < em->uorder; row++) { + /* + ** Minor optimization. + ** The col == 0 part of the loop is extracted so we don't + ** have to initialize p and pdv to 0. + */ + p = em->vcoeff[0] * (*data); + pdv = em->vcoeffDeriv[0] * (*data); + data += em->k; + for (col = 1; col < em->vorder; col++) { + /* Incrementally build up p, pdv value */ + p += em->vcoeff[col] * (*data); + pdv += em->vcoeffDeriv[col] * (*data); + data += em->k; + } + /* Use p, pdv value to incrementally add up r, du, dv */ + retPoint[j] += em->ucoeff[row] * p; + retdu[j] += em->ucoeffDeriv[row] * p; + retdv[j] += em->ucoeff[row] * pdv; + } + } +} + +void OpenGLSurfaceEvaluator::inDoDomain2EM(surfEvalMachine *em, REAL u, REAL v, + REAL *retPoint) +{ + int j, row, col; + REAL the_uprime; + REAL the_vprime; + REAL p; + REAL *data; + + if((em->u2 == em->u1) || (em->v2 == em->v1)) + return; + the_uprime = (u - em->u1) / (em->u2 - em->u1); + the_vprime = (v - em->v1) / (em->v2 - em->v1); + + /* Compute coefficients for values and derivs */ + + /* Use already cached values if possible */ + if(em->uprime != the_uprime) { + inPreEvaluate(em->uorder, the_uprime, em->ucoeff); + em->uprime = the_uprime; + } + if (em->vprime != the_vprime) { + inPreEvaluate(em->vorder, the_vprime, em->vcoeff); + em->vprime = the_vprime; + } + + for (j = 0; j < em->k; j++) { + data=em->ctlPoints+j; + retPoint[j] = 0.0; + for (row = 0; row < em->uorder; row++) { + /* + ** Minor optimization. + ** The col == 0 part of the loop is extracted so we don't + ** have to initialize p and pdv to 0. + */ + p = em->vcoeff[0] * (*data); + data += em->k; + for (col = 1; col < em->vorder; col++) { + /* Incrementally build up p, pdv value */ + p += em->vcoeff[col] * (*data); + data += em->k; + } + /* Use p, pdv value to incrementally add up r, du, dv */ + retPoint[j] += em->ucoeff[row] * p; + } + } +} + + +void OpenGLSurfaceEvaluator::inDoEvalCoord2EM(REAL u, REAL v) +{ + REAL temp_vertex[5]; + REAL temp_normal[3]; + REAL temp_color[4]; + REAL temp_texcoord[4]; + + if(texcoord_flag) + { + inDoDomain2EM(&em_texcoord, u,v, temp_texcoord); + texcoordCallBack(temp_texcoord, userData); + } + if(color_flag) + { + inDoDomain2EM(&em_color, u,v, temp_color); + colorCallBack(temp_color, userData); + } + + if(normal_flag) //there is a normla map + { + inDoDomain2EM(&em_normal, u,v, temp_normal); + normalCallBack(temp_normal, userData); + + if(vertex_flag) + { + inDoDomain2EM(&em_vertex, u,v,temp_vertex); + if(em_vertex.k == 4) + { + temp_vertex[0] /= temp_vertex[3]; + temp_vertex[1] /= temp_vertex[3]; + temp_vertex[2] /= temp_vertex[3]; + } + temp_vertex[3]=u; + temp_vertex[4]=v; + vertexCallBack(temp_vertex, userData); + } + } + else if(auto_normal_flag) //no normal map but there is a normal callbackfunctin + { + REAL du[4]; + REAL dv[4]; + + /*compute homegeneous point and partial derivatives*/ + inDoDomain2WithDerivsEM(&em_vertex, u,v,temp_vertex,du,dv); + + if(em_vertex.k ==4) + inComputeFirstPartials(temp_vertex, du, dv); + +#ifdef AVOID_ZERO_NORMAL + if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO) + { + + REAL tempdu[4]; + REAL tempdata[4]; + REAL u1 = em_vertex.u1; + REAL u2 = em_vertex.u2; + if(u-MYDELTA*(u2-u1) < u1) + u = u+ MYDELTA*(u2-u1); + else + u = u-MYDELTA*(u2-u1); + inDoDomain2WithDerivsEM(&em_vertex,u,v, tempdata, tempdu, dv); + + if(em_vertex.k ==4) + inComputeFirstPartials(temp_vertex, du, dv); + } + else if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO) + { + REAL tempdv[4]; + REAL tempdata[4]; + REAL v1 = em_vertex.v1; + REAL v2 = em_vertex.v2; + if(v-MYDELTA*(v2-v1) < v1) + v = v+ MYDELTA*(v2-v1); + else + v = v-MYDELTA*(v2-v1); + inDoDomain2WithDerivsEM(&em_vertex,u,v, tempdata, du, tempdv); + + if(em_vertex.k ==4) + inComputeFirstPartials(temp_vertex, du, dv); + } +#endif + + /*compute normal*/ + switch(em_vertex.k){ + case 3: + + inComputeNormal2(du, dv, temp_normal); + break; + case 4: + +// inComputeFirstPartials(temp_vertex, du, dv); + inComputeNormal2(du, dv, temp_normal); + + /*transform the homegeneous coordinate of retPoint into inhomogenous one*/ + temp_vertex[0] /= temp_vertex[3]; + temp_vertex[1] /= temp_vertex[3]; + temp_vertex[2] /= temp_vertex[3]; + break; + } + normalCallBack(temp_normal, userData); + temp_vertex[3] = u; + temp_vertex[4] = v; + vertexCallBack(temp_vertex, userData); + + }/*end if auto_normal*/ + else //no normal map, and no normal callback function + { + if(vertex_flag) + { + inDoDomain2EM(&em_vertex, u,v,temp_vertex); + if(em_vertex.k == 4) + { + temp_vertex[0] /= temp_vertex[3]; + temp_vertex[1] /= temp_vertex[3]; + temp_vertex[2] /= temp_vertex[3]; + } + temp_vertex[3] = u; + temp_vertex[4] = v; + vertexCallBack(temp_vertex, userData); + } + } +} + + +void OpenGLSurfaceEvaluator::inBPMEvalEM(bezierPatchMesh* bpm) +{ + int i,j,k; + float u,v; + + int ustride; + int vstride; + +#ifdef USE_LOD + if(bpm->bpatch != NULL) + { + bezierPatch* p=bpm->bpatch; + ustride = p->dimension * p->vorder; + vstride = p->dimension; + + glMap2f( (p->dimension == 3)? GL_MAP2_VERTEX_3 : GL_MAP2_VERTEX_4, + p->umin, + p->umax, + ustride, + p->uorder, + p->vmin, + p->vmax, + vstride, + p->vorder, + p->ctlpoints); + + +/* + inMap2fEM(0, p->dimension, + p->umin, + p->umax, + ustride, + p->uorder, + p->vmin, + p->vmax, + vstride, + p->vorder, + p->ctlpoints); +*/ + } +#else + + if(bpm->bpatch != NULL){ + bezierPatch* p = bpm->bpatch; + ustride = p->dimension * p->vorder; + vstride = p->dimension; + inMap2fEM(0, p->dimension, + p->umin, + p->umax, + ustride, + p->uorder, + p->vmin, + p->vmax, + vstride, + p->vorder, + p->ctlpoints); + } + if(bpm->bpatch_normal != NULL){ + bezierPatch* p = bpm->bpatch_normal; + ustride = p->dimension * p->vorder; + vstride = p->dimension; + inMap2fEM(1, p->dimension, + p->umin, + p->umax, + ustride, + p->uorder, + p->vmin, + p->vmax, + vstride, + p->vorder, + p->ctlpoints); + } + if(bpm->bpatch_color != NULL){ + bezierPatch* p = bpm->bpatch_color; + ustride = p->dimension * p->vorder; + vstride = p->dimension; + inMap2fEM(2, p->dimension, + p->umin, + p->umax, + ustride, + p->uorder, + p->vmin, + p->vmax, + vstride, + p->vorder, + p->ctlpoints); + } + if(bpm->bpatch_texcoord != NULL){ + bezierPatch* p = bpm->bpatch_texcoord; + ustride = p->dimension * p->vorder; + vstride = p->dimension; + inMap2fEM(3, p->dimension, + p->umin, + p->umax, + ustride, + p->uorder, + p->vmin, + p->vmax, + vstride, + p->vorder, + p->ctlpoints); + } +#endif + + + k=0; + for(i=0; i<bpm->index_length_array; i++) + { +#ifdef USE_LOD + if(bpm->type_array[i] == GL_POLYGON) //a mesh + { + GLfloat *temp = bpm->UVarray+k; + GLfloat u0 = temp[0]; + GLfloat v0 = temp[1]; + GLfloat u1 = temp[2]; + GLfloat v1 = temp[3]; + GLint nu = (GLint) ( temp[4]); + GLint nv = (GLint) ( temp[5]); + GLint umin = (GLint) ( temp[6]); + GLint vmin = (GLint) ( temp[7]); + GLint umax = (GLint) ( temp[8]); + GLint vmax = (GLint) ( temp[9]); + + glMapGrid2f(LOD_eval_level*nu, u0, u1, LOD_eval_level*nv, v0, v1); + glEvalMesh2(GL_FILL, LOD_eval_level*umin, LOD_eval_level*umax, LOD_eval_level*vmin, LOD_eval_level*vmax); + } + else + { + LOD_eval(bpm->length_array[i], bpm->UVarray+k, bpm->type_array[i], + 0 + ); + } + k+= 2*bpm->length_array[i]; + +#else //undef USE_LOD + +#ifdef CRACK_TEST +if( bpm->bpatch->umin == 2 && bpm->bpatch->umax == 3 + && bpm->bpatch->vmin ==2 && bpm->bpatch->vmax == 3) +{ +REAL vertex[4]; +REAL normal[4]; +#ifdef DEBUG +printf("***number ****1\n"); +#endif + +beginCallBack(GL_QUAD_STRIP, NULL); +inDoEvalCoord2EM(3.0, 3.0); +inDoEvalCoord2EM(2.0, 3.0); +inDoEvalCoord2EM(3.0, 2.7); +inDoEvalCoord2EM(2.0, 2.7); +inDoEvalCoord2EM(3.0, 2.0); +inDoEvalCoord2EM(2.0, 2.0); +endCallBack(NULL); + +beginCallBack(GL_TRIANGLE_STRIP, NULL); +inDoEvalCoord2EM(2.0, 3.0); +inDoEvalCoord2EM(2.0, 2.0); +inDoEvalCoord2EM(2.0, 2.7); +endCallBack(NULL); + +} +if( bpm->bpatch->umin == 1 && bpm->bpatch->umax == 2 + && bpm->bpatch->vmin ==2 && bpm->bpatch->vmax == 3) +{ +#ifdef DEBUG +printf("***number 3\n"); +#endif +beginCallBack(GL_QUAD_STRIP, NULL); +inDoEvalCoord2EM(2.0, 3.0); +inDoEvalCoord2EM(1.0, 3.0); +inDoEvalCoord2EM(2.0, 2.3); +inDoEvalCoord2EM(1.0, 2.3); +inDoEvalCoord2EM(2.0, 2.0); +inDoEvalCoord2EM(1.0, 2.0); +endCallBack(NULL); + +beginCallBack(GL_TRIANGLE_STRIP, NULL); +inDoEvalCoord2EM(2.0, 2.3); +inDoEvalCoord2EM(2.0, 2.0); +inDoEvalCoord2EM(2.0, 3.0); +endCallBack(NULL); + +} +return; +#endif //CRACK_TEST + + beginCallBack(bpm->type_array[i], userData); + + for(j=0; j<bpm->length_array[i]; j++) + { + u = bpm->UVarray[k]; + v = bpm->UVarray[k+1]; +#ifdef USE_LOD + LOD_EVAL_COORD(u,v); +// glEvalCoord2f(u,v); +#else + +#ifdef GENERIC_TEST + float temp_normal[3]; + float temp_vertex[3]; + if(temp_signal == 0) + { + gTessVertexSphere(u,v, temp_normal, temp_vertex); +//printf("normal=(%f,%f,%f)\n", temp_normal[0], temp_normal[1], temp_normal[2])//printf("veretx=(%f,%f,%f)\n", temp_vertex[0], temp_vertex[1], temp_vertex[2]); + normalCallBack(temp_normal, userData); + vertexCallBack(temp_vertex, userData); + } + else if(temp_signal == 1) + { + gTessVertexCyl(u,v, temp_normal, temp_vertex); +//printf("normal=(%f,%f,%f)\n", temp_normal[0], temp_normal[1], temp_normal[2])//printf("veretx=(%f,%f,%f)\n", temp_vertex[0], temp_vertex[1], temp_vertex[2]); + normalCallBack(temp_normal, userData); + vertexCallBack(temp_vertex, userData); + } + else +#endif //GENERIC_TEST + + inDoEvalCoord2EM(u,v); + +#endif //USE_LOD + + k += 2; + } + endCallBack(userData); + +#endif //USE_LOD + } +} + +void OpenGLSurfaceEvaluator::inBPMListEvalEM(bezierPatchMesh* list) +{ + bezierPatchMesh* temp; + for(temp = list; temp != NULL; temp = temp->next) + { + inBPMEvalEM(temp); + } +} + diff --git a/mesalib/src/glu/sgi/libnurbs/interface/mystdio.h b/mesalib/src/glu/sgi/libnurbs/interface/mystdio.h new file mode 100644 index 000000000..5ab49effd --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/interface/mystdio.h @@ -0,0 +1,60 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * mystdio.h + * + */ + +#ifndef __glumystdio_h_ +#define __glumystdio_h_ + +#ifdef STANDALONE +inline void _glu_dprintf( const char *, ... ) { } +#endif + +#ifdef LIBRARYBUILD +#ifndef NDEBUG +#include <stdio.h> +#define _glu_dprintf printf +#else +inline void _glu_dprintf( const char *, ... ) { } +#endif +#endif + +#ifdef GLBUILD +inline void _glu_dprintf( const char *, ... ) { } +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#endif /* __glumystdio_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/interface/mystdlib.h b/mesalib/src/glu/sgi/libnurbs/interface/mystdlib.h new file mode 100644 index 000000000..ab7a3b273 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/interface/mystdlib.h @@ -0,0 +1,57 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * mystdlib.h + * + */ + +#ifndef __glumystdlib_h_ +#define __glumystdlib_h_ + +#ifdef STANDALONE +typedef unsigned int size_t; +extern "C" void abort( void ); +extern "C" void * malloc( size_t ); +extern "C" void free( void * ); +#endif + +#ifdef LIBRARYBUILD +#include <stdlib.h> +#endif + +#ifdef GLBUILD +typedef unsigned int size_t; +extern "C" void abort( void ); +extern "C" void * malloc( size_t ); +extern "C" void free( void * ); +#endif + +#endif /* __glumystdlib_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/arc.cc b/mesalib/src/glu/sgi/libnurbs/internals/arc.cc new file mode 100644 index 000000000..b85139de9 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/arc.cc @@ -0,0 +1,347 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * arc.c++ + * + */ + +#include <stdio.h> +#include "glimports.h" +#include "mystdio.h" +#include "myassert.h" +#include "arc.h" +#include "bin.h" +#include "bezierarc.h" +#include "pwlarc.h" +#include "simplemath.h" + +/* local preprocessor definitions */ +#define ZERO 0.00001/*0.000001*/ + +const int Arc::bezier_tag = (1<<13); +const int Arc::arc_tag = (1<<3); +const int Arc::tail_tag = (1<<6); + +/*-------------------------------------------------------------------------- + * makeSide - attach a pwl arc to an arc and mark it as a border arc + *-------------------------------------------------------------------------- + */ + +void +Arc::makeSide( PwlArc *pwl, arc_side side ) +{ + assert( pwl != 0); + assert( pwlArc == 0 ); + assert( pwl->npts > 0 ); + assert( pwl->pts != 0); + pwlArc = pwl; + clearbezier(); + setside( side ); +} + + +/*-------------------------------------------------------------------------- + * numpts - count number of points on arc loop + *-------------------------------------------------------------------------- + */ + +int +Arc::numpts( void ) +{ + Arc_ptr jarc = this; + int npts = 0; + do { + npts += jarc->pwlArc->npts; + jarc = jarc->next; + } while( jarc != this ); + return npts; +} + +/*-------------------------------------------------------------------------- + * markverts - mark each point with id of arc + *-------------------------------------------------------------------------- + */ + +void +Arc::markverts( void ) +{ + Arc_ptr jarc = this; + + do { + TrimVertex *p = jarc->pwlArc->pts; + for( int i=0; i<jarc->pwlArc->npts; i++ ) + p[i].nuid = jarc->nuid; + jarc = jarc->next; + } while( jarc != this ); +} + +/*-------------------------------------------------------------------------- + * getextrema - find axis extrema on arc loop + *-------------------------------------------------------------------------- + */ + +void +Arc::getextrema( Arc_ptr extrema[4] ) +{ + REAL leftpt, botpt, rightpt, toppt; + + extrema[0] = extrema[1] = extrema[2] = extrema[3] = this; + + leftpt = rightpt = this->tail()[0]; + botpt = toppt = this->tail()[1]; + + for( Arc_ptr jarc = this->next; jarc != this; jarc = jarc->next ) { + if ( jarc->tail()[0] < leftpt || + (jarc->tail()[0] <= leftpt && jarc->rhead()[0]<=leftpt)) { + leftpt = jarc->pwlArc->pts->param[0]; + extrema[1] = jarc; + } + if ( jarc->tail()[0] > rightpt || + (jarc->tail()[0] >= rightpt && jarc->rhead()[0] >= rightpt)) { + rightpt = jarc->pwlArc->pts->param[0]; + extrema[3] = jarc; + } + if ( jarc->tail()[1] < botpt || + (jarc->tail()[1] <= botpt && jarc->rhead()[1] <= botpt )) { + botpt = jarc->pwlArc->pts->param[1]; + extrema[2] = jarc; + } + if ( jarc->tail()[1] > toppt || + (jarc->tail()[1] >= toppt && jarc->rhead()[1] >= toppt)) { + toppt = jarc->pwlArc->pts->param[1]; + extrema[0] = jarc; + } + } +} + + +/*------------------------------------------------------------------------- + * show - print to the stdout the vertices of a pwl arc + *------------------------------------------------------------------------- + */ + +void +Arc::show() +{ +#ifndef NDEBUG + _glu_dprintf( "\tPWLARC NP: %d FL: 1\n", pwlArc->npts ); + for( int i = 0; i < pwlArc->npts; i++ ) { + _glu_dprintf( "\t\tVERTEX %f %f\n", pwlArc->pts[i].param[0], + pwlArc->pts[i].param[1] ); + } +#endif +} + +/*------------------------------------------------------------------------- + * print - print out the vertices of all pwl arcs on a loop + *------------------------------------------------------------------------- + */ + +void +Arc::print( void ) +{ + Arc_ptr jarc = this; + +#ifndef NDEBUG + _glu_dprintf( "BGNTRIM\n" ); +#endif + do { + jarc->show( ); + jarc = jarc->next; + } while (jarc != this); +#ifndef NDEBUG + _glu_dprintf("ENDTRIM\n" ); +#endif +} + +/*------------------------------------------------------------------------- + * isDisconnected - check if tail of arc and head of prev meet + *------------------------------------------------------------------------- + */ + +int +Arc::isDisconnected( void ) +{ + if( pwlArc == 0 ) return 0; + if( prev->pwlArc == 0 ) return 0; + + REAL *p0 = tail(); + REAL *p1 = prev->rhead(); + + if( ((p0[0] - p1[0]) > ZERO) || ((p1[0] - p0[0]) > ZERO) || + ((p0[1] - p1[1]) > ZERO) || ((p1[1] - p0[1]) > ZERO) ) { +#ifndef NDEBUG + _glu_dprintf( "x coord = %f %f %f\n", p0[0], p1[0], p0[0] - p1[0] ); + _glu_dprintf( "y coord = %f %f %f\n", p0[1], p1[1], p0[1] - p1[1] ); +#endif + return 1; + } else { + /* average two points together */ + p0[0] = p1[0] = (p1[0] + p0[0]) * 0.5; + p0[1] = p1[1] = (p1[1] + p0[1]) * 0.5; + return 0; + } +} + +/*------------------------------------------------------------------------- + * neq_vert - assert that two 2D vertices are not equal + *------------------------------------------------------------------------- + */ + +inline static int +neq_vert( REAL *v1, REAL *v2 ) +{ + return ((v1[0] != v2[0]) || (v1[1] != v2[1] )) ? 1 : 0; +} + +/*------------------------------------------------------------------------- + * check - verify consistency of a loop, including + * 1) if pwl, no two consecutive vertices are identical + * 2) the circular link pointers are valid + * 3) the geometric info at the head and tail are consistent + *------------------------------------------------------------------------- + */ + +int +Arc::check( void ) +{ + if( this == 0 ) return 1; + Arc_ptr jarc = this; + do { + assert( (jarc->pwlArc != 0) || (jarc->bezierArc != 0) ); + + if (jarc->prev == 0 || jarc->next == 0) { +#ifndef NDEBUG + _glu_dprintf( "checkjarc:null next/prev pointer\n"); + jarc->print( ); +#endif + return 0; + } + + if (jarc->next->prev != jarc) { +#ifndef NDEBUG + _glu_dprintf( "checkjarc: pointer linkage screwed up\n"); + jarc->print( ); +#endif + return 0; + } + + if( jarc->pwlArc ) { +#ifndef NDEBUG + assert( jarc->pwlArc->npts >= 1 ); + assert( jarc->pwlArc->npts < 100000 ); +/* + for( int i=0; i < jarc->pwlArc->npts-1; i++ ) + assert( neq_vert( jarc->pwlArc->pts[i].param, + jarc->pwlArc->pts[i+1].param) ); +*/ +#endif + if( jarc->prev->pwlArc ) { + if( jarc->tail()[1] != jarc->prev->rhead()[1] ) { +#ifndef NDEBUG + _glu_dprintf( "checkjarc: geometric linkage screwed up 1\n"); + jarc->prev->show(); + jarc->show(); +#endif + return 0; + } + if( jarc->tail()[0] != jarc->prev->rhead()[0] ) { + +#ifndef NDEBUG + _glu_dprintf( "checkjarc: geometric linkage screwed up 2\n"); + jarc->prev->show(); + jarc->show(); +#endif + return 0; + } + } + if( jarc->next->pwlArc ) { + if( jarc->next->tail()[0] != jarc->rhead()[0] ) { +#ifndef NDEBUG + _glu_dprintf( "checkjarc: geometric linkage screwed up 3\n"); + jarc->show(); + jarc->next->show(); +#endif + return 0; + } + if( jarc->next->tail()[1] != jarc->rhead()[1] ) { +#ifndef NDEBUG + _glu_dprintf( "checkjarc: geometric linkage screwed up 4\n"); + jarc->show(); + jarc->next->show(); +#endif + return 0; + } + } + if( jarc->isbezier() ) { + assert( jarc->pwlArc->npts == 2 ); + assert( (jarc->pwlArc->pts[0].param[0] == \ + jarc->pwlArc->pts[1].param[0]) ||\ + (jarc->pwlArc->pts[0].param[1] == \ + jarc->pwlArc->pts[1].param[1]) ); + } + } + jarc = jarc->next; + } while (jarc != this); + return 1; +} + + +#define TOL 0.00001 + +inline long tooclose( REAL x, REAL y ) +{ + return (glu_abs(x-y) < TOL) ? 1 : 0; +} + + +/*-------------------------------------------------------------------------- + * append - append a jordan arc to a circularly linked list + *-------------------------------------------------------------------------- + */ + +Arc_ptr +Arc::append( Arc_ptr jarc ) +{ + if( jarc != 0 ) { + next = jarc->next; + prev = jarc; + next->prev = prev->next = this; + } else { + next = prev = this; + } + return this; +} + diff --git a/mesalib/src/glu/sgi/libnurbs/internals/arc.h b/mesalib/src/glu/sgi/libnurbs/internals/arc.h new file mode 100644 index 000000000..e986019c3 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/arc.h @@ -0,0 +1,133 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * arc.h + * + */ + +#ifndef __gluarc_h_ +#define __gluarc_h_ + +#include "myassert.h" +#include "bufpool.h" +#include "mystdio.h" +#include "types.h" +#include "pwlarc.h" +#include "trimvertex.h" + +class Bin; +class Arc; +struct BezierArc; + +typedef class Arc *Arc_ptr; + +enum arc_side { arc_none = 0, arc_right, arc_top, arc_left, arc_bottom }; + + +class Arc: public PooledObj { /* an arc, in two list, the trim list and bin */ + +public: + static const int bezier_tag; + static const int arc_tag; + static const int tail_tag; + Arc_ptr prev; /* trim list pointer */ + Arc_ptr next; /* trim list pointer */ + Arc_ptr link; /* bin pointers */ + BezierArc * bezierArc; /* associated bezier arc */ + PwlArc * pwlArc; /* associated pwl arc */ + long type; /* curve type */ + long nuid; + + inline Arc( Arc *, PwlArc * ); + inline Arc( arc_side, long ); + + Arc_ptr append( Arc_ptr ); + int check( void ); + int isMonotone( void ); + int isDisconnected( void ); + int numpts( void ); + void markverts( void ); + void getextrema( Arc_ptr[4] ); + void print( void ); + void show( void ); + void makeSide( PwlArc *, arc_side ); + inline int isTessellated() { return pwlArc ? 1 : 0; } + inline long isbezier() { return type & bezier_tag; } + inline void setbezier() { type |= bezier_tag; } + inline void clearbezier() { type &= ~bezier_tag; } + inline long npts() { return pwlArc->npts; } + inline TrimVertex * pts() { return pwlArc->pts; } + inline REAL * tail() { return pwlArc->pts[0].param; } + inline REAL * head() { return next->pwlArc->pts[0].param; } + inline REAL * rhead() { return pwlArc->pts[pwlArc->npts-1].param; } + inline long ismarked() { return type & arc_tag; } + inline void setmark() { type |= arc_tag; } + inline void clearmark() { type &= (~arc_tag); } + inline void clearside() { type &= ~(0x7 << 8); } + inline void setside( arc_side s ) { clearside(); type |= (((long)s)<<8); } + inline arc_side getside() { return (arc_side) ((type>>8) & 0x7); } + inline int getitail() { return type & tail_tag; } + inline void setitail() { type |= tail_tag; } + inline void clearitail() { type &= (~tail_tag); } +}; + +/*-------------------------------------------------------------------------- + * Arc - initialize a new Arc with the same type and uid of + * a given Arc and a given pwl arc + *-------------------------------------------------------------------------- + */ + +inline +Arc::Arc( Arc *j, PwlArc *p ) +{ + bezierArc = NULL; + pwlArc = p; + type = j->type; + nuid = j->nuid; +} + +/*-------------------------------------------------------------------------- + * Arc - initialize a new Arc with the same type and uid of + * a given Arc and a given pwl arc + *-------------------------------------------------------------------------- + */ + +inline +Arc::Arc( arc_side side, long _nuid ) +{ + bezierArc = NULL; + pwlArc = NULL; + type = 0; + setside( side ); + nuid = _nuid; +} + +#endif /* __gluarc_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/arcsorter.cc b/mesalib/src/glu/sgi/libnurbs/internals/arcsorter.cc new file mode 100644 index 000000000..1f85cb710 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/arcsorter.cc @@ -0,0 +1,172 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * arcsorter.c++ + * + */ + +#ifndef __gluarcsorter_c_ +#define __gluarcsorter_c_ + +#include "glimports.h" +#include "arc.h" +#include "arcsorter.h" +#include "subdivider.h" + +ArcSorter::ArcSorter(Subdivider &s) : Sorter( sizeof( Arc ** ) ), subdivider(s) +{ +} + +int +ArcSorter::qscmp( char *, char * ) +{ + _glu_dprintf( "ArcSorter::qscmp: pure virtual called\n" ); + return 0; +} + +void +ArcSorter::qsort( Arc **a, int n ) +{ + Sorter::qsort( (void *) a, n ); +} + +void +ArcSorter::qsexc( char *i, char *j )// i<-j, j<-i +{ + Arc **jarc1 = (Arc **) i; + Arc **jarc2 = (Arc **) j; + Arc *tmp = *jarc1; + *jarc1 = *jarc2; + *jarc2 = tmp; +} + +void +ArcSorter::qstexc( char *i, char *j, char *k )// i<-k, k<-j, j<-i +{ + Arc **jarc1 = (Arc **) i; + Arc **jarc2 = (Arc **) j; + Arc **jarc3 = (Arc **) k; + Arc *tmp = *jarc1; + *jarc1 = *jarc3; + *jarc3 = *jarc2; + *jarc2 = tmp; +} + + +ArcSdirSorter::ArcSdirSorter( Subdivider &s ) : ArcSorter(s) +{ +} + +int +ArcSdirSorter::qscmp( char *i, char *j ) +{ + Arc *jarc1 = *(Arc **) i; + Arc *jarc2 = *(Arc **) j; + + int v1 = (jarc1->getitail() ? 0 : (jarc1->pwlArc->npts - 1)); + int v2 = (jarc2->getitail() ? 0 : (jarc2->pwlArc->npts - 1)); + + REAL diff = jarc1->pwlArc->pts[v1].param[1] - + jarc2->pwlArc->pts[v2].param[1]; + + if( diff < 0.0) + return -1; + else if( diff > 0.0) + return 1; + else { + if( v1 == 0 ) { + if( jarc2->tail()[0] < jarc1->tail()[0] ) { + return subdivider.ccwTurn_sl( jarc2, jarc1 ) ? 1 : -1; + } else { + return subdivider.ccwTurn_sr( jarc2, jarc1 ) ? -1 : 1; + } + } else { + if( jarc2->head()[0] < jarc1->head()[0] ) { + return subdivider.ccwTurn_sl( jarc1, jarc2 ) ? -1 : 1; + } else { + return subdivider.ccwTurn_sr( jarc1, jarc2 ) ? 1 : -1; + } + } + } +} + +ArcTdirSorter::ArcTdirSorter( Subdivider &s ) : ArcSorter(s) +{ +} + +/*---------------------------------------------------------------------------- + * ArcTdirSorter::qscmp - + * compare two axis monotone arcs that are incident + * to the line T == compare_value. Determine which of the + * two intersects that line with a LESSER S value. If + * jarc1 does, return 1. If jarc2 does, return -1. + *---------------------------------------------------------------------------- + */ +int +ArcTdirSorter::qscmp( char *i, char *j ) +{ + Arc *jarc1 = *(Arc **) i; + Arc *jarc2 = *(Arc **) j; + + int v1 = (jarc1->getitail() ? 0 : (jarc1->pwlArc->npts - 1)); + int v2 = (jarc2->getitail() ? 0 : (jarc2->pwlArc->npts - 1)); + + REAL diff = jarc1->pwlArc->pts[v1].param[0] - + jarc2->pwlArc->pts[v2].param[0]; + + if( diff < 0.0) + return 1; + else if( diff > 0.0) + return -1; + else { + if( v1 == 0 ) { + if (jarc2->tail()[1] < jarc1->tail()[1]) { + return subdivider.ccwTurn_tl( jarc2, jarc1 ) ? 1 : -1; + } else { + return subdivider.ccwTurn_tr( jarc2, jarc1 ) ? -1 : 1; + } + } else { + if( jarc2->head()[1] < jarc1->head()[1] ) { + return subdivider.ccwTurn_tl( jarc1, jarc2 ) ? -1 : 1; + } else { + return subdivider.ccwTurn_tr( jarc1, jarc2 ) ? 1 : -1; + } + } + } +} + + + +#endif /* __gluarcsorter_c_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/arcsorter.h b/mesalib/src/glu/sgi/libnurbs/internals/arcsorter.h new file mode 100644 index 000000000..d72dd1e86 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/arcsorter.h @@ -0,0 +1,73 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * arcsorter.h + * + */ + +#ifndef __gluarcsorter_h_ +#define __gluarcsorter_h_ + +#include "sorter.h" +#include "arcsorter.h" + +class Arc; +class Subdivider; + +class ArcSorter : private Sorter { +public: + ArcSorter(Subdivider &); + void qsort( Arc **a, int n ); +protected: + virtual int qscmp( char *, char * ); + Subdivider& subdivider; +private: + void qsexc( char *i, char *j ); // i<-j, j<-i + void qstexc( char *i, char *j, char *k ); // i<-k, k<-j, j<-i +}; + + +class ArcSdirSorter : public ArcSorter { +public: + ArcSdirSorter( Subdivider & ); +private: + int qscmp( char *, char * ); +}; + + +class ArcTdirSorter : public ArcSorter { +public: + ArcTdirSorter( Subdivider & ); +private: + int qscmp( char *, char * ); +}; + +#endif /* __gluarcsorter_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/arctess.cc b/mesalib/src/glu/sgi/libnurbs/internals/arctess.cc new file mode 100644 index 000000000..29e7cf4c0 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/arctess.cc @@ -0,0 +1,611 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * arctessellator.c++ + * + */ + +#include "glimports.h" +#include "mystdio.h" +#include "myassert.h" +#include "arctess.h" +#include "bufpool.h" +#include "simplemath.h" +#include "bezierarc.h" +#include "trimvertex.h" +#include "trimvertpool.h" + +#define NOELIMINATION + +#define steps_function(large, small, rate) (max(1, 1+ (int) ((large-small)/rate))); + +/*----------------------------------------------------------------------------- + * ArcTessellator - construct an ArcTessellator + *----------------------------------------------------------------------------- + */ + +ArcTessellator::ArcTessellator( TrimVertexPool& t, Pool& p ) + : pwlarcpool(p), trimvertexpool(t) +{ +} + +/*----------------------------------------------------------------------------- + * ~ArcTessellator - destroy an ArcTessellator + *----------------------------------------------------------------------------- + */ + +ArcTessellator::~ArcTessellator( void ) +{ +} + +/*----------------------------------------------------------------------------- + * bezier - construct a bezier arc and attach it to an Arc + *----------------------------------------------------------------------------- + */ + +void +ArcTessellator::bezier( Arc *arc, REAL s1, REAL s2, REAL t1, REAL t2 ) +{ + assert( arc != 0 ); + assert( ! arc->isTessellated() ); + +#ifndef NDEBUG + switch( arc->getside() ) { + case arc_left: + assert( s1 == s2 ); + assert( t2 < t1 ); + break; + case arc_right: + assert( s1 == s2 ); + assert( t1 < t2 ); + break; + case arc_top: + assert( t1 == t2 ); + assert( s2 < s1 ); + break; + case arc_bottom: + assert( t1 == t2 ); + assert( s1 < s2 ); + break; + case arc_none: + (void) abort(); + break; + } +#endif + + TrimVertex *p = trimvertexpool.get(2); + arc->pwlArc = new(pwlarcpool) PwlArc( 2, p ); + p[0].param[0] = s1; + p[0].param[1] = t1; + p[1].param[0] = s2; + p[1].param[1] = t2; + assert( (s1 == s2) || (t1 == t2) ); + arc->setbezier(); +} + + +/*----------------------------------------------------------------------------- + * pwl_left - construct a left boundary pwl arc and attach it to an arc + *----------------------------------------------------------------------------- + */ + +void +ArcTessellator::pwl_left( Arc *arc, REAL s, REAL t1, REAL t2, REAL rate ) +{ + assert( t2 < t1 ); + +/* if(rate <= 0.06) rate = 0.06;*/ +/* int nsteps = 1 + (int) ((t1 - t2) / rate ); */ + int nsteps = steps_function(t1, t2, rate); + + + REAL stepsize = (t1 - t2) / (REAL) nsteps; + + TrimVertex *newvert = trimvertexpool.get( nsteps+1 ); + int i; + for( i = nsteps; i > 0; i-- ) { + newvert[i].param[0] = s; + newvert[i].param[1] = t2; + t2 += stepsize; + } + newvert[i].param[0] = s; + newvert[i].param[1] = t1; + + arc->makeSide( new(pwlarcpool) PwlArc( nsteps+1, newvert ), arc_left ); +} + +/*----------------------------------------------------------------------------- + * pwl_right - construct a right boundary pwl arc and attach it to an arc + *----------------------------------------------------------------------------- + */ + +void +ArcTessellator::pwl_right( Arc *arc, REAL s, REAL t1, REAL t2, REAL rate ) +{ + assert( t1 < t2 ); + +/* if(rate <= 0.06) rate = 0.06;*/ + +/* int nsteps = 1 + (int) ((t2 - t1) / rate ); */ + int nsteps = steps_function(t2,t1,rate); + REAL stepsize = (t2 - t1) / (REAL) nsteps; + + TrimVertex *newvert = trimvertexpool.get( nsteps+1 ); + int i; + for( i = 0; i < nsteps; i++ ) { + newvert[i].param[0] = s; + newvert[i].param[1] = t1; + t1 += stepsize; + } + newvert[i].param[0] = s; + newvert[i].param[1] = t2; + + arc->makeSide( new(pwlarcpool) PwlArc( nsteps+1, newvert ), arc_right ); +} + + +/*----------------------------------------------------------------------------- + * pwl_top - construct a top boundary pwl arc and attach it to an arc + *----------------------------------------------------------------------------- + */ + +void +ArcTessellator::pwl_top( Arc *arc, REAL t, REAL s1, REAL s2, REAL rate ) +{ + assert( s2 < s1 ); + +/* if(rate <= 0.06) rate = 0.06;*/ + +/* int nsteps = 1 + (int) ((s1 - s2) / rate ); */ + int nsteps = steps_function(s1,s2,rate); + REAL stepsize = (s1 - s2) / (REAL) nsteps; + + TrimVertex *newvert = trimvertexpool.get( nsteps+1 ); + int i; + for( i = nsteps; i > 0; i-- ) { + newvert[i].param[0] = s2; + newvert[i].param[1] = t; + s2 += stepsize; + } + newvert[i].param[0] = s1; + newvert[i].param[1] = t; + + arc->makeSide( new(pwlarcpool) PwlArc( nsteps+1, newvert ), arc_top ); +} + +/*----------------------------------------------------------------------------- + * pwl_bottom - construct a bottom boundary pwl arc and attach it to an arc + *----------------------------------------------------------------------------- + */ + +void +ArcTessellator::pwl_bottom( Arc *arc, REAL t, REAL s1, REAL s2, REAL rate ) +{ + assert( s1 < s2 ); + +/* if(rate <= 0.06) rate = 0.06;*/ + +/* int nsteps = 1 + (int) ((s2 - s1) / rate ); */ + int nsteps = steps_function(s2,s1,rate); + REAL stepsize = (s2 - s1) / (REAL) nsteps; + + TrimVertex *newvert = trimvertexpool.get( nsteps+1 ); + int i; + for( i = 0; i < nsteps; i++ ) { + newvert[i].param[0] = s1; + newvert[i].param[1] = t; + s1 += stepsize; + } + newvert[i].param[0] = s2; + newvert[i].param[1] = t; + + arc->makeSide( new(pwlarcpool) PwlArc( nsteps+1, newvert ), arc_bottom ); +} + +/*----------------------------------------------------------------------------- + * pwl - construct a pwl arc and attach it to an arc + *----------------------------------------------------------------------------- + */ + +void +ArcTessellator::pwl( Arc *arc, REAL s1, REAL s2, REAL t1, REAL t2, REAL rate ) +{ + +/* if(rate <= 0.06) rate = 0.06;*/ + + int snsteps = 1 + (int) (glu_abs(s2 - s1) / rate ); + int tnsteps = 1 + (int) (glu_abs(t2 - t1) / rate ); + int nsteps = max(1,max( snsteps, tnsteps )); + + REAL sstepsize = (s2 - s1) / (REAL) nsteps; + REAL tstepsize = (t2 - t1) / (REAL) nsteps; + TrimVertex *newvert = trimvertexpool.get( nsteps+1 ); + long i; + for( i = 0; i < nsteps; i++ ) { + newvert[i].param[0] = s1; + newvert[i].param[1] = t1; + s1 += sstepsize; + t1 += tstepsize; + } + newvert[i].param[0] = s2; + newvert[i].param[1] = t2; + + /* arc->makeSide( new(pwlarcpool) PwlArc( nsteps+1, newvert ), arc_bottom ); */ + arc->pwlArc = new(pwlarcpool) PwlArc( nsteps+1, newvert ); + + arc->clearbezier(); + arc->clearside( ); +} + + +/*----------------------------------------------------------------------------- + * tessellateLinear - constuct a linear pwl arc and attach it to an Arc + *----------------------------------------------------------------------------- + */ + +void +ArcTessellator::tessellateLinear( Arc *arc, REAL geo_stepsize, REAL arc_stepsize, int isrational ) +{ + assert( arc->pwlArc == NULL ); + REAL s1, s2, t1, t2; + + //we don't need to scale by arc_stepsize if the trim curve + //is piecewise linear. Reason: In pwl_right, pwl_left, pwl_top, pwl_left, + //and pwl, the nsteps is computed by deltaU (or V) /stepsize. + //The quantity deltaU/arc_stepsize doesn't have any meaning. And + //it causes problems: see bug 517641 + REAL stepsize = geo_stepsize; /* * arc_stepsize*/; + + BezierArc *b = arc->bezierArc; + + if( isrational ) { + s1 = b->cpts[0] / b->cpts[2]; + t1 = b->cpts[1] / b->cpts[2]; + s2 = b->cpts[b->stride+0] / b->cpts[b->stride+2]; + t2 = b->cpts[b->stride+1] / b->cpts[b->stride+2]; + } else { + s1 = b->cpts[0]; + t1 = b->cpts[1]; + s2 = b->cpts[b->stride+0]; + t2 = b->cpts[b->stride+1]; + } + if( s1 == s2 ) + if( t1 < t2 ) + pwl_right( arc, s1, t1, t2, stepsize ); + else + pwl_left( arc, s1, t1, t2, stepsize ); + else if( t1 == t2 ) + if( s1 < s2 ) + pwl_bottom( arc, t1, s1, s2, stepsize ); + else + pwl_top( arc, t1, s1, s2, stepsize ); + else + pwl( arc, s1, s2, t1, t2, stepsize ); +} + +/*----------------------------------------------------------------------------- + * tessellateNonlinear - constuct a nonlinear pwl arc and attach it to an Arc + *----------------------------------------------------------------------------- + */ + +void +ArcTessellator::tessellateNonlinear( Arc *arc, REAL geo_stepsize, REAL arc_stepsize, int isrational ) +{ + assert( arc->pwlArc == NULL ); + + REAL stepsize = geo_stepsize * arc_stepsize; + + BezierArc *bezierArc = arc->bezierArc; + + REAL size; //bounding box size of the curve in UV + { + int i,j; + REAL min_u, min_v, max_u,max_v; + min_u = max_u = bezierArc->cpts[0]; + min_v = max_v = bezierArc->cpts[1]; + for(i=1, j=bezierArc->stride; i<bezierArc->order; i++, j+= bezierArc->stride) + { + if(bezierArc->cpts[j] < min_u) + min_u = bezierArc->cpts[j]; + if(bezierArc->cpts[j] > max_u) + max_u = bezierArc->cpts[j]; + if(bezierArc->cpts[j+1] < min_v) + min_v = bezierArc->cpts[j+1]; + if(bezierArc->cpts[j+1] > max_v) + max_v = bezierArc->cpts[j+1]; + } + + size = max_u - min_u; + if(size < max_v - min_v) + size = max_v - min_v; + } + + /*int nsteps = 1 + (int) (1.0/stepsize);*/ + + int nsteps = (int) (size/stepsize); + if(nsteps <=0) + nsteps=1; + + TrimVertex *vert = trimvertexpool.get( nsteps+1 ); + REAL dp = 1.0/nsteps; + + + arc->pwlArc = new(pwlarcpool) PwlArc(); + arc->pwlArc->pts = vert; + + if( isrational ) { + REAL pow_u[MAXORDER], pow_v[MAXORDER], pow_w[MAXORDER]; + trim_power_coeffs( bezierArc, pow_u, 0 ); + trim_power_coeffs( bezierArc, pow_v, 1 ); + trim_power_coeffs( bezierArc, pow_w, 2 ); + + /* compute first point exactly */ + REAL *b = bezierArc->cpts; + vert->param[0] = b[0]/b[2]; + vert->param[1] = b[1]/b[2]; + + /* strength reduction on p = dp * step would introduce error */ + int step; +#ifndef NOELIMINATION + int ocanremove = 0; +#endif + register long order = bezierArc->order; + for( step=1, ++vert; step<nsteps; step++, vert++ ) { + register REAL p = dp * step; + register REAL u = pow_u[0]; + register REAL v = pow_v[0]; + register REAL w = pow_w[0]; + for( register int i = 1; i < order; i++ ) { + u = u * p + pow_u[i]; + v = v * p + pow_v[i]; + w = w * p + pow_w[i]; + } + vert->param[0] = u/w; + vert->param[1] = v/w; +#ifndef NOELIMINATION + REAL ds = glu_abs(vert[0].param[0] - vert[-1].param[0]); + REAL dt = glu_abs(vert[0].param[1] - vert[-1].param[1]); + int canremove = (ds<geo_stepsize && dt<geo_stepsize) ? 1 : 0; + REAL ods=0.0, odt=0.0; + + if( ocanremove && canremove ) { + REAL nds = ds + ods; + REAL ndt = dt + odt; + if( nds<geo_stepsize && ndt<geo_stepsize ) { + // remove previous point + --vert; + vert[0].param[0] = vert[1].param[0]; + vert[0].param[1] = vert[1].param[1]; + ods = nds; + odt = ndt; + ocanremove = 1; + } else { + ocanremove = canremove; + ods = ds; + odt = dt; + } + } else { + ocanremove = canremove; + ods = ds; + odt = dt; + } +#endif + } + + /* compute last point exactly */ + b += (order - 1) * bezierArc->stride; + vert->param[0] = b[0]/b[2]; + vert->param[1] = b[1]/b[2]; + + } else { + REAL pow_u[MAXORDER], pow_v[MAXORDER]; + trim_power_coeffs( bezierArc, pow_u, 0 ); + trim_power_coeffs( bezierArc, pow_v, 1 ); + + /* compute first point exactly */ + REAL *b = bezierArc->cpts; + vert->param[0] = b[0]; + vert->param[1] = b[1]; + + /* strength reduction on p = dp * step would introduce error */ + int step; +#ifndef NOELIMINATION + int ocanremove = 0; +#endif + register long order = bezierArc->order; + for( step=1, ++vert; step<nsteps; step++, vert++ ) { + register REAL p = dp * step; + register REAL u = pow_u[0]; + register REAL v = pow_v[0]; + for( register int i = 1; i < bezierArc->order; i++ ) { + u = u * p + pow_u[i]; + v = v * p + pow_v[i]; + } + vert->param[0] = u; + vert->param[1] = v; +#ifndef NOELIMINATION + REAL ds = glu_abs(vert[0].param[0] - vert[-1].param[0]); + REAL dt = glu_abs(vert[0].param[1] - vert[-1].param[1]); + int canremove = (ds<geo_stepsize && dt<geo_stepsize) ? 1 : 0; + REAL ods=0.0, odt=0.0; + + if( ocanremove && canremove ) { + REAL nds = ds + ods; + REAL ndt = dt + odt; + if( nds<geo_stepsize && ndt<geo_stepsize ) { + // remove previous point + --vert; + vert[0].param[0] = vert[1].param[0]; + vert[0].param[1] = vert[1].param[1]; + ods = nds; + odt = ndt; + ocanremove = 1; + } else { + ocanremove = canremove; + ods = ds; + odt = dt; + } + } else { + ocanremove = canremove; + ods = ds; + odt = dt; + } +#endif + } + + /* compute last point exactly */ + b += (order - 1) * bezierArc->stride; + vert->param[0] = b[0]; + vert->param[1] = b[1]; + } + arc->pwlArc->npts = vert - arc->pwlArc->pts + 1; +/* + for( TrimVertex *vt=pwlArc->pts; vt != vert-1; vt++ ) { + if( tooclose( vt[0].param[0], vt[1].param[0] ) ) + vt[1].param[0] = vt[0].param[0]; + if( tooclose( vt[0].param[1], vt[1].param[1] ) ) + vt[1].param[1] = vt[0].param[1]; + } +*/ +} + +const REAL ArcTessellator::gl_Bernstein[][MAXORDER][MAXORDER] = { + { + {1, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + {-1, 1, 0, 0, 0, 0, 0, 0 }, + {1, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + {1, -2, 1, 0, 0, 0, 0, 0 }, + {-2, 2, 0, 0, 0, 0, 0, 0 }, + {1, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + {-1, 3, -3, 1, 0, 0, 0, 0 }, + {3, -6, 3, 0, 0, 0, 0, 0 }, + {-3, 3, 0, 0, 0, 0, 0, 0 }, + {1, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + {1, -4, 6, -4, 1, 0, 0, 0 }, + {-4, 12, -12, 4, 0, 0, 0, 0 }, + {6, -12, 6, 0, 0, 0, 0, 0 }, + {-4, 4, 0, 0, 0, 0, 0, 0 }, + {1, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + {-1, 5, -10, 10, -5, 1, 0, 0 }, + {5, -20, 30, -20, 5, 0, 0, 0 }, + {-10, 30, -30, 10, 0, 0, 0, 0 }, + {10, -20, 10, 0, 0, 0, 0, 0 }, + {-5, 5, 0, 0, 0, 0, 0, 0 }, + {1, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + {1, -6, 15, -20, 15, -6, 1, 0 }, + {-6, 30, -60, 60, -30, 6, 0, 0 }, + {15, -60, 90, -60, 15, 0, 0, 0 }, + {-20, 60, -60, 20, 0, 0, 0, 0 }, + {15, -30, 15, 0, 0, 0, 0, 0 }, + {-6, 6, 0, 0, 0, 0, 0, 0 }, + {1, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + {-1, 7, -21, 35, -35, 21, -7, 1 }, + {7, -42, 105, -140, 105, -42, 7, 0 }, + {-21, 105, -210, 210, -105, 21, 0, 0 }, + {35, -140, 210, -140, 35, 0, 0, 0 }, + {-35, 105, -105, 35, 0, 0, 0, 0 }, + {21, -42, 21, 0, 0, 0, 0, 0 }, + {-7, 7, 0, 0, 0, 0, 0, 0 }, + {1, 0, 0, 0, 0, 0, 0, 0 } + }}; + + +/*----------------------------------------------------------------------------- + * trim_power_coeffs - compute power basis coefficients from bezier coeffients + *----------------------------------------------------------------------------- + */ +void +ArcTessellator::trim_power_coeffs( BezierArc *bez_arc, REAL *p, int coord ) +{ + register int stride = bez_arc->stride; + register int order = bez_arc->order; + register REAL *base = bez_arc->cpts + coord; + + REAL const (*mat)[MAXORDER][MAXORDER] = &gl_Bernstein[order-1]; + REAL const (*lrow)[MAXORDER] = &(*mat)[order]; + + /* WIN32 didn't like the following line within the for-loop */ + REAL const (*row)[MAXORDER] = &(*mat)[0]; + for( ; row != lrow; row++ ) { + register REAL s = 0.0; + register REAL *point = base; + register REAL const *mlast = *row + order; + for( REAL const *m = *row; m != mlast; m++, point += stride ) + s += *(m) * (*point); + *(p++) = s; + } +} diff --git a/mesalib/src/glu/sgi/libnurbs/internals/arctess.h b/mesalib/src/glu/sgi/libnurbs/internals/arctess.h new file mode 100644 index 000000000..7802af90c --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/arctess.h @@ -0,0 +1,66 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * arctess.h + * + */ + +#ifndef __gluarctess_h_ +#define __gluarctess_h_ + +#include "defines.h" +#include "types.h" +#include "arc.h" + +struct BezierArc; +class Pool; +class TrimVertexPool; + +class ArcTessellator { +public: + ArcTessellator( TrimVertexPool&, Pool& ); + ~ArcTessellator( void ); + void bezier( Arc_ptr, REAL, REAL, REAL, REAL ); + void pwl( Arc_ptr, REAL, REAL, REAL, REAL, REAL ); + void pwl_left( Arc_ptr, REAL, REAL, REAL, REAL ); + void pwl_right( Arc_ptr, REAL, REAL, REAL, REAL ); + void pwl_top( Arc_ptr, REAL, REAL, REAL, REAL ); + void pwl_bottom( Arc_ptr, REAL, REAL, REAL, REAL ); + void tessellateLinear( Arc_ptr, REAL, REAL, int ); + void tessellateNonlinear( Arc_ptr, REAL, REAL, int ); +private: + static const REAL gl_Bernstein[][MAXORDER][MAXORDER]; + Pool& pwlarcpool; + TrimVertexPool& trimvertexpool; + static void trim_power_coeffs( BezierArc *, REAL[MAXORDER], int ); +}; + +#endif /* __gluarctess_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/backend.cc b/mesalib/src/glu/sgi/libnurbs/internals/backend.cc new file mode 100644 index 000000000..88dc3f516 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/backend.cc @@ -0,0 +1,589 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * backend.c++ + * + */ + +/* Bezier surface backend + - interprets display mode (wireframe,shaded,...) +*/ +#include <stdio.h> +#include "glimports.h" +#include "mystdio.h" +#include "backend.h" +#include "basiccrveval.h" +#include "basicsurfeval.h" +#include "nurbsconsts.h" + +#define NOWIREFRAME + + +/*------------------------------------------------------------------------- + * bgnsurf - preamble to surface definition and evaluations + *------------------------------------------------------------------------- + */ +void +Backend::bgnsurf( int wiretris, int wirequads, long nuid ) +{ +/*#ifndef NOWIREFRAME*/ //need this for old version + wireframetris = wiretris; + wireframequads = wirequads; +/*#endif*/ + + /*in the spec, GLU_DISPLAY_MODE is either + * GLU_FILL + * GLU_OUTLINE_POLY + * GLU_OUTLINE_PATCH. + *In fact, GLU_FLL is has the same effect as + * set GL_FRONT_AND_BACK to be GL_FILL + * and GLU_OUTLINE_POLY is the same as set + * GL_FRONT_AND_BACK to be GL_LINE + *It is more efficient to do this once at the beginning of + *each surface than to do it for each primitive. + * The internal has more options: outline_triangle and outline_quad + *can be seperated. But since this is not in spec, and more importantly, + *this is not so useful, so we don't need to keep this option. + */ + + surfaceEvaluator.bgnmap2f( nuid ); + + if(wiretris) + surfaceEvaluator.polymode(N_MESHLINE); + else + surfaceEvaluator.polymode(N_MESHFILL); +} + +void +Backend::patch( REAL ulo, REAL uhi, REAL vlo, REAL vhi ) +{ + surfaceEvaluator.domain2f( ulo, uhi, vlo, vhi ); +} + +void +Backend::surfbbox( long type, REAL *from, REAL *to ) +{ + surfaceEvaluator.range2f( type, from, to ); +} + +/*------------------------------------------------------------------------- + * surfpts - pass a desription of a surface map + *------------------------------------------------------------------------- + */ +void +Backend::surfpts( + long type, /* geometry, color, texture, normal */ + REAL *pts, /* control points */ + long ustride, /* distance to next point in u direction */ + long vstride, /* distance to next point in v direction */ + int uorder, /* u parametric order */ + int vorder, /* v parametric order */ + REAL ulo, /* u lower bound */ + REAL uhi, /* u upper bound */ + REAL vlo, /* v lower bound */ + REAL vhi ) /* v upper bound */ +{ + surfaceEvaluator.map2f( type,ulo,uhi,ustride,uorder,vlo,vhi,vstride,vorder,pts ); + surfaceEvaluator.enable( type ); +} + +/*------------------------------------------------------------------------- + * surfgrid - define a lattice of points with origin and offset + *------------------------------------------------------------------------- + */ +void +Backend::surfgrid( REAL u0, REAL u1, long nu, REAL v0, REAL v1, long nv ) +{ + surfaceEvaluator.mapgrid2f( nu, u0, u1, nv, v0, v1 ); +} + +/*------------------------------------------------------------------------- + * surfmesh - evaluate a mesh of points on lattice + *------------------------------------------------------------------------- + */ +void +Backend::surfmesh( long u, long v, long n, long m ) +{ +#ifndef NOWIREFRAME + if( wireframequads ) { + long v0, v1; + long u0f = u, u1f = u+n; + long v0f = v, v1f = v+m; + long parity = (u & 1); + + for( v0 = v0f, v1 = v0f++ ; v0<v1f; v0 = v1, v1++ ) { + surfaceEvaluator.bgnline(); + for( long u = u0f; u<=u1f; u++ ) { + if( parity ) { + surfaceEvaluator.evalpoint2i( u, v0 ); + surfaceEvaluator.evalpoint2i( u, v1 ); + } else { + surfaceEvaluator.evalpoint2i( u, v1 ); + surfaceEvaluator.evalpoint2i( u, v0 ); + } + parity = 1 - parity; + } + surfaceEvaluator.endline(); + } + } else { + surfaceEvaluator.mapmesh2f( N_MESHFILL, u, u+n, v, v+m ); + } +#else + if( wireframequads ) { + + surfaceEvaluator.mapmesh2f( N_MESHLINE, u, u+n, v, v+m ); + } else { + + surfaceEvaluator.mapmesh2f( N_MESHFILL, u, u+n, v, v+m ); + } +#endif +} + +/*------------------------------------------------------------------------- + * endsurf - postamble to surface + *------------------------------------------------------------------------- + */ +void +Backend::endsurf( void ) +{ + surfaceEvaluator.endmap2f(); +} + +/***************************************/ +void +Backend::bgntfan( void ) +{ + surfaceEvaluator.bgntfan(); +/* + if(wireframetris) + surfaceEvaluator.polymode( N_MESHLINE ); + else + surfaceEvaluator.polymode( N_MESHFILL ); +*/ +} + +void +Backend::endtfan( void ) +{ + surfaceEvaluator.endtfan(); +} + +void +Backend::bgnqstrip( void ) +{ + surfaceEvaluator.bgnqstrip(); +/* + if(wireframequads) + surfaceEvaluator.polymode( N_MESHLINE ); + else + surfaceEvaluator.polymode( N_MESHFILL ); +*/ +} + +void +Backend::endqstrip( void ) +{ + surfaceEvaluator.endqstrip(); +} + +void +Backend::evalUStrip(int n_upper, REAL v_upper, REAL* upper_val, + int n_lower, REAL v_lower, REAL* lower_val + ) +{ + surfaceEvaluator.evalUStrip(n_upper, v_upper, upper_val, + n_lower, v_lower, lower_val); +} + +void +Backend::evalVStrip(int n_left, REAL u_left, REAL* left_val, + int n_right, REAL u_right, REAL* right_val + ) +{ + surfaceEvaluator.evalVStrip(n_left, u_left, left_val, + n_right, u_right, right_val); +} + +/***************************************/ + + +/*------------------------------------------------------------------------- + * bgntmesh - preamble to a triangle mesh + *------------------------------------------------------------------------- + */ +void +Backend::bgntmesh( const char * ) +{ +#ifndef NOWIREFRAME + + meshindex = 0; /* I think these need to be initialized to zero */ + npts = 0; + + if( !wireframetris ) { + surfaceEvaluator.bgntmesh(); + } +#else + + if( wireframetris ) { + surfaceEvaluator.bgntmesh(); + surfaceEvaluator.polymode( N_MESHLINE ); + } else { + surfaceEvaluator.bgntmesh(); + surfaceEvaluator.polymode( N_MESHFILL ); + } +#endif +} + +void +Backend::tmeshvert( GridTrimVertex *v ) +{ + if( v->isGridVert() ) { + tmeshvert( v->g ); + } else { + tmeshvert( v->t ); + } +} + +void +Backend::tmeshvertNOGE(TrimVertex *t) +{ +// surfaceEvaluator.inDoEvalCoord2NOGE( t->param[0], t->param[1], temp, ttt); +#ifdef USE_OPTTT + surfaceEvaluator.inDoEvalCoord2NOGE( t->param[0], t->param[1], t->cache_point, t->cache_normal); +#endif +} + +//opt for a line with the same u. +void +Backend::tmeshvertNOGE_BU(TrimVertex *t) +{ +#ifdef USE_OPTTT + surfaceEvaluator.inDoEvalCoord2NOGE_BU( t->param[0], t->param[1], t->cache_point, t->cache_normal); +#endif +} + +//opt for a line with the same v. +void +Backend::tmeshvertNOGE_BV(TrimVertex *t) +{ +#ifdef USE_OPTTT + surfaceEvaluator.inDoEvalCoord2NOGE_BV( t->param[0], t->param[1], t->cache_point, t->cache_normal); +#endif +} + +void +Backend::preEvaluateBU(REAL u) +{ + surfaceEvaluator.inPreEvaluateBU_intfac(u); +} + +void +Backend::preEvaluateBV(REAL v) +{ + surfaceEvaluator.inPreEvaluateBV_intfac(v); +} + + +/*------------------------------------------------------------------------- + * tmeshvert - evaluate a point on a triangle mesh + *------------------------------------------------------------------------- + */ +void +Backend::tmeshvert( TrimVertex *t ) +{ + +#ifndef NOWIREFRAME + const long nuid = t->nuid; +#endif + const REAL u = t->param[0]; + const REAL v = t->param[1]; + +#ifndef NOWIREFRAME + npts++; + if( wireframetris ) { + if( npts >= 3 ) { + surfaceEvaluator.bgnclosedline(); + if( mesh[0][2] == 0 ) + surfaceEvaluator.evalcoord2f( mesh[0][3], mesh[0][0], mesh[0][1] ); + else + surfaceEvaluator.evalpoint2i( (long) mesh[0][0], (long) mesh[0][1] ); + if( mesh[1][2] == 0 ) + surfaceEvaluator.evalcoord2f( mesh[1][3], mesh[1][0], mesh[1][1] ); + else + surfaceEvaluator.evalpoint2i( (long) mesh[1][0], (long) mesh[1][1] ); + surfaceEvaluator.evalcoord2f( nuid, u, v ); + surfaceEvaluator.endclosedline(); + } + mesh[meshindex][0] = u; + mesh[meshindex][1] = v; + mesh[meshindex][2] = 0; + mesh[meshindex][3] = nuid; + meshindex = (meshindex+1) % 2; + } else { + surfaceEvaluator.evalcoord2f( nuid, u, v ); + } +#else + + surfaceEvaluator.evalcoord2f( 0, u, v ); +//for uninitial memory read surfaceEvaluator.evalcoord2f( nuid, u, v ); +#endif +} + +//the same as tmeshvert(trimvertex), for efficiency purpose +void +Backend::tmeshvert( REAL u, REAL v ) +{ +#ifndef NOWIREFRAME + const long nuid = 0; + + npts++; + if( wireframetris ) { + if( npts >= 3 ) { + surfaceEvaluator.bgnclosedline(); + if( mesh[0][2] == 0 ) + surfaceEvaluator.evalcoord2f( mesh[0][3], mesh[0][0], mesh[0][1] ); + else + surfaceEvaluator.evalpoint2i( (long) mesh[0][0], (long) mesh[0][1] ); + if( mesh[1][2] == 0 ) + surfaceEvaluator.evalcoord2f( mesh[1][3], mesh[1][0], mesh[1][1] ); + else + surfaceEvaluator.evalpoint2i( (long) mesh[1][0], (long) mesh[1][1] ); + surfaceEvaluator.evalcoord2f( nuid, u, v ); + surfaceEvaluator.endclosedline(); + } + mesh[meshindex][0] = u; + mesh[meshindex][1] = v; + mesh[meshindex][2] = 0; + mesh[meshindex][3] = nuid; + meshindex = (meshindex+1) % 2; + } else { + surfaceEvaluator.evalcoord2f( nuid, u, v ); + } +#else + + surfaceEvaluator.evalcoord2f( 0, u, v ); +#endif +} + +/*------------------------------------------------------------------------- + * tmeshvert - evaluate a grid point of a triangle mesh + *------------------------------------------------------------------------- + */ +void +Backend::tmeshvert( GridVertex *g ) +{ + const long u = g->gparam[0]; + const long v = g->gparam[1]; + +#ifndef NOWIREFRAME + npts++; + if( wireframetris ) { + if( npts >= 3 ) { + surfaceEvaluator.bgnclosedline(); + if( mesh[0][2] == 0 ) + surfaceEvaluator.evalcoord2f( (long) mesh[0][3], mesh[0][0], mesh[0][1] ); + else + surfaceEvaluator.evalpoint2i( (long) mesh[0][0], (long) mesh[0][1] ); + if( mesh[1][2] == 0 ) + surfaceEvaluator.evalcoord2f( (long) mesh[1][3], mesh[1][0], mesh[1][1] ); + else + surfaceEvaluator.evalpoint2i( (long) mesh[1][0], (long) mesh[1][1] ); + surfaceEvaluator.evalpoint2i( u, v ); + surfaceEvaluator.endclosedline(); + } + mesh[meshindex][0] = u; + mesh[meshindex][1] = v; + mesh[meshindex][2] = 1; + meshindex = (meshindex+1) % 2; + } else { + surfaceEvaluator.evalpoint2i( u, v ); + } +#else + surfaceEvaluator.evalpoint2i( u, v ); +#endif +} + +/*------------------------------------------------------------------------- + * swaptmesh - perform a swap of the triangle mesh pointers + *------------------------------------------------------------------------- + */ +void +Backend::swaptmesh( void ) +{ +#ifndef NOWIREFRAME + if( wireframetris ) { + meshindex = 1 - meshindex; + } else { + surfaceEvaluator.swaptmesh(); + } +#else + surfaceEvaluator.swaptmesh(); +#endif +} + +/*------------------------------------------------------------------------- + * endtmesh - postamble to triangle mesh + *------------------------------------------------------------------------- + */ +void +Backend::endtmesh( void ) +{ +#ifndef NOWIREFRAME + if( ! wireframetris ) + surfaceEvaluator.endtmesh(); +#else + surfaceEvaluator.endtmesh(); +/* surfaceEvaluator.polymode( N_MESHFILL );*/ +#endif +} + + +/*------------------------------------------------------------------------- + * bgnoutline - preamble to outlined rendering + *------------------------------------------------------------------------- + */ +void +Backend::bgnoutline( void ) +{ + surfaceEvaluator.bgnline(); +} + +/*------------------------------------------------------------------------- + * linevert - evaluate a point on an outlined contour + *------------------------------------------------------------------------- + */ +void +Backend::linevert( TrimVertex *t ) +{ + surfaceEvaluator.evalcoord2f( t->nuid, t->param[0], t->param[1] ); +} + +/*------------------------------------------------------------------------- + * linevert - evaluate a grid point of an outlined contour + *------------------------------------------------------------------------- + */ +void +Backend::linevert( GridVertex *g ) +{ + surfaceEvaluator.evalpoint2i( g->gparam[0], g->gparam[1] ); +} + +/*------------------------------------------------------------------------- + * endoutline - postamble to outlined rendering + *------------------------------------------------------------------------- + */ +void +Backend::endoutline( void ) +{ + surfaceEvaluator.endline(); +} + +/*------------------------------------------------------------------------- + * triangle - output a triangle + *------------------------------------------------------------------------- + */ +void +Backend::triangle( TrimVertex *a, TrimVertex *b, TrimVertex *c ) +{ +/* bgntmesh( "spittriangle" );*/ + bgntfan(); + tmeshvert( a ); + tmeshvert( b ); + tmeshvert( c ); + endtfan(); +/* endtmesh();*/ +} + +void +Backend::bgncurv( void ) +{ + curveEvaluator.bgnmap1f( 0 ); +} + +void +Backend::segment( REAL ulo, REAL uhi ) +{ + curveEvaluator.domain1f( ulo, uhi ); +} + +void +Backend::curvpts( + long type, /* geometry, color, texture, normal */ + REAL *pts, /* control points */ + long stride, /* distance to next point */ + int order, /* parametric order */ + REAL ulo, /* lower parametric bound */ + REAL uhi ) /* upper parametric bound */ + +{ + curveEvaluator.map1f( type, ulo, uhi, stride, order, pts ); + curveEvaluator.enable( type ); +} + +void +Backend::curvgrid( REAL u0, REAL u1, long nu ) +{ + curveEvaluator.mapgrid1f( nu, u0, u1 ); +} + +void +Backend::curvmesh( long from, long n ) +{ + curveEvaluator.mapmesh1f( N_MESHFILL, from, from+n ); +} + +void +Backend::curvpt(REAL u) +{ + curveEvaluator.evalcoord1f( 0, u ); +} + +void +Backend::bgnline( void ) +{ + curveEvaluator.bgnline(); +} + +void +Backend::endline( void ) +{ + curveEvaluator.endline(); +} + +void +Backend::endcurv( void ) +{ + curveEvaluator.endmap1f(); +} diff --git a/mesalib/src/glu/sgi/libnurbs/internals/backend.h b/mesalib/src/glu/sgi/libnurbs/internals/backend.h new file mode 100644 index 000000000..6840cb19e --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/backend.h @@ -0,0 +1,113 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * backend.h + * + */ + +#ifndef __glubackend_h_ +#define __glubackend_h_ + +#include "trimvertex.h" +#include "gridvertex.h" +#include "gridtrimvertex.h" + +class BasicCurveEvaluator; +class BasicSurfaceEvaluator; + +class Backend { +private: + BasicCurveEvaluator& curveEvaluator; + BasicSurfaceEvaluator& surfaceEvaluator; +public: + Backend( BasicCurveEvaluator &c, BasicSurfaceEvaluator& e ) + : curveEvaluator(c), surfaceEvaluator(e) {} + + /* surface backend routines */ + void bgnsurf( int, int, long ); + void patch( REAL, REAL, REAL, REAL ); + void surfpts( long, REAL *, long, long, int, int, + REAL, REAL, REAL, REAL ); + void surfbbox( long, REAL *, REAL * ); + void surfgrid( REAL, REAL, long, REAL, REAL, long ); + void surfmesh( long, long, long, long ); + void bgntmesh( const char * ); + void endtmesh( void ); + void swaptmesh( void ); + void tmeshvert( GridTrimVertex * ); + void tmeshvert( TrimVertex * ); + void tmeshvert( GridVertex * ); + void tmeshvert( REAL u, REAL v ); + void linevert( TrimVertex * ); + void linevert( GridVertex * ); + void bgnoutline( void ); + void endoutline( void ); + void endsurf( void ); + void triangle( TrimVertex*, TrimVertex*, TrimVertex* ); + + void bgntfan(); + void endtfan(); + void bgnqstrip(); + void endqstrip(); + void evalUStrip(int n_upper, REAL v_upper, REAL* upper_val, + int n_lower, REAL v_lower, REAL* lower_val + ); + void evalVStrip(int n_left, REAL u_left, REAL* left_val, + int n_right, REAL v_right, REAL* right_val + ); + void tmeshvertNOGE(TrimVertex *t); + void tmeshvertNOGE_BU(TrimVertex *t); + void tmeshvertNOGE_BV(TrimVertex *t); + void preEvaluateBU(REAL u); + void preEvaluateBV(REAL v); + + + /* curve backend routines */ + void bgncurv( void ); + void segment( REAL, REAL ); + void curvpts( long, REAL *, long, int, REAL, REAL ); + void curvgrid( REAL, REAL, long ); + void curvmesh( long, long ); + void curvpt( REAL ); + void bgnline( void ); + void endline( void ); + void endcurv( void ); +private: +#ifndef NOWIREFRAME + int wireframetris; + int wireframequads; + int npts; + REAL mesh[3][4]; + int meshindex; +#endif +}; + +#endif /* __glubackend_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/basiccrveval.cc b/mesalib/src/glu/sgi/libnurbs/internals/basiccrveval.cc new file mode 100644 index 000000000..cc473e4c2 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/basiccrveval.cc @@ -0,0 +1,138 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * basiccrveval.c++ + * + */ + +#include "mystdio.h" +#include "types.h" +#include "basiccrveval.h" + +void +BasicCurveEvaluator::domain1f( REAL, REAL ) +{ +#ifndef NDEBUG + _glu_dprintf( "domain1f\n" ); +#endif +} + +void +BasicCurveEvaluator::range1f( long , REAL *, REAL * ) +{ +#ifndef NDEBUG + _glu_dprintf( "range1f\n" ); +#endif +} + +void +BasicCurveEvaluator::enable( long ) +{ +#ifndef NDEBUG + _glu_dprintf( "enable\n" ); +#endif +} + +void +BasicCurveEvaluator::disable( long ) +{ +#ifndef NDEBUG + _glu_dprintf( "disable\n" ); +#endif +} + +void +BasicCurveEvaluator::bgnmap1f( long ) +{ +#ifndef NDEBUG + _glu_dprintf( "bgnmap1f\n" ); +#endif +} + +void +BasicCurveEvaluator::map1f( long, REAL, REAL, long, long, REAL * ) +{ +#ifndef NDEBUG + _glu_dprintf( "map1f\n" ); +#endif +} + +void +BasicCurveEvaluator::mapgrid1f( long, REAL, REAL ) +{ +#ifndef NDEBUG + _glu_dprintf( "mapgrid1f\n" ); +#endif +} + +void +BasicCurveEvaluator::mapmesh1f( long, long, long ) +{ +#ifndef NDEBUG + _glu_dprintf( "mapmesh1f\n" ); +#endif +} + +void +BasicCurveEvaluator::evalcoord1f( long, REAL ) +{ +#ifndef NDEBUG + _glu_dprintf( "evalcoord1f\n" ); +#endif +} + +void +BasicCurveEvaluator::endmap1f( void ) +{ +#ifndef NDEBUG + _glu_dprintf( "endmap1f\n" ); +#endif +} + +void +BasicCurveEvaluator::bgnline( void ) +{ +#ifndef NDEBUG + _glu_dprintf( "bgnline\n" ); +#endif +} + +void +BasicCurveEvaluator::endline( void ) +{ +#ifndef NDEBUG + _glu_dprintf( "endline\n" ); +#endif +} diff --git a/mesalib/src/glu/sgi/libnurbs/internals/basiccrveval.h b/mesalib/src/glu/sgi/libnurbs/internals/basiccrveval.h new file mode 100644 index 000000000..277dc8dc9 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/basiccrveval.h @@ -0,0 +1,62 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * basiccurveeval.h + * + */ + +#ifndef __glubasiccrveval_h_ +#define __glubasiccrveval_h_ + +#include "types.h" +#include "displaymode.h" +#include "cachingeval.h" + +class BasicCurveEvaluator : public CachingEvaluator { +public: + virtual ~BasicCurveEvaluator() { /* silence warning*/ } + virtual void domain1f( REAL, REAL ); + virtual void range1f( long, REAL *, REAL * ); + + virtual void enable( long ); + virtual void disable( long ); + virtual void bgnmap1f( long ); + virtual void map1f( long, REAL, REAL, long, long, REAL * ); + virtual void mapgrid1f( long, REAL, REAL ); + virtual void mapmesh1f( long, long, long ); + virtual void evalcoord1f( long, REAL ); + virtual void endmap1f( void ); + + virtual void bgnline( void ); + virtual void endline( void ); +}; + +#endif /* __glubasiccrveval_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/basicsurfeval.cc b/mesalib/src/glu/sgi/libnurbs/internals/basicsurfeval.cc new file mode 100644 index 000000000..fad5dd0ad --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/basicsurfeval.cc @@ -0,0 +1,232 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * basicsurfaceevaluator.c++ + * + */ + +#include "mystdio.h" +#include "types.h" +#include "basicsurfeval.h" + +#ifdef __WATCOMC__ +#pragma warning 726 10 +#endif + +void +BasicSurfaceEvaluator::domain2f( REAL, REAL, REAL, REAL ) +{ +#ifndef NDEBUG + _glu_dprintf( "domain2f\n" ); +#endif +} + +void +BasicSurfaceEvaluator::polymode( long ) +{ +#ifndef NDEBUG + _glu_dprintf( "polymode\n" ); +#endif +} + +void +BasicSurfaceEvaluator::range2f( long type, REAL *from, REAL *to ) +{ +#ifndef NDEBUG + _glu_dprintf( "range2f type %ld, from (%g,%g), to (%g,%g)\n", + type, from[0], from[1], to[0], to[1] ); +#endif +} + +void +BasicSurfaceEvaluator::enable( long ) +{ +#ifndef NDEBUG + _glu_dprintf( "enable\n" ); +#endif +} + +void +BasicSurfaceEvaluator::disable( long ) +{ +#ifndef NDEBUG + _glu_dprintf( "disable\n" ); +#endif +} + +void +BasicSurfaceEvaluator::bgnmap2f( long ) +{ +#ifndef NDEBUG + _glu_dprintf( "bgnmap2f\n" ); +#endif +} + +void +BasicSurfaceEvaluator::endmap2f( void ) +{ +#ifndef NDEBUG + _glu_dprintf( "endmap2f\n" ); +#endif +} + +void +BasicSurfaceEvaluator::map2f( long, REAL, REAL, long, long, + REAL, REAL, long, long, + REAL * ) +{ +#ifndef NDEBUG + _glu_dprintf( "map2f\n" ); +#endif +} + +void +BasicSurfaceEvaluator::mapgrid2f( long, REAL, REAL, long, REAL, REAL ) +{ +#ifndef NDEBUG + _glu_dprintf( "mapgrid2f\n" ); +#endif +} + +void +BasicSurfaceEvaluator::mapmesh2f( long, long, long, long, long ) +{ +#ifndef NDEBUG + _glu_dprintf( "mapmesh2f\n" ); +#endif +} + +void +BasicSurfaceEvaluator::evalcoord2f( long, REAL, REAL ) +{ +#ifndef NDEBUG + _glu_dprintf( "evalcoord2f\n" ); +#endif +} + +void +BasicSurfaceEvaluator::evalpoint2i( long, long ) +{ +#ifndef NDEBUG + _glu_dprintf( "evalpoint2i\n" ); +#endif +} + +void +BasicSurfaceEvaluator::bgnline( void ) +{ +#ifndef NDEBUG + _glu_dprintf( "bgnline\n" ); +#endif +} + +void +BasicSurfaceEvaluator::endline( void ) +{ +#ifndef NDEBUG + _glu_dprintf( "endline\n" ); +#endif +} + +void +BasicSurfaceEvaluator::bgnclosedline( void ) +{ +#ifndef NDEBUG + _glu_dprintf( "bgnclosedline\n" ); +#endif +} + +void +BasicSurfaceEvaluator::endclosedline( void ) +{ +#ifndef NDEBUG + _glu_dprintf( "endclosedline\n" ); +#endif +} + +void +BasicSurfaceEvaluator::bgntfan( void ) +{ +#ifndef NDEBUG + _glu_dprintf( "bgntfan\n" ); +#endif +} + +void +BasicSurfaceEvaluator::endtfan( void ) +{ +} + + +void +BasicSurfaceEvaluator::bgntmesh( void ) +{ +#ifndef NDEBUG + _glu_dprintf( "bgntmesh\n" ); +#endif +} + +void +BasicSurfaceEvaluator::swaptmesh( void ) +{ +#ifndef NDEBUG + _glu_dprintf( "swaptmesh\n" ); +#endif +} + +void +BasicSurfaceEvaluator::endtmesh( void ) +{ +#ifndef NDEBUG + _glu_dprintf( "endtmesh\n" ); +#endif +} + +void +BasicSurfaceEvaluator::bgnqstrip( void ) +{ +#ifndef NDEBUG + _glu_dprintf( "bgnqstrip\n" ); +#endif +} + +void +BasicSurfaceEvaluator::endqstrip( void ) +{ +#ifndef NDEBUG + _glu_dprintf( "endqstrip\n" ); +#endif +} + diff --git a/mesalib/src/glu/sgi/libnurbs/internals/basicsurfeval.h b/mesalib/src/glu/sgi/libnurbs/internals/basicsurfeval.h new file mode 100644 index 000000000..8fe18a67f --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/basicsurfeval.h @@ -0,0 +1,90 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * basicsurfeval.h + * + */ + +#ifndef __glubasicsurfeval_h_ +#define __glubasicsurfeval_h_ + +#include "types.h" +#include "displaymode.h" +#include "cachingeval.h" + +class BasicSurfaceEvaluator : public CachingEvaluator { +public: + virtual ~BasicSurfaceEvaluator() { /* silence warning*/ } + virtual void range2f( long, REAL *, REAL * ); + virtual void domain2f( REAL, REAL, REAL, REAL ); + + virtual void enable( long ); + virtual void disable( long ); + virtual void bgnmap2f( long ); + virtual void map2f( long, REAL, REAL, long, long, + REAL, REAL, long, long, + REAL * ); + virtual void mapgrid2f( long, REAL, REAL, long, REAL, REAL ); + virtual void mapmesh2f( long, long, long, long, long ); + virtual void evalcoord2f( long, REAL, REAL ); + virtual void evalpoint2i( long, long ); + virtual void endmap2f( void ); + + virtual void polymode( long ); + virtual void bgnline( void ); + virtual void endline( void ); + virtual void bgnclosedline( void ); + virtual void endclosedline( void ); + virtual void bgntmesh( void ); + virtual void swaptmesh( void ); + virtual void endtmesh( void ); + virtual void bgnqstrip( void ); + virtual void endqstrip( void ); + + virtual void bgntfan( void ); + virtual void endtfan( void ); + + virtual void evalUStrip(int n_upper, REAL v_upper, REAL* upper_val, + int n_lower, REAL v_lower, REAL* lower_val + ) = 0; + + virtual void evalVStrip(int n_left, REAL u_left, REAL* left_val, + int n_right, REAL u_right, REAL* right_val + ) = 0; + virtual void inDoEvalCoord2NOGE(REAL u, REAL v, REAL* ret_point, REAL* ret_normal) = 0; + virtual void inDoEvalCoord2NOGE_BU(REAL u, REAL v, REAL* ret_point, REAL* ret_normal) = 0; + virtual void inDoEvalCoord2NOGE_BV(REAL u, REAL v, REAL* ret_point, REAL* ret_normal) = 0; + virtual void inPreEvaluateBV_intfac(REAL v ) = 0; + virtual void inPreEvaluateBU_intfac(REAL u ) = 0; + +}; + +#endif /* __glubasicsurfeval_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/bezierarc.h b/mesalib/src/glu/sgi/libnurbs/internals/bezierarc.h new file mode 100644 index 000000000..4acfb0948 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/bezierarc.h @@ -0,0 +1,51 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * bezierarc.h + * + */ + +#ifndef __glubezierarc_h +#define __glubezierarc_h + +#include "myassert.h" + +class Mapdesc; + +struct BezierArc : public PooledObj { /* a bezier arc */ + REAL * cpts; /* control points of arc */ + int order; /* order of arc */ + int stride; /* REAL distance between points */ + long type; /* curve type */ + Mapdesc * mapdesc; +}; + +#endif /* __glubezierarc_h */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/bin.cc b/mesalib/src/glu/sgi/libnurbs/internals/bin.cc new file mode 100644 index 000000000..54b406147 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/bin.cc @@ -0,0 +1,166 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * bin.c++ + * + */ + +#include "glimports.h" +#include "mystdio.h" +#include "myassert.h" +#include "bin.h" + +/*---------------------------------------------------------------------------- + * Constructor and destructor + *---------------------------------------------------------------------------- + */ +Bin::Bin() +{ + head = NULL; +} + +Bin::~Bin() +{ + assert( head == NULL); +} + +/*---------------------------------------------------------------------------- + * remove_this_arc - remove given Arc_ptr from bin + *---------------------------------------------------------------------------- + */ + +void +Bin::remove_this_arc( Arc_ptr arc ) +{ + Arc_ptr *j; + for( j = &(head); (*j != 0) && (*j != arc); j = &((*j)->link) ); + + if( *j != 0 ) { + if( *j == current ) + current = (*j)->link; + *j = (*j)->link; + } +} + +/*---------------------------------------------------------------------------- + * numarcs - count number of arcs in bin + *---------------------------------------------------------------------------- + */ + +int +Bin::numarcs() +{ + long count = 0; + for( Arc_ptr jarc = firstarc(); jarc; jarc = nextarc() ) + count++; + return count; +} + +/*---------------------------------------------------------------------------- + * adopt - place an orphaned arcs into their new parents bin + *---------------------------------------------------------------------------- + */ + +void +Bin::adopt() +{ + markall(); + + Arc_ptr orphan; + while( (orphan = removearc()) != NULL ) { + for( Arc_ptr parent = orphan->next; parent != orphan; parent = parent->next ) { + if (! parent->ismarked() ) { + orphan->link = parent->link; + parent->link = orphan; + orphan->clearmark(); + break; + } + } + } +} + + +/*---------------------------------------------------------------------------- + * show - print out descriptions of the arcs in the bin + *---------------------------------------------------------------------------- + */ + +void +Bin::show( char *name ) +{ +#ifndef NDEBUG + _glu_dprintf( "%s\n", name ); + for( Arc_ptr jarc = firstarc(); jarc; jarc = nextarc() ) + jarc->show( ); +#endif +} + + + +/*---------------------------------------------------------------------------- + * markall - mark all arcs with an identifying tag + *---------------------------------------------------------------------------- + */ + +void +Bin::markall() +{ + for( Arc_ptr jarc=firstarc(); jarc; jarc=nextarc() ) + jarc->setmark(); +} + +/*---------------------------------------------------------------------------- + * listBezier - print out all arcs that are untessellated border arcs + *---------------------------------------------------------------------------- + */ + +void +Bin::listBezier( void ) +{ + for( Arc_ptr jarc=firstarc(); jarc; jarc=nextarc() ) { + if( jarc->isbezier( ) ) { + assert( jarc->pwlArc->npts == 2 ); +#ifndef NDEBUG + TrimVertex *pts = jarc->pwlArc->pts; + REAL s1 = pts[0].param[0]; + REAL t1 = pts[0].param[1]; + REAL s2 = pts[1].param[0]; + REAL t2 = pts[1].param[1]; + _glu_dprintf( "arc (%g,%g) (%g,%g)\n", s1, t1, s2, t2 ); +#endif + } + } +} + diff --git a/mesalib/src/glu/sgi/libnurbs/internals/bin.h b/mesalib/src/glu/sgi/libnurbs/internals/bin.h new file mode 100644 index 000000000..2f976eb9b --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/bin.h @@ -0,0 +1,121 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * bin.h + * + */ + +#ifndef __glubin_h_ +#define __glubin_h_ + +#include "myassert.h" +#include "arc.h" +#include "defines.h" + +class Bin +{ /* a linked list of jordan arcs */ +private: + Arc_ptr head;/*first arc on list */ + Arc_ptr current; /* current arc on list */ +public: + Bin(); + ~Bin(); + inline Arc_ptr firstarc( void ); + inline Arc_ptr nextarc( void ); + inline Arc_ptr removearc( void ); + inline int isnonempty( void ) { return (head ? 1 : 0); } + inline void addarc( Arc_ptr ); + void remove_this_arc( Arc_ptr ); + int numarcs( void ); + void adopt( void ); + void markall( void ); + void show( char * ); + void listBezier( void ); +}; + +/*---------------------------------------------------------------------------- + * Bin::addarc - add an Arc_ptr to head of linked list of Arc_ptr + *---------------------------------------------------------------------------- + */ + +inline void +Bin::addarc( Arc_ptr jarc ) +{ + jarc->link = head; + head = jarc; +} + +/*---------------------------------------------------------------------------- + * Bin::removearc - remove first Arc_ptr from bin + *---------------------------------------------------------------------------- + */ + +inline Arc_ptr +Bin::removearc( void ) +{ + Arc_ptr jarc = head; + + if( jarc ) head = jarc->link; + return jarc; +} + + +/*---------------------------------------------------------------------------- + * BinIter::nextarc - return current arc in bin and advance pointer to next arc + *---------------------------------------------------------------------------- + */ + +inline Arc_ptr +Bin::nextarc( void ) +{ + Arc_ptr jarc = current; + +#ifdef DEBUG + assert( jarc->check() != 0 ); +#endif + + if( jarc ) current = jarc->link; + return jarc; +} + +/*---------------------------------------------------------------------------- + * BinIter::firstarc - set current arc to first arc of bin advance to next arc + *---------------------------------------------------------------------------- + */ + +inline Arc_ptr +Bin::firstarc( void ) +{ + current = head; + return nextarc( ); +} + +#endif /* __glubin_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/bufpool.cc b/mesalib/src/glu/sgi/libnurbs/internals/bufpool.cc new file mode 100644 index 000000000..8cc847ab2 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/bufpool.cc @@ -0,0 +1,110 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * bufpool.c++ + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "bufpool.h" + + +/*----------------------------------------------------------------------------- + * Pool - allocate a new pool of buffers + *----------------------------------------------------------------------------- + */ +Pool::Pool( int _buffersize, int initpoolsize, const char *n ) +{ + if((unsigned)_buffersize < sizeof(Buffer)) + buffersize = sizeof(Buffer); + else + buffersize = _buffersize; + initsize = initpoolsize * buffersize; + nextsize = initsize; + name = n; + magic = is_allocated; + nextblock = 0; + curblock = 0; + freelist = 0; + nextfree = 0; +} + +/*----------------------------------------------------------------------------- + * ~Pool - free a pool of buffers and the pool itself + *----------------------------------------------------------------------------- + */ + +Pool::~Pool( void ) +{ + assert( (this != 0) && (magic == is_allocated) ); + + while( nextblock ) { + delete [] blocklist[--nextblock]; + blocklist[nextblock] = 0; + } + magic = is_free; +} + + +void Pool::grow( void ) +{ + assert( (this != 0) && (magic == is_allocated) ); + curblock = new char[nextsize]; + blocklist[nextblock++] = curblock; + nextfree = nextsize; + nextsize *= 2; +} + +/*----------------------------------------------------------------------------- + * Pool::clear - free buffers associated with pool but keep pool + *----------------------------------------------------------------------------- + */ + +void +Pool::clear( void ) +{ + assert( (this != 0) && (magic == is_allocated) ); + + while( nextblock ) { + delete [] blocklist[--nextblock]; + blocklist[nextblock] = 0; + } + curblock = 0; + freelist = 0; + nextfree = 0; + if( nextsize > initsize ) + nextsize /= 2; +} diff --git a/mesalib/src/glu/sgi/libnurbs/internals/bufpool.h b/mesalib/src/glu/sgi/libnurbs/internals/bufpool.h new file mode 100644 index 000000000..0fa943375 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/bufpool.h @@ -0,0 +1,141 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * bufpool.h + * + */ + +#ifndef __glubufpool_h_ +#define __glubufpool_h_ + +#include "gluos.h" +#include "myassert.h" +#include "mystdlib.h" + +#define NBLOCKS 32 + +class Buffer { + friend class Pool; + Buffer * next; /* next buffer on free list */ +}; + +class Pool { +public: + Pool( int, int, const char * ); + ~Pool( void ); + inline void* new_buffer( void ); + inline void free_buffer( void * ); + void clear( void ); + +private: + void grow( void ); + +protected: + Buffer *freelist; /* linked list of free buffers */ + char *blocklist[NBLOCKS]; /* blocks of malloced memory */ + int nextblock; /* next free block index */ + char *curblock; /* last malloced block */ + int buffersize; /* bytes per buffer */ + int nextsize; /* size of next block of memory */ + int nextfree; /* byte offset past next free buffer */ + int initsize; + enum Magic { is_allocated = 0xf3a1, is_free = 0xf1a2 }; + const char *name; /* name of the pool */ + Magic magic; /* marker for valid pool */ +}; + +/*----------------------------------------------------------------------------- + * Pool::free_buffer - return a buffer to a pool + *----------------------------------------------------------------------------- + */ + +inline void +Pool::free_buffer( void *b ) +{ + assert( (this != 0) && (magic == is_allocated) ); + + /* add buffer to singly connected free list */ + + ((Buffer *) b)->next = freelist; + freelist = (Buffer *) b; +} + + +/*----------------------------------------------------------------------------- + * Pool::new_buffer - allocate a buffer from a pool + *----------------------------------------------------------------------------- + */ + +inline void * +Pool::new_buffer( void ) +{ + void *buffer; + + assert( (this != 0) && (magic == is_allocated) ); + + /* find free buffer */ + + if( freelist ) { + buffer = (void *) freelist; + freelist = freelist->next; + } else { + if( ! nextfree ) + grow( ); + nextfree -= buffersize;; + buffer = (void *) (curblock + nextfree); + } + return buffer; +} + +class PooledObj { +public: + inline void * operator new( size_t, Pool & ); + inline void * operator new( size_t, void *); + inline void * operator new( size_t s) + { return ::new char[s]; } + inline void operator delete( void * ) { assert( 0 ); } + inline void operator delete( void *, Pool & ) { assert( 0 ); } + inline void deleteMe( Pool & ); +}; + +inline void * +PooledObj::operator new( size_t, Pool& pool ) +{ + return pool.new_buffer(); +} + +inline void +PooledObj::deleteMe( Pool& pool ) +{ + pool.free_buffer( (void *) this ); +} + +#endif /* __glubufpool_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/cachingeval.cc b/mesalib/src/glu/sgi/libnurbs/internals/cachingeval.cc new file mode 100644 index 000000000..3fab38c10 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/cachingeval.cc @@ -0,0 +1,78 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * cachingeval.c++ + * + */ + +#include "cachingeval.h" + +int +CachingEvaluator::canRecord( void ) +{ + return 0; +} + +int +CachingEvaluator::canPlayAndRecord( void ) +{ + return 0; +} + +int +CachingEvaluator::createHandle( int ) +{ + return 0; +} + +void +CachingEvaluator::beginOutput( ServiceMode, int ) +{ +} + +void +CachingEvaluator::endOutput( void ) +{ +} + +void +CachingEvaluator::discardRecording( int ) +{ +} + +void +CachingEvaluator::playRecording( int ) +{ +} diff --git a/mesalib/src/glu/sgi/libnurbs/internals/cachingeval.h b/mesalib/src/glu/sgi/libnurbs/internals/cachingeval.h new file mode 100644 index 000000000..b390067a2 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/cachingeval.h @@ -0,0 +1,51 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * cachingeval.h + * + */ + +#ifndef __glucachingval_h_ +#define __glucachingval_h_ + +class CachingEvaluator { +public: + virtual ~CachingEvaluator() { /* silence warning*/ } + enum ServiceMode { play, record, playAndRecord }; + virtual int canRecord( void ); + virtual int canPlayAndRecord( void ); + virtual int createHandle( int handle ); + virtual void beginOutput( ServiceMode, int handle ); + virtual void endOutput( void ); + virtual void discardRecording( int handle ); + virtual void playRecording( int handle ); +}; +#endif /* __glucachingval_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/ccw.cc b/mesalib/src/glu/sgi/libnurbs/internals/ccw.cc new file mode 100644 index 000000000..eb01b7781 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/ccw.cc @@ -0,0 +1,565 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * ccw.c++ + * + */ + +#include "glimports.h" +#include "mystdio.h" +#include "myassert.h" +#include "subdivider.h" +#include "types.h" +#include "arc.h" +#include "trimvertex.h" +#include "simplemath.h" + +inline int +Subdivider::bbox( TrimVertex *a, TrimVertex *b, TrimVertex *c, int p ) +{ + return bbox( a->param[p], b->param[p], c->param[p], + a->param[1-p], b->param[1-p], c->param[1-p] ); +} + +int +Subdivider::ccwTurn_sr( Arc_ptr j1, Arc_ptr j2 ) // dir = 1 +{ + register TrimVertex *v1 = &j1->pwlArc->pts[j1->pwlArc->npts-1]; + register TrimVertex *v1last = &j1->pwlArc->pts[0]; + register TrimVertex *v2 = &j2->pwlArc->pts[0]; + register TrimVertex *v2last = &j2->pwlArc->pts[j2->pwlArc->npts-1]; + register TrimVertex *v1next = v1-1; + register TrimVertex *v2next = v2+1; + int sgn; + + assert( v1 != v1last ); + assert( v2 != v2last ); + +#ifndef NDEBUG + _glu_dprintf( "arc_ccw_turn, p = %d\n", 0 ); +#endif + + // the arcs lie on the line (0 == v1->param[0]) + if( v1->param[0] == v1next->param[0] && v2->param[0] == v2next->param[0] ) + return 0; + + if( v2next->param[0] < v2->param[0] || v1next->param[0] < v1->param[0] ) + ::mylongjmp( jumpbuffer, 28 ); + + if( v1->param[1] < v2->param[1] ) + return 0; + else if( v1->param[1] > v2->param[1] ) + return 1; + + while( 1 ) { + if( v1next->param[0] < v2next->param[0] ) { +#ifndef NDEBUG + _glu_dprintf( "case a\n" ); +#endif + assert( v1->param[0] <= v1next->param[0] ); + assert( v2->param[0] <= v1next->param[0] ); + switch( bbox( v2, v2next, v1next, 1 ) ) { + case -1: + return 0; + case 0: + sgn = ccw( v1next, v2, v2next ); + if( sgn != -1 ) { + return sgn; + } else { +#ifdef DEBUG + _glu_dprintf( "decr\n" ); +#endif + v1 = v1next--; + if( v1 == v1last ) { +#ifdef DEBUG + _glu_dprintf( "no good results\n" ); +#endif + return 0; // ill-conditioned, guess answer + } + } + break; + case 1: + return 1; + } + } else if( v1next->param[0] > v2next->param[0] ) { +#ifndef NDEBUG + _glu_dprintf( "case b\n" ); +#endif + assert( v1->param[0] <= v2next->param[0] ); + assert( v2->param[0] <= v2next->param[0] ); + switch( bbox( v1, v1next, v2next, 1 ) ) { + case -1: + return 1; + case 0: + sgn = ccw( v1next, v1, v2next ); + if( sgn != -1 ) { + return sgn; + } else { +#ifdef DEBUG + _glu_dprintf( "incr\n" ); +#endif + v2 = v2next++; + if( v2 == v2last ) { +#ifdef DEBUG + _glu_dprintf( "no good results\n" ); +#endif + return 0; // ill-conditioned, guess answer + } + } + break; + case 1: + return 0; + } + } else { +#ifndef NDEBUG + _glu_dprintf( "case ab\n" ); +#endif + if( v1next->param[1] < v2next->param[1] ) + return 0; + else if( v1next->param[1] > v2next->param[1] ) + return 1; + else { +#ifdef DEBUG + _glu_dprintf( "incr\n" ); +#endif + v2 = v2next++; + if( v2 == v2last ) { +#ifdef DEBUG + _glu_dprintf( "no good results\n" ); +#endif + return 0; // ill-conditioned, guess answer + } + } + } + } +} + +int +Subdivider::ccwTurn_sl( Arc_ptr j1, Arc_ptr j2 ) // dir = 0 +{ + register TrimVertex *v1 = &j1->pwlArc->pts[j1->pwlArc->npts-1]; + register TrimVertex *v1last = &j1->pwlArc->pts[0]; + register TrimVertex *v2 = &j2->pwlArc->pts[0]; + register TrimVertex *v2last = &j2->pwlArc->pts[j2->pwlArc->npts-1]; + register TrimVertex *v1next = v1-1; + register TrimVertex *v2next = v2+1; + int sgn; + + assert( v1 != v1last ); + assert( v2 != v2last ); + +#ifndef NDEBUG + _glu_dprintf( "arc_ccw_turn, p = %d\n", 0 ); +#endif + + // the arcs lie on the line (0 == v1->param[0]) + if( v1->param[0] == v1next->param[0] && v2->param[0] == v2next->param[0] ) + return 0; + + if( v2next->param[0] > v2->param[0] || v1next->param[0] > v1->param[0] ) + ::mylongjmp( jumpbuffer, 28 ); + + if( v1->param[1] < v2->param[1] ) + return 1; + else if( v1->param[1] > v2->param[1] ) + return 0; + + while( 1 ) { + if( v1next->param[0] > v2next->param[0] ) { +#ifndef NDEBUG + _glu_dprintf( "case c\n" ); +#endif + assert( v1->param[0] >= v1next->param[0] ); + assert( v2->param[0] >= v1next->param[0] ); + switch( bbox( v2next, v2, v1next, 1 ) ) { + case -1: + return 1; + case 0: + sgn = ccw( v1next, v2, v2next ); + if( sgn != -1 ) + return sgn; + else { + v1 = v1next--; +#ifdef DEBUG + _glu_dprintf( "decr\n" ); +#endif + if( v1 == v1last ) { +#ifdef DEBUG + _glu_dprintf( "no good results\n" ); +#endif + return 0; // ill-conditioned, guess answer + } + } + break; + case 1: + return 0; + } + } else if( v1next->param[0] < v2next->param[0] ) { +#ifndef NDEBUG + _glu_dprintf( "case d\n" ); +#endif + assert( v1->param[0] >= v2next->param[0] ); + assert( v2->param[0] >= v2next->param[0] ); + switch( bbox( v1next, v1, v2next, 1 ) ) { + case -1: + return 0; + case 0: + sgn = ccw( v1next, v1, v2next ); + if( sgn != -1 ) + return sgn; + else { + v2 = v2next++; +#ifdef DEBUG + _glu_dprintf( "incr\n" ); +#endif + if( v2 == v2last ) { +#ifdef DEBUG + _glu_dprintf( "no good results\n" ); +#endif + return 0; // ill-conditioned, guess answer + } + } + break; + case 1: + return 1; + } + } else { +#ifdef DEBUG + _glu_dprintf( "case cd\n" ); +#endif + if( v1next->param[1] < v2next->param[1] ) + return 1; + else if( v1next->param[1] > v2next->param[1] ) + return 0; + else { + v2 = v2next++; +#ifdef DEBUG + _glu_dprintf( "incr\n" ); +#endif + if( v2 == v2last ) { +#ifdef DEBUG + _glu_dprintf( "no good results\n" ); +#endif + return 0; // ill-conditioned, guess answer + } + } + } + } +} + +int +Subdivider::ccwTurn_tr( Arc_ptr j1, Arc_ptr j2 ) // dir = 1 +{ + register TrimVertex *v1 = &j1->pwlArc->pts[j1->pwlArc->npts-1]; + register TrimVertex *v1last = &j1->pwlArc->pts[0]; + register TrimVertex *v2 = &j2->pwlArc->pts[0]; + register TrimVertex *v2last = &j2->pwlArc->pts[j2->pwlArc->npts-1]; + register TrimVertex *v1next = v1-1; + register TrimVertex *v2next = v2+1; + int sgn; + + assert( v1 != v1last ); + assert( v2 != v2last ); + +#ifndef NDEBUG + _glu_dprintf( "arc_ccw_turn, p = %d\n", 1 ); +#endif + + // the arcs lie on the line (1 == v1->param[1]) + if( v1->param[1] == v1next->param[1] && v2->param[1] == v2next->param[1] ) + return 0; + + if( v2next->param[1] < v2->param[1] || v1next->param[1] < v1->param[1] ) + ::mylongjmp( jumpbuffer, 28 ); + + if( v1->param[0] < v2->param[0] ) + return 1; + else if( v1->param[0] > v2->param[0] ) + return 0; + + while( 1 ) { + if( v1next->param[1] < v2next->param[1] ) { +#ifndef NDEBUG + _glu_dprintf( "case a\n" ); +#endif + assert( v1->param[1] <= v1next->param[1] ); + assert( v2->param[1] <= v1next->param[1] ); + switch( bbox( v2, v2next, v1next, 0 ) ) { + case -1: + return 1; + case 0: + sgn = ccw( v1next, v2, v2next ); + if( sgn != -1 ) { + return sgn; + } else { +#ifdef DEBUG + _glu_dprintf( "decr\n" ); +#endif + v1 = v1next--; + if( v1 == v1last ) { +#ifdef DEBUG + _glu_dprintf( "no good results\n" ); +#endif + return 0; // ill-conditioned, guess answer + } + } + break; + case 1: + return 0; + } + } else if( v1next->param[1] > v2next->param[1] ) { +#ifndef NDEBUG + _glu_dprintf( "case b\n" ); +#endif + assert( v1->param[1] <= v2next->param[1] ); + assert( v2->param[1] <= v2next->param[1] ); + switch( bbox( v1, v1next, v2next, 0 ) ) { + case -1: + return 0; + case 0: + sgn = ccw( v1next, v1, v2next ); + if( sgn != -1 ) { + return sgn; + } else { +#ifdef DEBUG + _glu_dprintf( "incr\n" ); +#endif + v2 = v2next++; + if( v2 == v2last ) { +#ifdef DEBUG + _glu_dprintf( "no good results\n" ); +#endif + return 0; // ill-conditioned, guess answer + } + } + break; + case 1: + return 1; + } + } else { +#ifdef DEBUG + _glu_dprintf( "case ab\n" ); +#endif + if( v1next->param[0] < v2next->param[0] ) + return 1; + else if( v1next->param[0] > v2next->param[0] ) + return 0; + else { +#ifdef DEBUG + _glu_dprintf( "incr\n" ); +#endif + v2 = v2next++; + if( v2 == v2last ) { +#ifdef DEBUG + _glu_dprintf( "no good results\n" ); +#endif + return 0; // ill-conditioned, guess answer + } + } + } + } +} + +int +Subdivider::ccwTurn_tl( Arc_ptr j1, Arc_ptr j2 ) +{ + register TrimVertex *v1 = &j1->pwlArc->pts[j1->pwlArc->npts-1]; + register TrimVertex *v1last = &j1->pwlArc->pts[0]; + register TrimVertex *v2 = &j2->pwlArc->pts[0]; + register TrimVertex *v2last = &j2->pwlArc->pts[j2->pwlArc->npts-1]; + register TrimVertex *v1next = v1-1; + register TrimVertex *v2next = v2+1; + int sgn; + + assert( v1 != v1last ); + assert( v2 != v2last ); + +#ifndef NDEBUG + _glu_dprintf( "arc_ccw_turn, p = %d\n", 1 ); +#endif + + // the arcs lie on the line (1 == v1->param[1]) + if( v1->param[1] == v1next->param[1] && v2->param[1] == v2next->param[1] ) + return 0; + + if( v2next->param[1] > v2->param[1] || v1next->param[1] > v1->param[1] ) + ::mylongjmp( jumpbuffer, 28 ); + + if( v1->param[0] < v2->param[0] ) + return 0; + else if( v1->param[0] > v2->param[0] ) + return 1; + + while( 1 ) { + if( v1next->param[1] > v2next->param[1] ) { +#ifndef NDEBUG + _glu_dprintf( "case c\n" ); +#endif + assert( v1->param[1] >= v1next->param[1] ); + assert( v2->param[1] >= v1next->param[1] ); + switch( bbox( v2next, v2, v1next, 0 ) ) { + case -1: + return 0; + case 0: + sgn = ccw( v1next, v2, v2next ); + if( sgn != -1 ) + return sgn; + else { + v1 = v1next--; +#ifdef DEBUG + _glu_dprintf( "decr\n" ); +#endif + if( v1 == v1last ) { +#ifdef DEBUG + _glu_dprintf( "no good results\n" ); +#endif + return 0; // ill-conditioned, guess answer + } + } + break; + case 1: + return 1; + } + } else if( v1next->param[1] < v2next->param[1] ) { +#ifndef NDEBUG + _glu_dprintf( "case d\n" ); + assert( v1->param[1] >= v2next->param[1] ); + assert( v2->param[1] >= v2next->param[1] ); +#endif + switch( bbox( v1next, v1, v2next, 0 ) ) { + case -1: + return 1; + case 0: + sgn = ccw( v1next, v1, v2next ); + if( sgn != -1 ) + return sgn; + else { + v2 = v2next++; +#ifdef DEBUG + _glu_dprintf( "incr\n" ); +#endif + if( v2 == v2last ) { +#ifdef DEBUG + _glu_dprintf( "no good results\n" ); +#endif + return 0; // ill-conditioned, guess answer + } + } + break; + case 1: + return 0; + } + } else { +#ifdef DEBUG + _glu_dprintf( "case cd\n" ); +#endif + if( v1next->param[0] < v2next->param[0] ) + return 0; + else if( v1next->param[0] > v2next->param[0] ) + return 1; + else { + v2 = v2next++; +#ifdef DEBUG + _glu_dprintf( "incr\n" ); +#endif + if( v2 == v2last ) { +#ifdef DEBUG + _glu_dprintf( "no good results\n" ); +#endif + return 0; // ill-conditioned, guess answer + } + } + } + } +} + + +#ifndef NDEBUG +int +Subdivider::bbox( register REAL sa, register REAL sb, register REAL sc, + register REAL ta, register REAL tb, register REAL tc ) +#else +int +Subdivider::bbox( register REAL sa, register REAL sb, register REAL sc, + register REAL , register REAL , register REAL ) +#endif +{ +#ifndef NDEBUG + assert( tc >= ta ); + assert( tc <= tb ); +#endif + + if( sa < sb ) { + if( sc <= sa ) { + return -1; + } else if( sb <= sc ) { + return 1; + } else { + return 0; + } + } else if( sa > sb ) { + if( sc >= sa ) { + return 1; + } else if( sb >= sc ) { + return -1; + } else { + return 0; + } + } else { + if( sc > sa ) { + return 1; + } else if( sb > sc ) { + return -1; + } else { + return 0; + } + } +} + +/*---------------------------------------------------------------------------- + * ccw - determine how three points are oriented by computing their + * determinant. + * Return 1 if the vertices are ccw oriented, + * 0 if they are cw oriented, or + * -1 if the computation is ill-conditioned. + *---------------------------------------------------------------------------- + */ +int +Subdivider::ccw( TrimVertex *a, TrimVertex *b, TrimVertex *c ) +{ + REAL d = det3( a, b, c ); + if( glu_abs(d) < 0.0001 ) return -1; + return (d < 0.0) ? 0 : 1; +} diff --git a/mesalib/src/glu/sgi/libnurbs/internals/coveandtiler.cc b/mesalib/src/glu/sgi/libnurbs/internals/coveandtiler.cc new file mode 100644 index 000000000..ca5bf36b3 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/coveandtiler.cc @@ -0,0 +1,440 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * coveandtiler.c++ + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "coveandtiler.h" +#include "gridvertex.h" +#include "gridtrimvertex.h" +#include "uarray.h" +#include "backend.h" + + +const int CoveAndTiler::MAXSTRIPSIZE = 1000; + +CoveAndTiler::CoveAndTiler( Backend& b ) + : backend( b ) +{ } + +CoveAndTiler::~CoveAndTiler( void ) +{ } + +inline void +CoveAndTiler::output( GridVertex &gv ) +{ + backend.tmeshvert( &gv ); +} + +inline void +CoveAndTiler::output( TrimVertex *tv ) +{ + backend.tmeshvert( tv ); +} + +inline void +CoveAndTiler::output( GridTrimVertex& g ) +{ + backend.tmeshvert( &g ); +} + +void +CoveAndTiler::coveAndTile( void ) +{ + long ustart = (top.ustart >= bot.ustart) ? top.ustart : bot.ustart; + long uend = (top.uend <= bot.uend) ? top.uend : bot.uend; + if( ustart <= uend ) { + tile( bot.vindex, ustart, uend ); + if( top.ustart >= bot.ustart ) + coveUpperLeft(); + else + coveLowerLeft(); + + if( top.uend <= bot.uend ) + coveUpperRight(); + else + coveLowerRight(); + } else { + TrimVertex blv, tlv, *bl, *tl; + GridTrimVertex bllv, tllv; + TrimVertex *lf = left.first(); + TrimVertex *ll = left.last(); + if( lf->param[0] >= ll->param[0] ) { + blv.param[0] = lf->param[0]; + blv.param[1] = ll->param[1]; + blv.nuid = 0; // XXX + assert( blv.param[1] == bot.vval ); + bl = &blv; + tl = lf; + tllv.set( lf ); + if( ll->param[0] > uarray.uarray[top.ustart-1] ) { + bllv.set( ll ); + assert( ll->param[0] <= uarray.uarray[bot.ustart] ); + } else { + bllv.set( top.ustart-1, bot.vindex ); + } + coveUpperLeftNoGrid( bl ); + } else { + tlv.param[0] = ll->param[0]; + tlv.param[1] = lf->param[1]; + tlv.nuid = 0; // XXX + assert( tlv.param[1] == top.vval ); + tl = &tlv; + bl = ll; + bllv.set( ll ); + if( lf->param[0] > uarray.uarray[bot.ustart-1] ) { + assert( lf->param[0] <= uarray.uarray[bot.ustart] ); + tllv.set( lf ); + } else { + tllv.set( bot.ustart-1, top.vindex ); + } + coveLowerLeftNoGrid( tl ); + } + + TrimVertex brv, trv, *br, *tr; + GridTrimVertex brrv, trrv; + TrimVertex *rf = right.first(); + TrimVertex *rl = right.last(); + + if( rf->param[0] <= rl->param[0] ) { + brv.param[0] = rf->param[0]; + brv.param[1] = rl->param[1]; + brv.nuid = 0; // XXX + assert( brv.param[1] == bot.vval ); + br = &brv; + tr = rf; + trrv.set( rf ); + if( rl->param[0] < uarray.uarray[top.uend+1] ) { + assert( rl->param[0] >= uarray.uarray[top.uend] ); + brrv.set( rl ); + } else { + brrv.set( top.uend+1, bot.vindex ); + } + coveUpperRightNoGrid( br ); + } else { + trv.param[0] = rl->param[0]; + trv.param[1] = rf->param[1]; + trv.nuid = 0; // XXX + assert( trv.param[1] == top.vval ); + tr = &trv; + br = rl; + brrv.set( rl ); + if( rf->param[0] < uarray.uarray[bot.uend+1] ) { + assert( rf->param[0] >= uarray.uarray[bot.uend] ); + trrv.set( rf ); + } else { + trrv.set( bot.uend+1, top.vindex ); + } + coveLowerRightNoGrid( tr ); + } + + backend.bgntmesh( "doit" ); + output(trrv); + output(tllv); + output( tr ); + output( tl ); + output( br ); + output( bl ); + output(brrv); + output(bllv); + backend.endtmesh(); + } +} + +void +CoveAndTiler::tile( long vindex, long ustart, long uend ) +{ + long numsteps = uend - ustart; + + if( numsteps == 0 ) return; + + if( numsteps > MAXSTRIPSIZE ) { + long umid = ustart + (uend - ustart) / 2; + tile( vindex, ustart, umid ); + tile( vindex, umid, uend ); + } else { + backend.surfmesh( ustart, vindex-1, numsteps, 1 ); + } +} + +void +CoveAndTiler::coveUpperRight( void ) +{ + GridVertex tgv( top.uend, top.vindex ); + GridVertex gv( top.uend, bot.vindex ); + + right.first(); + backend.bgntmesh( "coveUpperRight" ); + output( right.next() ); + output( tgv ); + backend.swaptmesh(); + output( gv ); + coveUR(); + backend.endtmesh(); +} + +void +CoveAndTiler::coveUpperRightNoGrid( TrimVertex* br ) +{ + backend.bgntmesh( "coveUpperRight" ); + output( right.first() ); + output( right.next() ); + backend.swaptmesh(); + output( br ); + coveUR(); + backend.endtmesh(); +} + +void +CoveAndTiler::coveUR( ) +{ + GridVertex gv( top.uend, bot.vindex ); + TrimVertex *vert = right.next(); + if( vert == NULL ) return; + + assert( vert->param[0] >= uarray.uarray[gv.gparam[0]] ); + + if( gv.nextu() >= bot.uend ) { + for( ; vert; vert = right.next() ) { + output( vert ); + backend.swaptmesh(); + } + } else while( 1 ) { + if( vert->param[0] < uarray.uarray[gv.gparam[0]] ) { + output( vert ); + backend.swaptmesh(); + vert = right.next(); + if( vert == NULL ) break; + } else { + backend.swaptmesh(); + output( gv ); + if( gv.nextu() == bot.uend ) { + for( ; vert; vert = right.next() ) { + output( vert ); + backend.swaptmesh(); + } + break; + } + } + } +} + +void +CoveAndTiler::coveUpperLeft( void ) +{ + GridVertex tgv( top.ustart, top.vindex ); + GridVertex gv( top.ustart, bot.vindex ); + + left.first(); + backend.bgntmesh( "coveUpperLeft" ); + output( tgv ); + output( left.next() ); + output( gv ); + backend.swaptmesh(); + coveUL(); + backend.endtmesh(); +} + +void +CoveAndTiler::coveUpperLeftNoGrid( TrimVertex* bl ) +{ + backend.bgntmesh( "coveUpperLeftNoGrid" ); + output( left.first() ); + output( left.next() ); + output( bl ); + backend.swaptmesh(); + coveUL(); + backend.endtmesh(); +} + +void +CoveAndTiler::coveUL() +{ + GridVertex gv( top.ustart, bot.vindex ); + TrimVertex *vert = left.next(); + if( vert == NULL ) return; + assert( vert->param[0] <= uarray.uarray[gv.gparam[0]] ); + + if( gv.prevu() <= bot.ustart ) { + for( ; vert; vert = left.next() ) { + backend.swaptmesh(); + output( vert ); + } + } else while( 1 ) { + if( vert->param[0] > uarray.uarray[gv.gparam[0]] ) { + backend.swaptmesh(); + output( vert ); + vert = left.next(); + if( vert == NULL ) break; + } else { + output( gv ); + backend.swaptmesh(); + if( gv.prevu() == bot.ustart ) { + for( ; vert; vert = left.next() ) { + backend.swaptmesh(); + output( vert ); + } + break; + } + } + } +} + +void +CoveAndTiler::coveLowerLeft( void ) +{ + GridVertex bgv( bot.ustart, bot.vindex ); + GridVertex gv( bot.ustart, top.vindex ); + + left.last(); + backend.bgntmesh( "coveLowerLeft" ); + output( left.prev() ); + output( bgv ); + backend.swaptmesh(); + output( gv ); + coveLL(); + backend.endtmesh(); +} + +void +CoveAndTiler::coveLowerLeftNoGrid( TrimVertex* tl ) +{ + backend.bgntmesh( "coveLowerLeft" ); + output( left.last() ); + output( left.prev() ); + backend.swaptmesh(); + output( tl ); + coveLL( ); + backend.endtmesh(); +} + +void +CoveAndTiler::coveLL() +{ + GridVertex gv( bot.ustart, top.vindex ); + TrimVertex *vert = left.prev(); + if( vert == NULL ) return; + assert( vert->param[0] <= uarray.uarray[gv.gparam[0]] ); + + if( gv.prevu() <= top.ustart ) { + for( ; vert; vert = left.prev() ) { + output( vert ); + backend.swaptmesh(); + } + } else while( 1 ) { + if( vert->param[0] > uarray.uarray[gv.gparam[0]] ){ + output( vert ); + backend.swaptmesh(); + vert = left.prev(); + if( vert == NULL ) break; + } else { + backend.swaptmesh(); + output( gv ); + if( gv.prevu() == top.ustart ) { + for( ; vert; vert = left.prev() ) { + output( vert ); + backend.swaptmesh(); + } + break; + } + } + } +} + +void +CoveAndTiler::coveLowerRight( void ) +{ + GridVertex bgv( bot.uend, bot.vindex ); + GridVertex gv( bot.uend, top.vindex ); + + right.last(); + backend.bgntmesh( "coveLowerRight" ); + output( bgv ); + output( right.prev() ); + output( gv ); + backend.swaptmesh(); + coveLR(); + backend.endtmesh( ); +} + +void +CoveAndTiler::coveLowerRightNoGrid( TrimVertex* tr ) +{ + backend.bgntmesh( "coveLowerRIght" ); + output( right.last() ); + output( right.prev() ); + output( tr ); + backend.swaptmesh(); + coveLR(); + backend.endtmesh(); +} + +void +CoveAndTiler::coveLR( ) +{ + GridVertex gv( bot.uend, top.vindex ); + TrimVertex *vert = right.prev(); + if( vert == NULL ) return; + assert( vert->param[0] >= uarray.uarray[gv.gparam[0]] ); + + if( gv.nextu() >= top.uend ) { + for( ; vert; vert = right.prev() ) { + backend.swaptmesh(); + output( vert ); + } + } else while( 1 ) { + if( vert->param[0] < uarray.uarray[gv.gparam[0]] ) { + backend.swaptmesh(); + output( vert ); + vert = right.prev(); + if( vert == NULL ) break; + } else { + output( gv ); + backend.swaptmesh(); + if( gv.nextu() == top.uend ) { + for( ; vert; vert = right.prev() ) { + backend.swaptmesh(); + output( vert ); + } + break; + } + } + } +} + diff --git a/mesalib/src/glu/sgi/libnurbs/internals/coveandtiler.h b/mesalib/src/glu/sgi/libnurbs/internals/coveandtiler.h new file mode 100644 index 000000000..d454202e6 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/coveandtiler.h @@ -0,0 +1,72 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * coveandtiler.h + * + */ + +#ifndef __glucoveandtiler_h +#define __glucoveandtiler_h + +#include "trimregion.h" +#include "trimvertex.h" +#include "gridvertex.h" + +class Backend; +class GridTrimVertex; + +class CoveAndTiler : virtual public TrimRegion { +public: + CoveAndTiler( Backend& ); + ~CoveAndTiler( void ); + void coveAndTile( void ); +private: + Backend& backend; + static const int MAXSTRIPSIZE; + void tile( long, long, long ); + void coveLowerLeft( void ); + void coveLowerRight( void ); + void coveUpperLeft( void ); + void coveUpperRight( void ); + void coveUpperLeftNoGrid( TrimVertex * ); + void coveUpperRightNoGrid( TrimVertex * ); + void coveLowerLeftNoGrid( TrimVertex * ); + void coveLowerRightNoGrid( TrimVertex * ); + void coveLL( void ); + void coveLR( void ); + void coveUL( void ); + void coveUR( void ); + inline void output( GridTrimVertex& ); + inline void output( GridVertex& ); + inline void output( TrimVertex* ); +}; + +#endif /* __glucoveandtiler_h */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/curve.cc b/mesalib/src/glu/sgi/libnurbs/internals/curve.cc new file mode 100644 index 000000000..33e275264 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/curve.cc @@ -0,0 +1,198 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * curve.c++ + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "mymath.h" +#include "curve.h" +#include "mapdesc.h" +#include "types.h" +#include "quilt.h" +#include "nurbsconsts.h" + +/*-------------------------------------------------------------------------- + * Curve::Curve - copy curve from quilt and transform control points + *-------------------------------------------------------------------------- + */ + +Curve::Curve( Quilt_ptr geo, REAL pta, REAL ptb, Curve *c ) +{ + mapdesc = geo->mapdesc; + next = c; + needsSampling = mapdesc->isRangeSampling() ? 1 : 0; + cullval = mapdesc->isCulling() ? CULL_ACCEPT : CULL_TRIVIAL_ACCEPT; + order = geo->qspec[0].order; + stride = MAXCOORDS; + + REAL *ps = geo->cpts; + Quiltspec_ptr qs = geo->qspec; + ps += qs->offset; + ps += qs->index * qs->order * qs->stride; + + if( needsSampling ) + mapdesc->xformSampling( ps, qs->order, qs->stride, spts, stride ); + + if( cullval == CULL_ACCEPT ) + mapdesc->xformCulling( ps, qs->order, qs->stride, cpts, stride ); + + /* set untrimmed curve range */ + range[0] = qs->breakpoints[qs->index]; + range[1] = qs->breakpoints[qs->index+1]; + range[2] = range[1] - range[0]; + + if( range[0] != pta ) { + Curve lower( *this, pta, 0 ); + lower.next = next; + *this = lower; + } + if( range[1] != ptb ) { + Curve lower( *this, ptb, 0 ); + } +} + +/*-------------------------------------------------------------------------- + * Curve::Curve - subdivide a curve along an isoparametric line + *-------------------------------------------------------------------------- + */ + +Curve::Curve( Curve& upper, REAL value, Curve *c ) +{ + Curve &lower = *this; + + lower.next = c; + lower.mapdesc = upper.mapdesc; + lower.needsSampling = upper.needsSampling; + lower.order = upper.order; + lower.stride = upper.stride; + lower.cullval = upper.cullval; + + REAL d = (value - upper.range[0]) / upper.range[2]; + + if( needsSampling ) + mapdesc->subdivide( upper.spts, lower.spts, d, upper.stride, upper.order ); + + if( cullval == CULL_ACCEPT ) + mapdesc->subdivide( upper.cpts, lower.cpts, d, upper.stride, upper.order ); + + lower.range[0] = upper.range[0]; + lower.range[1] = value; + lower.range[2] = value - upper.range[0]; + upper.range[0] = value; + upper.range[2] = upper.range[1] - value; +} + + +/*-------------------------------------------------------------------------- + * Curve::clamp - clamp the sampling rate to a given maximum + *-------------------------------------------------------------------------- + */ + +void +Curve::clamp( void ) +{ + if( stepsize < minstepsize ) + stepsize = mapdesc->clampfactor * minstepsize; +} + +void +Curve::setstepsize( REAL max ) +{ + stepsize = ( max >= 1.0 ) ? (range[2] / max) : range[2]; + minstepsize = stepsize; +} + +void +Curve::getstepsize( void ) +{ + minstepsize= 0; + + if( mapdesc->isConstantSampling() ) { + // fixed number of samples per patch in each direction + // maxrate is number of s samples per patch + setstepsize( mapdesc->maxrate ); + } else if( mapdesc->isDomainSampling() ) { + // maxrate is number of s samples per unit s length of domain + setstepsize( mapdesc->maxrate * range[2] ); + } else { + // upper bound on path length between sample points + + assert( order <= MAXORDER ); + + /* points have been transformed, therefore they are homogeneous */ + REAL tmp[MAXORDER][MAXCOORDS]; + const int tstride = sizeof(tmp[0]) / sizeof(REAL); + int val = mapdesc->project( spts, stride, &tmp[0][0], tstride, order ); + + if( val == 0 ) { + // control points cross infinity, therefore derivatives are undefined + setstepsize( mapdesc->maxrate ); + } else { + REAL t = mapdesc->getProperty( N_PIXEL_TOLERANCE ); + if( mapdesc->isParametricDistanceSampling() ) { + REAL d = mapdesc->calcPartialVelocity( &tmp[0][0], tstride, order, 2, range[2] ); + stepsize = (d > 0.0) ? sqrtf( 8.0 * t / d ) : range[2]; + minstepsize = ( mapdesc->maxrate > 0.0 ) ? (range[2] / mapdesc->maxrate) : 0.0; + } else if( mapdesc->isPathLengthSampling() ) { + // t is upper bound on path (arc) length + REAL d = mapdesc->calcPartialVelocity( &tmp[0][0], tstride, order, 1, range[2] ); + stepsize = ( d > 0.0 ) ? (t / d) : range[2]; + minstepsize = ( mapdesc->maxrate > 0.0 ) ? (range[2] / mapdesc->maxrate) : 0.0; + } else { + // control points cross infinity, therefore partials are undefined + setstepsize( mapdesc->maxrate ); + } + } + } +} + +int +Curve::needsSamplingSubdivision( void ) +{ + return ( stepsize < minstepsize ) ? 1 : 0; +} + +int +Curve::cullCheck( void ) +{ + if( cullval == CULL_ACCEPT ) + cullval = mapdesc->cullCheck( cpts, order, stride ); + return cullval; +} + diff --git a/mesalib/src/glu/sgi/libnurbs/internals/curve.h b/mesalib/src/glu/sgi/libnurbs/internals/curve.h new file mode 100644 index 000000000..0da81c721 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/curve.h @@ -0,0 +1,70 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * curve.h + * + */ + +#ifndef __glucurve_h_ +#define __glucurve_h_ + +#include "types.h" +#include "defines.h" + +class Mapdesc; +class Quilt; + + +class Curve { +public: +friend class Curvelist; + Curve( Quilt *, REAL, REAL, Curve * ); + Curve( Curve&, REAL, Curve * ); + Curve * next; +private: + Mapdesc * mapdesc; + int stride; + int order; + int cullval; + int needsSampling; + REAL cpts[MAXORDER*MAXCOORDS]; + REAL spts[MAXORDER*MAXCOORDS]; + REAL stepsize; + REAL minstepsize; + REAL range[3]; + + void clamp( void ); + void setstepsize( REAL ); + void getstepsize( void ); + int cullCheck( void ); + int needsSamplingSubdivision( void ); +}; +#endif /* __glucurve_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/curvelist.cc b/mesalib/src/glu/sgi/libnurbs/internals/curvelist.cc new file mode 100644 index 000000000..872eb5816 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/curvelist.cc @@ -0,0 +1,110 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * curvelist.c++ + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "quilt.h" +#include "curvelist.h" +#include "curve.h" +#include "nurbsconsts.h" +#include "types.h" + +Curvelist::Curvelist( Quilt *quilts, REAL pta, REAL ptb ) +{ + curve = 0; + for( Quilt *q = quilts; q; q = q->next ) + curve = new Curve( q, pta, ptb, curve ); + range[0] = pta; + range[1] = ptb; + range[2] = ptb - pta; +} + +Curvelist::Curvelist( Curvelist &upper, REAL value ) +{ + Curvelist &lower = *this; + curve = 0; + for( Curve *c = upper.curve; c; c = c->next ) + curve = new Curve( *c, value, curve ); + + lower.range[0] = upper.range[0]; + lower.range[1] = value; + lower.range[2] = value - upper.range[0]; + upper.range[0] = value; + upper.range[2] = upper.range[1] - value; +} + +Curvelist::~Curvelist() +{ + while( curve ) { + Curve *c = curve; + curve = curve->next; + delete c; + } +} + +int +Curvelist::cullCheck( void ) +{ + for( Curve *c = curve; c; c = c->next ) + if( c->cullCheck() == CULL_TRIVIAL_REJECT ) + return CULL_TRIVIAL_REJECT; + return CULL_ACCEPT; +} + +void +Curvelist::getstepsize( void ) +{ + stepsize = range[2]; + Curve *c; + for( c = curve; c; c = c->next ) { + c->getstepsize(); + c->clamp(); + stepsize = ((c->stepsize < stepsize) ? c->stepsize : stepsize); + if( c->needsSamplingSubdivision() ) break; + } + needsSubdivision = ( c ) ? 1 : 0; +} + +int +Curvelist::needsSamplingSubdivision( void ) +{ + return needsSubdivision; +} + diff --git a/mesalib/src/glu/sgi/libnurbs/internals/curvelist.h b/mesalib/src/glu/sgi/libnurbs/internals/curvelist.h new file mode 100644 index 000000000..733a5115d --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/curvelist.h @@ -0,0 +1,62 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * curvelist.h + * + */ + +#ifndef __glucurvelist_h_ +#define __glucurvelist_h_ + +#include "types.h" +#include "defines.h" + +class Mapdesc; +class Quilt; +class Curve; + +class Curvelist +{ +friend class Subdivider; +public: + Curvelist( Quilt *, REAL, REAL ); + Curvelist( Curvelist &, REAL ); + ~Curvelist( void ); + int cullCheck( void ); + void getstepsize( void ); + int needsSamplingSubdivision(); +private: + Curve *curve; + float range[3]; + int needsSubdivision; + float stepsize; +}; +#endif /* __glucurvelist_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/curvesub.cc b/mesalib/src/glu/sgi/libnurbs/internals/curvesub.cc new file mode 100644 index 000000000..f85acc269 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/curvesub.cc @@ -0,0 +1,103 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * curvesub.c++ + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "subdivider.h" +#include "renderhints.h" +#include "backend.h" +#include "quilt.h" +#include "curvelist.h" +#include "curve.h" +#include "nurbsconsts.h" + +/*-------------------------------------------------------------------------- + * drawCurves - main curve rendering entry point + *-------------------------------------------------------------------------- + */ + +void +Subdivider::drawCurves( void ) +{ + REAL from[1], to[1]; + Flist bpts; + qlist->getRange( from, to, bpts ); + + renderhints.init( ); + + backend.bgncurv(); + for( int i=bpts.start; i<bpts.end-1; i++ ) { + REAL pta, ptb; + pta = bpts.pts[i]; + ptb = bpts.pts[i+1]; + + qlist->downloadAll( &pta, &ptb, backend ); + + Curvelist curvelist( qlist, pta, ptb ); + samplingSplit( curvelist, renderhints.maxsubdivisions ); + } + backend.endcurv(); +} + + +/*-------------------------------------------------------------------------- + * samplingSplit - recursively subdivide patch, cull check each subpatch + *-------------------------------------------------------------------------- + */ + +void +Subdivider::samplingSplit( Curvelist& curvelist, int subdivisions ) +{ + if( curvelist.cullCheck() == CULL_TRIVIAL_REJECT ) return; + + curvelist.getstepsize(); + + if( curvelist.needsSamplingSubdivision() && (subdivisions > 0) ) { + REAL mid = ( curvelist.range[0] + curvelist.range[1] ) * 0.5; + Curvelist lowerlist( curvelist, mid ); + samplingSplit( lowerlist, subdivisions-1 ); // lower + samplingSplit( curvelist, subdivisions-1 ); // upper + } else { + long nu = 1 + ((long) (curvelist.range[2] / curvelist.stepsize)); + backend.curvgrid( curvelist.range[0], curvelist.range[1], nu ); + backend.curvmesh( 0, nu ); + } +} + diff --git a/mesalib/src/glu/sgi/libnurbs/internals/dataTransform.cc b/mesalib/src/glu/sgi/libnurbs/internals/dataTransform.cc new file mode 100644 index 000000000..55c0fbb15 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/dataTransform.cc @@ -0,0 +1,209 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include <stdlib.h> +#include <stdio.h> +#include "glimports.h" +#include "myassert.h" +#include "nurbsconsts.h" +#include "trimvertex.h" +#include "dataTransform.h" + +extern directedLine* arcLoopToDLineLoop(Arc_ptr loop); + +#if 0 // UNUSED +static directedLine* copy_loop(Arc_ptr loop, Real2* vertArray, int& index, directedLine dline_buf[], sampledLine sline_buf[], int& index_dline) +{ + directedLine *ret; + int old_index = index; + int i = index; + int j; + for(j=0; j<loop->pwlArc->npts-1; j++, i++) + { + vertArray[i][0] = loop->pwlArc->pts[j].param[0]; + vertArray[i][1] = loop->pwlArc->pts[j].param[1]; + } + loop->clearmark(); + + for(Arc_ptr jarc = loop->next; jarc != loop; jarc=jarc->next) + { + for(j=0; j<jarc->pwlArc->npts-1; j++, i++) + { + vertArray[i][0] = jarc->pwlArc->pts[j].param[0]; + vertArray[i][1] = jarc->pwlArc->pts[j].param[1]; + } + jarc->clearmark(); + } + //copy the first vertex again + vertArray[i][0] = loop->pwlArc->pts[0].param[0]; + vertArray[i][1] = loop->pwlArc->pts[0].param[1]; + i++; + index=i; + + directedLine* dline; + sampledLine* sline; + sline = &sline_buf[index_dline]; + dline = &dline_buf[index_dline]; + sline->init(2, &vertArray[old_index]); + dline->init(INCREASING, sline); + ret = dline; + index_dline++; + + for(i=old_index+1; i<= index-2; i++) + { + sline = &sline_buf[index_dline]; + dline = &dline_buf[index_dline]; + sline->init(2, &vertArray[i]); + dline->init(INCREASING, sline); + ret->insert(dline); + index_dline++; + } + return ret; +} +#endif + +#if 0 // UNUSED +static int num_edges(Bin& bin) +{ + int sum=0; + for(Arc_ptr jarc = bin.firstarc(); jarc; jarc=bin.nextarc()) + sum += jarc->pwlArc->npts-1; + return sum; +} +#endif + +/* +directedLine* bin_to_DLineLoops(Bin& bin) +{ + directedLine *ret=NULL; + directedLine *temp; + + int numedges = num_edges(bin); + directedLine* dline_buf = new directedLine[numedges]; //not work for N32? + sampledLine* sline_buf=new sampledLine[numedges]; + + Real2* vertArray = new Real2[numedges*2]; + int index = 0; + int index_dline = 0; + bin.markall(); + + for(Arc_ptr jarc = bin.firstarc(); jarc; jarc=bin.nextarc()) + { + if(jarc->ismarked()) + { + assert(jarc->check() != 0); + Arc_ptr jarchead = jarc; + do { + jarc->clearmark(); + jarc = jarc->next; + } while(jarc != jarchead); + temp=copy_loop(jarchead, vertArray, index, dline_buf, sline_buf, index_dline); + ret = temp->insertPolygon(ret); + } + } + + return ret; +} +*/ + + +directedLine* bin_to_DLineLoops(Bin& bin) +{ + directedLine *ret=NULL; + directedLine *temp; + bin.markall(); + for(Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc()){ + if(jarc->ismarked()) { + assert(jarc->check() != 0); + Arc_ptr jarchead = jarc; + do { + jarc->clearmark(); + jarc = jarc->next; + } while(jarc != jarchead); + temp = arcLoopToDLineLoop(jarc); + ret = temp->insertPolygon(ret); + } + } + return ret; +} + +directedLine* o_pwlcurve_to_DLines(directedLine* original, O_pwlcurve* pwl) +{ + directedLine* ret = original; + for(Int i=0; i<pwl->npts-1; i++) + { + sampledLine* sline = new sampledLine(2); + sline->setPoint(0, pwl->pts[i].param); + sline->setPoint(1, pwl->pts[i+1].param); + directedLine* dline = new directedLine(INCREASING, sline); + if(ret == NULL) + ret = dline; + else + ret->insert(dline); + } + return ret; +} + +directedLine* o_curve_to_DLineLoop(O_curve* cur) +{ + directedLine *ret; + if(cur == NULL) + return NULL; + assert(cur->curvetype == ct_pwlcurve); + ret = o_pwlcurve_to_DLines(NULL, cur->curve.o_pwlcurve); + for(O_curve* temp = cur->next; temp != NULL; temp = temp->next) + { + assert(temp->curvetype == ct_pwlcurve); + ret = o_pwlcurve_to_DLines(ret, temp->curve.o_pwlcurve); + } + return ret; +} + +directedLine* o_trim_to_DLineLoops(O_trim* trim) +{ + O_trim* temp; + directedLine *ret; + if(trim == NULL) + return NULL; + ret = o_curve_to_DLineLoop(trim->o_curve); + + for(temp=trim->next; temp != NULL; temp = temp->next) + { + ret = ret->insertPolygon(o_curve_to_DLineLoop(temp->o_curve)); + } + return ret; +} diff --git a/mesalib/src/glu/sgi/libnurbs/internals/dataTransform.h b/mesalib/src/glu/sgi/libnurbs/internals/dataTransform.h new file mode 100644 index 000000000..7898df754 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/dataTransform.h @@ -0,0 +1,59 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ +/* +*/ + +#ifndef _DATA_TRANSFORM_H +#define _DATA_TRANSFORM_H + +#include "reader.h" +#include "directedLine.h" +#include "bin.h" +directedLine* bin_to_DLineLoops(Bin& bin); + +/*transform the pwlcurve into a number of directedline lines + *insert these directedlines into orignal which is supposed to be + *the part of the trimming loop obtained so far. + *return the updated trimkming loop. + */ +directedLine* o_pwlcurve_to_DLines(directedLine* original, O_pwlcurve* pwl); + +/*transform a trim loop (curve) into a directedLine loop + */ +directedLine* o_curve_to_DLineLoop(O_curve* curve); + +/*transform a list of trim loops (trim) into + *a list of polygons represented as directedLine*. + */ +directedLine* o_trim_to_DLineLoops(O_trim* trim); + + +#endif + diff --git a/mesalib/src/glu/sgi/libnurbs/internals/defines.h b/mesalib/src/glu/sgi/libnurbs/internals/defines.h new file mode 100644 index 000000000..32950d613 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/defines.h @@ -0,0 +1,50 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * defines.h + * + */ + +#ifndef __gludefines_h_ +#define __gludefines_h_ + +/* culling constants */ +#define CULL_TRIVIAL_REJECT 0 +#define CULL_TRIVIAL_ACCEPT 1 +#define CULL_ACCEPT 2 + +/* maximum order of a B-Spline */ +#define MAXORDER 24 + +/* maximum dimension of any B-spline range space */ +#define MAXCOORDS 5 + +#endif /* __gludefines_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/displaylist.cc b/mesalib/src/glu/sgi/libnurbs/internals/displaylist.cc new file mode 100644 index 000000000..48593c637 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/displaylist.cc @@ -0,0 +1,82 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * displaylist.c++ + * + */ + +#include "glimports.h" +#include "mystdio.h" +#include "nurbstess.h" +#include "displaylist.h" + + +DisplayList::DisplayList( NurbsTessellator *_nt ) : + dlnodePool( sizeof( Dlnode ), 1, "dlnodepool" ) +{ + lastNode = &nodes; + nt = _nt; +} + +DisplayList::~DisplayList( void ) +{ + for( Dlnode *nextNode; nodes; nodes = nextNode ) { + nextNode = nodes->next; + if( nodes->cleanup != 0 ) (nt->*nodes->cleanup)( nodes->arg ); + //nodes->deleteMe(dlnodePool); + } +} + +void +DisplayList::play( void ) +{ + for( Dlnode *node = nodes; node; node = node->next ) + if( node->work != 0 ) (nt->*node->work)( node->arg ); +} + +void +DisplayList::endList( void ) +{ + *lastNode = 0; +} + +void +DisplayList::append( PFVS work, void *arg, PFVS cleanup ) +{ + Dlnode *node = new(dlnodePool) Dlnode( work, arg, cleanup ); + *lastNode = node; + lastNode = &(node->next); +} + diff --git a/mesalib/src/glu/sgi/libnurbs/internals/displaylist.h b/mesalib/src/glu/sgi/libnurbs/internals/displaylist.h new file mode 100644 index 000000000..22cbec378 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/displaylist.h @@ -0,0 +1,78 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * displaylist.h + * + */ + +#ifndef __gludisplaylist_h_ +#define __gludisplaylist_h_ + +#include "glimports.h" +#include "mysetjmp.h" +#include "mystdio.h" +#include "bufpool.h" + +class NurbsTessellator; + +typedef void (NurbsTessellator::*PFVS)( void * ); + +struct Dlnode : public PooledObj { + Dlnode( PFVS, void *, PFVS ); + PFVS work; + void * arg; + PFVS cleanup; + Dlnode * next; +}; + +inline +Dlnode::Dlnode( PFVS _work, void *_arg, PFVS _cleanup ) +{ + work = _work; + arg = _arg; + cleanup = _cleanup; +} + +class DisplayList { +public: + DisplayList( NurbsTessellator * ); + ~DisplayList( void ); + void play( void ); + void append( PFVS work, void *arg, PFVS cleanup ); + void endList( void ); +private: + Dlnode *nodes; + Pool dlnodePool; + Dlnode **lastNode; + NurbsTessellator *nt; +}; + +#endif /* __gludisplaylist_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/displaymode.h b/mesalib/src/glu/sgi/libnurbs/internals/displaymode.h new file mode 100644 index 000000000..53968b2f1 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/displaymode.h @@ -0,0 +1,40 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ +/* +*/ + +#ifndef __gludisplaymode_h_ +#define __gludisplaymode_h_ + +#define N_MESHFILL 0 +#define N_MESHLINE 1 +#define N_MESHPOINT 2 + +#endif /* __gludisplaymode_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/flist.cc b/mesalib/src/glu/sgi/libnurbs/internals/flist.cc new file mode 100644 index 000000000..d3162b9f5 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/flist.cc @@ -0,0 +1,118 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * flist.c++ + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "flist.h" + +/*---------------------------------------------------------------------------- + * Flist::Flist - initialize a REAL number array + *---------------------------------------------------------------------------- + */ +Flist::Flist( void ) +{ + npts = 0; + pts = 0; + start = end = 0; +} + +/*---------------------------------------------------------------------------- + * Flist::~Flist - free a REAL number array + *---------------------------------------------------------------------------- + */ +Flist::~Flist( void ) +{ + if( npts ) delete[] pts; +} + +void +Flist::add( REAL x ) +{ + pts[end++] = x; + assert( end <= npts ); +} + +/*---------------------------------------------------------------------------- + * Flist::filter - remove duplicate numbers from array + *---------------------------------------------------------------------------- + */ +void Flist::filter( void ) +{ + sorter.qsort( pts, end ); + start = 0; + + int j = 0; + for( int i = 1; i < end; i++ ) { + if( pts[i] == pts[i-j-1] ) + j++; + pts[i-j] = pts[i]; + } + end -= j; +} + +/*---------------------------------------------------------------------------- + * Flist::grow - ensure that array is large enough + *---------------------------------------------------------------------------- + */ +void Flist::grow( int maxpts ) +{ + if( npts < maxpts ) { + if( npts ) delete[] pts; + npts = 2 * maxpts; + pts = new REAL[npts]; + assert( pts != 0 ); + } + start = end = 0; +} + +/*---------------------------------------------------------------------------- + * Flist::taper - ignore head and tail of array + *---------------------------------------------------------------------------- + */ +void Flist::taper( REAL from, REAL to ) +{ + while( pts[start] != from ) + start++; + + while( pts[end-1] != to ) + end--; +} + + diff --git a/mesalib/src/glu/sgi/libnurbs/internals/flist.h b/mesalib/src/glu/sgi/libnurbs/internals/flist.h new file mode 100644 index 000000000..014273ebe --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/flist.h @@ -0,0 +1,59 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * flist.h + * + */ + +#ifndef __gluflist_h_ +#define __gluflist_h_ + +#include "types.h" +#include "flistsorter.h" + +class Flist { +public: + REAL * pts; /* head of array */ + int npts; /* number of points in array */ + int start; /* first important point index */ + int end; /* last important point index */ + + Flist( void ); + ~Flist( void ); + void add( REAL x ); + void filter( void ); + void grow( int); + void taper( REAL , REAL ); +protected: + FlistSorter sorter; +}; + +#endif /* __gluflist_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/flistsorter.cc b/mesalib/src/glu/sgi/libnurbs/internals/flistsorter.cc new file mode 100644 index 000000000..d49bdea3e --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/flistsorter.cc @@ -0,0 +1,81 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * flistsorter.c++ + * + */ + +#include "glimports.h" +#include "flistsorter.h" + +FlistSorter::FlistSorter( void ) : Sorter( sizeof( REAL ) ) +{ +} + +void +FlistSorter::qsort( REAL *p, int n ) +{ + Sorter::qsort( (char *)p, n ); +} + +int +FlistSorter::qscmp( char *i, char *j ) +{ + REAL f0 = *(REAL *)i; + REAL f1 = *(REAL *)j; + return (f0 < f1) ? -1 : 1; +} + +void +FlistSorter::qsexc( char *i, char *j ) +{ + REAL *f0 = (REAL *)i; + REAL *f1 = (REAL *)j; + REAL tmp = *f0; + *f0 = *f1; + *f1 = tmp; +} + +void +FlistSorter::qstexc( char *i, char *j, char *k ) +{ + REAL *f0 = (REAL *)i; + REAL *f1 = (REAL *)j; + REAL *f2 = (REAL *)k; + REAL tmp = *f0; + *f0 = *f2; + *f2 = *f1; + *f1 = tmp; +} diff --git a/mesalib/src/glu/sgi/libnurbs/internals/flistsorter.h b/mesalib/src/glu/sgi/libnurbs/internals/flistsorter.h new file mode 100644 index 000000000..65e6a572e --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/flistsorter.h @@ -0,0 +1,53 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * flistsorter.h + * + */ + +#ifndef __gluflistsorter_h_ +#define __gluflistsorter_h_ + +#include "sorter.h" +#include "types.h" + +class FlistSorter : public Sorter { +public: + FlistSorter(void); + virtual ~FlistSorter() { /* silence warning*/ } + void qsort( REAL *a, int n ); + +protected: + virtual int qscmp( char *, char * ); + virtual void qsexc( char *i, char *j ); // i<-j, j<-i + virtual void qstexc( char *i, char *j, char *k ); // i<-k, k<-j, j<-i +}; +#endif /* __gluflistsorter_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/gridline.h b/mesalib/src/glu/sgi/libnurbs/internals/gridline.h new file mode 100644 index 000000000..1a92e3b13 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/gridline.h @@ -0,0 +1,46 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * gridline.h + * + */ + +#ifndef __glugridline_h_ +#define __glugridline_h_ + +struct Gridline { + long v; + REAL vval; + long vindex; + long ustart; + long uend; + }; +#endif /* __glugridline_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/gridtrimvertex.h b/mesalib/src/glu/sgi/libnurbs/internals/gridtrimvertex.h new file mode 100644 index 000000000..707f649d2 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/gridtrimvertex.h @@ -0,0 +1,89 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * gridtrimvertex.h + * + */ + +#ifndef __glugridtrimvertex_h_ +#define __glugridtrimvertex_h_ + +#include "mystdlib.h" +#include "bufpool.h" +#include "trimvertex.h" +#include "gridvertex.h" + +class GridTrimVertex : public PooledObj +{ +private: + TrimVertex dummyt; + GridVertex dummyg; +public: + GridTrimVertex() { g = 0; t = 0; } + TrimVertex *t; + GridVertex *g; + + inline void set( long, long ); + inline void set( REAL, REAL ); + inline void set( TrimVertex * ); + inline void clear( void ) { t = 0; g = 0; }; + inline int isGridVert() { return g ? 1 : 0 ; } + inline int isTrimVert() { return t ? 1 : 0 ; } + inline void output(); +}; + +inline void +GridTrimVertex::set( long x, long y ) +{ + g = &dummyg; + dummyg.gparam[0] = x; + dummyg.gparam[1] = y; +} + +inline void +GridTrimVertex::set( REAL x, REAL y ) +{ + g = 0; + t = &dummyt; + dummyt.param[0] = x; + dummyt.param[1] = y; + dummyt.nuid = 0; +} + +inline void +GridTrimVertex::set( TrimVertex *v ) +{ + g = 0; + t = v; +} + +typedef GridTrimVertex *GridTrimVertex_p; +#endif /* __glugridtrimvertex_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/gridvertex.h b/mesalib/src/glu/sgi/libnurbs/internals/gridvertex.h new file mode 100644 index 000000000..36a65c7bd --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/gridvertex.h @@ -0,0 +1,48 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * gridvertex.h + * + */ + +#ifndef __glugridvertex_h_ +#define __glugridvertex_h_ + +struct GridVertex { + long gparam[2]; + GridVertex( void ) {} + GridVertex( long u, long v ) { gparam[0] = u, gparam[1] = v; } + void set( long u, long v ) { gparam[0] = u, gparam[1] = v; } + long nextu() { return gparam[0]++; } + long prevu() { return gparam[0]--; } +}; + +#endif /* __glugridvertex_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/hull.cc b/mesalib/src/glu/sgi/libnurbs/internals/hull.cc new file mode 100644 index 000000000..389ba66fb --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/hull.cc @@ -0,0 +1,165 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * hull.c++ + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "hull.h" +#include "gridvertex.h" +#include "gridtrimvertex.h" +#include "gridline.h" +#include "trimline.h" +#include "uarray.h" +#include "trimregion.h" + +Hull::Hull( void ) +{} + +Hull::~Hull( void ) +{} + +/*---------------------------------------------------------------------- + * Hull:init - this routine does the initialization needed before any + * calls to nextupper or nextlower can be made. + *---------------------------------------------------------------------- + */ +void +Hull::init( void ) +{ + TrimVertex *lfirst = left.first(); + TrimVertex *llast = left.last(); + if( lfirst->param[0] <= llast->param[0] ) { + fakeleft.init( left.first() ); + upper.left = &fakeleft; + lower.left = &left; + } else { + fakeleft.init( left.last() ); + lower.left = &fakeleft; + upper.left = &left; + } + upper.left->last(); + lower.left->first(); + + if( top.ustart <= top.uend ) { + upper.line = ⊤ + upper.index = top.ustart; + } else + upper.line = 0; + + if( bot.ustart <= bot.uend ) { + lower.line = ⊥ + lower.index = bot.ustart; + } else + lower.line = 0; + + TrimVertex *rfirst = right.first(); + TrimVertex *rlast = right.last(); + if( rfirst->param[0] <= rlast->param[0] ) { + fakeright.init( right.last() ); + lower.right = &fakeright; + upper.right = &right; + } else { + fakeright.init( right.first() ); + upper.right = &fakeright; + lower.right = &right; + } + upper.right->first(); + lower.right->last(); +} + +/*---------------------------------------------------------------------- + * nextupper - find next vertex on upper hull of trim region. + * - if vertex is on trim curve, set vtop point to + * that vertex. if vertex is on grid, set vtop to + * point to temporary area and stuff coordinants into + * temporary vertex. Also, place grid coords in temporary + * grid vertex. + *---------------------------------------------------------------------- + */ +GridTrimVertex * +Hull::nextupper( GridTrimVertex *gv ) +{ + if( upper.left ) { + gv->set( upper.left->prev() ); + if( gv->isTrimVert() ) return gv; + upper.left = 0; + } + + if( upper.line ) { + assert( upper.index <= upper.line->uend ); + gv->set( uarray.uarray[upper.index], upper.line->vval ); + gv->set( upper.index, upper.line->vindex ); + if( upper.index++ == upper.line->uend ) upper.line = 0; + return gv; + } + + if( upper.right ) { + gv->set( upper.right->next() ); + if( gv->isTrimVert() ) return gv; + upper.right = 0; + } + + return 0; +} + +GridTrimVertex * +Hull::nextlower( register GridTrimVertex *gv ) +{ + if( lower.left ) { + gv->set( lower.left->next() ); + if( gv->isTrimVert() ) return gv; + lower.left = 0; + } + + if( lower.line ) { + gv->set( uarray.uarray[lower.index], lower.line->vval ); + gv->set( lower.index, lower.line->vindex ); + if( lower.index++ == lower.line->uend ) lower.line = 0; + return gv; + } + + if( lower.right ) { + gv->set( lower.right->prev() ); + if( gv->isTrimVert() ) return gv; + lower.right = 0; + } + + return 0; +} + diff --git a/mesalib/src/glu/sgi/libnurbs/internals/hull.h b/mesalib/src/glu/sgi/libnurbs/internals/hull.h new file mode 100644 index 000000000..dfe865267 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/hull.h @@ -0,0 +1,69 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * hull.h + * + */ + +#ifndef __gluhull_h_ +#define __gluhull_h_ + +#include "trimline.h" +#include "trimregion.h" +#include "trimvertex.h" +#include "gridtrimvertex.h" + +struct Gridline; +class Uarray; + +class Hull : virtual public TrimRegion { +public: + Hull( void ); + ~Hull( void ); + void init( void ); + GridTrimVertex * nextlower( GridTrimVertex * ); + GridTrimVertex * nextupper( GridTrimVertex * ); +private: + struct Side { + Trimline *left; + Gridline *line; + Trimline *right; + long index; + }; + + Side lower; + Side upper; + Trimline fakeleft; + Trimline fakeright; +}; + + +#endif /* __gluhull_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/intersect.cc b/mesalib/src/glu/sgi/libnurbs/internals/intersect.cc new file mode 100644 index 000000000..b39ea2121 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/intersect.cc @@ -0,0 +1,665 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * intersect.c++ + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "subdivider.h" +#include "arc.h" +#include "bin.h" +#include "backend.h" +#include "trimvertpool.h" + +/*#define NOTDEF*/ + +enum i_result { INTERSECT_VERTEX, INTERSECT_EDGE }; + +/* local functions */ +#ifndef NDEBUG // for asserts only +static int arc_classify( Arc_ptr, int, REAL ); +#endif +static enum i_result pwlarc_intersect( PwlArc *, int, REAL, int, int[3] ); + + +void +Subdivider::partition( Bin & bin, Bin & left, Bin & intersections, + Bin & right, Bin & unknown, int param, REAL value ) +{ + Bin headonleft, headonright, tailonleft, tailonright; + + for( Arc_ptr jarc = bin.removearc(); jarc; jarc = bin.removearc() ) { + + REAL tdiff = jarc->tail()[param] - value; + REAL hdiff = jarc->head()[param] - value; + + if( tdiff > 0.0 ) { + if( hdiff > 0.0 ) { + right.addarc( jarc ); + } else if( hdiff == 0.0 ) { + tailonright.addarc( jarc ); + } else { + Arc_ptr jtemp; + switch( arc_split(jarc, param, value, 0) ) { + case 2: + tailonright.addarc( jarc ); + headonleft.addarc( jarc->next ); + break; + case 31: + assert( jarc->head()[param] > value ); + right.addarc( jarc ); + tailonright.addarc( jtemp = jarc->next ); + headonleft.addarc( jtemp->next ); + break; + case 32: + assert( jarc->head()[param] <= value ); + tailonright .addarc( jarc ); + headonleft.addarc( jtemp = jarc->next ); + left.addarc( jtemp->next ); + break; + case 4: + right.addarc( jarc ); + tailonright.addarc( jtemp = jarc->next ); + headonleft.addarc( jtemp = jtemp->next ); + left.addarc( jtemp->next ); + } + } + } else if( tdiff == 0.0 ) { + if( hdiff > 0.0 ) { + headonright.addarc( jarc ); + } else if( hdiff == 0.0 ) { + unknown.addarc( jarc ); + } else { + headonleft.addarc( jarc ); + } + } else { + if( hdiff > 0.0 ) { + Arc_ptr jtemp; + switch( arc_split(jarc, param, value, 1) ) { + case 2: + tailonleft.addarc( jarc ); + headonright.addarc( jarc->next ); + break; + case 31: + assert( jarc->head()[param] < value ); + left.addarc( jarc ); + tailonleft.addarc( jtemp = jarc->next ); + headonright.addarc( jtemp->next ); + break; + case 32: + assert( jarc->head()[param] >= value ); + tailonleft.addarc( jarc ); + headonright.addarc( jtemp = jarc->next ); + right.addarc( jtemp->next ); + break; + case 4: + left.addarc( jarc ); + tailonleft.addarc( jtemp = jarc->next ); + headonright.addarc( jtemp = jtemp->next ); + right.addarc( jtemp->next ); + } + } else if( hdiff == 0.0 ) { + tailonleft.addarc( jarc ); + } else { + left.addarc( jarc ); + } + } + } + if( param == 0 ) { + classify_headonleft_s( headonleft, intersections, left, value ); + classify_tailonleft_s( tailonleft, intersections, left, value ); + classify_headonright_s( headonright, intersections, right, value ); + classify_tailonright_s( tailonright, intersections, right, value ); + } else { + classify_headonleft_t( headonleft, intersections, left, value ); + classify_tailonleft_t( tailonleft, intersections, left, value ); + classify_headonright_t( headonright, intersections, right, value ); + classify_tailonright_t( tailonright, intersections, right, value ); + } +} + +inline static void +vert_interp( TrimVertex *n, TrimVertex *l, TrimVertex *r, int p, REAL val ) +{ + assert( val > l->param[p]); + assert( val < r->param[p]); + + n->nuid = l->nuid; + + n->param[p] = val; + if( l->param[1-p] != r->param[1-p] ) { + REAL ratio = (val - l->param[p]) / (r->param[p] - l->param[p]); + n->param[1-p] = l->param[1-p] + + ratio * (r->param[1-p] - l->param[1-p]); + } else { + n->param[1-p] = l->param[1-p]; + } +} + +int +Subdivider::arc_split( Arc_ptr jarc, int param, REAL value, int dir ) +{ + int maxvertex = jarc->pwlArc->npts; + Arc_ptr jarc1; + TrimVertex* v = jarc->pwlArc->pts; + + int loc[3]; + switch( pwlarc_intersect( jarc->pwlArc, param, value, dir, loc ) ) { + + // When the parameter value lands on a vertex, life is sweet + case INTERSECT_VERTEX: { + jarc1 = new(arcpool) Arc( jarc, new( pwlarcpool) PwlArc( maxvertex-loc[1], &v[loc[1]] ) ); + jarc->pwlArc->npts = loc[1] + 1; + jarc1->next = jarc->next; + jarc1->next->prev = jarc1; + jarc->next = jarc1; + jarc1->prev = jarc; + assert(jarc->check() != 0); + return 2; + } + + // When the parameter value intersects an edge, we have to + // interpolate a new vertex. There are special cases + // if the new vertex is adjacent to one or both of the + // endpoints of the arc. + case INTERSECT_EDGE: { + int i, j; + if( dir == 0 ) { + i = loc[0]; + j = loc[2]; + } else { + i = loc[2]; + j = loc[0]; + } + +#ifndef NOTDEF + // The split is between vertices at index j and i, in that + // order (j < i) + + // JEB: This code is my idea of how to do the split without + // increasing the number of links. I'm doing this so that + // the is_rect routine can recognize rectangles created by + // subdivision. In exchange for simplifying the curve list, + // however, it costs in allocated space and vertex copies. + + TrimVertex *newjunk = trimvertexpool.get(maxvertex -i+1 /*-j*/); + int k; + for(k=0; k<maxvertex-i; k++) + { + newjunk[k+1] = v[i+k]; + newjunk[k+1].nuid = jarc->nuid; + } + + TrimVertex *vcopy = trimvertexpool.get(maxvertex); + for(k=0; k<maxvertex; k++) + { + vcopy[k].param[0] = v[k].param[0]; + vcopy[k].param[1] = v[k].param[1]; + } + jarc->pwlArc->pts=vcopy; + + v[i].nuid = jarc->nuid; + v[j].nuid = jarc->nuid; + vert_interp( &newjunk[0], &v[loc[0]], &v[loc[2]], param, value ); + + if( showingDegenerate() ) + backend.triangle( &v[i], &newjunk[0], &v[j] ); + + vcopy[j+1].param[0]=newjunk[0].param[0]; + vcopy[j+1].param[1]=newjunk[0].param[1]; + + + jarc1 = new(arcpool) Arc( jarc, + new(pwlarcpool) PwlArc(maxvertex-i+1 , newjunk ) ); + + jarc->pwlArc->npts = j+2; + jarc1->next = jarc->next; + jarc1->next->prev = jarc1; + jarc->next = jarc1; + jarc1->prev = jarc; + assert(jarc->check() != 0); + + return 2; +#endif //not NOTDEF + // JEB: This is the original version: +#ifdef NOTDEF + Arc_ptr jarc2, jarc3; + + TrimVertex *newjunk = trimvertexpool.get(3); + v[i].nuid = jarc->nuid; + v[j].nuid = jarc->nuid; + newjunk[0] = v[j]; + newjunk[2] = v[i]; + vert_interp( &newjunk[1], &v[loc[0]], &v[loc[2]], param, value ); + + if( showingDegenerate() ) + backend.triangle( &newjunk[2], &newjunk[1], &newjunk[0] ); + + // New vertex adjacent to both endpoints + if (maxvertex == 2) { + jarc1 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk+1 ) ); + jarc->pwlArc->npts = 2; + jarc->pwlArc->pts = newjunk; + jarc1->next = jarc->next; + jarc1->next->prev = jarc1; + jarc->next = jarc1; + jarc1->prev = jarc; + assert(jarc->check() != 0); + + return 2; + + // New vertex adjacent to ending point of arc + } else if (maxvertex - j == 2) { + jarc1 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk ) ); + jarc2 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk+1 ) ); + jarc->pwlArc->npts = maxvertex-1; + jarc2->next = jarc->next; + jarc2->next->prev = jarc2; + jarc->next = jarc1; + jarc1->prev = jarc; + jarc1->next = jarc2; + jarc2->prev = jarc1; + assert(jarc->check() != 0); + return 31; + + // New vertex adjacent to starting point of arc + } else if (i == 1) { + jarc1 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk+1 ) ); + jarc2 = new(arcpool) Arc( jarc, + new(pwlarcpool) PwlArc( maxvertex-1, &jarc->pwlArc->pts[1] ) ); + jarc->pwlArc->npts = 2; + jarc->pwlArc->pts = newjunk; + jarc2->next = jarc->next; + jarc2->next->prev = jarc2; + jarc->next = jarc1; + jarc1->prev = jarc; + jarc1->next = jarc2; + jarc2->prev = jarc1; + assert(jarc->check() != 0); + return 32; + + // It's somewhere in the middle + } else { + jarc1 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk ) ); + jarc2 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk+1 ) ); + jarc3 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( maxvertex-i, v+i ) ); + jarc->pwlArc->npts = j + 1; + jarc3->next = jarc->next; + jarc3->next->prev = jarc3; + jarc->next = jarc1; + jarc1->prev = jarc; + jarc1->next = jarc2; + jarc2->prev = jarc1; + jarc2->next = jarc3; + jarc3->prev = jarc2; + assert(jarc->check() != 0); + return 4; + } +#endif // NOTDEF + } + default: + return -1; //picked -1 since it's not used + } +} + +/*---------------------------------------------------------------------------- + * pwlarc_intersect - find intersection of pwlArc and isoparametric line + *---------------------------------------------------------------------------- + */ + +static enum i_result +pwlarc_intersect( + PwlArc *pwlArc, + int param, + REAL value, + int dir, + int loc[3] ) +{ + assert( pwlArc->npts > 0 ); + + if( dir ) { + TrimVertex *v = pwlArc->pts; + int imin = 0; + int imax = pwlArc->npts - 1; + assert( value > v[imin].param[param] ); + assert( value < v[imax].param[param] ); + while( (imax - imin) > 1 ) { + int imid = (imax + imin)/2; + if( v[imid].param[param] > value ) + imax = imid; + else if( v[imid].param[param] < value ) + imin = imid; + else { + loc[1] = imid; + return INTERSECT_VERTEX; + } + } + loc[0] = imin; + loc[2] = imax; + return INTERSECT_EDGE; + } else { + TrimVertex *v = pwlArc->pts; + int imax = 0; + int imin = pwlArc->npts - 1; + assert( value > v[imin].param[param] ); + assert( value < v[imax].param[param] ); + while( (imin - imax) > 1 ) { + int imid = (imax + imin)/2; + if( v[imid].param[param] > value ) + imax = imid; + else if( v[imid].param[param] < value ) + imin = imid; + else { + loc[1] = imid; + return INTERSECT_VERTEX; + } + } + loc[0] = imin; + loc[2] = imax; + return INTERSECT_EDGE; + } +} + +/*---------------------------------------------------------------------------- + * arc_classify - determine which side of a line a jarc lies + *---------------------------------------------------------------------------- + */ + +#ifndef NDEBUG // for asserts only +static int +arc_classify( Arc_ptr jarc, int param, REAL value ) +{ + REAL tdiff, hdiff; + if( param == 0 ) { + tdiff = jarc->tail()[0] - value; + hdiff = jarc->head()[0] - value; + } else { + tdiff = jarc->tail()[1] - value; + hdiff = jarc->head()[1] - value; + } + + if( tdiff > 0.0 ) { + if( hdiff > 0.0 ) { + return 0x11; + } else if( hdiff == 0.0 ) { + return 0x12; + } else { + return 0x10; + } + } else if( tdiff == 0.0 ) { + if( hdiff > 0.0 ) { + return 0x21; + } else if( hdiff == 0.0 ) { + return 0x22; + } else { + return 0x20; + } + } else { + if( hdiff > 0.0 ) { + return 0x01; + } else if( hdiff == 0.0 ) { + return 0x02; + } else { + return 0; + } + } +} +#endif + +void +Subdivider::classify_tailonleft_s( Bin& bin, Bin& in, Bin& out, REAL val ) +{ + /* tail at left, head on line */ + Arc_ptr j; + + while( (j = bin.removearc()) != NULL ) { + assert( arc_classify( j, 0, val ) == 0x02 ); + j->clearitail(); + + REAL diff = j->next->head()[0] - val; + if( diff > 0.0 ) { + in.addarc( j ); + } else if( diff < 0.0 ) { + if( ccwTurn_sl( j, j->next ) ) + out.addarc( j ); + else + in.addarc( j ); + } else { + if( j->next->tail()[1] > j->next->head()[1] ) + in.addarc(j); + else + out.addarc(j); + } + } +} + +void +Subdivider::classify_tailonleft_t( Bin& bin, Bin& in, Bin& out, REAL val ) +{ + /* tail at left, head on line */ + Arc_ptr j; + + while( (j = bin.removearc()) != NULL ) { + assert( arc_classify( j, 1, val ) == 0x02 ); + j->clearitail(); + + REAL diff = j->next->head()[1] - val; + if( diff > 0.0 ) { + in.addarc( j ); + } else if( diff < 0.0 ) { + if( ccwTurn_tl( j, j->next ) ) + out.addarc( j ); + else + in.addarc( j ); + } else { + if (j->next->tail()[0] > j->next->head()[0] ) + out.addarc( j ); + else + in.addarc( j ); + } + } +} + +void +Subdivider::classify_headonleft_s( Bin& bin, Bin& in, Bin& out, REAL val ) +{ + /* tail on line, head at left */ + Arc_ptr j; + + while( (j = bin.removearc()) != NULL ) { + assert( arc_classify( j, 0, val ) == 0x20 ); + + j->setitail(); + + REAL diff = j->prev->tail()[0] - val; + if( diff > 0.0 ) { + out.addarc( j ); + } else if( diff < 0.0 ) { + if( ccwTurn_sl( j->prev, j ) ) + out.addarc( j ); + else + in.addarc( j ); + } else { + if( j->prev->tail()[1] > j->prev->head()[1] ) + in.addarc( j ); + else + out.addarc( j ); + } + } +} + +void +Subdivider::classify_headonleft_t( Bin& bin, Bin& in, Bin& out, REAL val ) +{ + /* tail on line, head at left */ + Arc_ptr j; + + while( (j = bin.removearc()) != NULL ) { + assert( arc_classify( j, 1, val ) == 0x20 ); + j->setitail(); + + REAL diff = j->prev->tail()[1] - val; + if( diff > 0.0 ) { + out.addarc( j ); + } else if( diff < 0.0 ) { + if( ccwTurn_tl( j->prev, j ) ) + out.addarc( j ); + else + in.addarc( j ); + } else { + if( j->prev->tail()[0] > j->prev->head()[0] ) + out.addarc( j ); + else + in.addarc( j ); + } + } +} + + +void +Subdivider::classify_tailonright_s( Bin& bin, Bin& in, Bin& out, REAL val ) +{ + /* tail at right, head on line */ + Arc_ptr j; + + while( (j = bin.removearc()) != NULL ) { + assert( arc_classify( j, 0, val ) == 0x12); + + j->clearitail(); + + REAL diff = j->next->head()[0] - val; + if( diff > 0.0 ) { + if( ccwTurn_sr( j, j->next ) ) + out.addarc( j ); + else + in.addarc( j ); + } else if( diff < 0.0 ) { + in.addarc( j ); + } else { + if( j->next->tail()[1] > j->next->head()[1] ) + out.addarc( j ); + else + in.addarc( j ); + } + } +} + +void +Subdivider::classify_tailonright_t( Bin& bin, Bin& in, Bin& out, REAL val ) +{ + /* tail at right, head on line */ + Arc_ptr j; + + while( (j = bin.removearc()) != NULL ) { + assert( arc_classify( j, 1, val ) == 0x12); + + j->clearitail(); + + REAL diff = j->next->head()[1] - val; + if( diff > 0.0 ) { + if( ccwTurn_tr( j, j->next ) ) + out.addarc( j ); + else + in.addarc( j ); + } else if( diff < 0.0 ) { + in.addarc( j ); + } else { + if( j->next->tail()[0] > j->next->head()[0] ) + in.addarc( j ); + else + out.addarc( j ); + } + } +} + +void +Subdivider::classify_headonright_s( Bin& bin, Bin& in, Bin& out, REAL val ) +{ + /* tail on line, head at right */ + Arc_ptr j; + + while( (j = bin.removearc()) != NULL ) { + assert( arc_classify( j, 0, val ) == 0x21 ); + + j->setitail(); + + REAL diff = j->prev->tail()[0] - val; + if( diff > 0.0 ) { + if( ccwTurn_sr( j->prev, j ) ) + out.addarc( j ); + else + in.addarc( j ); + } else if( diff < 0.0 ) { + out.addarc( j ); + } else { + if( j->prev->tail()[1] > j->prev->head()[1] ) + out.addarc( j ); + else + in.addarc( j ); + } + } +} + +void +Subdivider::classify_headonright_t( Bin& bin, Bin& in, Bin& out, REAL val ) +{ + /* tail on line, head at right */ + Arc_ptr j; + + while( (j = bin.removearc()) != NULL ) { + assert( arc_classify( j, 1, val ) == 0x21 ); + + j->setitail(); + + REAL diff = j->prev->tail()[1] - val; + if( diff > 0.0 ) { + if( ccwTurn_tr( j->prev, j ) ) + out.addarc( j ); + else + in.addarc( j ); + } else if( diff < 0.0 ) { + out.addarc( j ); + } else { + if( j->prev->tail()[0] > j->prev->head()[0] ) + in.addarc( j ); + else + out.addarc( j ); + } + } +} + diff --git a/mesalib/src/glu/sgi/libnurbs/internals/jarcloc.h b/mesalib/src/glu/sgi/libnurbs/internals/jarcloc.h new file mode 100644 index 000000000..5297036fa --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/jarcloc.h @@ -0,0 +1,87 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * jarcloc.h + * + */ + +#ifndef __glujarcloc_h_ +#define __glujarcloc_h_ + +#include "arc.h" + +class Jarcloc { +private: + Arc_ptr arc; + TrimVertex *p; + TrimVertex *plast; +public: + inline void init( Arc_ptr a, long first, long last ) { arc = a; p=&a->pwlArc->pts[first]; plast = &a->pwlArc->pts[last]; } + inline TrimVertex * getnextpt( void ); + inline TrimVertex * getprevpt( void ); + inline void reverse(); +}; + +inline void +Jarcloc::reverse() +{ + if( plast == &arc->pwlArc->pts[0] ) + plast = &arc->pwlArc->pts[arc->pwlArc->npts - 1]; + else + plast = &arc->pwlArc->pts[0]; +} + +inline TrimVertex * +Jarcloc::getnextpt() +{ + assert( p <= plast ); + if( p == plast ) { + arc = arc->next; + p = &arc->pwlArc->pts[0]; + plast = &arc->pwlArc->pts[arc->pwlArc->npts - 1]; + assert( p < plast ); + } + return p++; +} + +inline TrimVertex * +Jarcloc::getprevpt() +{ + assert( p >= plast ); + if( p == plast ) { + arc = arc->prev; + p = &arc->pwlArc->pts[arc->pwlArc->npts - 1]; + plast = &arc->pwlArc->pts[0]; + assert( p > plast ); + } + return p--; +} +#endif /* __glujarcloc_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/knotvector.cc b/mesalib/src/glu/sgi/libnurbs/internals/knotvector.cc new file mode 100644 index 000000000..9eb5cbace --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/knotvector.cc @@ -0,0 +1,139 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * knotvector.c++ + * + */ + +#include "glimports.h" +#include "mystdio.h" +#include "myassert.h" +#include "knotvector.h" +#include "defines.h" + +#ifdef __WATCOMC__ +#pragma warning 726 10 +#endif + +void Knotvector::init( long _knotcount, long _stride, long _order, INREAL *_knotlist ) +{ + knotcount = _knotcount; + stride = _stride; + order = _order; + knotlist = new Knot[_knotcount]; + assert( knotlist != 0 ); + + for( int i = 0; i != _knotcount; i++ ) + knotlist[i] = (Knot) _knotlist[i]; +} + +Knotvector::Knotvector( void ) +{ + knotlist = 0; +} + +Knotvector::~Knotvector( void ) +{ + if( knotlist ) delete[] knotlist; +} + +int Knotvector::validate( void ) +{ + /* kindex is used as an array index so subtract one first, + * this propagates throughout the code so study carefully */ + long kindex = knotcount-1; + + if( order < 1 || order > MAXORDER ) { + // spline order un-supported + return( 1 ); + } + + if( knotcount < (2 * order) ) { + // too few knots + return( 2 ); + } + + if( identical( knotlist[kindex-(order-1)], knotlist[order-1]) ) { + // valid knot range is empty + return( 3 ); + } + + for( long i = 0; i < kindex; i++) + if( knotlist[i] > knotlist[i+1] ) { + // decreasing knot sequence + return( 4 ); + } + + /* check for valid multiplicity */ + + /* kindex is currently the index of the last knot. + * In the next loop it is decremented to ignore the last knot + * and the loop stops when kindex is 2 so as to ignore the first + * knot as well. These knots are not used in computing + * knot multiplicities. + */ + + long multi = 1; + for( ; kindex >= 1; kindex-- ) { + if( knotlist[kindex] - knotlist[kindex-1] < TOLERANCE ) { + multi++; + continue; + } + if ( multi > order ) { + // knot multiplicity greater than order of spline + return( 5 ); + } + multi = 1; + } + + if ( multi > order ) { + // knot multiplicity greater than order of spline + return( 5 ); + } + + return 0; +} + +void Knotvector::show( const char *msg ) +{ +#ifndef NDEBUG + _glu_dprintf( "%s\n", msg ); + _glu_dprintf( "order = %ld, count = %ld\n", order, knotcount ); + + for( int i=0; i<knotcount; i++ ) + _glu_dprintf( "knot[%d] = %g\n", i, knotlist[i] ); +#endif +} + diff --git a/mesalib/src/glu/sgi/libnurbs/internals/knotvector.h b/mesalib/src/glu/sgi/libnurbs/internals/knotvector.h new file mode 100644 index 000000000..85b162f6f --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/knotvector.h @@ -0,0 +1,62 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * knotvector.h + * + */ + +#ifndef __gluknotvector_h_ +#define __gluknotvector_h_ + +#include "types.h" + +struct Knotvector { /* a knot vector */ + Knotvector( void ); + ~Knotvector( void ); + void init( long, long, long, INREAL * ); + int validate( void ); + void show( const char * ); + + long order; /* order of spline */ + long knotcount; /* number of knots */ + long stride; /* bytes between points */ + Knot * knotlist; /* global knot vector */ +}; + +/* tolerance to test knot coincidence */ +#define TOLERANCE 1.0e-5 + +inline int +identical( Knot x, Knot y ) +{ + return ((x-y) < TOLERANCE) ? 1 : 0; +} +#endif /* __gluknotvector_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/mapdesc.cc b/mesalib/src/glu/sgi/libnurbs/internals/mapdesc.cc new file mode 100644 index 000000000..d59f8fd39 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/mapdesc.cc @@ -0,0 +1,841 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * mapdesc.c++ + * + */ + +#include <stdio.h> +#include "glimports.h" +#include "mystdio.h" +#include "myassert.h" +#include "mystring.h" +#include "mymath.h" +#include "backend.h" +#include "nurbsconsts.h" +#include "mapdesc.h" + +Mapdesc::Mapdesc( long _type, int _israt, int _ncoords, Backend& b ) + : backend( b ) +{ + type = _type; + isrational = _israt; + ncoords = _ncoords; + hcoords = _ncoords + (_israt ? 0 : 1 ); + inhcoords = _ncoords - (_israt ? 1 : 0 ); + mask = ((1<<(inhcoords*2))-1); + next = 0; + + assert( hcoords <= MAXCOORDS ); + assert( inhcoords >= 1 ); + + pixel_tolerance = 1.0; + error_tolerance = 1.0; + bbox_subdividing = N_NOBBOXSUBDIVISION; + culling_method = N_NOCULLING; + sampling_method = N_NOSAMPLING; + clampfactor = N_NOCLAMPING; + minsavings = N_NOSAVINGSSUBDIVISION; + s_steps = 0.0; + t_steps = 0.0; + maxrate = ( s_steps < 0.0 ) ? 0.0 : s_steps; + maxsrate = ( s_steps < 0.0 ) ? 0.0 : s_steps; + maxtrate = ( t_steps < 0.0 ) ? 0.0 : t_steps; + identify( bmat ); + identify( cmat ); + identify( smat ); + for( int i = 0; i != inhcoords; i++ ) + bboxsize[i] = 1.0; +} + +void +Mapdesc::setBboxsize( INREAL *mat ) +{ + for( int i = 0; i != inhcoords; i++ ) + bboxsize[i] = (REAL) mat[i]; +} + +void +Mapdesc::identify( REAL dest[MAXCOORDS][MAXCOORDS] ) +{ + memset( dest, 0, sizeof( dest ) ); + for( int i=0; i != hcoords; i++ ) + dest[i][i] = 1.0; +} + +void +Mapdesc::surfbbox( REAL bb[2][MAXCOORDS] ) +{ + backend.surfbbox( type, bb[0], bb[1] ); +} + +void +Mapdesc::copy( REAL dest[MAXCOORDS][MAXCOORDS], long n, INREAL *src, + long rstride, long cstride ) +{ + assert( n >= 0 ); + for( int i=0; i != n; i++ ) + for( int j=0; j != n; j++ ) + dest[i][j] = src[i*rstride + j*cstride]; +} + +/*-------------------------------------------------------------------------- + * copyPt - copy a homogeneous point + *-------------------------------------------------------------------------- + */ +void +Mapdesc::copyPt( REAL *d, REAL *s ) +{ + assert( hcoords > 0 ); + switch( hcoords ) { + case 4: + d[3] = s[3]; + d[2] = s[2]; + d[1] = s[1]; + d[0] = s[0]; + break; + case 3: + d[2] = s[2]; + d[1] = s[1]; + d[0] = s[0]; + break; + case 2: + d[1] = s[1]; + d[0] = s[0]; + break; + case 1: + d[0] = s[0]; + break; + case 5: + d[4] = s[4]; + d[3] = s[3]; + d[2] = s[2]; + d[1] = s[1]; + d[0] = s[0]; + break; + default: + memcpy( d, s, hcoords * sizeof( REAL ) ); + break; + } +} + +/*-------------------------------------------------------------------------- + * sumPt - compute affine combination of two homogeneous points + *-------------------------------------------------------------------------- + */ +void +Mapdesc::sumPt( REAL *dst, REAL *src1, REAL *src2, register REAL alpha, register REAL beta ) +{ + assert( hcoords > 0 ); + switch( hcoords ) { + case 4: + dst[3] = src1[3] * alpha + src2[3] * beta; + dst[2] = src1[2] * alpha + src2[2] * beta; + dst[1] = src1[1] * alpha + src2[1] * beta; + dst[0] = src1[0] * alpha + src2[0] * beta; + break; + case 3: + dst[2] = src1[2] * alpha + src2[2] * beta; + dst[1] = src1[1] * alpha + src2[1] * beta; + dst[0] = src1[0] * alpha + src2[0] * beta; + break; + case 2: + dst[1] = src1[1] * alpha + src2[1] * beta; + dst[0] = src1[0] * alpha + src2[0] * beta; + break; + case 1: + dst[0] = src1[0] * alpha + src2[0] * beta; + break; + case 5: + dst[4] = src1[4] * alpha + src2[4] * beta; + dst[3] = src1[3] * alpha + src2[3] * beta; + dst[2] = src1[2] * alpha + src2[2] * beta; + dst[1] = src1[1] * alpha + src2[1] * beta; + dst[0] = src1[0] * alpha + src2[0] * beta; + break; + default: { + for( int i = 0; i != hcoords; i++ ) + dst[i] = src1[i] * alpha + src2[i] * beta; + } + break; + } +} + +/*-------------------------------------------------------------------------- + * clipbits - compute bit-vector indicating point/window position + * of a (transformed) homogeneous point + *-------------------------------------------------------------------------- + */ +unsigned int +Mapdesc::clipbits( REAL *p ) +{ + assert( inhcoords >= 0 ); + assert( inhcoords <= 3 ); + + register int nc = inhcoords; + register REAL pw = p[nc]; + register REAL nw = -pw; + register unsigned int bits = 0; + + if( pw == 0.0 ) return mask; + + if( pw > 0.0 ) { + switch( nc ) { + case 3: + if( p[2] <= pw ) bits |= (1<<5); + if( p[2] >= nw ) bits |= (1<<4); + if( p[1] <= pw ) bits |= (1<<3); + if( p[1] >= nw ) bits |= (1<<2); + if( p[0] <= pw ) bits |= (1<<1); + if( p[0] >= nw ) bits |= (1<<0); + return bits; + case 2: + if( p[1] <= pw ) bits |= (1<<3); + if( p[1] >= nw ) bits |= (1<<2); + if( p[0] <= pw ) bits |= (1<<1); + if( p[0] >= nw ) bits |= (1<<0); + return bits; + case 1: + if( p[0] <= pw ) bits |= (1<<1); + if( p[0] >= nw ) bits |= (1<<0); + return bits; + default: { + int bit = 1; + for( int i=0; i<nc; i++ ) { + if( p[i] >= nw ) bits |= bit; + bit <<= 1; + if( p[i] <= pw ) bits |= bit; + bit <<= 1; + } + abort(); + break; + } + } + } else { + switch( nc ) { + case 3: + if( p[2] <= nw ) bits |= (1<<5); + if( p[2] >= pw ) bits |= (1<<4); + if( p[1] <= nw ) bits |= (1<<3); + if( p[1] >= pw ) bits |= (1<<2); + if( p[0] <= nw ) bits |= (1<<1); + if( p[0] >= pw ) bits |= (1<<0); + return bits; + case 2: + if( p[1] <= nw ) bits |= (1<<3); + if( p[1] >= pw ) bits |= (1<<2); + if( p[0] <= nw ) bits |= (1<<1); + if( p[0] >= pw ) bits |= (1<<0); + return bits; + case 1: + if( p[0] <= nw ) bits |= (1<<1); + if( p[0] >= pw ) bits |= (1<<0); + return bits; + default: { + int bit = 1; + for( int i=0; i<nc; i++ ) { + if( p[i] >= pw ) bits |= bit; + bit <<= 1; + if( p[i] <= nw ) bits |= bit; + bit <<= 1; + } + abort(); + break; + } + } + } + return bits; +} + +/*-------------------------------------------------------------------------- + * xformRational - transform a homogeneous point + *-------------------------------------------------------------------------- + */ +void +Mapdesc::xformRational( Maxmatrix mat, REAL *d, REAL *s ) +{ + assert( hcoords >= 0 ); + + if( hcoords == 3 ) { + REAL x = s[0]; + REAL y = s[1]; + REAL z = s[2]; + d[0] = x*mat[0][0]+y*mat[1][0]+z*mat[2][0]; + d[1] = x*mat[0][1]+y*mat[1][1]+z*mat[2][1]; + d[2] = x*mat[0][2]+y*mat[1][2]+z*mat[2][2]; + } else if( hcoords == 4 ) { + REAL x = s[0]; + REAL y = s[1]; + REAL z = s[2]; + REAL w = s[3]; + d[0] = x*mat[0][0]+y*mat[1][0]+z*mat[2][0]+w*mat[3][0]; + d[1] = x*mat[0][1]+y*mat[1][1]+z*mat[2][1]+w*mat[3][1]; + d[2] = x*mat[0][2]+y*mat[1][2]+z*mat[2][2]+w*mat[3][2]; + d[3] = x*mat[0][3]+y*mat[1][3]+z*mat[2][3]+w*mat[3][3]; + } else { + for( int i=0; i != hcoords; i++ ) { + d[i] = 0; + for( int j = 0; j != hcoords; j++ ) + d[i] += s[j] * mat[j][i]; + } + } +} + +/*-------------------------------------------------------------------------- + * xformNonrational - transform a inhomogeneous point to a homogeneous point + *-------------------------------------------------------------------------- + */ +void +Mapdesc::xformNonrational( Maxmatrix mat, REAL *d, REAL *s ) +{ + if( inhcoords == 2 ) { + REAL x = s[0]; + REAL y = s[1]; + d[0] = x*mat[0][0]+y*mat[1][0]+mat[2][0]; + d[1] = x*mat[0][1]+y*mat[1][1]+mat[2][1]; + d[2] = x*mat[0][2]+y*mat[1][2]+mat[2][2]; + } else if( inhcoords == 3 ) { + REAL x = s[0]; + REAL y = s[1]; + REAL z = s[2]; + d[0] = x*mat[0][0]+y*mat[1][0]+z*mat[2][0]+mat[3][0]; + d[1] = x*mat[0][1]+y*mat[1][1]+z*mat[2][1]+mat[3][1]; + d[2] = x*mat[0][2]+y*mat[1][2]+z*mat[2][2]+mat[3][2]; + d[3] = x*mat[0][3]+y*mat[1][3]+z*mat[2][3]+mat[3][3]; + } else { + assert( inhcoords >= 0 ); + for( int i=0; i != hcoords; i++ ) { + d[i] = mat[inhcoords][i]; + for( int j = 0; j < inhcoords; j++ ) + d[i] += s[j] * mat[j][i]; + } + } +} + +/*-------------------------------------------------------------------------- + * xformAndCullCheck - transform a set of points that may be EITHER + * homogeneous or inhomogeneous depending on the map description and + * check if they are either completely inside, completely outside, + * or intersecting the viewing frustrum. + *-------------------------------------------------------------------------- + */ +int +Mapdesc::xformAndCullCheck( + REAL *pts, int uorder, int ustride, int vorder, int vstride ) +{ + assert( uorder > 0 ); + assert( vorder > 0 ); + + unsigned int inbits = mask; + unsigned int outbits = 0; + + REAL *p = pts; + for( REAL *pend = p + uorder * ustride; p != pend; p += ustride ) { + REAL *q = p; + for( REAL *qend = q + vorder * vstride; q != qend; q += vstride ) { + REAL cpts[MAXCOORDS]; + xformCulling( cpts, q ); + unsigned int bits = clipbits( cpts ); + outbits |= bits; + inbits &= bits; + if( ( outbits == (unsigned int)mask ) && ( inbits != (unsigned int)mask ) ) return CULL_ACCEPT; + } + } + + if( outbits != (unsigned int)mask ) { + return CULL_TRIVIAL_REJECT; + } else if( inbits == (unsigned int)mask ) { + return CULL_TRIVIAL_ACCEPT; + } else { + return CULL_ACCEPT; + } +} + +/*-------------------------------------------------------------------------- + * cullCheck - check if a set of homogeneous transformed points are + * either completely inside, completely outside, + * or intersecting the viewing frustrum. + *-------------------------------------------------------------------------- + */ +int +Mapdesc::cullCheck( REAL *pts, int uorder, int ustride, int vorder, int vstride ) +{ + unsigned int inbits = mask; + unsigned int outbits = 0; + + REAL *p = pts; + for( REAL *pend = p + uorder * ustride; p != pend; p += ustride ) { + REAL *q = p; + for( REAL *qend = q + vorder * vstride; q != qend; q += vstride ) { + unsigned int bits = clipbits( q ); + outbits |= bits; + inbits &= bits; + if( ( outbits == (unsigned int)mask ) && ( inbits != (unsigned int)mask ) ) return CULL_ACCEPT; + } + } + + if( outbits != (unsigned int)mask ) { + return CULL_TRIVIAL_REJECT; + } else if( inbits == (unsigned int)mask ) { + return CULL_TRIVIAL_ACCEPT; + } else { + return CULL_ACCEPT; + } +} + +/*-------------------------------------------------------------------------- + * cullCheck - check if a set of homogeneous transformed points are + * either completely inside, completely outside, + * or intersecting the viewing frustrum. + *-------------------------------------------------------------------------- + */ +int +Mapdesc::cullCheck( REAL *pts, int order, int stride ) +{ + unsigned int inbits = mask; + unsigned int outbits = 0; + + REAL *p = pts; + for( REAL *pend = p + order * stride; p != pend; p += stride ) { + unsigned int bits = clipbits( p ); + outbits |= bits; + inbits &= bits; + if( ( outbits == (unsigned int)mask ) && ( inbits != (unsigned int)mask ) ) return CULL_ACCEPT; + } + + if( outbits != (unsigned int)mask ) { + return CULL_TRIVIAL_REJECT; + } else if( inbits == (unsigned int)mask ) { + return CULL_TRIVIAL_ACCEPT; + } else { + return CULL_ACCEPT; + } +} + +/*-------------------------------------------------------------------------- + * xformSampling - transform a set of points that may be EITHER + * homogeneous or inhomogeneous depending on the map description + * into sampling space + *-------------------------------------------------------------------------- + */ +void +Mapdesc::xformSampling( REAL *pts, int order, int stride, REAL *sp, int outstride ) +{ + xformMat( smat, pts, order, stride, sp, outstride ); +} + +void +Mapdesc::xformBounding( REAL *pts, int order, int stride, REAL *sp, int outstride ) +{ + xformMat( bmat, pts, order, stride, sp, outstride ); +} + +/*-------------------------------------------------------------------------- + * xformCulling - transform a set of points that may be EITHER + * homogeneous or inhomogeneous depending on the map description + * into culling space + *-------------------------------------------------------------------------- + */ +void +Mapdesc::xformCulling( REAL *pts, int order, int stride, REAL *cp, int outstride ) +{ + xformMat( cmat, pts, order, stride, cp, outstride ); +} + +/*-------------------------------------------------------------------------- + * xformCulling - transform a set of points that may be EITHER + * homogeneous or inhomogeneous depending on the map description + * into culling space + *-------------------------------------------------------------------------- + */ +void +Mapdesc::xformCulling( REAL *pts, + int uorder, int ustride, + int vorder, int vstride, + REAL *cp, int outustride, int outvstride ) +{ + xformMat( cmat, pts, uorder, ustride, vorder, vstride, cp, outustride, outvstride ); +} + +/*-------------------------------------------------------------------------- + * xformSampling - transform a set of points that may be EITHER + * homogeneous or inhomogeneous depending on the map description + * into sampling space + *-------------------------------------------------------------------------- + */ +void +Mapdesc::xformSampling( REAL *pts, + int uorder, int ustride, + int vorder, int vstride, + REAL *sp, int outustride, int outvstride ) +{ + xformMat( smat, pts, uorder, ustride, vorder, vstride, sp, outustride, outvstride ); +} + +void +Mapdesc::xformBounding( REAL *pts, + int uorder, int ustride, + int vorder, int vstride, + REAL *sp, int outustride, int outvstride ) +{ + xformMat( bmat, pts, uorder, ustride, vorder, vstride, sp, outustride, outvstride ); +} + +void +Mapdesc::xformMat( + Maxmatrix mat, + REAL * pts, + int order, + int stride, + REAL * cp, + int outstride ) +{ + if( isrational ) { + REAL *pend = pts + order * stride; + for( REAL *p = pts ; p != pend; p += stride ) { + xformRational( mat, cp, p ); + cp += outstride; + } + } else { + REAL *pend = pts + order * stride; + for( REAL *p = pts ; p != pend; p += stride ) { + xformNonrational( mat, cp, p ); + cp += outstride; + } + } +} + +void +Mapdesc::xformMat( Maxmatrix mat, REAL *pts, + int uorder, int ustride, + int vorder, int vstride, + REAL *cp, int outustride, int outvstride ) +{ + if( isrational ) { + REAL *pend = pts + uorder * ustride; + for( REAL *p = pts ; p != pend; p += ustride ) { + REAL *cpts2 = cp; + REAL *qend = p + vorder * vstride; + for( REAL *q = p; q != qend; q += vstride ) { + xformRational( mat, cpts2, q ); + cpts2 += outvstride; + } + cp += outustride; + } + } else { + REAL *pend = pts + uorder * ustride; + for( REAL *p = pts ; p != pend; p += ustride ) { + REAL *cpts2 = cp; + REAL *qend = p + vorder * vstride; + for( REAL *q = p; q != qend; q += vstride ) { + xformNonrational( mat, cpts2, q ); + cpts2 += outvstride; + } + cp += outustride; + } + } +} + +/*-------------------------------------------------------------------------- + * subdivide - subdivide a curve along an isoparametric line + *-------------------------------------------------------------------------- + */ + +void +Mapdesc::subdivide( REAL *src, REAL *dst, REAL v, int stride, int order ) +{ + REAL mv = 1.0 - v; + + for( REAL *send=src+stride*order; src!=send; send-=stride, dst+=stride ) { + copyPt( dst, src ); + REAL *qpnt = src + stride; + for( REAL *qp=src; qpnt!=send; qp=qpnt, qpnt+=stride ) + sumPt( qp, qp, qpnt, mv, v ); + } +} + +/*-------------------------------------------------------------------------- + * subdivide - subdivide a patch along an isoparametric line + *-------------------------------------------------------------------------- + */ + +void +Mapdesc::subdivide( REAL *src, REAL *dst, REAL v, + int so, int ss, int to, int ts ) +{ + REAL mv = 1.0 - v; + + for( REAL *slast = src+ss*so; src != slast; src += ss, dst += ss ) { + REAL *sp = src; + REAL *dp = dst; + for( REAL *send = src+ts*to; sp != send; send -= ts, dp += ts ) { + copyPt( dp, sp ); + REAL *qp = sp; + for( REAL *qpnt = sp+ts; qpnt != send; qp = qpnt, qpnt += ts ) + sumPt( qp, qp, qpnt, mv, v ); + } + } +} + + +#define sign(x) ((x > 0) ? 1 : ((x < 0.0) ? -1 : 0)) + +/*-------------------------------------------------------------------------- + * project - project a set of homogeneous coordinates into inhomogeneous ones + *-------------------------------------------------------------------------- + */ +int +Mapdesc::project( REAL *src, int rstride, int cstride, + REAL *dest, int trstride, int tcstride, + int nrows, int ncols ) +{ + int s = sign( src[inhcoords] ); + REAL *rlast = src + nrows * rstride; + REAL *trptr = dest; + for( REAL *rptr=src; rptr != rlast; rptr+=rstride, trptr+=trstride ) { + REAL *clast = rptr + ncols * cstride; + REAL *tcptr = trptr; + for( REAL *cptr = rptr; cptr != clast; cptr+=cstride, tcptr+=tcstride ) { + REAL *coordlast = cptr + inhcoords; + if( sign( *coordlast ) != s ) return 0; + REAL *tcoord = tcptr; + for( REAL *coord = cptr; coord != coordlast; coord++, tcoord++ ) { + *tcoord = *coord / *coordlast; + } + } + } + return 1; +} + +/*-------------------------------------------------------------------------- + * project - project a set of homogeneous coordinates into inhomogeneous ones + *-------------------------------------------------------------------------- + */ +int +Mapdesc::project( REAL *src, int stride, REAL *dest, int tstride, int ncols ) +{ + int s = sign( src[inhcoords] ); + + REAL *clast = src + ncols * stride; + for( REAL *cptr = src, *tcptr = dest; cptr != clast; cptr+=stride, tcptr+=tstride ) { + REAL *coordlast = cptr + inhcoords; + if( sign( *coordlast ) != s ) return 0; + for( REAL *coord = cptr, *tcoord = tcptr; coord != coordlast; coord++, tcoord++ ) + *tcoord = *coord / *coordlast; + } + + return 1; +} + +int +Mapdesc::bboxTooBig( + REAL *p, + int rstride, + int cstride, + int nrows, + int ncols, + REAL bb[2][MAXCOORDS] ) +{ + REAL bbpts[MAXORDER][MAXORDER][MAXCOORDS]; + const int trstride = sizeof(bbpts[0]) / sizeof(REAL); + const int tcstride = sizeof(bbpts[0][0]) / sizeof(REAL); + + // points have been transformed, therefore they are homogeneous + // project points + int val = project( p, rstride, cstride, + &bbpts[0][0][0], trstride, tcstride, nrows, ncols ); + if( val == 0 ) return -1; + + // compute bounding box + bbox( bb, &bbpts[0][0][0], trstride, tcstride, nrows, ncols ); + + // find out if bounding box can't fit in unit cube + if( bbox_subdividing == N_BBOXROUND ) { + for( int k=0; k != inhcoords; k++ ) + if( ceilf(bb[1][k]) - floorf(bb[0][k]) > bboxsize[k] ) return 1; + } else { + for( int k=0; k != inhcoords; k++ ) + if( bb[1][k] - bb[0][k] > bboxsize[k] ) return 1; + } + return 0; +} + +void +Mapdesc::bbox( + REAL bb[2][MAXCOORDS], + REAL *p, + int rstride, + int cstride, + int nrows, + int ncols ) +{ + int k; + for( k=0; k != inhcoords; k++ ) + bb[0][k] = bb[1][k] = p[k]; + + for( int i=0; i != nrows; i++ ) + for( int j=0; j != ncols; j++ ) + for( k=0; k != inhcoords; k++ ) { + REAL x = p[i*rstride + j*cstride + k]; + if( x < bb[0][k] ) bb[0][k] = x; + else if( x > bb[1][k] ) bb[1][k] = x; + } +} + +/*-------------------------------------------------------------------------- + * calcVelocityRational - calculate upper bound on first partial derivative + * of a homogeneous set of points and bounds on each row of points. + *-------------------------------------------------------------------------- + */ +REAL +Mapdesc::calcVelocityRational( REAL *p, int stride, int ncols ) +{ + REAL tmp[MAXORDER][MAXCOORDS]; + + assert( ncols <= MAXORDER ); + + const int tstride = sizeof(tmp[0]) / sizeof(REAL); + + if( project( p, stride, &tmp[0][0], tstride, ncols ) ) { + return calcPartialVelocity( &tmp[0][0], tstride, ncols, 1, 1.0 ); + } else { /* XXX */ + return calcPartialVelocity( &tmp[0][0], tstride, ncols, 1, 1.0 ); + } +} + +/*-------------------------------------------------------------------------- + * calcVelocityNonrational - calculate upper bound on first partial + * derivative of a inhomogeneous set of points. + *-------------------------------------------------------------------------- + */ +REAL +Mapdesc::calcVelocityNonrational( REAL *pts, int stride, int ncols ) +{ + return calcPartialVelocity( pts, stride, ncols, 1, 1.0 ); +} + +int +Mapdesc::isProperty( long property ) +{ + switch ( property ) { + case N_PIXEL_TOLERANCE: + case N_ERROR_TOLERANCE: + case N_CULLING: + case N_BBOX_SUBDIVIDING: + case N_S_STEPS: + case N_T_STEPS: + case N_SAMPLINGMETHOD: + case N_CLAMPFACTOR: + case N_MINSAVINGS: + return 1; + default: + return 0; + } +} + +REAL +Mapdesc::getProperty( long property ) +{ + switch ( property ) { + case N_PIXEL_TOLERANCE: + return pixel_tolerance; + case N_ERROR_TOLERANCE: + return error_tolerance; + case N_CULLING: + return culling_method; + case N_BBOX_SUBDIVIDING: + return bbox_subdividing; + case N_S_STEPS: + return s_steps; + case N_T_STEPS: + return t_steps; + case N_SAMPLINGMETHOD: + return sampling_method; + case N_CLAMPFACTOR: + return clampfactor; + case N_MINSAVINGS: + return minsavings; + default: + abort(); + return -1; //not necessary, needed to shut up compiler + } +} + +void +Mapdesc::setProperty( long property, REAL value ) +{ + + switch ( property ) { + case N_PIXEL_TOLERANCE: + pixel_tolerance = value; + break; + case N_ERROR_TOLERANCE: + error_tolerance = value; + break; + case N_CULLING: + culling_method = value; + break; + case N_BBOX_SUBDIVIDING: + if( value <= 0.0 ) value = N_NOBBOXSUBDIVISION; + bbox_subdividing = value; + break; + case N_S_STEPS: + if( value < 0.0 ) value = 0.0; + s_steps = value; + maxrate = ( value < 0.0 ) ? 0.0 : value; + maxsrate = ( value < 0.0 ) ? 0.0 : value; + break; + case N_T_STEPS: + if( value < 0.0 ) value = 0.0; + t_steps = value; + maxtrate = ( value < 0.0 ) ? 0.0 : value; + break; + case N_SAMPLINGMETHOD: + sampling_method = value; + break; + case N_CLAMPFACTOR: + if( value <= 0.0 ) value = N_NOCLAMPING; + clampfactor = value; + break; + case N_MINSAVINGS: + if( value <= 0.0 ) value = N_NOSAVINGSSUBDIVISION; + minsavings = value; + break; + default: + abort(); + break; + } +} + diff --git a/mesalib/src/glu/sgi/libnurbs/internals/mapdesc.h b/mesalib/src/glu/sgi/libnurbs/internals/mapdesc.h new file mode 100644 index 000000000..6f06154f9 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/mapdesc.h @@ -0,0 +1,271 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * mapdesc.h + * + */ + +#ifndef __glumapdesc_h_ +#define __glumapdesc_h_ + +#include "mystdio.h" +#include "types.h" +#include "defines.h" +#include "bufpool.h" +#include "nurbsconsts.h" + +typedef REAL Maxmatrix[MAXCOORDS][MAXCOORDS]; + +class Backend; + +class Mapdesc : public PooledObj { + friend class Maplist; + +public: + Mapdesc( long, int, int, Backend & ); + int isProperty( long ); + REAL getProperty( long ); + void setProperty( long, REAL ); + int isConstantSampling( void ); + int isDomainSampling( void ); + int isRangeSampling( void ); + int isSampling( void ); + int isParametricDistanceSampling( void ); + int isObjectSpaceParaSampling( void ); + int isObjectSpacePathSampling( void ); + int isSurfaceAreaSampling( void ); + int isPathLengthSampling( void ); + int isCulling( void ); + int isBboxSubdividing( void ); + long getType( void ); + + /* curve routines */ + void subdivide( REAL *, REAL *, REAL, int, int ); + int cullCheck( REAL *, int, int ); + void xformBounding( REAL *, int, int, REAL *, int ); + void xformCulling( REAL *, int, int, REAL *, int ); + void xformSampling( REAL *, int, int, REAL *, int ); + void xformMat( Maxmatrix, REAL *, int, int, REAL *, int ); + REAL calcPartialVelocity ( REAL *, int, int, int, REAL ); + int project( REAL *, int, REAL *, int, int ); + REAL calcVelocityRational( REAL *, int, int ); + REAL calcVelocityNonrational( REAL *, int, int ); + + /* surface routines */ + void subdivide( REAL *, REAL *, REAL, int, int, int, int ); + int cullCheck( REAL *, int, int, int, int ); + void xformBounding( REAL *, int, int, int, int, REAL *, int, int ); + void xformCulling( REAL *, int, int, int, int, REAL *, int, int ); + void xformSampling( REAL *, int, int, int, int, REAL *, int, int ); + void xformMat( Maxmatrix, REAL *, int, int, int, int, REAL *, int, int ); + REAL calcPartialVelocity ( REAL *, REAL *, int, int, int, int, int, int, REAL, REAL, int ); + int project( REAL *, int, int, REAL *, int, int, int, int); + void surfbbox( REAL bb[2][MAXCOORDS] ); + + int bboxTooBig( REAL *, int, int, int, int, REAL [2][MAXCOORDS] ); + int xformAndCullCheck( REAL *, int, int, int, int ); + + void identify( REAL[MAXCOORDS][MAXCOORDS] ); + void setBboxsize( INREAL *); + inline void setBmat( INREAL*, long, long ); + inline void setCmat( INREAL*, long, long ); + inline void setSmat( INREAL*, long, long ); + inline int isRational( void ); + inline int getNcoords( void ); + + REAL pixel_tolerance; /* pathlength sampling tolerance */ + REAL error_tolerance; /* parametric error sampling tolerance*/ + REAL object_space_error_tolerance; /* object space tess*/ + REAL clampfactor; + REAL minsavings; + REAL maxrate; + REAL maxsrate; + REAL maxtrate; + REAL bboxsize[MAXCOORDS]; + +private: + long type; + int isrational; + int ncoords; + int hcoords; + int inhcoords; + int mask; + Maxmatrix bmat; + Maxmatrix cmat; + Maxmatrix smat; + REAL s_steps; /* max samples in s direction */ + REAL t_steps; /* max samples in t direction */ + REAL sampling_method; + REAL culling_method; /* check for culling */ + REAL bbox_subdividing; + Mapdesc * next; + Backend & backend; + + void bbox( REAL [2][MAXCOORDS], REAL *, int, int, int, int ); + REAL maxDifference( int, REAL *, int ); + static void copy( Maxmatrix, long, INREAL *, long, long ); + + /* individual control point routines */ + static void transform4d( float[4], float[4], float[4][4] ); + static void multmatrix4d ( float[4][4], const float[4][4], + const float[4][4] ); + void copyPt( REAL *, REAL * ); + void sumPt( REAL *, REAL *, REAL *, REAL, REAL ); + void xformSampling( REAL *, REAL * ); + void xformCulling( REAL *, REAL * ); + void xformRational( Maxmatrix, REAL *, REAL * ); + void xformNonrational( Maxmatrix, REAL *, REAL * ); + unsigned int clipbits( REAL * ); +}; + +inline void +Mapdesc::setBmat( INREAL *mat, long rstride, long cstride ) +{ + copy( bmat, hcoords, mat, rstride, cstride ); +} + +inline void +Mapdesc::setCmat( INREAL *mat, long rstride, long cstride ) +{ + copy( cmat, hcoords, mat, rstride, cstride ); +} + +inline void +Mapdesc::setSmat( INREAL *mat, long rstride, long cstride ) +{ + copy( smat, hcoords, mat, rstride, cstride ); +} + +inline long +Mapdesc::getType( void ) +{ + return type; +} + +inline void +Mapdesc::xformCulling( REAL *d, REAL *s ) +{ + if( isrational ) + xformRational( cmat, d, s ); + else + xformNonrational( cmat, d, s ); +} + +inline void +Mapdesc::xformSampling( REAL *d, REAL *s ) +{ + if( isrational ) + xformRational( smat, d, s ); + else + xformNonrational( smat, d, s ); +} + +inline int +Mapdesc::isRational( void ) +{ + return isrational ? 1 : 0; +} + +inline int +Mapdesc::getNcoords( void ) +{ + return ncoords; +} + +inline int +Mapdesc::isConstantSampling( void ) +{ + return ((sampling_method == N_FIXEDRATE) ? 1 : 0); +} + +inline int +Mapdesc::isDomainSampling( void ) +{ + return ((sampling_method == N_DOMAINDISTANCE) ? 1 : 0); +} + +inline int +Mapdesc::isParametricDistanceSampling( void ) +{ + return ((sampling_method == N_PARAMETRICDISTANCE) ? 1 : 0); +} + +inline int +Mapdesc::isObjectSpaceParaSampling( void ) +{ + return ((sampling_method == N_OBJECTSPACE_PARA) ? 1 : 0); +} + +inline int +Mapdesc::isObjectSpacePathSampling( void ) +{ + return ((sampling_method == N_OBJECTSPACE_PATH) ? 1 : 0); +} + +inline int +Mapdesc::isSurfaceAreaSampling( void ) +{ + return ((sampling_method == N_SURFACEAREA) ? 1 : 0); +} + +inline int +Mapdesc::isPathLengthSampling( void ) +{ + return ((sampling_method == N_PATHLENGTH) ? 1 : 0); +} + +inline int +Mapdesc::isRangeSampling( void ) +{ + return ( isParametricDistanceSampling() || isPathLengthSampling() || + isSurfaceAreaSampling() || + isObjectSpaceParaSampling() || + isObjectSpacePathSampling()); +} + +inline int +Mapdesc::isSampling( void ) +{ + return isRangeSampling() || isConstantSampling() || isDomainSampling(); +} + +inline int +Mapdesc::isCulling( void ) +{ + return ((culling_method != N_NOCULLING) ? 1 : 0); +} + +inline int +Mapdesc::isBboxSubdividing( void ) +{ + return ((bbox_subdividing != N_NOBBOXSUBDIVISION) ? 1 : 0); +} +#endif /* __glumapdesc_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/mapdescv.cc b/mesalib/src/glu/sgi/libnurbs/internals/mapdescv.cc new file mode 100644 index 000000000..35b38b141 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/mapdescv.cc @@ -0,0 +1,243 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * mapdescv.c++ + * + */ + +#include "glimports.h" +#include "mystdio.h" +#include "myassert.h" +#include "mystring.h" +#include "mymath.h" +#include "nurbsconsts.h" +#include "mapdesc.h" + +/*-------------------------------------------------------------------------- + * calcPartialVelocity - calculate maximum magnitude of a given partial + * derivative + *-------------------------------------------------------------------------- + */ +REAL +Mapdesc::calcPartialVelocity ( + REAL *p, + int stride, + int ncols, + int partial, + REAL range ) +{ + REAL tmp[MAXORDER][MAXCOORDS]; + REAL mag[MAXORDER]; + + assert( ncols <= MAXORDER ); + + int j, k, t; + // copy inhomogeneous control points into temporary array + for( j=0; j != ncols; j++ ) + for( k=0; k != inhcoords; k++ ) + tmp[j][k] = p[j*stride + k]; + + for( t=0; t != partial; t++ ) + for( j=0; j != ncols-t-1; j++ ) + for( k=0; k != inhcoords; k++ ) + tmp[j][k] = tmp[j+1][k] - tmp[j][k]; + + // compute magnitude and store in mag array + for( j=0; j != ncols-partial; j++ ) { + mag[j] = 0.0; + for( k=0; k != inhcoords; k++ ) + mag[j] += tmp[j][k] * tmp[j][k]; + } + + // compute scale factor + REAL fac = 1; + REAL invt = 1.0 / range; + for( t = ncols-1; t != ncols-1-partial; t-- ) + fac *= t * invt; + + // compute max magnitude of all entries in array + REAL max = 0.0; + for( j=0; j != ncols-partial; j++ ) + if( mag[j] > max ) max = mag[j]; + max = fac * sqrtf( (float) max ); + + return max; +} + +/*-------------------------------------------------------------------------- + * calcPartialVelocity - calculate maximum magnitude of a given partial + * derivative + *-------------------------------------------------------------------------- + */ +REAL +Mapdesc::calcPartialVelocity ( + REAL *dist, + REAL *p, + int rstride, + int cstride, + int nrows, + int ncols, + int spartial, + int tpartial, + REAL srange, + REAL trange, + int side ) +{ + REAL tmp[MAXORDER][MAXORDER][MAXCOORDS]; + REAL mag[MAXORDER][MAXORDER]; + + assert( nrows <= MAXORDER ); + assert( ncols <= MAXORDER ); + + REAL *tp = &tmp[0][0][0]; + REAL *mp = &mag[0][0]; + const int istride = sizeof( tmp[0]) / sizeof( tmp[0][0][0] ); + const int jstride = sizeof( tmp[0][0]) / sizeof( tmp[0][0][0] ); + /* + const int kstride = sizeof( tmp[0][0][0]) / sizeof( tmp[0][0][0] ); + */ + const int mistride = sizeof( mag[0]) / sizeof( mag[0][0] ); + const int mjstride = sizeof( mag[0][0]) / sizeof( mag[0][0] ); + const int idist = nrows * istride; + const int jdist = ncols * jstride; + /* + const int kdist = inhcoords * kstride; + */ + const int id = idist - spartial * istride; + const int jd = jdist - tpartial * jstride; + + { + // copy control points + REAL *ti = tp; + REAL *qi = p; + REAL *til = tp + idist; + for( ; ti != til; ) { + REAL *tj = ti; + REAL *qj = qi; + REAL *tjl = ti + jdist; + for( ; tj != tjl; ) { + for( int k=0; k != inhcoords; k++ ) { + tj[k] = qj[k]; + } + tj += jstride; + qj += cstride; + } + ti += istride; + qi += rstride; + } + } + + { + // compute (s)-partial derivative control points + REAL *til = tp + idist - istride; + const REAL *till = til - ( spartial * istride ); + for( ; til != till; til -= istride ) + for( REAL *ti = tp; ti != til; ti += istride ) + for( REAL *tj = ti, *tjl = tj + jdist; tj != tjl; tj += jstride ) + for( int k=0; k != inhcoords; k++ ) + tj[k] = tj[k+istride] - tj[k]; + } + + { + // compute (s,t)-partial derivative control points + REAL *tjl = tp + jdist - jstride; + const REAL *tjll = tjl - ( tpartial * jstride ); + for( ; tjl != tjll; tjl -= jstride ) + for( REAL *tj = tp; tj != tjl; tj += jstride ) + for( REAL *ti = tj, *til = ti + id; ti != til; ti += istride ) + for( int k=0; k != inhcoords; k++ ) + ti[k] = ti[k+jstride] - ti[k]; + + } + + REAL max = 0.0; + { + // compute magnitude and store in mag array + memset( (void *) mp, 0, sizeof( mag ) ); + for( REAL *ti = tp, *mi = mp, *til = tp + id; ti != til; ti += istride, mi += mistride ) + for( REAL *tj = ti, *mj = mi, *tjl = ti + jd; tj != tjl; tj += jstride, mj += mjstride ) { + for( int k=0; k != inhcoords; k++ ) + *mj += tj[k] * tj[k]; + if( *mj > max ) max = *mj; + } + + } + + int i, j; + + // compute scale factor + REAL fac = 1.0; + { + REAL invs = 1.0 / srange; + REAL invt = 1.0 / trange; + for( int s = nrows-1, slast = s-spartial; s != slast; s-- ) + fac *= s * invs; + for( int t = ncols-1, tlast = t-tpartial; t != tlast; t-- ) + fac *= t * invt; + } + + if( side == 0 ) { + // compute max magnitude of first and last column + dist[0] = 0.0; + dist[1] = 0.0; + for( i=0; i != nrows-spartial; i++ ) { + j = 0; + if( mag[i][j] > dist[0] ) dist[0] = mag[i][j]; + + j = ncols-tpartial-1; + if( mag[i][j] > dist[1] ) dist[1] = mag[i][j]; + } + dist[0] = fac * sqrtf( dist[0] ); + dist[1] = fac * sqrtf( dist[1] ); + } else if( side == 1 ) { + // compute max magnitude of first and last row + dist[0] = 0.0; + dist[1] = 0.0; + for( j=0; j != ncols-tpartial; j++ ) { + i = 0; + if( mag[i][j] > dist[0] ) dist[0] = mag[i][j]; + + i = nrows-spartial-1; + if( mag[i][j] > dist[1] ) dist[1] = mag[i][j]; + } + dist[0] = fac * sqrtf( dist[0] ); + dist[1] = fac * sqrtf( dist[1] ); + } + + max = fac * sqrtf( (float) max ); + + return max; +} + diff --git a/mesalib/src/glu/sgi/libnurbs/internals/maplist.cc b/mesalib/src/glu/sgi/libnurbs/internals/maplist.cc new file mode 100644 index 000000000..f944d1529 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/maplist.cc @@ -0,0 +1,117 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * maplist.c++ + * + */ + +#include "glimports.h" +#include "mystdio.h" +#include "myassert.h" +#include "mymath.h" +#include "nurbsconsts.h" +#include "maplist.h" +#include "mapdesc.h" +#include "backend.h" + +Maplist::Maplist( Backend& b ) + : mapdescPool( sizeof( Mapdesc ), 10, "mapdesc pool" ), + backend( b ) +{ + maps = 0; lastmap = &maps; +} + +void +Maplist::initialize( void ) +{ + freeMaps(); + define( N_P2D, 0, 2 ); + define( N_P2DR, 1, 3 ); +} + +void +Maplist::add( long type, int israt, int ncoords ) +{ + *lastmap = new(mapdescPool) Mapdesc( type, israt, ncoords, backend ); + lastmap = &((*lastmap)->next); +} + +void +Maplist::define( long type, int israt, int ncoords ) +{ +#ifndef NDEBUG // to avoid warning + Mapdesc *m = locate( type ); + assert( m == NULL || ( m->isrational == israt && m->ncoords == ncoords ) ); +#endif + add( type, israt, ncoords ); +} + +void +Maplist::remove( Mapdesc *m ) +{ + for( Mapdesc **curmap = &maps; *curmap; curmap = &((*curmap)->next) ) { + if( *curmap == m ) { + *curmap = m->next; + m->deleteMe( mapdescPool ); + return; + } + } + abort(); +} + +void +Maplist::freeMaps( void ) +{ + mapdescPool.clear(); + maps = 0; + lastmap = &maps; +} + +Mapdesc * +Maplist::find( long type ) +{ + Mapdesc *val = locate( type ); + assert( val != 0 ); + return val; +} + +Mapdesc * +Maplist::locate( long type ) +{ + Mapdesc *m; + for( m = maps; m; m = m->next ) + if( m->getType() == type ) break; + return m; +} diff --git a/mesalib/src/glu/sgi/libnurbs/internals/maplist.h b/mesalib/src/glu/sgi/libnurbs/internals/maplist.h new file mode 100644 index 000000000..49720e49b --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/maplist.h @@ -0,0 +1,81 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * maplist.h + * + */ + +#ifndef __glumaplist_h_ +#define __glumaplist_h_ + +#include "types.h" +#include "defines.h" +#include "bufpool.h" + +class Backend; +class Mapdesc; + +class Maplist { +public: + Maplist( Backend & ); + void define( long, int, int ); + inline void undefine( long ); + inline int isMap( long ); + + void initialize( void ); + Mapdesc * find( long ); + Mapdesc * locate( long ); + +private: + Pool mapdescPool; + Mapdesc * maps; + Mapdesc ** lastmap; + Backend & backend; + + void add( long, int, int ); + void remove( Mapdesc * ); + void freeMaps( void ); +}; + +inline int +Maplist::isMap( long type ) +{ + return (locate( type ) ? 1 : 0); +} + +inline void +Maplist::undefine( long type ) +{ + Mapdesc *m = locate( type ); + assert( m != 0 ); + remove( m ); +} +#endif /* __glumaplist_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/mesher.cc b/mesalib/src/glu/sgi/libnurbs/internals/mesher.cc new file mode 100644 index 000000000..9cc436adb --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/mesher.cc @@ -0,0 +1,486 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * mesher.c++ + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "gridvertex.h" +#include "gridtrimvertex.h" +#include "jarcloc.h" +#include "gridline.h" +#include "trimline.h" +#include "uarray.h" +#include "backend.h" +#include "mesher.h" + + +const float Mesher::ZERO = 0.0; + +Mesher::Mesher( Backend& b ) + : backend( b ), + p( sizeof( GridTrimVertex ), 100, "GridTrimVertexPool" ) +{ + stacksize = 0; + vdata = 0; + lastedge = 0; //needed to prevent purify UMR +} + +Mesher::~Mesher( void ) +{ + if( vdata ) delete[] vdata; +} + +void +Mesher::init( unsigned int npts ) +{ + p.clear(); + if( stacksize < npts ) { + stacksize = 2 * npts; + if( vdata ) delete[] vdata; + vdata = new GridTrimVertex_p[stacksize]; + } +} + +inline void +Mesher::push( GridTrimVertex *gt ) +{ + assert( itop+1 != (int)stacksize ); + vdata[++itop] = gt; +} + +inline void +Mesher::pop( long ) +{ +} + +inline void +Mesher::openMesh() +{ + backend.bgntmesh( "addedge" ); +} + +inline void +Mesher::closeMesh() +{ + backend.endtmesh(); +} + +inline void +Mesher::swapMesh() +{ + backend.swaptmesh(); +} + +inline void +Mesher::clearStack() +{ + itop = -1; + last[0] = 0; +} + +void +Mesher::finishLower( GridTrimVertex *gtlower ) +{ + for( push(gtlower); + nextlower( gtlower=new(p) GridTrimVertex ); + push(gtlower) ) + addLower(); + addLast(); +} + +void +Mesher::finishUpper( GridTrimVertex *gtupper ) +{ + for( push(gtupper); + nextupper( gtupper=new(p) GridTrimVertex ); + push(gtupper) ) + addUpper(); + addLast(); +} + +void +Mesher::mesh( void ) +{ + GridTrimVertex *gtlower, *gtupper; + + Hull::init( ); + nextupper( gtupper = new(p) GridTrimVertex ); + nextlower( gtlower = new(p) GridTrimVertex ); + + clearStack(); + openMesh(); + push(gtupper); + + nextupper( gtupper = new(p) GridTrimVertex ); + nextlower( gtlower ); + + assert( gtupper->t && gtlower->t ); + + if( gtupper->t->param[0] < gtlower->t->param[0] ) { + push(gtupper); + lastedge = 1; + if( nextupper( gtupper=new(p) GridTrimVertex ) == 0 ) { + finishLower(gtlower); + return; + } + } else if( gtupper->t->param[0] > gtlower->t->param[0] ) { + push(gtlower); + lastedge = 0; + if( nextlower( gtlower=new(p) GridTrimVertex ) == 0 ) { + finishUpper(gtupper); + return; + } + } else { + if( lastedge == 0 ) { + push(gtupper); + lastedge = 1; + if( nextupper(gtupper=new(p) GridTrimVertex) == 0 ) { + finishLower(gtlower); + return; + } + } else { + push(gtlower); + lastedge = 0; + if( nextlower( gtlower=new(p) GridTrimVertex ) == 0 ) { + finishUpper(gtupper); + return; + } + } + } + + while ( 1 ) { + if( gtupper->t->param[0] < gtlower->t->param[0] ) { + push(gtupper); + addUpper(); + if( nextupper( gtupper=new(p) GridTrimVertex ) == 0 ) { + finishLower(gtlower); + return; + } + } else if( gtupper->t->param[0] > gtlower->t->param[0] ) { + push(gtlower); + addLower(); + if( nextlower( gtlower=new(p) GridTrimVertex ) == 0 ) { + finishUpper(gtupper); + return; + } + } else { + if( lastedge == 0 ) { + push(gtupper); + addUpper(); + if( nextupper( gtupper=new(p) GridTrimVertex ) == 0 ) { + finishLower(gtlower); + return; + } + } else { + push(gtlower); + addLower(); + if( nextlower( gtlower=new(p) GridTrimVertex ) == 0 ) { + finishUpper(gtupper); + return; + } + } + } + } +} + +inline int +Mesher::isCcw( int ilast ) +{ + REAL area = det3( vdata[ilast]->t, vdata[itop-1]->t, vdata[itop-2]->t ); + return (area < ZERO) ? 0 : 1; +} + +inline int +Mesher::isCw( int ilast ) +{ + REAL area = det3( vdata[ilast]->t, vdata[itop-1]->t, vdata[itop-2]->t ); + return (area > -ZERO) ? 0 : 1; +} + +inline int +Mesher::equal( int x, int y ) +{ + return( last[0] == vdata[x] && last[1] == vdata[y] ); +} + +inline void +Mesher::copy( int x, int y ) +{ + last[0] = vdata[x]; last[1] = vdata[y]; +} + +inline void +Mesher::move( int x, int y ) +{ + vdata[x] = vdata[y]; +} + +inline void +Mesher::output( int x ) +{ + backend.tmeshvert( vdata[x] ); +} + +/*--------------------------------------------------------------------------- + * addedge - addedge an edge to the triangulation + * + * This code has been re-written to generate large triangle meshes + * from a monotone polygon. Although smaller triangle meshes + * could be generated faster and with less code, larger meshes + * actually give better SYSTEM performance. This is because + * vertices are processed in the backend slower than they are + * generated by this code and any decrease in the number of vertices + * results in a decrease in the time spent in the backend. + *--------------------------------------------------------------------------- + */ + +void +Mesher::addLast( ) +{ + register int ilast = itop; + + if( lastedge == 0 ) { + if( equal( 0, 1 ) ) { + output( ilast ); + swapMesh(); + for( register int i = 2; i < ilast; i++ ) { + swapMesh(); + output( i ); + } + copy( ilast, ilast-1 ); + } else if( equal( ilast-2, ilast-1) ) { + swapMesh(); + output( ilast ); + for( register int i = ilast-3; i >= 0; i-- ) { + output( i ); + swapMesh(); + } + copy( 0, ilast ); + } else { + closeMesh(); openMesh(); + output( ilast ); + output( 0 ); + for( register int i = 1; i < ilast; i++ ) { + swapMesh(); + output( i ); + } + copy( ilast, ilast-1 ); + } + } else { + if( equal( 1, 0) ) { + swapMesh(); + output( ilast ); + for( register int i = 2; i < ilast; i++ ) { + output( i ); + swapMesh(); + } + copy( ilast-1, ilast ); + } else if( equal( ilast-1, ilast-2) ) { + output( ilast ); + swapMesh(); + for( register int i = ilast-3; i >= 0; i-- ) { + swapMesh(); + output( i ); + } + copy( ilast, 0 ); + } else { + closeMesh(); openMesh(); + output( 0 ); + output( ilast ); + for( register int i = 1; i < ilast; i++ ) { + output( i ); + swapMesh(); + } + copy( ilast-1, ilast ); + } + } + closeMesh(); + //for( register long k=0; k<=ilast; k++ ) pop( k ); +} + +void +Mesher::addUpper( ) +{ + register int ilast = itop; + + if( lastedge == 0 ) { + if( equal( 0, 1 ) ) { + output( ilast ); + swapMesh(); + for( register int i = 2; i < ilast; i++ ) { + swapMesh(); + output( i ); + } + copy( ilast, ilast-1 ); + } else if( equal( ilast-2, ilast-1) ) { + swapMesh(); + output( ilast ); + for( register int i = ilast-3; i >= 0; i-- ) { + output( i ); + swapMesh(); + } + copy( 0, ilast ); + } else { + closeMesh(); openMesh(); + output( ilast ); + output( 0 ); + for( register int i = 1; i < ilast; i++ ) { + swapMesh(); + output( i ); + } + copy( ilast, ilast-1 ); + } + lastedge = 1; + //for( register long k=0; k<ilast-1; k++ ) pop( k ); + move( 0, ilast-1 ); + move( 1, ilast ); + itop = 1; + } else { + if( ! isCcw( ilast ) ) return; + do { + itop--; + } while( (itop > 1) && isCcw( ilast ) ); + + if( equal( ilast-1, ilast-2 ) ) { + output( ilast ); + swapMesh(); + for( register int i=ilast-3; i>=itop-1; i-- ) { + swapMesh(); + output( i ); + } + copy( ilast, itop-1 ); + } else if( equal( itop, itop-1 ) ) { + swapMesh(); + output( ilast ); + for( register int i = itop+1; i < ilast; i++ ) { + output( i ); + swapMesh(); + } + copy( ilast-1, ilast ); + } else { + closeMesh(); openMesh(); + output( ilast ); + output( ilast-1 ); + for( register int i=ilast-2; i>=itop-1; i-- ) { + swapMesh(); + output( i ); + } + copy( ilast, itop-1 ); + } + //for( register int k=itop; k<ilast; k++ ) pop( k ); + move( itop, ilast ); + } +} + +void +Mesher::addLower() +{ + register int ilast = itop; + + if( lastedge == 1 ) { + if( equal( 1, 0) ) { + swapMesh(); + output( ilast ); + for( register int i = 2; i < ilast; i++ ) { + output( i ); + swapMesh(); + } + copy( ilast-1, ilast ); + } else if( equal( ilast-1, ilast-2) ) { + output( ilast ); + swapMesh(); + for( register int i = ilast-3; i >= 0; i-- ) { + swapMesh(); + output( i ); + } + copy( ilast, 0 ); + } else { + closeMesh(); openMesh(); + output( 0 ); + output( ilast ); + for( register int i = 1; i < ilast; i++ ) { + output( i ); + swapMesh(); + } + copy( ilast-1, ilast ); + } + + lastedge = 0; + //for( register long k=0; k<ilast-1; k++ ) pop( k ); + move( 0, ilast-1 ); + move( 1, ilast ); + itop = 1; + } else { + if( ! isCw( ilast ) ) return; + do { + itop--; + } while( (itop > 1) && isCw( ilast ) ); + + if( equal( ilast-2, ilast-1) ) { + swapMesh(); + output( ilast ); + for( register int i=ilast-3; i>=itop-1; i--) { + output( i ); + swapMesh( ); + } + copy( itop-1, ilast ); + } else if( equal( itop-1, itop) ) { + output( ilast ); + swapMesh(); + for( register int i=itop+1; i<ilast; i++ ) { + swapMesh( ); + output( i ); + } + copy( ilast, ilast-1 ); + } else { + closeMesh(); openMesh(); + output( ilast-1 ); + output( ilast ); + for( register int i=ilast-2; i>=itop-1; i-- ) { + output( i ); + swapMesh( ); + } + copy( itop-1, ilast ); + } + //for( register int k=itop; k<ilast; k++ ) pop( k ); + move( itop, ilast ); + } +} + + diff --git a/mesalib/src/glu/sgi/libnurbs/internals/mesher.h b/mesalib/src/glu/sgi/libnurbs/internals/mesher.h new file mode 100644 index 000000000..bb65d0f1c --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/mesher.h @@ -0,0 +1,83 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * mesher.h + * + */ + +#ifndef __glumesher_h_ +#define __glumesher_h_ + +#include "hull.h" + +class TrimRegion; +class Backend; +class Pool; +// struct GridTrimVertex; + + +class Mesher : virtual public TrimRegion, public Hull { +public: + Mesher( Backend & ); + ~Mesher( void ); + void init( unsigned int ); + void mesh( void ); + +private: + static const float ZERO; + Backend& backend; + + Pool p; + unsigned int stacksize; + GridTrimVertex ** vdata; + GridTrimVertex * last[2]; + int itop; + int lastedge; + + inline void openMesh( void ); + inline void swapMesh( void ); + inline void closeMesh( void ); + inline int isCcw( int ); + inline int isCw( int ); + inline void clearStack( void ); + inline void push( GridTrimVertex * ); + inline void pop( long ); + inline void move( int, int ); + inline int equal( int, int ); + inline void copy( int, int ); + inline void output( int ); + void addUpper( void ); + void addLower( void ); + void addLast( void ); + void finishUpper( GridTrimVertex * ); + void finishLower( GridTrimVertex * ); +}; +#endif /* __glumesher_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/monoTriangulationBackend.cc b/mesalib/src/glu/sgi/libnurbs/internals/monoTriangulationBackend.cc new file mode 100644 index 000000000..2830cc743 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/monoTriangulationBackend.cc @@ -0,0 +1,397 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include "monoTriangulation.h" +#include "polyUtil.h" +#include "backend.h" +#include "arc.h" + +void reflexChain::outputFan(Real v[2], Backend* backend) +{ + Int i; + /* + TrimVertex trimVert; + */ + backend->bgntfan(); + + /* + trimVert.param[0]=v[0]; + trimVert.param[1]=v[1]; + backend->tmeshvert(&trimVert); + */ + backend->tmeshvert(v[0], v[1]); + + if(isIncreasing) { + for(i=0; i<index_queue; i++) + { + /* + trimVert.param[0]=queue[i][0]; + trimVert.param[1]=queue[i][1]; + backend->tmeshvert(&trimVert); + */ + backend->tmeshvert(queue[i][0], queue[i][1]); + } + } + else { + for(i=index_queue-1; i>=0; i--) + { + /* + trimVert.param[0]=queue[i][0]; + trimVert.param[1]=queue[i][1]; + backend->tmeshvert(&trimVert); + */ + backend->tmeshvert(queue[i][0], queue[i][1]); + } + } + backend->endtfan(); +} + +void reflexChain::processNewVertex(Real v[2], Backend* backend) +{ + Int i,j,k; + Int isReflex; + /*TrimVertex trimVert;*/ + /*if there are at most one vertex in the queue, then simply insert + */ + if(index_queue <=1){ + insert(v); + return; + } + + /*there are at least two vertices in the queue*/ + j=index_queue-1; + + for(i=j; i>=1; i--) { + if(isIncreasing) { + isReflex = (area(queue[i-1], queue[i], v) <= 0.0); + } + else /*decreasing*/{ + isReflex = (area(v, queue[i], queue[i-1]) <= 0.0); + } + if(isReflex) { + break; + } + } + + /* + *if i<j then vertices: i+1--j are convex + * output triangle fan: + * v, and queue[i], i+1, ..., j + */ + if(i<j) + { + backend->bgntfan(); + /* + trimVert.param[0]=v[0]; + trimVert.param[1]=v[1]; + backend->tmeshvert(& trimVert); + */ + backend->tmeshvert(v[0], v[1]); + + if(isIncreasing) { + for(k=i; k<=j; k++) + { + /* + trimVert.param[0]=queue[k][0]; + trimVert.param[1]=queue[k][1]; + backend->tmeshvert(& trimVert); + */ + backend->tmeshvert(queue[k][0], queue[k][1]); + } + } + else { + for(k=j; k>=i; k--) + { + /* + trimVert.param[0]=queue[k][0]; + trimVert.param[1]=queue[k][1]; + backend->tmeshvert(& trimVert); + */ + backend->tmeshvert(queue[k][0], queue[k][1]); + } + } + + backend->endtfan(); + } + + /*delete vertices i+1--j from the queue*/ + index_queue = i+1; + /*finally insert v at the end of the queue*/ + insert(v); + +} + + +void monoTriangulationRec(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, + vertexArray* dec_chain, Int dec_current, + Backend* backend) +{ + assert( inc_chain != NULL && dec_chain != NULL); + assert( ! (inc_current>=inc_chain->getNumElements() && + dec_current>=dec_chain->getNumElements())); + Int inc_nVertices; + Int dec_nVertices; + Real** inc_array ; + Real** dec_array ; + Int i; + assert( ! ( (inc_chain==NULL) && (dec_chain==NULL))); + + if(inc_current>=inc_chain->getNumElements()) /*no more vertices on inc_chain*/ + { + + dec_array = dec_chain->getArray(); + dec_nVertices = dec_chain->getNumElements(); + reflexChain rChain(20,0); + /*put the top vertex into the reflex chain*/ + rChain.processNewVertex(topVertex, backend); + /*process all the vertices on the dec_chain*/ + for(i=dec_current; i<dec_nVertices; i++){ + rChain.processNewVertex(dec_array[i], backend); + } + /*process the bottom vertex*/ + rChain.processNewVertex(botVertex, backend); + + } + else if(dec_current>= dec_chain->getNumElements()) /*no more vertices on dec_chain*/ + { + inc_array = inc_chain->getArray(); + inc_nVertices= inc_chain->getNumElements(); + reflexChain rChain(20,1); + /*put the top vertex into the reflex chain*/ + rChain.processNewVertex(topVertex, backend); + /*process all the vertices on the inc_chain*/ + for(i=inc_current; i<inc_nVertices; i++){ + rChain.processNewVertex(inc_array[i], backend); + } + /*process the bottom vertex*/ + rChain.processNewVertex(botVertex, backend); + } + else /*neither chain is empty*/ + { + inc_array = inc_chain -> getArray(); + dec_array = dec_chain -> getArray(); + inc_nVertices= inc_chain->getNumElements(); + dec_nVertices= dec_chain->getNumElements(); + /*if top of inc_chain is 'lower' than top of dec_chain, process all the + *vertices on the dec_chain which are higher than top of inc_chain + */ + if(compV2InY(inc_array[inc_current], dec_array[dec_current]) <= 0) + { + + reflexChain rChain(20, 0); + rChain.processNewVertex(topVertex, backend); + for(i=dec_current; i<dec_nVertices; i++) + { + if(compV2InY(inc_array[inc_current], dec_array[i]) <= 0) + rChain.processNewVertex(dec_array[i], backend); + else + break; + } + rChain.outputFan(inc_array[inc_current], backend); + monoTriangulationRec(dec_array[i-1], botVertex, + inc_chain, inc_current, + dec_chain, i, + backend); + } + else /*compV2InY(inc_array[inc_current], dec_array[dec_current]) > 0*/ + { + + reflexChain rChain(20, 1); + rChain.processNewVertex(topVertex, backend); + for(i=inc_current; i<inc_nVertices; i++) + { + if(compV2InY(inc_array[i], dec_array[dec_current]) >0) + rChain.processNewVertex(inc_array[i], backend); + else + break; + } + rChain.outputFan(dec_array[dec_current], backend); + monoTriangulationRec(inc_array[i-1], botVertex, + inc_chain, i, + dec_chain, dec_current, + backend); + } + }/*end case neither is empty*/ +} + + +void monoTriangulationFunBackend(Arc_ptr loop, Int (*compFun)(Real*, Real*), Backend* backend) +{ + Int i; + /*find the top vertex, bottom vertex, inccreasing chain, and decreasing chain, + *then call monoTriangulationRec + */ + Arc_ptr tempV; + Arc_ptr topV; + Arc_ptr botV; + topV = botV = loop; + for(tempV = loop->next; tempV != loop; tempV = tempV->next) + { + if(compFun(topV->tail(), tempV->tail())<0) { + topV = tempV; + } + if(compFun(botV->tail(), tempV->tail())>0) { + botV = tempV; + } + } + + /*creat increase and decrease chains*/ + vertexArray inc_chain(20); /*this is a dynamic array*/ + for(i=1; i<=topV->pwlArc->npts-2; i++) { /*the first vertex is the top vertex which doesn't belong to inc_chain*/ + inc_chain.appendVertex(topV->pwlArc->pts[i].param); + } + for(tempV = topV->next; tempV != botV; tempV = tempV->next) + { + for(i=0; i<=tempV->pwlArc->npts-2; i++){ + inc_chain.appendVertex(tempV->pwlArc->pts[i].param); + } + } + + vertexArray dec_chain(20); + for(tempV = topV->prev; tempV != botV; tempV = tempV->prev) + { + for(i=tempV->pwlArc->npts-2; i>=0; i--){ + dec_chain.appendVertex(tempV->pwlArc->pts[i].param); + } + } + for(i=botV->pwlArc->npts-2; i>=1; i--){ + dec_chain.appendVertex(tempV->pwlArc->pts[i].param); + } + + monoTriangulationRecFunBackend(topV->tail(), botV->tail(), &inc_chain, 0, &dec_chain, 0, compFun, backend); + +} + +/*if compFun == compV2InY, top to bottom: V-monotone + *if compFun == compV2InX, right to left: U-monotone + */ +void monoTriangulationRecFunBackend(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, + vertexArray* dec_chain, Int dec_current, + Int (*compFun)(Real*, Real*), + Backend* backend) +{ + assert( inc_chain != NULL && dec_chain != NULL); + assert( ! (inc_current>=inc_chain->getNumElements() && + dec_current>=dec_chain->getNumElements())); + Int inc_nVertices; + Int dec_nVertices; + Real** inc_array ; + Real** dec_array ; + Int i; + assert( ! ( (inc_chain==NULL) && (dec_chain==NULL))); + + if(inc_current>=inc_chain->getNumElements()) /*no more vertices on inc_chain*/ + { + + dec_array = dec_chain->getArray(); + dec_nVertices = dec_chain->getNumElements(); + reflexChain rChain(20,0); + /*put the top vertex into the reflex chain*/ + rChain.processNewVertex(topVertex, backend); + /*process all the vertices on the dec_chain*/ + for(i=dec_current; i<dec_nVertices; i++){ + rChain.processNewVertex(dec_array[i], backend); + } + /*process the bottom vertex*/ + rChain.processNewVertex(botVertex, backend); + + } + else if(dec_current>= dec_chain->getNumElements()) /*no more vertices on dec_chain*/ + { + inc_array = inc_chain->getArray(); + inc_nVertices= inc_chain->getNumElements(); + reflexChain rChain(20,1); + /*put the top vertex into the reflex chain*/ + rChain.processNewVertex(topVertex, backend); + /*process all the vertices on the inc_chain*/ + for(i=inc_current; i<inc_nVertices; i++){ + rChain.processNewVertex(inc_array[i], backend); + } + /*process the bottom vertex*/ + rChain.processNewVertex(botVertex, backend); + } + else /*neither chain is empty*/ + { + inc_array = inc_chain -> getArray(); + dec_array = dec_chain -> getArray(); + inc_nVertices= inc_chain->getNumElements(); + dec_nVertices= dec_chain->getNumElements(); + /*if top of inc_chain is 'lower' than top of dec_chain, process all the + *vertices on the dec_chain which are higher than top of inc_chain + */ + if(compFun(inc_array[inc_current], dec_array[dec_current]) <= 0) + { + + reflexChain rChain(20, 0); + rChain.processNewVertex(topVertex, backend); + for(i=dec_current; i<dec_nVertices; i++) + { + if(compFun(inc_array[inc_current], dec_array[i]) <= 0) + rChain.processNewVertex(dec_array[i], backend); + else + break; + } + rChain.outputFan(inc_array[inc_current], backend); + monoTriangulationRecFunBackend(dec_array[i-1], botVertex, + inc_chain, inc_current, + dec_chain, i, + compFun, + backend); + } + else /*compFun(inc_array[inc_current], dec_array[dec_current]) > 0*/ + { + + reflexChain rChain(20, 1); + rChain.processNewVertex(topVertex, backend); + for(i=inc_current; i<inc_nVertices; i++) + { + if(compFun(inc_array[i], dec_array[dec_current]) >0) + rChain.processNewVertex(inc_array[i], backend); + else + break; + } + rChain.outputFan(dec_array[dec_current], backend); + monoTriangulationRecFunBackend(inc_array[i-1], botVertex, + inc_chain, i, + dec_chain, dec_current, + compFun, + backend); + } + }/*end case neither is empty*/ +} diff --git a/mesalib/src/glu/sgi/libnurbs/internals/monotonizer.cc b/mesalib/src/glu/sgi/libnurbs/internals/monotonizer.cc new file mode 100644 index 000000000..5845d310b --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/monotonizer.cc @@ -0,0 +1,260 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * monotonizer.c++ + * + */ + +#include "glimports.h" +#include "mystdio.h" +#include "myassert.h" +#include "arc.h" +#include "arctess.h" +#include "bezierarc.h" +#include "bin.h" +#include "mapdesc.h" +#include "nurbsconsts.h" +#include "subdivider.h" + +/*----------------------------------------------------------------------------- + * Subdivider::decompose - break all curves into monotone arcs + *----------------------------------------------------------------------------- + */ +int +Subdivider::decompose( Bin& bin, REAL geo_stepsize ) +{ + Arc_ptr jarc; + for( jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) { + if( ! jarc->isTessellated() ) { + /* points have not been transformed, therefore they may be either + homogeneous or inhomogeneous */ + tessellate( jarc, geo_stepsize ); + if( jarc->isDisconnected() || jarc->next->isDisconnected() ) + return 1; + } + } + + for( jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) { + monotonize( jarc, bin ); + } + +#ifndef NDEBUG + for( jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) { + assert( isMonotone( jarc ) != 0 ); + } +#endif + + return 0; +} + +void +Subdivider::tessellate( Arc_ptr jarc, REAL geo_stepsize ) +{ + BezierArc *b = jarc->bezierArc; + Mapdesc *mapdesc = b->mapdesc; + + if( mapdesc->isRational() ) { + REAL max = mapdesc->calcVelocityRational( b->cpts, b->stride, b->order ); + REAL arc_stepsize = (max > 1.0) ? (1.0/max) : 1.0; + if( jarc->bezierArc->order != 2 ) + arctessellator.tessellateNonlinear( jarc, geo_stepsize, arc_stepsize, 1 ); + else { + arctessellator.tessellateLinear( jarc, geo_stepsize, arc_stepsize, 1 ); + } + } else { + REAL max = mapdesc->calcVelocityNonrational( b->cpts, b->stride, b->order ); + REAL arc_stepsize = (max > 1.0) ? (1.0/max) : 1.0; + if( jarc->bezierArc->order != 2 ) + arctessellator.tessellateNonlinear( jarc, geo_stepsize, arc_stepsize, 0 ); + else { + arctessellator.tessellateLinear( jarc, geo_stepsize, arc_stepsize, 0 ); + } + } +} + +/*------------------------------------------------------------------------- + * Subdivider::monotonize - break up a jordan arc into s,t-monotone + * components. This code will remove degenerate segments, including + * arcs of only a single point. + *------------------------------------------------------------------------- + */ +void +Subdivider::monotonize( Arc_ptr jarc, Bin& bin ) +{ + TrimVertex *firstvert = jarc->pwlArc->pts; + TrimVertex *lastvert = firstvert + (jarc->pwlArc->npts - 1); + long uid = jarc->nuid; + arc_side side = jarc->getside(); + dir sdir = none; + dir tdir = none; + int degenerate = 1; + + int nudegenerate; + int change; + + TrimVertex *vert; + for( vert = firstvert; vert != lastvert; vert++ ) { + + nudegenerate = 1; + change = 0; + + /* check change relative to s axis, clear degenerate bit if needed */ + REAL sdiff = vert[1].param[0] - vert[0].param[0]; + if( sdiff == 0 ) { + if( sdir != same ) { + sdir = same; + change = 1; + } + } else if( sdiff < 0.0 ) { + if( sdir != down ) { + sdir = down; + change = 1; + } + nudegenerate = 0; + } else { + if( sdir != up ) { + sdir = up; + change = 1; + } + nudegenerate = 0; + } + + /* check change relative to t axis, clear degenerate bit if needed */ + REAL tdiff = vert[1].param[1] - vert[0].param[1]; + if( tdiff == 0 ) { + if( tdir != same ) { + tdir = same; + change = 1; + } + } else if( tdiff < 0.0 ) { + if( tdir != down ) { + tdir = down; + change = 1; + } + nudegenerate = 0; + } else { + if( tdir != up ) { + tdir = up; + change = 1; + } + nudegenerate = 0; + } + + if( change ) { + if( ! degenerate ) { + /* make last segment into separate pwl curve */ + jarc->pwlArc->npts = vert - firstvert + 1; + jarc = (new(arcpool) Arc( side, uid ))->append( jarc ); + jarc->pwlArc = new(pwlarcpool) PwlArc(); + bin.addarc( jarc ); + } + firstvert = jarc->pwlArc->pts = vert; + degenerate = nudegenerate; + } + } + jarc->pwlArc->npts = vert - firstvert + 1; + + if( degenerate ) { + /* remove jarc from circularly linked list */ + jarc->prev->next = jarc->next; + jarc->next->prev = jarc->prev; + + assert( jarc->prev->check( ) != 0 ); + assert( jarc->next->check( ) != 0 ); + + /* remove jarc from bin */ + bin.remove_this_arc( jarc ); + + jarc->pwlArc->deleteMe( pwlarcpool ); jarc->pwlArc = 0; + jarc->deleteMe( arcpool ); + } +} + +/*------------------------------------------------------------------------- + * Subdivider::isMonotone - return true if arc is monotone AND non-degenerate + *------------------------------------------------------------------------- + */ +int +Subdivider::isMonotone( Arc_ptr jarc ) +{ + TrimVertex *firstvert = jarc->pwlArc->pts; + TrimVertex *lastvert = firstvert + (jarc->pwlArc->npts - 1); + + if( firstvert == lastvert ) return 1; + + TrimVertex *vert = firstvert; + enum dir sdir; + enum dir tdir; + + REAL diff = vert[1].param[0] - vert[0].param[0]; + if( diff == 0.0 ) + sdir = same; + else if( diff < 0.0 ) + sdir = down; + else + sdir = up; + + diff = vert[1].param[1] - vert[0].param[1]; + if( diff == 0.0 ) + tdir = same; + else if( diff < 0.0 ) + tdir = down; + else + tdir = up; + + if( (sdir == same) && (tdir == same) ) return 0; + + for( ++vert ; vert != lastvert; vert++ ) { + diff = vert[1].param[0] - vert[0].param[0]; + if( diff == 0.0 ) { + if( sdir != same ) return 0; + } else if( diff < 0.0 ) { + if( sdir != down ) return 0; + } else { + if( sdir != up ) return 0; + } + + diff = vert[1].param[1] - vert[0].param[1]; + if( diff == 0.0 ) { + if( tdir != same ) return 0; + } else if( diff < 0.0 ) { + if( tdir != down ) return 0; + } else { + if( tdir != up ) return 0; + } + } + return 1; +} + diff --git a/mesalib/src/glu/sgi/libnurbs/internals/monotonizer.h b/mesalib/src/glu/sgi/libnurbs/internals/monotonizer.h new file mode 100644 index 000000000..e951084ff --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/monotonizer.h @@ -0,0 +1,64 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * monotonizer.h + * + */ + +#ifndef __glumonotonizer_h_ +#define __glumonotonizer_h_ + +#include "mysetjmp.h" +#include "types.h" + +class Arc; +class ArcTessellator; +class Pool; +class Bin; +class PwlArcPool; +class Mapdesc; + +class Monotonizer { + ArcTessellator& arctessellator; + Pool& arcpool; + Pool& pwlarcpool; + jmp_buf& nurbsJmpBuf; + + enum dir { down, same, up, none }; + void tessellate( Arc *, REAL ); + void monotonize( Arc *, Bin & ); + int isMonotone( Arc * ); +public: + Monotonizer( ArcTessellator& at, Pool& ap, Pool& p, jmp_buf& j ) + : arctessellator(at), arcpool(ap), pwlarcpool(p), nurbsJmpBuf(j) {} + int decompose( Bin &, REAL ); +}; +#endif /* __glumonotonizer_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/myassert.h b/mesalib/src/glu/sgi/libnurbs/internals/myassert.h new file mode 100644 index 000000000..cbd6006f5 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/myassert.h @@ -0,0 +1,51 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * myassert.h + * + */ + +#ifndef __glumyassert_h_ +#define __glumyassert_h_ + +#ifdef STANDALONE +#define assert(EX) ((void)0) +#endif + +#ifdef LIBRARYBUILD +#include <assert.h> +#endif + +#ifdef GLBUILD +#define assert(EX) ((void)0) +#endif + +#endif /* __glumyassert_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/mycode.cc b/mesalib/src/glu/sgi/libnurbs/internals/mycode.cc new file mode 100644 index 000000000..3625cacd7 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/mycode.cc @@ -0,0 +1,67 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include "mymath.h" + +#ifdef NEEDCEILF + +float ceilf( float x ) +{ + if( x < 0 ) { + float nx = -x; + int ix = (int) nx; + return (float) -ix; + } else { + int ix = (int) x; + if( x == (float) ix ) return x; + return (float) (ix+1); + } +} + +float floorf( float x ) +{ + if( x < 0 ) { + float nx = -x; + int ix = (int) nx; + if( nx == (float) ix ) return x; + return (float) -(ix+1); + } else { + int ix = (int) x; + return (float) ix; + } +} +#endif diff --git a/mesalib/src/glu/sgi/libnurbs/internals/mymath.h b/mesalib/src/glu/sgi/libnurbs/internals/mymath.h new file mode 100644 index 000000000..17ef7237f --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/mymath.h @@ -0,0 +1,68 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * mymath.h + * + */ + +#ifndef __glumymath_h_ +#define __glumymath_h_ + +#ifdef GLBUILD +#define sqrtf gl_fsqrt +#endif + +#if defined(GLBUILD) || defined(STANDALONE) +#define M_SQRT2 1.41421356237309504880 +#define ceilf myceilf +#define floorf myfloorf +#define sqrtf sqrt +extern "C" double sqrt(double); +extern "C" float ceilf(float); +extern "C" float floorf(float); +#define NEEDCEILF +#endif + +#ifdef LIBRARYBUILD +#include <math.h> +#endif + +#if !defined sqrtf +# define sqrtf(x) ((float)sqrt(x)) +#endif +#if !defined ceilf +# define ceilf(x) ((float)ceil(x)) +#endif +#if !defined floorf +# define floorf(x) ((float)floor(x)) +#endif + +#endif /* __glumymath_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/mysetjmp.h b/mesalib/src/glu/sgi/libnurbs/internals/mysetjmp.h new file mode 100644 index 000000000..2a3f6a87b --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/mysetjmp.h @@ -0,0 +1,85 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * mysetjmp.h + * + */ + +#ifndef __glumysetjmp_h_ +#define __glumysetjmp_h_ + +#ifdef STANDALONE +struct JumpBuffer; +extern "C" JumpBuffer *newJumpbuffer( void ); +extern "C" void deleteJumpbuffer(JumpBuffer *); +extern "C" void mylongjmp( JumpBuffer *, int ); +extern "C" int mysetjmp( JumpBuffer * ); +#endif + +#ifdef GLBUILD +#define setjmp gl_setjmp +#define longjmp gl_longjmp +#endif + +#if defined(LIBRARYBUILD) || defined(GLBUILD) +#include <setjmp.h> +#include <stdlib.h> + +struct JumpBuffer { + jmp_buf buf; +}; + +inline JumpBuffer * +newJumpbuffer( void ) +{ + return (JumpBuffer *) malloc( sizeof( JumpBuffer ) ); +} + +inline void +deleteJumpbuffer(JumpBuffer *jb) +{ + free( (void *) jb); +} + +inline void +mylongjmp( JumpBuffer *j, int code ) +{ + ::longjmp( j->buf, code ); +} + +inline int +mysetjmp( JumpBuffer *j ) +{ + return setjmp( j->buf ); +} +#endif + +#endif /* __glumysetjmp_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/mystring.h b/mesalib/src/glu/sgi/libnurbs/internals/mystring.h new file mode 100644 index 000000000..d2952da89 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/mystring.h @@ -0,0 +1,56 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * mystring.h + * + */ + +#ifndef __glumystring_h_ +#define __glumystring_h_ + +#ifdef STANDALONE +typedef unsigned int size_t; +extern "C" void * memcpy(void *, const void *, size_t); +extern "C" void * memset(void *, int, size_t); +#endif + +#ifdef GLBUILD +#define memcpy(a,b,c) bcopy(b,a,c) +#define memset(a,b,c) bzero(a,c) +extern "C" void bcopy(const void *, void *, int); +extern "C" void bzero(void *, int); +#endif + +#ifdef LIBRARYBUILD +#include <string.h> +#endif + +#endif /* __glumystring_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/nurbsconsts.h b/mesalib/src/glu/sgi/libnurbs/internals/nurbsconsts.h new file mode 100644 index 000000000..acc5d7f31 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/nurbsconsts.h @@ -0,0 +1,120 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * nurbsconsts.h + * + */ + +#ifndef __glunurbsconsts_h_ +#define __glunurbsconsts_h_ + +/* NURBS Properties - one set per map, + each takes a single INREAL arg */ +#define N_SAMPLING_TOLERANCE 1 +#define N_S_RATE 6 +#define N_T_RATE 7 +#define N_CLAMPFACTOR 13 +#define N_NOCLAMPING 0.0 +#define N_MINSAVINGS 14 +#define N_NOSAVINGSSUBDIVISION 0.0 + +/* NURBS Properties - one set per map, + each takes an enumerated value */ +#define N_CULLING 2 +#define N_NOCULLING 0.0 +#define N_CULLINGON 1.0 +#define N_SAMPLINGMETHOD 10 +#define N_NOSAMPLING 0.0 +#define N_FIXEDRATE 3.0 +#define N_DOMAINDISTANCE 2.0 +#define N_PARAMETRICDISTANCE 5.0 +#define N_PATHLENGTH 6.0 +#define N_SURFACEAREA 7.0 +#define N_OBJECTSPACE_PARA 8.0 +#define N_OBJECTSPACE_PATH 9.0 +#define N_BBOX_SUBDIVIDING 17 +#define N_NOBBOXSUBDIVISION 0.0 +#define N_BBOXTIGHT 1.0 +#define N_BBOXROUND 2.0 + +/* NURBS Rendering Properties - one set per renderer + each takes an enumerated value */ +#define N_DISPLAY 3 +#define N_FILL 1.0 +#define N_OUTLINE_POLY 2.0 +#define N_OUTLINE_TRI 3.0 +#define N_OUTLINE_QUAD 4.0 +#define N_OUTLINE_PATCH 5.0 +#define N_OUTLINE_PARAM 6.0 +#define N_OUTLINE_PARAM_S 7.0 +#define N_OUTLINE_PARAM_ST 8.0 +#define N_OUTLINE_SUBDIV 9.0 +#define N_OUTLINE_SUBDIV_S 10.0 +#define N_OUTLINE_SUBDIV_ST 11.0 +#define N_ISOLINE_S 12.0 +#define N_ERRORCHECKING 4 +#define N_NOMSG 0.0 +#define N_MSG 1.0 + +/* GL 4.0 propeties not defined above */ +#ifndef N_PIXEL_TOLERANCE +#define N_PIXEL_TOLERANCE N_SAMPLING_TOLERANCE +#define N_ERROR_TOLERANCE 20 +#define N_SUBDIVISIONS 5 +#define N_TILES 8 +#define N_TMP1 9 +#define N_TMP2 N_SAMPLINGMETHOD +#define N_TMP3 11 +#define N_TMP4 12 +#define N_TMP5 N_CLAMPFACTOR +#define N_TMP6 N_MINSAVINGS +#define N_S_STEPS N_S_RATE +#define N_T_STEPS N_T_RATE +#endif + +/* NURBS Rendering Properties - one set per map, + each takes an INREAL matrix argument */ +#define N_CULLINGMATRIX 1 +#define N_SAMPLINGMATRIX 2 +#define N_BBOXMATRIX 3 + + +/* NURBS Rendering Properties - one set per map, + each takes an INREAL vector argument */ +#define N_BBOXSIZE 4 + +/* type argument for trimming curves */ +#ifndef N_P2D +#define N_P2D 0x8 +#define N_P2DR 0xd +#endif + +#endif /* __glunurbsconsts_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/nurbsinterfac.cc b/mesalib/src/glu/sgi/libnurbs/internals/nurbsinterfac.cc new file mode 100644 index 000000000..520bd419e --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/nurbsinterfac.cc @@ -0,0 +1,537 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * nurbsinterfac.c++ + * + */ + +#include "glimports.h" +#include "mystdio.h" +#include "nurbsconsts.h" +#include "nurbstess.h" +#include "bufpool.h" +#include "quilt.h" +#include "displaylist.h" +#include "knotvector.h" +#include "mapdesc.h" + +#define THREAD( work, arg, cleanup ) \ + if( dl ) {\ + arg->save = 1;\ + dl->append( (PFVS)&NurbsTessellator::work, (void *) arg, (PFVS)&NurbsTessellator::cleanup );\ + } else {\ + arg->save = 0;\ + work( arg );\ + } + +#define THREAD2( work ) \ + if( dl ) {\ + dl->append( (PFVS)&NurbsTessellator::work, 0, 0 );\ + } else {\ + work( );\ + } + +NurbsTessellator::NurbsTessellator( BasicCurveEvaluator &c, BasicSurfaceEvaluator& e) + : maplist( backend ), + backend( c, e ), + subdivider( renderhints, backend ), + o_pwlcurvePool( sizeof( O_pwlcurve ), 32, "o_pwlcurvePool" ), + o_nurbscurvePool( sizeof( O_nurbscurve ), 32, "o_nurbscurvePool"), + o_curvePool( sizeof( O_curve ), 32, "o_curvePool" ), + o_trimPool( sizeof( O_trim ), 32, "o_trimPool" ), + o_surfacePool( sizeof( O_surface ), 1, "o_surfacePool" ), + o_nurbssurfacePool( sizeof( O_nurbssurface ), 4, "o_nurbssurfacePool" ), + propertyPool( sizeof( Property ), 32, "propertyPool" ), + quiltPool( sizeof( Quilt ), 32, "quiltPool" ) +{ + dl = 0; + inSurface = 0; + inCurve = 0; + inTrim = 0; + playBack = 0; + jumpbuffer = newJumpbuffer(); + subdivider.setJumpbuffer( jumpbuffer ); +} + +NurbsTessellator::~NurbsTessellator( void ) +{ + if( inTrim ) { + do_nurbserror( 12 ); + endtrim(); + } + + if( inSurface ) { + *nextNurbssurface = 0; + do_freeall(); + } + + if (jumpbuffer) { + deleteJumpbuffer(jumpbuffer); + jumpbuffer= 0; + } +} + +/*----------------------------------------------------------------------------- + * bgnsurface - allocate and initialize an o_surface structure + * + * Client: GL user + *----------------------------------------------------------------------------- + */ +void +NurbsTessellator::bgnsurface( long nuid ) +{ + O_surface *o_surface = new(o_surfacePool) O_surface; + o_surface->nuid = nuid; + THREAD( do_bgnsurface, o_surface, do_freebgnsurface ); +} + +/*----------------------------------------------------------------------------- + * bgncurve - allocate an initialize an o_curve structure + * + * Client: GL user + *----------------------------------------------------------------------------- + */ +void +NurbsTessellator::bgncurve( long nuid ) +{ + O_curve *o_curve = new(o_curvePool) O_curve; + o_curve->nuid = nuid; + THREAD( do_bgncurve, o_curve, do_freebgncurve ); +} +/*----------------------------------------------------------------------------- + * endcurve - + * + * Client: + *----------------------------------------------------------------------------- + */ + +void +NurbsTessellator::endcurve( void ) +{ + THREAD2( do_endcurve ); +} + +/*----------------------------------------------------------------------------- + * endsurface - user level end of surface call + * + * Client: GL user + *----------------------------------------------------------------------------- + */ +void +NurbsTessellator::endsurface( void ) +{ + THREAD2( do_endsurface ); +} + + +/*----------------------------------------------------------------------------- + * bgntrim - allocate and initialize a new trim loop structure (o_trim ) + * + * Client: GL user + *----------------------------------------------------------------------------- + */ +void +NurbsTessellator::bgntrim( void ) +{ + O_trim *o_trim = new(o_trimPool) O_trim; + THREAD( do_bgntrim, o_trim, do_freebgntrim ); +} + +/*----------------------------------------------------------------------------- + * endtrim - + * + * Client: GL user + *----------------------------------------------------------------------------- + */ +void +NurbsTessellator::endtrim( void ) +{ + THREAD2( do_endtrim ); +} + + +/*----------------------------------------------------------------------------- + * pwlcurve - + * + * count - number of points on curve + * array - array of points on curve + * byte_stride - distance between points in bytes + * type - valid data flag + * + * Client: Gl user + *----------------------------------------------------------------------------- + */ +void +NurbsTessellator::pwlcurve( long count, INREAL array[], long byte_stride, long type ) +{ + Mapdesc *mapdesc = maplist.locate( type ); + + if( mapdesc == 0 ) { + do_nurbserror( 35 ); + isDataValid = 0; + return; + } + + if ( (type != N_P2D) && (type != N_P2DR) ) { + do_nurbserror( 22 ); + isDataValid = 0; + return; + } + if( count < 0 ) { + do_nurbserror( 33 ); + isDataValid = 0; + return; + } + if( byte_stride < 0 ) { + do_nurbserror( 34 ); + isDataValid = 0; + return; + } + +#ifdef NOTDEF + if( mapdesc->isRational() ) { + INREAL *p = array; + INREAL x = p[0]; INREAL y = p[1]; INREAL w = p[2]; + p = (INREAL *) (((char *) p) + byte_stride); + for( long i = 1; i != count; i++ ) { + if( p[0] == x && p[1] == y && p[2] == w ) break; + x = p[0]; y = p[1]; w = p[2]; + p = (INREAL *) (((char *) p) + byte_stride); + } + if( i != count ) { + do_nurbserror( 37 ); + _glu_dprintf( "point %d (%f,%f)\n", i, x, y ); + isDataValid = 0; + return; + } + } else { + INREAL *p = array; + INREAL x = p[0]; INREAL y = p[1]; + p = (INREAL *) (((char *) p) + byte_stride); + for( long i = 1; i != count; i++ ) { + if( p[0] == x && p[1] == y ) break; + x = p[0]; y = p[1]; + p = (INREAL *) (((char *) p) + byte_stride); + } + if( i != count ) { + do_nurbserror( 37 ); + _glu_dprintf( "point %d (%f,%f)\n", i, x, y ); + isDataValid = 0; + return; + } + } +#endif + + O_pwlcurve *o_pwlcurve = new(o_pwlcurvePool) O_pwlcurve( type, count, array, byte_stride, extTrimVertexPool.get((int)count) ); + THREAD( do_pwlcurve, o_pwlcurve, do_freepwlcurve ); +} + + +/*----------------------------------------------------------------------------- + * nurbscurve - + * + * Client: GL user + *----------------------------------------------------------------------------- + */ +void +NurbsTessellator::nurbscurve( + long nknots, /* number of p knots */ + INREAL knot[], /* nondecreasing knot values in p */ + long byte_stride, /* distance in bytes between control points */ + INREAL ctlarray[], /* pointer to first control point */ + long order, /* order of spline */ + long type ) /* description of range space */ +{ + + Mapdesc *mapdesc = maplist.locate( type ); + + if( mapdesc == 0 ) { + do_nurbserror( 35 ); + isDataValid = 0; + return; + } + + if( ctlarray == 0 ) { + do_nurbserror( 36 ); + isDataValid = 0; + return; + } + + if( byte_stride < 0 ) { + do_nurbserror( 34 ); + isDataValid = 0; + return; + } + + Knotvector knots; + + knots.init( nknots, byte_stride, order, knot ); + if( do_check_knots( &knots, "curve" ) ) return; + + O_nurbscurve *o_nurbscurve = new(o_nurbscurvePool) O_nurbscurve(type); + o_nurbscurve->bezier_curves = new(quiltPool) Quilt(mapdesc); + o_nurbscurve->bezier_curves->toBezier( knots,ctlarray, mapdesc->getNcoords() ); + + THREAD( do_nurbscurve, o_nurbscurve, do_freenurbscurve ); +} + + +/*----------------------------------------------------------------------------- + * nurbssurface - + * + * Client: User routine + *----------------------------------------------------------------------------- + */ +void +NurbsTessellator::nurbssurface( + long sknot_count, /* number of s knots */ + INREAL sknot[], /* nondecreasing knot values in s */ + long tknot_count, /* number of t knots */ + INREAL tknot[], /* nondecreasing knot values in t */ + long s_byte_stride, /* s step size in memory bytes */ + long t_byte_stride, /* t step size in memory bytes */ + INREAL ctlarray[], /* pointer to first control point */ + long sorder, /* order of the spline in s parameter */ + long torder, /* order of the spline in t parameter */ + long type) /* description of range space */ +{ + Mapdesc *mapdesc = maplist.locate( type ); + + if( mapdesc == 0 ) { + do_nurbserror( 35 ); + isDataValid = 0; + return; + } + + if( s_byte_stride < 0 ) { + do_nurbserror( 34 ); + isDataValid = 0; + return; + } + + if( t_byte_stride < 0 ) { + do_nurbserror( 34 ); + isDataValid = 0; + return; + } + + Knotvector sknotvector, tknotvector; + + sknotvector.init( sknot_count, s_byte_stride, sorder, sknot ); + if( do_check_knots( &sknotvector, "surface" ) ) return; + + tknotvector.init( tknot_count, t_byte_stride, torder, tknot ); + if( do_check_knots( &tknotvector, "surface" ) ) return; + + O_nurbssurface *o_nurbssurface = new(o_nurbssurfacePool) O_nurbssurface(type); + o_nurbssurface->bezier_patches = new(quiltPool) Quilt(mapdesc); + + o_nurbssurface->bezier_patches->toBezier( sknotvector, tknotvector, + ctlarray, mapdesc->getNcoords() ); + THREAD( do_nurbssurface, o_nurbssurface, do_freenurbssurface ); +} + + +/*----------------------------------------------------------------------------- + * setnurbsproperty - + * + *----------------------------------------------------------------------------- + */ +void +NurbsTessellator::setnurbsproperty( long tag, INREAL value ) +{ + if( ! renderhints.isProperty( tag ) ) { + do_nurbserror( 26 ); + } else { + Property *prop = new(propertyPool) Property( tag, value ); + THREAD( do_setnurbsproperty, prop, do_freenurbsproperty ); + } +} + +/*----------------------------------------------------------------------------- + * setnurbsproperty - + * + *----------------------------------------------------------------------------- + */ +void +NurbsTessellator::setnurbsproperty( long type, long tag, INREAL value ) +{ + Mapdesc *mapdesc = maplist.locate( type ); + + if( mapdesc == 0 ) { + do_nurbserror( 35 ); + return; + } + + if( ! mapdesc->isProperty( tag ) ) { + do_nurbserror( 26 ); + return; + } + + Property *prop = new(propertyPool) Property( type, tag, value ); + THREAD( do_setnurbsproperty2, prop, do_freenurbsproperty ); +} + + +/*----------------------------------------------------------------------------- + * getnurbsproperty - + * + *----------------------------------------------------------------------------- + */ + +void +NurbsTessellator::getnurbsproperty( long tag, INREAL *value ) +{ + if( renderhints.isProperty( tag ) ) { + *value = renderhints.getProperty( tag ); + } else { + do_nurbserror( 26 ); + } +} + +/*----------------------------------------------------------------------------- + * getnurbsproperty - + * + *----------------------------------------------------------------------------- + */ + +void +NurbsTessellator::getnurbsproperty( long type, long tag, INREAL *value ) +{ + Mapdesc *mapdesc = maplist.locate( type ); + + if( mapdesc == 0 ) + do_nurbserror( 35 ); + + if( mapdesc->isProperty( tag ) ) { + *value = mapdesc->getProperty( tag ); + } else { + do_nurbserror( 26 ); + } +} + +/*-------------------------------------------------------------------------- + * setnurbsproperty - accept a user supplied matrix as culling or sampling mat + *-------------------------------------------------------------------------- + */ + +void +NurbsTessellator::setnurbsproperty( long type, long purpose, INREAL *mat ) +{ + // XXX - cannot be put in display list + Mapdesc *mapdesc = maplist.locate( type ); + + if( mapdesc == 0 ) { + do_nurbserror( 35 ); + isDataValid = 0; + } else if( purpose == N_BBOXSIZE ) { + mapdesc->setBboxsize( mat ); + } else { +#ifndef NDEBUG + _glu_dprintf( "ERRORRORRORR!!!\n"); +#endif + } +} + +/*-------------------------------------------------------------------------- + * setnurbsproperty - accept a user supplied matrix as culling or sampling mat + *-------------------------------------------------------------------------- + */ + +void +NurbsTessellator::setnurbsproperty( long type, long purpose, INREAL *mat, + long rstride, long cstride ) +{ + // XXX - cannot be put in display list + Mapdesc *mapdesc = maplist.locate( type ); + + if( mapdesc == 0 ) { + do_nurbserror( 35 ); + isDataValid = 0; + } else if( purpose == N_CULLINGMATRIX ) { + mapdesc->setCmat( mat, rstride, cstride ); + } else if( purpose == N_SAMPLINGMATRIX ) { + mapdesc->setSmat( mat, rstride, cstride ); + } else if( purpose == N_BBOXMATRIX ) { + mapdesc->setBmat( mat, rstride, cstride ); + } else { +#ifndef NDEBUG + _glu_dprintf( "ERRORRORRORR!!!\n"); +#endif + } +} + +void +NurbsTessellator::redefineMaps( void ) +{ + maplist.initialize(); +} + +void +NurbsTessellator::defineMap( long type, long rational, long ncoords ) +{ + maplist.define( type, (int) rational, (int) ncoords ); +} + +void +NurbsTessellator::discardRecording( void *_dl ) +{ + delete (DisplayList *) _dl; +} + +void * +NurbsTessellator::beginRecording( void ) +{ + dl = new DisplayList( this ); + return (void *) dl; +} + +void +NurbsTessellator::endRecording( void ) +{ + dl->endList(); + dl = 0; +} + +void +NurbsTessellator::playRecording( void *_dl ) +{ + playBack = 1; + bgnrender(); + ((DisplayList *)_dl)->play(); + endrender(); + playBack = 0; +} + diff --git a/mesalib/src/glu/sgi/libnurbs/internals/nurbstess.cc b/mesalib/src/glu/sgi/libnurbs/internals/nurbstess.cc new file mode 100644 index 000000000..68dfd95f3 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/nurbstess.cc @@ -0,0 +1,691 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * nurbstess.c++ + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "mysetjmp.h" +#include "mystdio.h" +#include "nurbsconsts.h" +#include "nurbstess.h" +#include "bufpool.h" +#include "quilt.h" +#include "knotvector.h" +#include "mapdesc.h" +#include "maplist.h" + +void +NurbsTessellator::set_domain_distance_u_rate(REAL u_rate) +{ + subdivider.set_domain_distance_u_rate(u_rate); +} + +void +NurbsTessellator::set_domain_distance_v_rate(REAL v_rate) +{ + subdivider.set_domain_distance_v_rate(v_rate); +} + +void +NurbsTessellator::set_is_domain_distance_sampling(int flag) +{ + subdivider.set_is_domain_distance_sampling(flag); +} + +void +NurbsTessellator::resetObjects( void ) +{ + subdivider.clear(); +} + +void +NurbsTessellator::makeobj( int ) +{ +#ifndef NDEBUG + _glu_dprintf( "makeobj\n" ); +#endif +} + +void +NurbsTessellator::closeobj( void ) +{ +#ifndef NDEBUG + _glu_dprintf( "closeobj\n" ); +#endif +} + +void +NurbsTessellator::bgnrender( void ) +{ +#ifndef NDEBUG + _glu_dprintf( "bgnrender\n" ); +#endif +} + +void +NurbsTessellator::endrender( void ) +{ +#ifndef NDEBUG + _glu_dprintf( "endrender\n" ); +#endif +} + +/*----------------------------------------------------------------------------- + * do_freebgnsurface - free o_surface structure + * + * Client: do_freeall(), bgnsurface() + *----------------------------------------------------------------------------- + */ +void +NurbsTessellator::do_freebgnsurface( O_surface *o_surface ) +{ + o_surface->deleteMe( o_surfacePool ); +} + + +/*----------------------------------------------------------------------------- + * do_bgnsurface - begin the display of a surface + * + * Client: bgnsurface() + *----------------------------------------------------------------------------- + */ +void +NurbsTessellator::do_bgnsurface( O_surface *o_surface ) +{ + if( inSurface ) { + do_nurbserror( 27 ); + endsurface(); + } + inSurface = 1; + + if( ! playBack ) bgnrender(); + + isTrimModified = 0; + isSurfaceModified = 0; + isDataValid = 1; + numTrims = 0; + currentSurface = o_surface; + nextTrim = &( currentSurface->o_trim ); + nextNurbssurface = &( currentSurface->o_nurbssurface ); +} + +/*----------------------------------------------------------------------------- + * do_bgncurve - begin the display of a curve + * + * Client: bgncurve() + *----------------------------------------------------------------------------- + */ +void +NurbsTessellator::do_bgncurve( O_curve *o_curve ) +{ + if ( inCurve ) { + do_nurbserror( 6 ); + endcurve(); + } + + inCurve = 1; + currentCurve = o_curve; + currentCurve->curvetype = ct_none; + + if( inTrim ) { + if( *nextCurve != o_curve ) { + isCurveModified = 1; + *nextCurve = o_curve; + } + } else { + if( ! playBack ) bgnrender(); + isDataValid = 1; + } + nextCurve = &(o_curve->next); + nextPwlcurve = &(o_curve->curve.o_pwlcurve); + nextNurbscurve = &(o_curve->curve.o_nurbscurve); +} + +/*----------------------------------------------------------------------------- + * do_endcurve - + * + * Client: endcurve() + *----------------------------------------------------------------------------- + */ + +void +NurbsTessellator::do_endcurve( void ) +{ + if( ! inCurve ) { + do_nurbserror( 7 ); + return; + } + inCurve = 0; + + *nextCurve = 0; + if (currentCurve->curvetype == ct_nurbscurve) + *nextNurbscurve = 0; + else + *nextPwlcurve = 0; + + if ( ! inTrim ) { + if( ! isDataValid ) { + do_freecurveall( currentCurve ); + return; + } + + int errval; + errval = ::mysetjmp( jumpbuffer ); + if( errval == 0 ) { + if( currentCurve->curvetype == ct_nurbscurve ) { + subdivider.beginQuilts(); + for( O_nurbscurve *n = currentCurve->curve.o_nurbscurve; n != 0; n = n->next ) + subdivider.addQuilt( n->bezier_curves ); + subdivider.endQuilts(); + subdivider.drawCurves(); + if( ! playBack ) endrender(); + } else { + /* XXX */ + if( ! playBack ) endrender(); + /*do_draw_pwlcurve( currentCurve->curve.o_pwlcurve ) */; + do_nurbserror( 9 ); + } + } else { + if( ! playBack ) endrender(); + do_nurbserror( errval ); + } + do_freecurveall( currentCurve ); + resetObjects(); + } +} + +/*----------------------------------------------------------------------------- + * do_endsurface - mark end of surface, display surface, free immediate data + * + * Client: + *----------------------------------------------------------------------------- + */ +void +NurbsTessellator::do_endsurface( void ) +{ + if( inTrim ) { + do_nurbserror( 12 ); + endtrim(); + } + + if( ! inSurface ) { + do_nurbserror( 13 ); + return; + } + inSurface = 0; + + *nextNurbssurface = 0; + + if( ! isDataValid ) { + do_freeall( ); + return; + } + + if( *nextTrim != 0 ) { + isTrimModified = 1; + *nextTrim = 0; + } + + int errval; + + errval = ::mysetjmp( jumpbuffer ); + if( errval == 0 ) { + if( numTrims > 0 ) { + + subdivider.beginTrims(); + for( O_trim *trim = currentSurface->o_trim; trim; trim = trim->next ) { + subdivider.beginLoop(); + for( O_curve *curve = trim->o_curve; curve; curve = curve->next ) { + curve->used = 0; + assert( curve->curvetype != ct_none ); + if (curve->curvetype == ct_pwlcurve) { + O_pwlcurve *c = curve->curve.o_pwlcurve; + subdivider.addArc( c->npts, c->pts, curve->nuid ); + } else { + Quilt *quilt = curve->curve.o_nurbscurve->bezier_curves; + Quiltspec *qspec = quilt->qspec; + REAL *cpts = quilt->cpts + qspec->offset; + REAL *cptsend = cpts + (qspec->width * qspec->order * qspec->stride); + for( ; cpts != cptsend; cpts += qspec->order*qspec->stride ) + subdivider.addArc( cpts, quilt, curve->nuid ); + } + } + subdivider.endLoop(); + } + subdivider.endTrims(); + } + + subdivider.beginQuilts(); + for( O_nurbssurface *n = currentSurface->o_nurbssurface; n; n = n->next ) + subdivider.addQuilt( n->bezier_patches ); + subdivider.endQuilts(); + subdivider.drawSurfaces( currentSurface->nuid ); + if( ! playBack ) endrender(); + } else { + if( ! playBack ) endrender(); + do_nurbserror( errval ); + } + + do_freeall( ); + resetObjects(); +} + +/*----------------------------------------------------------------------------- + * do_freeall - free all data allocated in immediate mode + * + * Client: + *----------------------------------------------------------------------------- + */ +void +NurbsTessellator::do_freeall( void ) +{ + for( O_trim *o_trim = currentSurface->o_trim; o_trim; ) { + O_trim *next_o_trim = o_trim->next; + for( O_curve *curve = o_trim->o_curve; curve; ) { + O_curve *next_o_curve = curve->next; + do_freecurveall( curve ); + curve = next_o_curve; + } + if( o_trim->save == 0 ) do_freebgntrim( o_trim ); + o_trim = next_o_trim; + } + + O_nurbssurface *nurbss, *next_nurbss; + for( nurbss= currentSurface->o_nurbssurface; nurbss; nurbss = next_nurbss) { + next_nurbss = nurbss->next; + if( nurbss->save == 0 ) + do_freenurbssurface( nurbss ); + else + nurbss->used = 0; + } + + if( currentSurface->save == 0 ) do_freebgnsurface( currentSurface ); +} + +void +NurbsTessellator::do_freecurveall( O_curve *curve ) +{ + assert( curve->curvetype != ct_none ); + + if( curve->curvetype == ct_nurbscurve ) { + O_nurbscurve *ncurve, *next_ncurve; + for( ncurve=curve->curve.o_nurbscurve; ncurve; ncurve=next_ncurve ) { + next_ncurve = ncurve->next; + if( ncurve->save == 0 ) + do_freenurbscurve( ncurve ); + else + ncurve->used = 0; + } + } else { + O_pwlcurve *pcurve, *next_pcurve; + for( pcurve=curve->curve.o_pwlcurve; pcurve; pcurve=next_pcurve ) { + next_pcurve = pcurve->next; + if( pcurve->save == 0 ) + do_freepwlcurve( pcurve ); + else + pcurve->used = 0; + } + } + if( curve->save == 0 ) + do_freebgncurve( curve ); +} + + +/*----------------------------------------------------------------------------- + * do_freebgntrim - free the space allocated for a trim loop + * + * Client: + *----------------------------------------------------------------------------- + */ +void +NurbsTessellator::do_freebgntrim( O_trim *o_trim ) +{ + o_trim->deleteMe( o_trimPool ); +} + + +/*----------------------------------------------------------------------------- + * do_bgntrim - link in a trim loop to the current trimmed surface description + * + * Client: bgntrim() + *----------------------------------------------------------------------------- + */ +void +NurbsTessellator::do_bgntrim( O_trim *o_trim ) +{ + + if( ! inSurface ) { + do_nurbserror( 15 ); + bgnsurface( 0 ); + inSurface = 2; + } + + if( inTrim ) { + do_nurbserror( 16 ); + endtrim(); + } + inTrim = 1; + + if( *nextTrim != o_trim ) { + isTrimModified = 1; + *nextTrim = o_trim; + } + + currentTrim = o_trim; + nextTrim = &(o_trim->next); + nextCurve = &(o_trim->o_curve); +} + + +/*----------------------------------------------------------------------------- + * do_endtrim - mark the end of the current trim loop + * + * Client: endtrim() + *----------------------------------------------------------------------------- + */ +void +NurbsTessellator::do_endtrim( void ) +{ + if( ! inTrim ) { + do_nurbserror( 17 ); + return; + } + inTrim = 0; + + if( currentTrim->o_curve == 0 ) { + do_nurbserror( 18 ); + isDataValid = 0; + } + + numTrims++; + + if( *nextCurve != 0 ) { + isTrimModified = 1; + *nextCurve = 0; + } +} + +/*----------------------------------------------------------------------------- + * do_freepwlcurve - + * + * Client: + *----------------------------------------------------------------------------- + */ +void +NurbsTessellator::do_freepwlcurve( O_pwlcurve *o_pwlcurve ) +{ + o_pwlcurve->deleteMe( o_pwlcurvePool ); +} + +void +NurbsTessellator::do_freebgncurve( O_curve *o_curve ) +{ + o_curve->deleteMe( o_curvePool ); +} + +/*----------------------------------------------------------------------------- + * do_pwlcurve - link in pwl trim loop to the current surface description + * + * Client: pwlcurve() + *----------------------------------------------------------------------------- + */ +void +NurbsTessellator::do_pwlcurve( O_pwlcurve *o_pwlcurve ) +{ + if( ! inTrim ) { + do_nurbserror( 19 ); + if( o_pwlcurve->save == 0 ) + do_freepwlcurve(o_pwlcurve ); + return; + } + + if( ! inCurve ) { + bgncurve( 0 ); + inCurve = 2; + } + + if( o_pwlcurve->used ) { + do_nurbserror( 20 ); + isDataValid = 0; + return; + } else + o_pwlcurve->used = 1; + + if( currentCurve->curvetype == ct_none ) { + currentCurve->curvetype = ct_pwlcurve; + } else if( currentCurve->curvetype != ct_pwlcurve ) { + do_nurbserror( 21 ); + isDataValid = 0; + return; + } + + if( *nextPwlcurve != o_pwlcurve ) { + isCurveModified = 1; + *nextPwlcurve = o_pwlcurve; + } + nextPwlcurve = &(o_pwlcurve->next); + + if( o_pwlcurve->owner != currentCurve ) { + isCurveModified = 1; + o_pwlcurve->owner = currentCurve; + } + + if( (inCurve == 2) ) + endcurve(); +} + + +/*----------------------------------------------------------------------------- + * do_freenurbscurve - + * + * Client: + *----------------------------------------------------------------------------- + */ +void +NurbsTessellator::do_freenurbscurve( O_nurbscurve *o_nurbscurve ) +{ + o_nurbscurve->bezier_curves->deleteMe( quiltPool ); + o_nurbscurve->deleteMe( o_nurbscurvePool ); +} + + +/*----------------------------------------------------------------------------- + * do_nurbscurve - + * + * Client: nurbscurve() + *----------------------------------------------------------------------------- + */ +void +NurbsTessellator::do_nurbscurve( O_nurbscurve *o_nurbscurve ) +{ + if ( ! inCurve ) { + bgncurve( 0 ); + inCurve = 2; + } + + if( o_nurbscurve->used ) { + /* error - curve was already called in current surface */ + do_nurbserror( 23 ); + isDataValid = 0; + return; + } else + o_nurbscurve->used = 1; + + if( currentCurve->curvetype == ct_none ) { + currentCurve->curvetype = ct_nurbscurve; + } else if( currentCurve->curvetype != ct_nurbscurve ) { + do_nurbserror( 24 ); + isDataValid = 0; + return; + } + + if( *nextNurbscurve != o_nurbscurve ) { + isCurveModified = 1; + *nextNurbscurve = o_nurbscurve; + } + + nextNurbscurve = &(o_nurbscurve->next); + + if( o_nurbscurve->owner != currentCurve ) { + isCurveModified = 1; + o_nurbscurve->owner = currentCurve; + } + + if( o_nurbscurve->owner == 0 ) + isCurveModified = 1; + + if( inCurve == 2 ) + endcurve(); +} + + +/*----------------------------------------------------------------------------- + * do_freenurbssurface - + * + * Client: + *----------------------------------------------------------------------------- + */ + +void +NurbsTessellator::do_freenurbssurface( O_nurbssurface *o_nurbssurface ) +{ + o_nurbssurface->bezier_patches->deleteMe( quiltPool ); + o_nurbssurface->deleteMe( o_nurbssurfacePool ); +} + +/*----------------------------------------------------------------------------- + * do_nurbssurface - + * + * Client: nurbssurface() + *----------------------------------------------------------------------------- + */ +void +NurbsTessellator::do_nurbssurface( O_nurbssurface *o_nurbssurface ) +{ + if( ! inSurface ) { + bgnsurface( 0 ); + inSurface = 2; + } + + if( o_nurbssurface->used ) { + /* error - surface was already called in current block */ + do_nurbserror( 25 ); + isDataValid = 0; + return; + } else + o_nurbssurface->used = 1; + + if( *nextNurbssurface != o_nurbssurface ) { + isSurfaceModified = 1; + *nextNurbssurface = o_nurbssurface; + } + + if( o_nurbssurface->owner != currentSurface ) { + isSurfaceModified = 1; + o_nurbssurface->owner = currentSurface; + } + nextNurbssurface = &(o_nurbssurface->next); + + if( inSurface == 2 ) + endsurface(); +} + + +/*----------------------------------------------------------------------------- + * do_freenurbsproperty + * + *----------------------------------------------------------------------------- + */ + +void +NurbsTessellator::do_freenurbsproperty( Property *prop ) +{ + prop->deleteMe( propertyPool ); +} + + +/*----------------------------------------------------------------------------- + * do_setnurbsproperty - + * + *----------------------------------------------------------------------------- + */ + +void +NurbsTessellator::do_setnurbsproperty( Property *prop ) +{ + renderhints.setProperty( prop->tag, prop->value ); + if( prop->save == 0 ) + do_freenurbsproperty( prop ); +} + +void +NurbsTessellator::do_setnurbsproperty2( Property *prop ) +{ + Mapdesc *mapdesc = maplist.find( prop->type ); + + mapdesc->setProperty( prop->tag, prop->value ); + if( prop->save == 0 ) + do_freenurbsproperty( prop ); +} + +void +NurbsTessellator::errorHandler( int ) +{ +} + +void +NurbsTessellator::do_nurbserror( int msg ) +{ + errorHandler( msg ); +} + +int +NurbsTessellator::do_check_knots( Knotvector *knots, const char *msg ) +{ + int status = knots->validate(); + if( status ) { + do_nurbserror( status ); + if( renderhints.errorchecking != N_NOMSG ) knots->show( msg ); + } + return status; +} + + + + + diff --git a/mesalib/src/glu/sgi/libnurbs/internals/nurbstess.h b/mesalib/src/glu/sgi/libnurbs/internals/nurbstess.h new file mode 100644 index 000000000..a6869002f --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/nurbstess.h @@ -0,0 +1,172 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * nurbstess.h + * + */ + +#ifndef __glunurbstess_h_ +#define __glunurbstess_h_ + +#include "mysetjmp.h" +#include "subdivider.h" +#include "renderhints.h" +#include "backend.h" +#include "maplist.h" +#include "reader.h" +#include "nurbsconsts.h" + +struct Knotvector; +class Quilt; +class DisplayList; +class BasicCurveEvaluator; +class BasicSurfaceEvaluator; + +class NurbsTessellator { +public: + NurbsTessellator( BasicCurveEvaluator &c, + BasicSurfaceEvaluator &e ); + virtual ~NurbsTessellator( void ); + + void getnurbsproperty( long, INREAL * ); + void getnurbsproperty( long, long, INREAL * ); + void setnurbsproperty( long, INREAL ); + void setnurbsproperty( long, long, INREAL ); + void setnurbsproperty( long, long, INREAL * ); + void setnurbsproperty( long, long, INREAL *, long, long ); + + // called before a tessellation begins/ends + virtual void bgnrender( void ); + virtual void endrender( void ); + + // called to make a display list of the output vertices + virtual void makeobj( int n ); + virtual void closeobj( void ); + + // called when a error occurs + virtual void errorHandler( int ); + + void bgnsurface( long ); + void endsurface( void ); + void bgntrim( void ); + void endtrim( void ); + void bgncurve( long ); + void endcurve( void ); + void pwlcurve( long, INREAL[], long, long ); + void nurbscurve( long, INREAL[], long, INREAL[], long, long ); + void nurbssurface( long, INREAL[], long, INREAL[], long, long, + INREAL[], long, long, long ); + + void defineMap( long, long, long ); + void redefineMaps( void ); + + // recording of input description + void discardRecording( void * ); + void * beginRecording( void ); + void endRecording( void ); + void playRecording( void * ); + + //for optimizing untrimmed nurbs in the case of domain distance sampling + void set_domain_distance_u_rate(REAL u_rate); + void set_domain_distance_v_rate(REAL v_rate); + void set_is_domain_distance_sampling(int flag); + + +protected: + Renderhints renderhints; + Maplist maplist; + Backend backend; + +private: + + void resetObjects( void ); + int do_check_knots( Knotvector *, const char * ); + void do_nurbserror( int ); + void do_bgncurve( O_curve * ); + void do_endcurve( void ); + void do_freeall( void ); + void do_freecurveall( O_curve * ); + void do_freebgntrim( O_trim * ); + void do_freebgncurve( O_curve * ); + void do_freepwlcurve( O_pwlcurve * ); + void do_freenurbscurve( O_nurbscurve * ); + void do_freenurbssurface( O_nurbssurface * ); + void do_freebgnsurface( O_surface * ); + void do_bgnsurface( O_surface * ); + void do_endsurface( void ); + void do_bgntrim( O_trim * ); + void do_endtrim( void ); + void do_pwlcurve( O_pwlcurve * ); + void do_nurbscurve( O_nurbscurve * ); + void do_nurbssurface( O_nurbssurface * ); + void do_freenurbsproperty( Property * ); + void do_setnurbsproperty( Property * ); + void do_setnurbsproperty2( Property * ); + + Subdivider subdivider; + JumpBuffer* jumpbuffer; + Pool o_pwlcurvePool; + Pool o_nurbscurvePool; + Pool o_curvePool; + Pool o_trimPool; + Pool o_surfacePool; + Pool o_nurbssurfacePool; + Pool propertyPool; +public: + Pool quiltPool; +private: + TrimVertexPool extTrimVertexPool; + + int inSurface; /* bgnsurface seen */ + int inCurve; /* bgncurve seen */ + int inTrim; /* bgntrim seen */ + int isCurveModified; /* curve changed */ + int isTrimModified; /* trim curves changed */ + int isSurfaceModified; /* surface changed */ + int isDataValid; /* all data is good */ + int numTrims; /* valid trim regions */ + int playBack; + + O_trim** nextTrim; /* place to link o_trim */ + O_curve** nextCurve; /* place to link o_curve */ + O_nurbscurve** nextNurbscurve; /* place to link o_nurbscurve */ + O_pwlcurve** nextPwlcurve; /* place to link o_pwlcurve */ + O_nurbssurface** nextNurbssurface; /* place to link o_nurbssurface */ + + O_surface* currentSurface; + O_trim* currentTrim; + O_curve* currentCurve; + + DisplayList *dl; + +}; + +#endif /* __glunurbstess_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/patch.cc b/mesalib/src/glu/sgi/libnurbs/internals/patch.cc new file mode 100644 index 000000000..808baa69e --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/patch.cc @@ -0,0 +1,504 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * patch.c++ + * + */ + +#include <stdio.h> +#include "glimports.h" +#include "mystdio.h" +#include "myassert.h" +#include "mymath.h" +#include "mystring.h" +#include "patch.h" +#include "mapdesc.h" +#include "quilt.h" +#include "nurbsconsts.h" +#include "simplemath.h" //for glu_abs function in ::singleStep(); + + +/*-------------------------------------------------------------------------- + * Patch - copy patch from quilt and transform control points + *-------------------------------------------------------------------------- + */ + +Patch::Patch( Quilt_ptr geo, REAL *pta, REAL *ptb, Patch *n ) +{ +/* pspec[i].range is uninit here */ + mapdesc = geo->mapdesc; + cullval = mapdesc->isCulling() ? CULL_ACCEPT : CULL_TRIVIAL_ACCEPT; + notInBbox = mapdesc->isBboxSubdividing() ? 1 : 0; + needsSampling = mapdesc->isRangeSampling() ? 1 : 0; + pspec[0].order = geo->qspec[0].order; + pspec[1].order = geo->qspec[1].order; + pspec[0].stride = pspec[1].order * MAXCOORDS; + pspec[1].stride = MAXCOORDS; + + /* transform control points to sampling and culling spaces */ + REAL *ps = geo->cpts; + geo->select( pta, ptb ); + ps += geo->qspec[0].offset; + ps += geo->qspec[1].offset; + ps += geo->qspec[0].index * geo->qspec[0].order * geo->qspec[0].stride; + ps += geo->qspec[1].index * geo->qspec[1].order * geo->qspec[1].stride; + + if( needsSampling ) { + mapdesc->xformSampling( ps, geo->qspec[0].order, geo->qspec[0].stride, + geo->qspec[1].order, geo->qspec[1].stride, + spts, pspec[0].stride, pspec[1].stride ); + } + + if( cullval == CULL_ACCEPT ) { + mapdesc->xformCulling( ps, geo->qspec[0].order, geo->qspec[0].stride, + geo->qspec[1].order, geo->qspec[1].stride, + cpts, pspec[0].stride, pspec[1].stride ); + } + + if( notInBbox ) { + mapdesc->xformBounding( ps, geo->qspec[0].order, geo->qspec[0].stride, + geo->qspec[1].order, geo->qspec[1].stride, + bpts, pspec[0].stride, pspec[1].stride ); + } + + /* set scale range */ + pspec[0].range[0] = geo->qspec[0].breakpoints[geo->qspec[0].index]; + pspec[0].range[1] = geo->qspec[0].breakpoints[geo->qspec[0].index+1]; + pspec[0].range[2] = pspec[0].range[1] - pspec[0].range[0]; + + pspec[1].range[0] = geo->qspec[1].breakpoints[geo->qspec[1].index]; + pspec[1].range[1] = geo->qspec[1].breakpoints[geo->qspec[1].index+1]; + pspec[1].range[2] = pspec[1].range[1] - pspec[1].range[0]; + + // may need to subdivide to match range of sub-patch + if( pspec[0].range[0] != pta[0] ) { + assert( pspec[0].range[0] < pta[0] ); + Patch lower( *this, 0, pta[0], 0 ); + *this = lower; + } + + if( pspec[0].range[1] != ptb[0] ) { + assert( pspec[0].range[1] > ptb[0] ); + Patch upper( *this, 0, ptb[0], 0 ); + } + + if( pspec[1].range[0] != pta[1] ) { + assert( pspec[1].range[0] < pta[1] ); + Patch lower( *this, 1, pta[1], 0 ); + *this = lower; + } + + if( pspec[1].range[1] != ptb[1] ) { + assert( pspec[1].range[1] > ptb[1] ); + Patch upper( *this, 1, ptb[1], 0 ); + } + checkBboxConstraint(); + next = n; +} + +/*-------------------------------------------------------------------------- + * Patch - subdivide a patch along an isoparametric line + *-------------------------------------------------------------------------- + */ + +Patch::Patch( Patch& upper, int param, REAL value, Patch *n ) +{ + Patch& lower = *this; + + lower.cullval = upper.cullval; + lower.mapdesc = upper.mapdesc; + lower.notInBbox = upper.notInBbox; + lower.needsSampling = upper.needsSampling; + lower.pspec[0].order = upper.pspec[0].order; + lower.pspec[1].order = upper.pspec[1].order; + lower.pspec[0].stride = upper.pspec[0].stride; + lower.pspec[1].stride = upper.pspec[1].stride; + lower.next = n; + + /* reset scale range */ + switch( param ) { + case 0: { + REAL d = (value-upper.pspec[0].range[0]) / upper.pspec[0].range[2]; + if( needsSampling ) + mapdesc->subdivide( upper.spts, lower.spts, d, pspec[1].order, + pspec[1].stride, pspec[0].order, pspec[0].stride ); + + if( cullval == CULL_ACCEPT ) + mapdesc->subdivide( upper.cpts, lower.cpts, d, pspec[1].order, + pspec[1].stride, pspec[0].order, pspec[0].stride ); + + if( notInBbox ) + mapdesc->subdivide( upper.bpts, lower.bpts, d, pspec[1].order, + pspec[1].stride, pspec[0].order, pspec[0].stride ); + + lower.pspec[0].range[0] = upper.pspec[0].range[0]; + lower.pspec[0].range[1] = value; + lower.pspec[0].range[2] = value - upper.pspec[0].range[0]; + upper.pspec[0].range[0] = value; + upper.pspec[0].range[2] = upper.pspec[0].range[1] - value; + + lower.pspec[1].range[0] = upper.pspec[1].range[0]; + lower.pspec[1].range[1] = upper.pspec[1].range[1]; + lower.pspec[1].range[2] = upper.pspec[1].range[2]; + break; + } + case 1: { + REAL d = (value-upper.pspec[1].range[0]) / upper.pspec[1].range[2]; + if( needsSampling ) + mapdesc->subdivide( upper.spts, lower.spts, d, pspec[0].order, + pspec[0].stride, pspec[1].order, pspec[1].stride ); + if( cullval == CULL_ACCEPT ) + mapdesc->subdivide( upper.cpts, lower.cpts, d, pspec[0].order, + pspec[0].stride, pspec[1].order, pspec[1].stride ); + if( notInBbox ) + mapdesc->subdivide( upper.bpts, lower.bpts, d, pspec[0].order, + pspec[0].stride, pspec[1].order, pspec[1].stride ); + lower.pspec[0].range[0] = upper.pspec[0].range[0]; + lower.pspec[0].range[1] = upper.pspec[0].range[1]; + lower.pspec[0].range[2] = upper.pspec[0].range[2]; + + lower.pspec[1].range[0] = upper.pspec[1].range[0]; + lower.pspec[1].range[1] = value; + lower.pspec[1].range[2] = value - upper.pspec[1].range[0]; + upper.pspec[1].range[0] = value; + upper.pspec[1].range[2] = upper.pspec[1].range[1] - value; + break; + } + } + + // inherit bounding box + if( mapdesc->isBboxSubdividing() && ! notInBbox ) + memcpy( lower.bb, upper.bb, sizeof( bb ) ); + + lower.checkBboxConstraint(); + upper.checkBboxConstraint(); +} + +/*-------------------------------------------------------------------------- + * clamp - clamp the sampling rate to a given maximum + *-------------------------------------------------------------------------- + */ + +void +Patch::clamp( void ) +{ + if( mapdesc->clampfactor != N_NOCLAMPING ) { + pspec[0].clamp( mapdesc->clampfactor ); + pspec[1].clamp( mapdesc->clampfactor ); + } +} + +void +Patchspec::clamp( REAL clampfactor ) +{ + if( sidestep[0] < minstepsize ) + sidestep[0] = clampfactor * minstepsize; + if( sidestep[1] < minstepsize ) + sidestep[1] = clampfactor * minstepsize; + if( stepsize < minstepsize ) + stepsize = clampfactor * minstepsize; +} + +void +Patch::checkBboxConstraint( void ) +{ + if( notInBbox && + mapdesc->bboxTooBig( bpts, pspec[0].stride, pspec[1].stride, + pspec[0].order, pspec[1].order, bb ) != 1 ) { + notInBbox = 0; + } +} + +void +Patch::bbox( void ) +{ + if( mapdesc->isBboxSubdividing() ) + mapdesc->surfbbox( bb ); +} + +/*-------------------------------------------------------------------------- + * getstepsize - compute the sampling density across the patch + * and determine if patch needs to be subdivided + *-------------------------------------------------------------------------- + */ + +void +Patch::getstepsize( void ) +{ + pspec[0].minstepsize = pspec[1].minstepsize = 0; + pspec[0].needsSubdivision = pspec[1].needsSubdivision = 0; + + if( mapdesc->isConstantSampling() ) { + // fixed number of samples per patch in each direction + // maxsrate is number of s samples per patch + // maxtrate is number of t samples per patch + pspec[0].getstepsize( mapdesc->maxsrate ); + pspec[1].getstepsize( mapdesc->maxtrate ); + + } else if( mapdesc->isDomainSampling() ) { + // maxsrate is number of s samples per unit s length of domain + // maxtrate is number of t samples per unit t length of domain + pspec[0].getstepsize( mapdesc->maxsrate * pspec[0].range[2] ); + pspec[1].getstepsize( mapdesc->maxtrate * pspec[1].range[2] ); + + } else if( ! needsSampling ) { + pspec[0].singleStep(); + pspec[1].singleStep(); + } else { + // upper bound on path length between sample points + REAL tmp[MAXORDER][MAXORDER][MAXCOORDS]; + const int trstride = sizeof(tmp[0]) / sizeof(REAL); + const int tcstride = sizeof(tmp[0][0]) / sizeof(REAL); + + assert( pspec[0].order <= MAXORDER ); + + /* points have been transformed, therefore they are homogeneous */ + + int val = mapdesc->project( spts, pspec[0].stride, pspec[1].stride, + &tmp[0][0][0], trstride, tcstride, + pspec[0].order, pspec[1].order ); + if( val == 0 ) { + // control points cross infinity, therefore partials are undefined + pspec[0].getstepsize( mapdesc->maxsrate ); + pspec[1].getstepsize( mapdesc->maxtrate ); + } else { + REAL t1 = mapdesc->getProperty( N_PIXEL_TOLERANCE ); +// REAL t2 = mapdesc->getProperty( N_ERROR_TOLERANCE ); + pspec[0].minstepsize = ( mapdesc->maxsrate > 0.0 ) ? + (pspec[0].range[2] / mapdesc->maxsrate) : 0.0; + pspec[1].minstepsize = ( mapdesc->maxtrate > 0.0 ) ? + (pspec[1].range[2] / mapdesc->maxtrate) : 0.0; + if( mapdesc->isParametricDistanceSampling() || + mapdesc->isObjectSpaceParaSampling() ) { + + REAL t2; + t2 = mapdesc->getProperty( N_ERROR_TOLERANCE ); + + // t2 is upper bound on the distance between surface and tessellant + REAL ssv[2], ttv[2]; + REAL ss = mapdesc->calcPartialVelocity( ssv, &tmp[0][0][0], trstride, tcstride, pspec[0].order, pspec[1].order, 2, 0, pspec[0].range[2], pspec[1].range[2], 0 ); + REAL st = mapdesc->calcPartialVelocity( 0, &tmp[0][0][0], trstride, tcstride, pspec[0].order, pspec[1].order, 1, 1, pspec[0].range[2], pspec[1].range[2], -1 ); + REAL tt = mapdesc->calcPartialVelocity( ttv, &tmp[0][0][0], trstride, tcstride, pspec[0].order, pspec[1].order, 0, 2, pspec[0].range[2], pspec[1].range[2], 1 ); + //make sure that ss st and tt are nonnegative: + if(ss <0) ss = -ss; + if(st <0) st = -st; + if(tt <0) tt = -tt; + + if( ss != 0.0 && tt != 0.0 ) { + /* printf( "ssv[0] %g ssv[1] %g ttv[0] %g ttv[1] %g\n", + ssv[0], ssv[1], ttv[0], ttv[1] ); */ + REAL ttq = sqrtf( (float) ss ); + REAL ssq = sqrtf( (float) tt ); + REAL ds = sqrtf( 4 * t2 * ttq / ( ss * ttq + st * ssq ) ); + REAL dt = sqrtf( 4 * t2 * ssq / ( tt * ssq + st * ttq ) ); + pspec[0].stepsize = ( ds < pspec[0].range[2] ) ? ds : pspec[0].range[2]; + REAL scutoff = 2.0 * t2 / ( pspec[0].range[2] * pspec[0].range[2]); + pspec[0].sidestep[0] = (ssv[0] > scutoff) ? sqrtf( 2.0 * t2 / ssv[0] ) : pspec[0].range[2]; + pspec[0].sidestep[1] = (ssv[1] > scutoff) ? sqrtf( 2.0 * t2 / ssv[1] ) : pspec[0].range[2]; + + pspec[1].stepsize = ( dt < pspec[1].range[2] ) ? dt : pspec[1].range[2]; + REAL tcutoff = 2.0 * t2 / ( pspec[1].range[2] * pspec[1].range[2]); + pspec[1].sidestep[0] = (ttv[0] > tcutoff) ? sqrtf( 2.0 * t2 / ttv[0] ) : pspec[1].range[2]; + pspec[1].sidestep[1] = (ttv[1] > tcutoff) ? sqrtf( 2.0 * t2 / ttv[1] ) : pspec[1].range[2]; + } else if( ss != 0.0 ) { + REAL x = pspec[1].range[2] * st; + REAL ds = ( sqrtf( x * x + 8.0 * t2 * ss ) - x ) / ss; + pspec[0].stepsize = ( ds < pspec[0].range[2] ) ? ds : pspec[0].range[2]; + REAL scutoff = 2.0 * t2 / ( pspec[0].range[2] * pspec[0].range[2]); + pspec[0].sidestep[0] = (ssv[0] > scutoff) ? sqrtf( 2.0 * t2 / ssv[0] ) : pspec[0].range[2]; + pspec[0].sidestep[1] = (ssv[1] > scutoff) ? sqrtf( 2.0 * t2 / ssv[1] ) : pspec[0].range[2]; + pspec[1].singleStep(); + } else if( tt != 0.0 ) { + REAL x = pspec[0].range[2] * st; + REAL dt = ( sqrtf( x * x + 8.0 * t2 * tt ) - x ) / tt; + pspec[0].singleStep(); + REAL tcutoff = 2.0 * t2 / ( pspec[1].range[2] * pspec[1].range[2]); + pspec[1].stepsize = ( dt < pspec[1].range[2] ) ? dt : pspec[1].range[2]; + pspec[1].sidestep[0] = (ttv[0] > tcutoff) ? sqrtf( 2.0 * t2 / ttv[0] ) : pspec[1].range[2]; + pspec[1].sidestep[1] = (ttv[1] > tcutoff) ? sqrtf( 2.0 * t2 / ttv[1] ) : pspec[1].range[2]; + } else { + if( 4.0 * t2 > st * pspec[0].range[2] * pspec[1].range[2] ) { + pspec[0].singleStep(); + pspec[1].singleStep(); + } else { + REAL area = 4.0 * t2 / st; + REAL ds = sqrtf( area * pspec[0].range[2] / pspec[1].range[2] ); + REAL dt = sqrtf( area * pspec[1].range[2] / pspec[0].range[2] ); + pspec[0].stepsize = ( ds < pspec[0].range[2] ) ? ds : pspec[0].range[2]; + pspec[0].sidestep[0] = pspec[0].range[2]; + pspec[0].sidestep[1] = pspec[0].range[2]; + + pspec[1].stepsize = ( dt < pspec[1].range[2] ) ? dt : pspec[1].range[2]; + pspec[1].sidestep[0] = pspec[1].range[2]; + pspec[1].sidestep[1] = pspec[1].range[2]; + } + } + } else if( mapdesc->isPathLengthSampling() || + mapdesc->isObjectSpacePathSampling()) { + // t1 is upper bound on path length + REAL msv[2], mtv[2]; + REAL ms = mapdesc->calcPartialVelocity( msv, &tmp[0][0][0], trstride, tcstride, pspec[0].order, pspec[1].order, 1, 0, pspec[0].range[2], pspec[1].range[2], 0 ); + REAL mt = mapdesc->calcPartialVelocity( mtv, &tmp[0][0][0], trstride, tcstride, pspec[0].order, pspec[1].order, 0, 1, pspec[0].range[2], pspec[1].range[2], 1 ); + REAL side_scale = 1.0; + + if( ms != 0.0 ) { + if( mt != 0.0 ) { +/* REAL d = t1 / ( ms * ms + mt * mt );*/ +/* REAL ds = mt * d;*/ + REAL ds = t1 / (2.0*ms); +/* REAL dt = ms * d;*/ + REAL dt = t1 / (2.0*mt); + pspec[0].stepsize = ( ds < pspec[0].range[2] ) ? ds : pspec[0].range[2]; + pspec[0].sidestep[0] = ( msv[0] * pspec[0].range[2] > t1 ) ? (side_scale* t1 / msv[0]) : pspec[0].range[2]; + pspec[0].sidestep[1] = ( msv[1] * pspec[0].range[2] > t1 ) ? (side_scale* t1 / msv[1]) : pspec[0].range[2]; + + pspec[1].stepsize = ( dt < pspec[1].range[2] ) ? dt : pspec[1].range[2]; + pspec[1].sidestep[0] = ( mtv[0] * pspec[1].range[2] > t1 ) ? (side_scale*t1 / mtv[0]) : pspec[1].range[2]; + pspec[1].sidestep[1] = ( mtv[1] * pspec[1].range[2] > t1 ) ? (side_scale*t1 / mtv[1]) : pspec[1].range[2]; + } else { + pspec[0].stepsize = ( t1 < ms * pspec[0].range[2] ) ? (t1 / ms) : pspec[0].range[2]; + pspec[0].sidestep[0] = ( msv[0] * pspec[0].range[2] > t1 ) ? (t1 / msv[0]) : pspec[0].range[2]; + pspec[0].sidestep[1] = ( msv[1] * pspec[0].range[2] > t1 ) ? (t1 / msv[1]) : pspec[0].range[2]; + + pspec[1].singleStep(); + } + } else { + if( mt != 0.0 ) { + pspec[0].singleStep(); + + pspec[1].stepsize = ( t1 < mt * pspec[1].range[2] ) ? (t1 / mt) : pspec[1].range[2]; + pspec[1].sidestep[0] = ( mtv[0] * pspec[1].range[2] > t1 ) ? (t1 / mtv[0]) : pspec[1].range[2]; + pspec[1].sidestep[1] = ( mtv[1] * pspec[1].range[2] > t1 ) ? (t1 / mtv[1]) : pspec[1].range[2]; + } else { + pspec[0].singleStep(); + pspec[1].singleStep(); + } + } + } else if( mapdesc->isSurfaceAreaSampling() ) { + // t is the square root of area +/* + REAL msv[2], mtv[2]; + REAL ms = mapdesc->calcPartialVelocity( msv, &tmp[0][0][0], trstride, tcstride, pspec[0].order, pspec[1].order, 1, 0, pspec[0].range[2], pspec[1].range[2], 0 ); + REAL mt = mapdesc->calcPartialVelocity( mtv, &tmp[0][0][0], trstride, tcstride, pspec[0].order, pspec[1].order, 0, 1, pspec[0].range[2], pspec[1].range[2], 1 ); + if( ms != 0.0 && mt != 0.0 ) { + REAL d = 1.0 / (ms * mt); + t *= M_SQRT2; + REAL ds = t * sqrtf( d * pspec[0].range[2] / pspec[1].range[2] ); + REAL dt = t * sqrtf( d * pspec[1].range[2] / pspec[0].range[2] ); + pspec[0].stepsize = ( ds < pspec[0].range[2] ) ? ds : pspec[0].range[2]; + pspec[0].sidestep[0] = ( msv[0] * pspec[0].range[2] > t ) ? (t / msv[0]) : pspec[0].range[2]; + pspec[0].sidestep[1] = ( msv[1] * pspec[0].range[2] > t ) ? (t / msv[1]) : pspec[0].range[2]; + + pspec[1].stepsize = ( dt < pspec[1].range[2] ) ? dt : pspec[1].range[2]; + pspec[1].sidestep[0] = ( mtv[0] * pspec[1].range[2] > t ) ? (t / mtv[0]) : pspec[1].range[2]; + pspec[1].sidestep[1] = ( mtv[1] * pspec[1].range[2] > t ) ? (t / mtv[1]) : pspec[1].range[2]; + } else { + pspec[0].singleStep(); + pspec[1].singleStep(); + } +*/ + } else { + pspec[0].singleStep(); + pspec[1].singleStep(); + } + } + } + +#ifdef DEBUG + _glu_dprintf( "sidesteps %g %g %g %g, stepsize %g %g\n", + pspec[0].sidestep[0], pspec[0].sidestep[1], + pspec[1].sidestep[0], pspec[1].sidestep[1], + pspec[0].stepsize, pspec[1].stepsize ); +#endif + + if( mapdesc->minsavings != N_NOSAVINGSSUBDIVISION ) { + REAL savings = 1./(pspec[0].stepsize * pspec[1].stepsize) ; + savings-= (2./( pspec[0].sidestep[0] + pspec[0].sidestep[1] )) * + (2./( pspec[1].sidestep[0] + pspec[1].sidestep[1] )); + + savings *= pspec[0].range[2] * pspec[1].range[2]; + if( savings > mapdesc->minsavings ) { + pspec[0].needsSubdivision = pspec[1].needsSubdivision = 1; + } + } + + if( pspec[0].stepsize < pspec[0].minstepsize ) pspec[0].needsSubdivision = 1; + if( pspec[1].stepsize < pspec[1].minstepsize ) pspec[1].needsSubdivision = 1; + needsSampling = (needsSampling ? needsSamplingSubdivision() : 0); +} + +void +Patchspec::singleStep() +{ + stepsize = sidestep[0] = sidestep[1] = glu_abs(range[2]); +} + +void +Patchspec::getstepsize( REAL max ) // max is number of samples for entire patch +{ + stepsize = ( max >= 1.0 ) ? range[2] / max : range[2]; + if (stepsize < 0.0) { + stepsize = -stepsize; + } + sidestep[0] = sidestep[1] = minstepsize = stepsize; +} + +int +Patch::needsSamplingSubdivision( void ) +{ + return (pspec[0].needsSubdivision || pspec[1].needsSubdivision) ? 1 : 0; +} + +int +Patch::needsNonSamplingSubdivision( void ) +{ + return notInBbox; +} + +int +Patch::needsSubdivision( int param ) +{ + return pspec[param].needsSubdivision; +} + +int +Patch::cullCheck( void ) +{ + if( cullval == CULL_ACCEPT ) + cullval = mapdesc->cullCheck( cpts, pspec[0].order, pspec[0].stride, + pspec[1].order, pspec[1].stride ); + return cullval; +} + diff --git a/mesalib/src/glu/sgi/libnurbs/internals/patch.h b/mesalib/src/glu/sgi/libnurbs/internals/patch.h new file mode 100644 index 000000000..324a25938 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/patch.h @@ -0,0 +1,94 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * patch.h + * + */ + +#ifndef __glupatch_h_ +#define __glupatch_h_ + +#include "types.h" +#include "defines.h" + +class Quilt; +class Mapdesc; + + +struct Pspec { + REAL range[3]; + REAL sidestep[2]; + REAL stepsize; + REAL minstepsize; + int needsSubdivision; +}; + +struct Patchspec : public Pspec { + int order; + int stride; + void clamp( REAL ); + void getstepsize( REAL ); + void singleStep( void ); +}; + +class Patch { +public: +friend class Subdivider; +friend class Quilt; +friend class Patchlist; + Patch( Quilt *, REAL*, REAL *, Patch * ); + Patch( Patch &, int, REAL, Patch * ); + void bbox( void ); + void clamp( void ); + void getstepsize( void ); + int cullCheck( void ); + int needsSubdivision( int ); + int needsSamplingSubdivision( void ); + int needsNonSamplingSubdivision( void ); + + int get_uorder() {return pspec[0].order;} + int get_vorder() {return pspec[1].order;} + +private: + + Mapdesc* mapdesc; + Patch* next; + int cullval; + int notInBbox; + int needsSampling; + REAL cpts[MAXORDER*MAXORDER*MAXCOORDS]; //culling pts + REAL spts[MAXORDER*MAXORDER*MAXCOORDS]; //sampling pts + REAL bpts[MAXORDER*MAXORDER*MAXCOORDS]; //bbox pts + Patchspec pspec[2]; + void checkBboxConstraint( void ); + REAL bb[2][MAXCOORDS]; +}; +#endif /* __glupatch_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/patchlist.cc b/mesalib/src/glu/sgi/libnurbs/internals/patchlist.cc new file mode 100644 index 000000000..989d2dd00 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/patchlist.cc @@ -0,0 +1,170 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * patchlist.c++ + * + */ + +#include <stdio.h> +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "quilt.h" +#include "patchlist.h" +#include "patch.h" +#include "nurbsconsts.h" + +Patchlist::Patchlist( Quilt *quilts, REAL *pta, REAL *ptb ) +{ + patch = 0; + for( Quilt *q = quilts; q; q = q->next ) + patch = new Patch( q, pta, ptb, patch ); + pspec[0].range[0] = pta[0]; + pspec[0].range[1] = ptb[0]; + pspec[0].range[2] = ptb[0] - pta[0]; + + pspec[1].range[0] = pta[1]; + pspec[1].range[1] = ptb[1]; + pspec[1].range[2] = ptb[1] - pta[1]; +} + +Patchlist::Patchlist( Patchlist &upper, int param, REAL value) +{ + Patchlist &lower = *this; + patch = 0; + for( Patch *p = upper.patch; p; p = p->next ) + patch = new Patch( *p, param, value, patch ); + + if( param == 0 ) { + lower.pspec[0].range[0] = upper.pspec[0].range[0]; + lower.pspec[0].range[1] = value; + lower.pspec[0].range[2] = value - upper.pspec[0].range[0]; + upper.pspec[0].range[0] = value; + upper.pspec[0].range[2] = upper.pspec[0].range[1] - value; + lower.pspec[1] = upper.pspec[1]; + } else { + lower.pspec[0] = upper.pspec[0]; + lower.pspec[1].range[0] = upper.pspec[1].range[0]; + lower.pspec[1].range[1] = value; + lower.pspec[1].range[2] = value - upper.pspec[1].range[0]; + upper.pspec[1].range[0] = value; + upper.pspec[1].range[2] = upper.pspec[1].range[1] - value; + } +} + +Patchlist::~Patchlist() +{ + while( patch ) { + Patch *p = patch; + patch = patch->next; + delete p; + } +} + +int +Patchlist::cullCheck( void ) +{ + for( Patch *p = patch; p; p = p->next ) + if( p->cullCheck() == CULL_TRIVIAL_REJECT ) + return CULL_TRIVIAL_REJECT; + return CULL_ACCEPT; +} + +void +Patchlist::getRanges(REAL ranges[4]) +{ + ranges[0] = pspec[0].range[0]; + ranges[1] = pspec[0].range[1]; + ranges[2] = pspec[1].range[0]; + ranges[3] = pspec[1].range[1]; +} + +void +Patchlist::getstepsize( void ) +{ + pspec[0].stepsize = pspec[0].range[2]; + pspec[0].sidestep[0] = pspec[0].range[2]; + pspec[0].sidestep[1] = pspec[0].range[2]; + + pspec[1].stepsize = pspec[1].range[2]; + pspec[1].sidestep[0] = pspec[1].range[2]; + pspec[1].sidestep[1] = pspec[1].range[2]; + + for( Patch *p = patch; p; p = p->next ) { + p->getstepsize(); + p->clamp(); + pspec[0].stepsize = ((p->pspec[0].stepsize < pspec[0].stepsize) ? p->pspec[0].stepsize : pspec[0].stepsize); + pspec[0].sidestep[0] = ((p->pspec[0].sidestep[0] < pspec[0].sidestep[0]) ? p->pspec[0].sidestep[0] : pspec[0].sidestep[0]); + pspec[0].sidestep[1] = ((p->pspec[0].sidestep[1] < pspec[0].sidestep[1]) ? p->pspec[0].sidestep[1] : pspec[0].sidestep[1]); + pspec[1].stepsize = ((p->pspec[1].stepsize < pspec[1].stepsize) ? p->pspec[1].stepsize : pspec[1].stepsize); + pspec[1].sidestep[0] = ((p->pspec[1].sidestep[0] < pspec[1].sidestep[0]) ? p->pspec[1].sidestep[0] : pspec[1].sidestep[0]); + pspec[1].sidestep[1] = ((p->pspec[1].sidestep[1] < pspec[1].sidestep[1]) ? p->pspec[1].sidestep[1] : pspec[1].sidestep[1]); + } +} + +void +Patchlist::bbox( void ) +{ + for( Patch *p = patch; p; p = p->next ) + p->bbox(); +} + +int +Patchlist::needsNonSamplingSubdivision( void ) +{ + notInBbox = 0; + for( Patch *p = patch; p; p = p->next ) + notInBbox |= p->needsNonSamplingSubdivision(); + return notInBbox; +} + +int +Patchlist::needsSamplingSubdivision( void ) +{ + pspec[0].needsSubdivision = 0; + pspec[1].needsSubdivision = 0; + + for( Patch *p = patch; p; p = p->next ) { + pspec[0].needsSubdivision |= p->pspec[0].needsSubdivision; + pspec[1].needsSubdivision |= p->pspec[0].needsSubdivision; + } + return (pspec[0].needsSubdivision || pspec[1].needsSubdivision) ? 1 : 0; +} + +int +Patchlist::needsSubdivision( int param ) +{ + return pspec[param].needsSubdivision; +} diff --git a/mesalib/src/glu/sgi/libnurbs/internals/patchlist.h b/mesalib/src/glu/sgi/libnurbs/internals/patchlist.h new file mode 100644 index 000000000..9bfc5b47a --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/patchlist.h @@ -0,0 +1,92 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * patchlist.h + * + */ + +#ifndef __glupatchlist_h_ +#define __glupatchlist_h_ + +#include "types.h" +#include "defines.h" +#include "patch.h" + +class Quilt; + +class Patchlist { +friend class Subdivider; +public: + Patchlist( Quilt *, REAL *, REAL * ); + Patchlist( Patchlist &, int , REAL ); + ~Patchlist(); + void bbox(); + int cullCheck( void ); + void getstepsize( void ); + int needsNonSamplingSubdivision( void ); + int needsSamplingSubdivision( void ); + int needsSubdivision( int ); + REAL getStepsize( int ); + void getRanges(REAL ranges[4]); + + int get_uorder(); + int get_vorder(); +private: + Patch *patch; + int notInBbox; + int needsSampling; + Pspec pspec[2]; +}; + +inline REAL +Patchlist::getStepsize( int param ) +{ + return pspec[param].stepsize; +} + +inline int +Patchlist::get_uorder() +{ + return patch->get_uorder(); + +} + +inline int + Patchlist::get_vorder() +{ + return patch->get_vorder(); +} + + + + + +#endif /* __glupatchlist_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/pwlarc.h b/mesalib/src/glu/sgi/libnurbs/internals/pwlarc.h new file mode 100644 index 000000000..2e5175a6f --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/pwlarc.h @@ -0,0 +1,78 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * pwlarc.h + * + */ + +#ifndef __glupwlarc_h_ +#define __glupwlarc_h_ + +#include "myassert.h" +#include "nurbsconsts.h" + +class TrimVertex; + +class PwlArc : public PooledObj { /* a piecewise-linear arc */ +public: + TrimVertex * pts; /* sample points */ + int npts; /* number of sample points */ + long type; /* curve type */ + inline PwlArc( void ); + inline PwlArc( int, TrimVertex * ); + inline PwlArc( int, TrimVertex *, long ); +}; + +inline +PwlArc::PwlArc( void ) +{ + type = N_P2D; + pts = 0; + npts = -1; +} + +inline +PwlArc::PwlArc( int _npts, TrimVertex *_pts ) +{ + pts = _pts; + npts = _npts; + type = N_P2D; +} + +inline +PwlArc::PwlArc( int _npts, TrimVertex *_pts, long _type ) +{ + pts = _pts; + npts = _npts; + type = _type; +} + +#endif /* __glupwlarc_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/quilt.cc b/mesalib/src/glu/sgi/libnurbs/internals/quilt.cc new file mode 100644 index 000000000..4fc58b747 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/quilt.cc @@ -0,0 +1,276 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * quilt.c++ + * + */ + +#include "glimports.h" +#include "mystdio.h" +#include "myassert.h" +#include "quilt.h" +#include "backend.h" +#include "mapdesc.h" +#include "flist.h" +#include "knotvector.h" +#include "patchlist.h" +#include "math.h" //fglu_abs() +#include "simplemath.h" //min() + +/* local preprocessor definitions */ +#define DEF_PATCH_STEPSIZE .4 +#define fsizeof(x) (sizeof(x)/sizeof(REAL)) + + +Quilt::Quilt( Mapdesc *_mapdesc ) +{ + mapdesc = _mapdesc; +} + +void +Quilt::deleteMe( Pool& p ) +{ + for( Quiltspec *q=qspec; q != eqspec; q++ ) { +#if 1 + if( q->breakpoints) delete[] q->breakpoints; q->breakpoints = 0; +#else + if( q->breakpoints) { + delete[] q->breakpoints; + q->breakpoints = 0; +printf("in here\n"); + } +#endif + } + if( cpts ) delete[] cpts; + cpts = 0; + PooledObj::deleteMe( p ); +} + +void +Quilt::show( void ) +{ +#ifndef NDEBUG + int nc = mapdesc->getNcoords(); + REAL *ps = cpts; + ps += qspec[0].offset; + ps += qspec[1].offset; + for( int i=0; i!= qspec[0].order * qspec[0].width; i++ ) { + for( int j = 0; j!= qspec[1].order * qspec[1].width; j++ ) { + for( int k=0; k < nc; k++ ) + _glu_dprintf( "%g ", ps[i*qspec[0].stride + j*qspec[1].stride + k] ); + _glu_dprintf( "\n" ); + } + _glu_dprintf( "\n" ); + } + _glu_dprintf( "\n" ); +#endif +} + +/*-------------------------------------------------------------------------- + * Quilt::select - find which map in each quilt contains the points + * pta and ptb with pta[i] < ptb[i] + *-------------------------------------------------------------------------- + */ + +void +Quilt::select( REAL *pta, REAL *ptb ) +{ + int dim = eqspec - qspec; + int i, j; + for( i=0; i<dim; i++) { + for( j=qspec[i].width-1; j>=0; j-- ) + if( (qspec[i].breakpoints[j] <= pta[i] ) && + (ptb[i] <= qspec[i].breakpoints[j+1] ) ) + break; + assert( j != -1 ); + qspec[i].index = j; + } +} + +void +Quilt::download( Backend &backend ) +{ + if( getDimension() == 2 ) { + REAL *ps = cpts; + ps += qspec[0].offset; + ps += qspec[1].offset; + ps += qspec[0].index * qspec[0].order * qspec[0].stride; + ps += qspec[1].index * qspec[1].order * qspec[1].stride; + backend.surfpts( mapdesc->getType(), ps, + qspec[0].stride, + qspec[1].stride, + qspec[0].order, + qspec[1].order, + qspec[0].breakpoints[qspec[0].index], + qspec[0].breakpoints[qspec[0].index+1], + qspec[1].breakpoints[qspec[1].index], + qspec[1].breakpoints[qspec[1].index+1] ); + } else { + REAL *ps = cpts; + ps += qspec[0].offset; + ps += qspec[0].index * qspec[0].order * qspec[0].stride; + backend.curvpts( mapdesc->getType(), ps, + qspec[0].stride, + qspec[0].order, + qspec[0].breakpoints[qspec[0].index], + qspec[0].breakpoints[qspec[0].index+1] ); + } +} + +/*-------------------------------------------------------------------------- + * Quilt::downloadAll - download each map that contains the current patch + *-------------------------------------------------------------------------- + */ + +void +Quilt::downloadAll( REAL *pta, REAL *ptb, Backend &backend ) +{ + for( Quilt *m = this; m; m=m->next ) { + m->select( pta, ptb ); + m->download( backend ); + } +} + +/*-------------------------------------------------------------------------- + * Quilt::isCulled - determine if an entire quilt is trivially rejected. + *-------------------------------------------------------------------------- + */ + +int +Quilt::isCulled( void ) +{ + if( mapdesc->isCulling() ) + return mapdesc->xformAndCullCheck( cpts + qspec[0].offset + qspec[1].offset, + qspec[0].order * qspec[0].width, qspec[0].stride, + qspec[1].order * qspec[1].width, qspec[1].stride ); + else + return CULL_ACCEPT; +} + +/*--------------------------------------------------------------------------- + * Quilt::getRange - retrieve the valid paramater range of a set of quilts + *--------------------------------------------------------------------------- + */ +void +Quilt::getRange( REAL *from, REAL *to, Flist& slist, Flist &tlist ) +{ + getRange( from, to, 0, slist ); + getRange( from, to, 1, tlist ); +} + +/*--------------------------------------------------------------------------- + * Quilt::getRange - retrieve the valid paramater range of a set of quilts + *--------------------------------------------------------------------------- + */ +void +Quilt::getRange( REAL *from, REAL *to, int i, Flist &list ) +{ + Quilt *maps = this; + from[i] = maps->qspec[i].breakpoints[0]; + to[i] = maps->qspec[i].breakpoints[maps->qspec[i].width]; + int maxpts = 0; + Quilt_ptr m; + for( m=maps; m; m=m->next ) { + if( m->qspec[i].breakpoints[0] > from[i] ) + from[i] = m->qspec[i].breakpoints[0]; + if( m->qspec[i].breakpoints[m->qspec[i].width] < to[i] ) + to[i] = m->qspec[i].breakpoints[m->qspec[i].width]; + maxpts += m->qspec[i].width + 1; + } + + list.grow( maxpts ); + + for( m=maps; m; m=m->next ) + for( int j=0; j<=m->qspec[i].width; j++ ) { + list.add( m->qspec[i].breakpoints[j] ); + } + + list.filter( ); + list.taper( from[i], to[i] ); +} + +void +Quilt::getRange( REAL *from, REAL *to, Flist& slist ) +{ + getRange( from, to, 0, slist ); +} + +void +Quilt::findRates( Flist& slist, Flist& tlist, REAL rate[2] ) +{ + findSampleRates( slist, tlist ); + rate[0] = qspec[0].step_size; + rate[1] = qspec[1].step_size; + + for( Quilt *q = next; q; q = q->next ) { + q->findSampleRates( slist, tlist ); + if( q->qspec[0].step_size < rate[0] ) + rate[0] = q->qspec[0].step_size; + if( q->qspec[1].step_size < rate[1] ) + rate[1] = q->qspec[1].step_size; + } +} + +void +Quilt::findSampleRates( Flist& slist, Flist& tlist ) +{ + qspec[0].step_size = DEF_PATCH_STEPSIZE * + (qspec[0].breakpoints[qspec[0].width] - qspec[0].breakpoints[0]); + qspec[1].step_size = DEF_PATCH_STEPSIZE * + (qspec[1].breakpoints[qspec[1].width] - qspec[1].breakpoints[0]); + + for( int i = slist.start; i < slist.end-1; i++ ) { + for( int j = tlist.start; j < tlist.end-1; j++ ) { + + REAL pta[2], ptb[2]; + pta[0] = slist.pts[i]; + ptb[0] = slist.pts[i+1]; + pta[1] = tlist.pts[j]; + ptb[1] = tlist.pts[j+1]; + Patchlist patchlist( this, pta, ptb ); + patchlist.getstepsize(); + + { + float edge_len_s = min(glu_abs(ptb[0]-pta[0]),1.0); + float edge_len_t = min(glu_abs(ptb[1]-pta[1]),1.0); + + if( patchlist.getStepsize(0)/edge_len_s < qspec[0].step_size ) + qspec[0].step_size = patchlist.getStepsize(0)/edge_len_s; + if( patchlist.getStepsize(1)/edge_len_t < qspec[1].step_size ) + qspec[1].step_size = patchlist.getStepsize(1)/edge_len_t; + } + } + } +} diff --git a/mesalib/src/glu/sgi/libnurbs/internals/quilt.h b/mesalib/src/glu/sgi/libnurbs/internals/quilt.h new file mode 100644 index 000000000..fe1e3309e --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/quilt.h @@ -0,0 +1,92 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * quilt.h + * + */ + +#ifndef __gluquilt_h_ +#define __gluquilt_h_ + +#include "defines.h" +#include "bufpool.h" +#include "types.h" + +class Backend; +class Mapdesc; +class Flist; +struct Knotvector; + +/* constants for memory allocation of NURBS to Bezier conversion */ +#define MAXDIM 2 + +struct Quiltspec { /* a specification for a dimension of a quilt */ + int stride; /* words between points */ + int width; /* number of segments */ + int offset; /* words to first point */ + int order; /* order */ + int index; /* current segment number */ + int bdry[2]; /* boundary edge flag */ + REAL step_size; + Knot * breakpoints; +}; + +typedef Quiltspec *Quiltspec_ptr; + +class Quilt : public PooledObj { /* an array of bezier patches */ +public: + Quilt( Mapdesc * ); + Mapdesc * mapdesc; /* map descriptor */ + REAL * cpts; /* control points */ + Quiltspec qspec[MAXDIM]; /* the dimensional data */ + Quiltspec_ptr eqspec; /* qspec trailer */ + Quilt *next; /* next quilt in linked list */ + +public: + void deleteMe( Pool& ); + void toBezier( Knotvector &, INREAL *, long ); + void toBezier( Knotvector &, Knotvector &, INREAL *, long ); + void select( REAL *, REAL * ); + int getDimension( void ) { return eqspec - qspec; } + void download( Backend & ); + void downloadAll( REAL *, REAL *, Backend & ); + int isCulled( void ); + void getRange( REAL *, REAL *, Flist&, Flist & ); + void getRange( REAL *, REAL *, int, Flist & ); + void getRange( REAL *, REAL *, Flist& ); + void findRates( Flist& slist, Flist& tlist, REAL[2] ); + void findSampleRates( Flist& slist, Flist& tlist ); + void show(); +}; + +typedef class Quilt *Quilt_ptr; + +#endif /* __gluquilt_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/reader.cc b/mesalib/src/glu/sgi/libnurbs/internals/reader.cc new file mode 100644 index 000000000..6135eef60 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/reader.cc @@ -0,0 +1,146 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * reader.c++ + * + */ + +#include <stdio.h> +#include "glimports.h" +#include "nurbsconsts.h" +#include "reader.h" +#include "trimvertex.h" +#include "simplemath.h" + +//when read a pwlCurve, if two consecutive points are the same, then +//eliminate one of them. This makes the tessellator more robust. The spec +//assumes the application makes sure there are no redundant points. +//but in Inspector, the trim curves seem to have redundant points a lot. +//I guess other similar users may have the same problem. + +#define ELIMINATE_REDUNDANT_POINTS + +#ifdef ELIMINATE_REDUNDANT_POINTS +#define equal(x,y) ( glu_abs(x-y) <= 0.00001) +#endif + +#ifdef ELIMINATE_REDUNDANT_POINTS +O_pwlcurve::O_pwlcurve( long _type, long count, INREAL *array, long byte_stride, TrimVertex *trimpts ) +{ + next = 0; + used = 0; + owner = 0; + pts = trimpts; + npts = (int) count; + int i; + + /* copy user data into internal trimming data structures */ + switch( _type ) { + case N_P2D: { + TrimVertex *v = pts; + TrimVertex *prev = NULL; + int num = 0; + int doit; + for(i=0; i<count; i++) { + doit = 1; + if(prev != NULL) + { + if(equal(prev->param[0], array[0]) && equal(prev->param[1], array[1])) + { + doit = 0; + } + } + + if(doit) + { + v->param[0] = (REAL) array[0]; + v->param[1] = (REAL) array[1]; + prev = v; + v++; + num++; + } + array = (INREAL *) (((char *) array) + byte_stride); + } + npts = num; + break; + } + case N_P2DR: { + TrimVertex *v = pts; + for( TrimVertex *lastv = v + count; v != lastv; v++ ) { + v->param[0] = (REAL) array[0] / (REAL) array[2]; + v->param[1] = (REAL) array[1] / (REAL) array[2]; + array = (INREAL *) (((char *) array) + byte_stride); + } + break; + } + } +} +#else +O_pwlcurve::O_pwlcurve( long _type, long count, INREAL *array, long byte_stride, TrimVertex *trimpts ) +{ + next = 0; + used = 0; + owner = 0; + pts = trimpts; + npts = (int) count; + + /* copy user data into internal trimming data structures */ + switch( _type ) { + case N_P2D: { + TrimVertex *v = pts; + for( TrimVertex *lastv = v + count; v != lastv; v++ ) { + v->param[0] = (REAL) array[0]; + v->param[1] = (REAL) array[1]; + array = (INREAL *) (((char *) array) + byte_stride); + } + break; + } + case N_P2DR: { + TrimVertex *v = pts; + for( TrimVertex *lastv = v + count; v != lastv; v++ ) { + v->param[0] = (REAL) array[0] / (REAL) array[2]; + v->param[1] = (REAL) array[1] / (REAL) array[2]; + array = (INREAL *) (((char *) array) + byte_stride); + } + break; + } + } +} +#endif + + + + + diff --git a/mesalib/src/glu/sgi/libnurbs/internals/reader.h b/mesalib/src/glu/sgi/libnurbs/internals/reader.h new file mode 100644 index 000000000..8a8dcebb5 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/reader.h @@ -0,0 +1,132 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * reader.h + * + */ + +#ifndef __glureader_h_ +#define __glureader_h_ + +#include "bufpool.h" +#include "types.h" + +enum Curvetype { ct_nurbscurve, ct_pwlcurve, ct_none }; + +struct Property; +struct O_surface; +struct O_nurbssurface; +struct O_trim; +class O_pwlcurve; +struct O_nurbscurve; +struct O_curve; +class Quilt; +class TrimVertex; + + +struct O_curve : public PooledObj { + union { + O_nurbscurve *o_nurbscurve; + O_pwlcurve *o_pwlcurve; + } curve; + Curvetype curvetype; /* arc type: pwl or nurbs */ + O_curve * next; /* next arc in loop */ + O_surface * owner; /* owning surface */ + int used; /* curve called in cur surf */ + int save; /* 1 if in display list */ + long nuid; + O_curve() { next = 0; used = 0; owner = 0; + curve.o_pwlcurve = 0; } + }; + +struct O_nurbscurve : public PooledObj { + Quilt *bezier_curves; /* array of bezier curves */ + long type; /* range descriptor */ + REAL tesselation; /* tesselation tolerance */ + int method; /* tesselation method */ + O_nurbscurve * next; /* next curve in list */ + int used; /* curve called in cur surf */ + int save; /* 1 if in display list */ + O_curve * owner; /* owning curve */ + O_nurbscurve( long _type ) + { type = _type; owner = 0; next = 0; used = 0; } + }; + +class O_pwlcurve : public PooledObj { +public: + TrimVertex *pts; /* array of trim vertices */ + int npts; /* number of trim vertices */ + O_pwlcurve * next; /* next curve in list */ + int used; /* curve called in cur surf */ + int save; /* 1 if in display list */ + O_curve * owner; /* owning curve */ + O_pwlcurve( long, long, INREAL *, long, TrimVertex * ); + }; + +struct O_trim : public PooledObj { + O_curve *o_curve; /* closed trim loop */ + O_trim * next; /* next loop along trim */ + int save; /* 1 if in display list */ + O_trim() { next = 0; o_curve = 0; } + }; + +struct O_nurbssurface : public PooledObj { + Quilt * bezier_patches;/* array of bezier patches */ + long type; /* range descriptor */ + O_surface * owner; /* owning surface */ + O_nurbssurface * next; /* next surface in chain */ + int save; /* 1 if in display list */ + int used; /* 1 if prev called in block */ + O_nurbssurface( long _type ) + { type = _type; owner = 0; next = 0; used = 0; } + }; + +struct O_surface : public PooledObj { + O_nurbssurface * o_nurbssurface; /* linked list of surfaces */ + O_trim * o_trim; /* list of trim loops */ + int save; /* 1 if in display list */ + long nuid; + O_surface() { o_trim = 0; o_nurbssurface = 0; } + }; + +struct Property : public PooledObj { + long type; + long tag; + REAL value; + int save; /* 1 if in display list */ + Property( long _type, long _tag, INREAL _value ) + { type = _type; tag = _tag; value = (REAL) _value; } + Property( long _tag, INREAL _value ) + { type = 0; tag = _tag; value = (REAL) _value; } + }; + +class NurbsTessellator; +#endif /* __glureader_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/renderhints.cc b/mesalib/src/glu/sgi/libnurbs/internals/renderhints.cc new file mode 100644 index 000000000..a3aa62d42 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/renderhints.cc @@ -0,0 +1,133 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * renderhints.c++ + * + */ + +#include "glimports.h" +#include "mystdio.h" +#include "renderhints.h" +#include "defines.h" +#include "nurbsconsts.h" + + +/*-------------------------------------------------------------------------- + * Renderhints::Renderhints - set all window specific options + *-------------------------------------------------------------------------- + */ +Renderhints::Renderhints() +{ + display_method = N_FILL; + errorchecking = N_MSG; + subdivisions = 6.0; + tmp1 = 0.0; +} + +void +Renderhints::init( void ) +{ + maxsubdivisions = (int) subdivisions; + if( maxsubdivisions < 0 ) maxsubdivisions = 0; + + + if( display_method == N_FILL ) { + wiretris = 0; + wirequads = 0; + } else if( display_method == N_OUTLINE_TRI ) { + wiretris = 1; + wirequads = 0; + } else if( display_method == N_OUTLINE_QUAD ) { + wiretris = 0; + wirequads = 1; + } else { + wiretris = 1; + wirequads = 1; + } +} + +int +Renderhints::isProperty( long property ) +{ + switch ( property ) { + case N_DISPLAY: + case N_ERRORCHECKING: + case N_SUBDIVISIONS: + case N_TMP1: + return 1; + default: + return 0; + } +} + +REAL +Renderhints::getProperty( long property ) +{ + switch ( property ) { + case N_DISPLAY: + return display_method; + case N_ERRORCHECKING: + return errorchecking; + case N_SUBDIVISIONS: + return subdivisions; + case N_TMP1: + return tmp1; + default: + abort(); + return -1; //not necessary, needed to shut up compiler + } +} + +void +Renderhints::setProperty( long property, REAL value ) +{ + switch ( property ) { + case N_DISPLAY: + display_method = value; + break; + case N_ERRORCHECKING: + errorchecking = value; + break; + case N_SUBDIVISIONS: + subdivisions = value; + break; + case N_TMP1: /* unused */ + tmp1 = value; + break; + default: + abort(); + break; + } +} diff --git a/mesalib/src/glu/sgi/libnurbs/internals/renderhints.h b/mesalib/src/glu/sgi/libnurbs/internals/renderhints.h new file mode 100644 index 000000000..444f649be --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/renderhints.h @@ -0,0 +1,60 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * renderhints.h + * + */ + +#ifndef __glurenderhints_h_ +#define __glurenderhints_h_ + +#include "types.h" + +class Renderhints { +public: + Renderhints( void ); + void init( void ); + int isProperty( long ); + REAL getProperty( long ); + void setProperty( long, REAL ); + + REAL display_method; /* display mode */ + REAL errorchecking; /* activate error checking */ + REAL subdivisions; /* maximum number of subdivisions per patch */ + REAL tmp1; /* unused */ + + int displaydomain; + int maxsubdivisions; + int wiretris; + int wirequads; +}; + +#endif /* __glurenderhints_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/simplemath.h b/mesalib/src/glu/sgi/libnurbs/internals/simplemath.h new file mode 100644 index 000000000..0a060c57e --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/simplemath.h @@ -0,0 +1,50 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * simplemath.h + * + */ + +#ifndef __glusimplemath_h_ +#define __glusimplemath_h_ + +/* simple inline routines */ + +inline int +max( int x, int y ) { return ( x < y ) ? y : x; } + +inline REAL +min( REAL x, REAL y ) { return ( x > y ) ? y : x; } + +inline REAL +glu_abs( REAL x ) { return ( x < 0.0 ) ? -x : x; } + +#endif /* __glusimplemath_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/slicer.cc b/mesalib/src/glu/sgi/libnurbs/internals/slicer.cc new file mode 100644 index 000000000..27d2a650d --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/slicer.cc @@ -0,0 +1,1300 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * slicer.c++ + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <math.h> +#include "glimports.h" +#include "mystdio.h" +#include "myassert.h" +#include "bufpool.h" +#include "slicer.h" +#include "backend.h" +#include "arc.h" +#include "gridtrimvertex.h" +#include "simplemath.h" +#include "trimvertex.h" +#include "varray.h" + +#include "polyUtil.h" //for area() + +//static int count=0; + +/*USE_OPTTT is initiated in trimvertex.h*/ + +#ifdef USE_OPTTT + #include <GL/gl.h> +#endif + +//#define USE_READ_FLAG //whether to use new or old tesselator + //if defined, it reads "flagFile", + // if the number is 1, then use new tess + // otherwise, use the old tess. + //if not defined, then use new tess. +#ifdef USE_READ_FLAG +static Int read_flag(char* name); +Int newtess_flag = read_flag("flagFile"); +#endif + +//#define COUNT_TRIANGLES +#ifdef COUNT_TRIANGLES +Int num_triangles = 0; +Int num_quads = 0; +#endif + +#define max(a,b) ((a>b)? a:b) +#define ZERO 0.00001 /*determing whether a loop is a rectngle or not*/ +#define equalRect(a,b) ((glu_abs(a-b) <= ZERO)? 1:0) //only used in tessellating a rectangle + +#if 0 // UNUSED +static Int is_Convex(Arc_ptr loop) +{ + if(area(loop->tail(), loop->head(), loop->next->head()) <0 ) + return 0; + for(Arc_ptr jarc = loop->next; jarc != loop; jarc = jarc->next) + { + if(area(jarc->tail(), jarc->head(), jarc->next->head()) < 0) + return 0; + } + return 1; +} +#endif + +/******triangulate a monotone polygon**************/ +#include "monoTriangulation.h" +#if 0 // UNUSED +static int is_U_monotone(Arc_ptr loop) +{ + int n_changes=0; + int prev_sign; + int cur_sign; + Arc_ptr temp; + + cur_sign = compV2InX(loop->head(), loop->tail()); + + n_changes = (compV2InX(loop->prev->head(), loop->prev->tail()) + != cur_sign); + + for(temp=loop->next; temp != loop; temp = temp->next) + { + prev_sign = cur_sign; + cur_sign = compV2InX(temp->head(), temp->tail()); + if(cur_sign != prev_sign) + { +#ifdef DEBUG + printf("***change signe\n"); +#endif + n_changes++; + } + } + if(n_changes == 2) return 1; + else + return 0; +} +#endif + +inline int compInY(REAL a[2], REAL b[2]) +{ + if(a[1] < b[1]) + return -1; + else if (a[1] > b[1]) + return 1; + else if(a[0] > b[0]) + return 1; + else return -1; +} + +void monoTriangulationLoop(Arc_ptr loop, Backend& backend, primStream* pStream) +{ + int i; + //find the top, bottom, increasing and decreasing chain + //then call monoTrianulation + Arc_ptr jarc, temp; + Arc_ptr top; + Arc_ptr bot; + top = bot = loop; + if(compInY(loop->tail(), loop->prev->tail()) < 0) + { + //first find bot + for(temp = loop->next; temp != loop; temp = temp->next) + { + if(compInY(temp->tail(), temp->prev->tail()) > 0) + break; + } + bot = temp->prev; + //then find top + for(temp=loop->prev; temp != loop; temp = temp->prev) + { + if(compInY(temp->tail(), temp->prev->tail()) > 0) + break; + } + top = temp; + } + else //loop > loop->prev + { + for(temp=loop->next; temp != loop; temp = temp->next) + { + if(compInY(temp->tail(), temp->prev->tail()) < 0) + break; + } + top = temp->prev; + for(temp=loop->prev; temp != loop; temp = temp->prev) + { + if(compInY(temp->tail(), temp->prev->tail()) < 0) + break; + } + bot = temp; + } + //creat increase and decrease chains + vertexArray inc_chain(50); //this is a dynamci array + for(i=1; i<=top->pwlArc->npts-2; i++) + { + //the first vertex is the top which doesn't below to inc_chain + inc_chain.appendVertex(top->pwlArc->pts[i].param); + } + for(jarc=top->next; jarc != bot; jarc = jarc->next) + { + for(i=0; i<=jarc->pwlArc->npts-2; i++) + { + inc_chain.appendVertex(jarc->pwlArc->pts[i].param); + } + + } + vertexArray dec_chain(50); + for(jarc = top->prev; jarc != bot; jarc = jarc->prev) + { + for(i=jarc->pwlArc->npts-2; i>=0; i--) + { + dec_chain.appendVertex(jarc->pwlArc->pts[i].param); + } + } + for(i=bot->pwlArc->npts-2; i>=1; i--) + { + dec_chain.appendVertex(jarc->pwlArc->pts[i].param); + } + + monoTriangulationRec(top->tail(), bot->tail(), &inc_chain, 0, + &dec_chain, 0, &backend); + +} + +/********tesselate a rectanlge (OPTIMIZATION**************/ +static void triangulateRectGen(Arc_ptr loop, int n_ulines, int n_vlines, Backend& backend); + +static Int is_rect(Arc_ptr loop) +{ + Int nlines =1; + for(Arc_ptr jarc = loop->next; jarc != loop; jarc = jarc->next) + { + nlines++; + if(nlines == 5) + break; + } + if(nlines != 4) + return 0; + + +/* +printf("here1\n"); +printf("loop->tail=(%f,%f)\n", loop->tail()[0], loop->tail()[1]); +printf("loop->head=(%f,%f)\n", loop->head()[0], loop->head()[1]); +printf("loop->next->tail=(%f,%f)\n", loop->next->tail()[0], loop->next->tail()[1]); +printf("loop->next->head=(%f,%f)\n", loop->next->head()[0], loop->next->head()[1]); +if(fglu_abs(loop->tail()[0] - loop->head()[0])<0.000001) + printf("equal 1\n"); +if(loop->next->tail()[1] == loop->next->head()[1]) + printf("equal 2\n"); +*/ + + if( (glu_abs(loop->tail()[0] - loop->head()[0])<=ZERO) && + (glu_abs(loop->next->tail()[1] - loop->next->head()[1])<=ZERO) && + (glu_abs(loop->prev->tail()[1] - loop->prev->head()[1])<=ZERO) && + (glu_abs(loop->prev->prev->tail()[0] - loop->prev->prev->head()[0])<=ZERO) + ) + return 1; + else if + ( (glu_abs(loop->tail()[1] - loop->head()[1]) <= ZERO) && + (glu_abs(loop->next->tail()[0] - loop->next->head()[0]) <= ZERO) && + (glu_abs(loop->prev->tail()[0] - loop->prev->head()[0]) <= ZERO) && + (glu_abs(loop->prev->prev->tail()[1] - loop->prev->prev->head()[1]) <= ZERO) + ) + return 1; + else + return 0; +} + + +//a line with the same u for opt +#ifdef USE_OPTTT +static void evalLineNOGE_BU(TrimVertex *verts, int n, Backend& backend) +{ + int i; + backend.preEvaluateBU(verts[0].param[0]); + for(i=0; i<n; i++) + backend.tmeshvertNOGE_BU(&verts[i]); +} +#endif + +//a line with the same v for opt +#ifdef USE_OPTTT +static void evalLineNOGE_BV(TrimVertex *verts, int n, Backend& backend) +{ + int i; + backend.preEvaluateBV(verts[0].param[1]); + + for(i=0; i<n; i++) + backend.tmeshvertNOGE_BV(&verts[i]); +} +#endif + +#ifdef USE_OPTTT +static void evalLineNOGE(TrimVertex *verts, int n, Backend& backend) +{ + + if(verts[0].param[0] == verts[n-1].param[0]) //all u;s are equal + evalLineNOGE_BU(verts, n, backend); + else if(verts[0].param[1] == verts[n-1].param[1]) //all v's are equal + evalLineNOGE_BV(verts, n, backend); + else + { + int i; + for(i=0; i<n; i++) + backend.tmeshvertNOGE(&verts[i]); + } +} +#endif + +inline void OPT_OUTVERT(TrimVertex& vv, Backend& backend) +{ + +#ifdef USE_OPTTT + glNormal3fv(vv.cache_normal); + glVertex3fv(vv.cache_point); +#else + + backend.tmeshvert(&vv); + +#endif + +} + +static void triangulateRectAux(PwlArc* top, PwlArc* bot, PwlArc* left, PwlArc* right, Backend& backend); + +static void triangulateRect(Arc_ptr loop, Backend& backend, int TB_or_LR, int ulinear, int vlinear) +{ + //we know the loop is a rectangle, but not sure which is top + Arc_ptr top, bot, left, right; + if(loop->tail()[1] == loop->head()[1]) + { + if(loop->tail()[1] > loop->prev->prev->tail()[1]) + { + + top = loop; + } + else{ + + top = loop->prev->prev; + } + } + else + { + if(loop->tail()[0] > loop->prev->prev->tail()[0]) + { + //loop is the right arc + + top = loop->next; + } + else + { + + top = loop->prev; + } + } + left = top->next; + bot = left->next; + right= bot->next; + + //if u, v are both nonlinear, then if the + //boundary is tessellated dense, we also + //sample the inside to get a better tesslletant. + if( (!ulinear) && (!vlinear)) + { + int nu = top->pwlArc->npts; + if(nu < bot->pwlArc->npts) + nu = bot->pwlArc->npts; + int nv = left->pwlArc->npts; + if(nv < right->pwlArc->npts) + nv = right->pwlArc->npts; +/* + if(nu > 2 && nv > 2) + { + triangulateRectGen(top, nu-2, nv-2, backend); + return; + } +*/ + } + + if(TB_or_LR == 1) + triangulateRectAux(top->pwlArc, bot->pwlArc, left->pwlArc, right->pwlArc, backend); + else if(TB_or_LR == -1) + triangulateRectAux(left->pwlArc, right->pwlArc, bot->pwlArc, top->pwlArc, backend); + else + { + Int maxPointsTB = top->pwlArc->npts + bot->pwlArc->npts; + Int maxPointsLR = left->pwlArc->npts + right->pwlArc->npts; + + if(maxPointsTB < maxPointsLR) + triangulateRectAux(left->pwlArc, right->pwlArc, bot->pwlArc, top->pwlArc, backend); + else + triangulateRectAux(top->pwlArc, bot->pwlArc, left->pwlArc, right->pwlArc, backend); + } +} + +static void triangulateRectAux(PwlArc* top, PwlArc* bot, PwlArc* left, PwlArc* right, Backend& backend) +{ //if(maxPointsTB >= maxPointsLR) + { + + Int d, topd_left, topd_right, botd_left, botd_right, i,j; + d = left->npts /2; + +#ifdef USE_OPTTT + evalLineNOGE(top->pts, top->npts, backend); + evalLineNOGE(bot->pts, bot->npts, backend); + evalLineNOGE(left->pts, left->npts, backend); + evalLineNOGE(right->pts, right->npts, backend); +#endif + + if(top->npts == 2) { + backend.bgntfan(); + OPT_OUTVERT(top->pts[0], backend);//the root + for(i=0; i<left->npts; i++){ + OPT_OUTVERT(left->pts[i], backend); + } + for(i=1; i<= bot->npts-2; i++){ + OPT_OUTVERT(bot->pts[i], backend); + } + backend.endtfan(); + + backend.bgntfan(); + OPT_OUTVERT(bot->pts[bot->npts-2], backend); + for(i=0; i<right->npts; i++){ + OPT_OUTVERT(right->pts[i], backend); + } + backend.endtfan(); + } + else if(bot->npts == 2) { + backend.bgntfan(); + OPT_OUTVERT(bot->pts[0], backend);//the root + for(i=0; i<right->npts; i++){ + OPT_OUTVERT(right->pts[i], backend); + } + for(i=1; i<= top->npts-2; i++){ + OPT_OUTVERT(top->pts[i], backend); + } + backend.endtfan(); + + backend.bgntfan(); + OPT_OUTVERT(top->pts[top->npts-2], backend); + for(i=0; i<left->npts; i++){ + OPT_OUTVERT(left->pts[i], backend); + } + backend.endtfan(); + } + else { //both top and bot have >=3 points + + backend.bgntfan(); + + OPT_OUTVERT(top->pts[top->npts-2], backend); + + for(i=0; i<=d; i++) + { + OPT_OUTVERT(left->pts[i], backend); + } + backend.endtfan(); + + backend.bgntfan(); + + OPT_OUTVERT(bot->pts[1], backend); + + OPT_OUTVERT(top->pts[top->npts-2], backend); + + for(i=d; i< left->npts; i++) + { + OPT_OUTVERT(left->pts[i], backend); + } + backend.endtfan(); + + d = right->npts/2; + //output only when d<right->npts-1 and + // + if(d<right->npts-1) + { + backend.bgntfan(); + // backend.tmeshvert(& top->pts[1]); + OPT_OUTVERT(top->pts[1], backend); + for(i=d; i< right->npts; i++) + { + // backend.tmeshvert(& right->pts[i]); + + OPT_OUTVERT(right->pts[i], backend); + + } + backend.endtfan(); + } + + backend.bgntfan(); + // backend.tmeshvert(& bot->pts[bot->npts-2]); + OPT_OUTVERT( bot->pts[bot->npts-2], backend); + for(i=0; i<=d; i++) + { + // backend.tmeshvert(& right->pts[i]); + OPT_OUTVERT(right->pts[i], backend); + + } + + // backend.tmeshvert(& top->pts[1]); + OPT_OUTVERT(top->pts[1], backend); + + backend.endtfan(); + + + topd_left = top->npts-2; + topd_right = 1; //topd_left>= topd_right + + botd_left = 1; + botd_right = bot->npts-2; //botd_left<= bot_dright + + + if(top->npts < bot->npts) + { + int delta=bot->npts - top->npts; + int u = delta/2; + botd_left = 1+ u; + botd_right = bot->npts-2-( delta-u); + + if(botd_left >1) + { + backend.bgntfan(); + // backend.tmeshvert(& top->pts[top->npts-2]); + OPT_OUTVERT(top->pts[top->npts-2], backend); + for(i=1; i<= botd_left; i++) + { + // backend.tmeshvert(& bot->pts[i]); + OPT_OUTVERT(bot->pts[i] , backend); + } + backend.endtfan(); + } + if(botd_right < bot->npts-2) + { + backend.bgntfan(); + OPT_OUTVERT(top->pts[1], backend); + for(i=botd_right; i<= bot->npts-2; i++) + OPT_OUTVERT(bot->pts[i], backend); + backend.endtfan(); + } + } + else if(top->npts> bot->npts) + { + int delta=top->npts-bot->npts; + int u = delta/2; + topd_left = top->npts-2 - u; + topd_right = 1+delta-u; + + if(topd_left < top->npts-2) + { + backend.bgntfan(); + // backend.tmeshvert(& bot->pts[1]); + OPT_OUTVERT(bot->pts[1], backend); + for(i=topd_left; i<= top->npts-2; i++) + { + // backend.tmeshvert(& top->pts[i]); + OPT_OUTVERT(top->pts[i], backend); + } + backend.endtfan(); + } + if(topd_right > 1) + { + backend.bgntfan(); + OPT_OUTVERT(bot->pts[bot->npts-2], backend); + for(i=1; i<= topd_right; i++) + OPT_OUTVERT(top->pts[i], backend); + backend.endtfan(); + } + } + + if(topd_left <= topd_right) + return; + + backend.bgnqstrip(); + for(j=botd_left, i=topd_left; i>=topd_right; i--,j++) + { + // backend.tmeshvert(& top->pts[i]); + // backend.tmeshvert(& bot->pts[j]); + OPT_OUTVERT(top->pts[i], backend); + OPT_OUTVERT(bot->pts[j], backend); + } + backend.endqstrip(); + + } + } +} + + +static void triangulateRectCenter(int n_ulines, REAL* u_val, + int n_vlines, REAL* v_val, + Backend& backend) +{ + + // XXX this code was patched by Diego Santa Cruz <Diego.SantaCruz@epfl.ch> + // to fix a problem in which glMapGrid2f() was called with bad parameters. + // This has beens submitted to SGI but not integrated as of May 1, 2001. + if(n_ulines>1 && n_vlines>1) { + backend.surfgrid(u_val[0], u_val[n_ulines-1], n_ulines-1, + v_val[n_vlines-1], v_val[0], n_vlines-1); + backend.surfmesh(0,0,n_ulines-1,n_vlines-1); + } + + return; + + /* + for(i=0; i<n_vlines-1; i++) + { + + backend.bgnqstrip(); + for(j=0; j<n_ulines; j++) + { + trimVert.param[0] = u_val[j]; + trimVert.param[1] = v_val[i+1]; + backend.tmeshvert(& trimVert); + + trimVert.param[1] = v_val[i]; + backend.tmeshvert(& trimVert); + } + backend.endqstrip(); + + } + */ +} + +//it works for top, bot, left ad right, you need ot select correct arguments +static void triangulateRectTopGen(Arc_ptr arc, int n_ulines, REAL* u_val, Real v, int dir, int is_u, Backend& backend) +{ + + if(is_u) + { + int i,k; + REAL* upper_val = (REAL*) malloc(sizeof(REAL) * arc->pwlArc->npts); + assert(upper_val); + if(dir) + { + for(k=0,i=arc->pwlArc->npts-1; i>=0; i--,k++) + { + upper_val[k] = arc->pwlArc->pts[i].param[0]; + } + backend.evalUStrip(arc->pwlArc->npts, arc->pwlArc->pts[0].param[1], + upper_val, + n_ulines, v, u_val); + } + else + { + for(k=0,i=0; i<arc->pwlArc->npts; i++,k++) + { + upper_val[k] = arc->pwlArc->pts[i].param[0]; + + } + + backend.evalUStrip( + n_ulines, v, u_val, + arc->pwlArc->npts, arc->pwlArc->pts[0].param[1], upper_val + ); + } + + free(upper_val); + return; + } + else //is_v + { + int i,k; + REAL* left_val = (REAL*) malloc(sizeof(REAL) * arc->pwlArc->npts); + assert(left_val); + if(dir) + { + for(k=0,i=arc->pwlArc->npts-1; i>=0; i--,k++) + { + left_val[k] = arc->pwlArc->pts[i].param[1]; + } + backend.evalVStrip(arc->pwlArc->npts, arc->pwlArc->pts[0].param[0], + left_val, + n_ulines, v, u_val); + } + else + { + for(k=0,i=0; i<arc->pwlArc->npts; i++,k++) + { + left_val[k] = arc->pwlArc->pts[i].param[1]; + } + backend.evalVStrip( + n_ulines, v, u_val, + arc->pwlArc->npts, arc->pwlArc->pts[0].param[0], left_val + ); + } + free(left_val); + return; + } + + //the following is a different version of the above code. If you comment + //the above code, the following code will still work. The reason to leave + //the folliwng code here is purely for testing purpose. + /* + int i,j; + PwlArc* parc = arc->pwlArc; + int d1 = parc->npts-1; + int d2 = 0; + TrimVertex trimVert; + trimVert.nuid = 0;//???? + REAL* temp_u_val = u_val; + if(dir ==0) //have to reverse u_val + { + temp_u_val = (REAL*) malloc(sizeof(REAL) * n_ulines); + assert(temp_u_val); + for(i=0; i<n_ulines; i++) + temp_u_val[i] = u_val[n_ulines-1-i]; + } + u_val = temp_u_val; + + if(parc->npts > n_ulines) + { + d1 = n_ulines-1; + + backend.bgntfan(); + if(is_u){ + trimVert.param[0] = u_val[0]; + trimVert.param[1] = v; + } + else + { + trimVert.param[1] = u_val[0]; + trimVert.param[0] = v; + } + + backend.tmeshvert(& trimVert); + for(i=d1; i< parc->npts; i++) + backend.tmeshvert(& parc->pts[i]); + backend.endtfan(); + + + } + else if(parc->npts < n_ulines) + { + d2 = n_ulines-parc->npts; + + + backend.bgntfan(); + backend.tmeshvert(& parc->pts[parc->npts-1]); + for(i=0; i<= d2; i++) + { + if(is_u){ + trimVert.param[0] = u_val[i]; + trimVert.param[1] = v; + } + else + { + trimVert.param[1] = u_val[i]; + trimVert.param[0] = v; + } + backend.tmeshvert(&trimVert); + } + backend.endtfan(); + + } + if(d1>0){ + + + backend.bgnqstrip(); + for(i=d1, j=d2; i>=0; i--, j++) + { + backend.tmeshvert(& parc->pts[i]); + + if(is_u){ + trimVert.param[0] = u_val[j]; + trimVert.param[1] = v; + } + else{ + trimVert.param[1] = u_val[j]; + trimVert.param[0] = v; + } + backend.tmeshvert(&trimVert); + + + + } + backend.endqstrip(); + + + } + if(dir == 0) //temp_u_val was mallocated + free(temp_u_val); + */ +} + +//n_ulines is the number of ulines inside, and n_vlines is the number of vlines +//inside, different from meanings elsewhere!!! +static void triangulateRectGen(Arc_ptr loop, int n_ulines, int n_vlines, Backend& backend) +{ + + int i; + //we know the loop is a rectangle, but not sure which is top + Arc_ptr top, bot, left, right; + + if(equalRect(loop->tail()[1] , loop->head()[1])) + { + + if(loop->tail()[1] > loop->prev->prev->tail()[1]) + { + + top = loop; + } + else{ + + top = loop->prev->prev; + } + } + else + { + if(loop->tail()[0] > loop->prev->prev->tail()[0]) + { + //loop is the right arc + + top = loop->next; + } + else + { + + top = loop->prev; + } + } + + left = top->next; + bot = left->next; + right= bot->next; + +#ifdef COUNT_TRIANGLES + num_triangles += loop->pwlArc->npts + + left->pwlArc->npts + + bot->pwlArc->npts + + right->pwlArc->npts + + 2*n_ulines + 2*n_vlines + -8; + num_quads += (n_ulines-1)*(n_vlines-1); +#endif +/* + backend.surfgrid(left->tail()[0], right->tail()[0], n_ulines+1, + top->tail()[1], bot->tail()[1], n_vlines+1); +// if(n_ulines>1 && n_vlines>1) + backend.surfmesh(0,0,n_ulines+1,n_vlines+1); +return; +*/ + REAL* u_val=(REAL*) malloc(sizeof(REAL)*n_ulines); + assert(u_val); + REAL* v_val=(REAL*)malloc(sizeof(REAL) * n_vlines); + assert(v_val); + REAL u_stepsize = (right->tail()[0] - left->tail()[0])/( (REAL) n_ulines+1); + REAL v_stepsize = (top->tail()[1] - bot->tail()[1])/( (REAL) n_vlines+1); + Real temp=left->tail()[0]+u_stepsize; + for(i=0; i<n_ulines; i++) + { + u_val[i] = temp; + temp += u_stepsize; + } + temp = bot->tail()[1] + v_stepsize; + for(i=0; i<n_vlines; i++) + { + v_val[i] = temp; + temp += v_stepsize; + } + + triangulateRectTopGen(top, n_ulines, u_val, v_val[n_vlines-1], 1,1, backend); + triangulateRectTopGen(bot, n_ulines, u_val, v_val[0], 0, 1, backend); + triangulateRectTopGen(left, n_vlines, v_val, u_val[0], 1, 0, backend); + triangulateRectTopGen(right, n_vlines, v_val, u_val[n_ulines-1], 0,0, backend); + + + + + //triangulate the center + triangulateRectCenter(n_ulines, u_val, n_vlines, v_val, backend); + + free(u_val); + free(v_val); + +} + + + + +/**********for reading newtess_flag from a file**********/ +#ifdef USE_READ_FLAG +static Int read_flag(char* name) +{ + Int ret; + FILE* fp = fopen(name, "r"); + if(fp == NULL) + { + fprintf(stderr, "can't open file %s\n", name); + exit(1); + } + fscanf(fp, "%i", &ret); + fclose(fp); + return ret; +} +#endif + +/***********nextgen tess****************/ +#include "sampleMonoPoly.h" +directedLine* arcToDLine(Arc_ptr arc) +{ + int i; + Real vert[2]; + directedLine* ret; + sampledLine* sline = new sampledLine(arc->pwlArc->npts); + for(i=0; i<arc->pwlArc->npts; i++) + { + vert[0] = arc->pwlArc->pts[i].param[0]; + vert[1] = arc->pwlArc->pts[i].param[1]; + sline->setPoint(i, vert); + } + ret = new directedLine(INCREASING, sline); + return ret; +} + +/*an pwlArc may not be a straight line*/ +directedLine* arcToMultDLines(directedLine* original, Arc_ptr arc) +{ + directedLine* ret = original; + int is_linear = 0; + if(arc->pwlArc->npts == 2 ) + is_linear = 1; + else if(area(arc->pwlArc->pts[0].param, arc->pwlArc->pts[1].param, arc->pwlArc->pts[arc->pwlArc->npts-1].param) == 0.0) + is_linear = 1; + + if(is_linear) + { + directedLine *dline = arcToDLine(arc); + if(ret == NULL) + ret = dline; + else + ret->insert(dline); + return ret; + } + else /*not linear*/ + { + for(Int i=0; i<arc->pwlArc->npts-1; i++) + { + Real vert[2][2]; + vert[0][0] = arc->pwlArc->pts[i].param[0]; + vert[0][1] = arc->pwlArc->pts[i].param[1]; + vert[1][0] = arc->pwlArc->pts[i+1].param[0]; + vert[1][1] = arc->pwlArc->pts[i+1].param[1]; + + sampledLine *sline = new sampledLine(2, vert); + directedLine *dline = new directedLine(INCREASING, sline); + if(ret == NULL) + ret = dline; + else + ret->insert(dline); + } + return ret; + } +} + + + +directedLine* arcLoopToDLineLoop(Arc_ptr loop) +{ + directedLine* ret; + + if(loop == NULL) + return NULL; + ret = arcToMultDLines(NULL, loop); +//ret->printSingle(); + for(Arc_ptr temp = loop->next; temp != loop; temp = temp->next){ + ret = arcToMultDLines(ret, temp); +//ret->printSingle(); + } + + return ret; +} + +/* +void Slicer::evalRBArray(rectBlockArray* rbArray, gridWrap* grid) +{ + TrimVertex *trimVert = (TrimVertex*)malloc(sizeof(TrimVertex)); + trimVert -> nuid = 0;//???? + + Real* u_values = grid->get_u_values(); + Real* v_values = grid->get_v_values(); + + Int i,j,k,l; + + for(l=0; l<rbArray->get_n_elements(); l++) + { + rectBlock* block = rbArray->get_element(l); + for(k=0, i=block->get_upGridLineIndex(); i>block->get_lowGridLineIndex(); i--, k++) + { + + backend.bgnqstrip(); + for(j=block->get_leftIndices()[k+1]; j<= block->get_rightIndices()[k+1]; j++) + { + trimVert->param[0] = u_values[j]; + trimVert->param[1] = v_values[i]; + backend.tmeshvert(trimVert); + + trimVert->param[1] = v_values[i-1]; + backend.tmeshvert(trimVert); + + } + backend.endqstrip(); + + } + } + + free(trimVert); +} +*/ + +void Slicer::evalRBArray(rectBlockArray* rbArray, gridWrap* grid) +{ + Int i,j,k; + + Int n_vlines=grid->get_n_vlines(); + //the reason to switch the position of v_max and v_min is because of the + //the orientation problem. glEvalMesh generates quad_strip clockwise, but + //we need counter-clockwise. + backend.surfgrid(grid->get_u_min(), grid->get_u_max(), grid->get_n_ulines()-1, + grid->get_v_max(), grid->get_v_min(), n_vlines-1); + + + for(j=0; j<rbArray->get_n_elements(); j++) + { + rectBlock* block = rbArray->get_element(j); + Int low = block->get_lowGridLineIndex(); + Int high = block->get_upGridLineIndex(); + + for(k=0, i=high; i>low; i--, k++) + { + backend.surfmesh(block->get_leftIndices()[k+1], n_vlines-1-i, block->get_rightIndices()[k+1]-block->get_leftIndices()[k+1], 1); + } + } +} + + +void Slicer::evalStream(primStream* pStream) +{ + Int i,j,k; + k=0; +/* TrimVertex X;*/ + TrimVertex *trimVert =/*&X*/ (TrimVertex*)malloc(sizeof(TrimVertex)); + trimVert -> nuid = 0;//??? + Real* vertices = pStream->get_vertices(); //for efficiency + for(i=0; i<pStream->get_n_prims(); i++) + { + + //ith primitive has #vertices = lengths[i], type=types[i] + switch(pStream->get_type(i)){ + case PRIMITIVE_STREAM_FAN: + + backend.bgntfan(); + + for(j=0; j<pStream->get_length(i); j++) + { + trimVert->param[0] = vertices[k]; + trimVert->param[1] = vertices[k+1]; + backend.tmeshvert(trimVert); + +// backend.tmeshvert(vertices[k], vertices[k+1]); + k += 2; + } + backend.endtfan(); + break; + + default: + fprintf(stderr, "evalStream: not implemented yet\n"); + exit(1); + + } + } + free(trimVert); +} + + + + +void Slicer::slice_new(Arc_ptr loop) +{ +//count++; +//if(count == 78) count=1; +//printf("count=%i\n", count); +//if( ! (4<= count && count <=4)) return; + + + Int num_ulines; + Int num_vlines; + Real uMin, uMax, vMin, vMax; + Real mydu, mydv; + uMin = uMax = loop->tail()[0]; + vMin = vMax = loop->tail()[1]; + mydu = (du>0)? du: -du; + mydv = (dv>0)? dv: -dv; + + for(Arc_ptr jarc=loop->next; jarc != loop; jarc = jarc->next) + { + + if(jarc->tail()[0] < uMin) + uMin = jarc->tail()[0]; + if(jarc->tail()[0] > uMax) + uMax = jarc->tail()[0]; + if(jarc->tail()[1] < vMin) + vMin = jarc->tail()[1]; + if(jarc->tail()[1] > vMax) + vMax = jarc->tail()[1]; + } + + if (uMax == uMin) + return; // prevent divide-by-zero. Jon Perry. 17 June 2002 + + if(mydu > uMax - uMin) + num_ulines = 2; + else + { + num_ulines = 3 + (Int) ((uMax-uMin)/mydu); + } + if(mydv>=vMax-vMin) + num_vlines = 2; + else + { + num_vlines = 2+(Int)((vMax-vMin)/mydv); + } + + Int isRect = is_rect(loop); + + if(isRect && (num_ulines<=2 || num_vlines<=2)) + { + if(vlinear) + triangulateRect(loop, backend, 1, ulinear, vlinear); + else if(ulinear) + triangulateRect(loop, backend, -1, ulinear, vlinear); + else + triangulateRect(loop, backend, 0, ulinear, vlinear); + } + + else if(isRect) + { + triangulateRectGen(loop, num_ulines-2, num_vlines-2, backend); + } + else if( (num_ulines<=2 || num_vlines <=2) && ulinear) + { + monoTriangulationFunBackend(loop, compV2InY, &backend); + } + else if( (!ulinear) && (!vlinear) && (num_ulines == 2) && (num_vlines > 2)) + { + monoTriangulationFunBackend(loop, compV2InY, &backend); + } + else + { + directedLine* poly = arcLoopToDLineLoop(loop); + + gridWrap grid(num_ulines, num_vlines, uMin, uMax, vMin, vMax); + primStream pStream(20, 20); + rectBlockArray rbArray(20); + + sampleMonoPoly(poly, &grid, ulinear, vlinear, &pStream, &rbArray); + + evalStream(&pStream); + + evalRBArray(&rbArray, &grid); + +#ifdef COUNT_TRIANGLES + num_triangles += pStream.num_triangles(); + num_quads += rbArray.num_quads(); +#endif + poly->deleteSinglePolygonWithSline(); + } + +#ifdef COUNT_TRIANGLES + printf("num_triangles=%i\n", num_triangles); + printf("num_quads = %i\n", num_quads); +#endif +} + +void Slicer::slice(Arc_ptr loop) +{ +#ifdef USE_READ_FLAG + if(read_flag("flagFile")) + slice_new(loop); + else + slice_old(loop); + +#else + slice_new(loop); +#endif + +} + + + +Slicer::Slicer( Backend &b ) + : CoveAndTiler( b ), Mesher( b ), backend( b ) +{ + ulinear = 0; + vlinear = 0; +} + +Slicer::~Slicer() +{ +} + +void +Slicer::setisolines( int x ) +{ + isolines = x; +} + +void +Slicer::setstriptessellation( REAL x, REAL y ) +{ + assert(x > 0 && y > 0); + du = x; + dv = y; + setDu( du ); +} + +void +Slicer::slice_old( Arc_ptr loop ) +{ + loop->markverts(); + + Arc_ptr extrema[4]; + loop->getextrema( extrema ); + + unsigned int npts = loop->numpts(); + TrimRegion::init( npts, extrema[0] ); + + Mesher::init( npts ); + + long ulines = uarray.init( du, extrema[1], extrema[3] ); +//printf("ulines = %i\n", ulines); + Varray varray; + long vlines = varray.init( dv, extrema[0], extrema[2] ); +//printf("vlines = %i\n", vlines); + long botv = 0; + long topv; + TrimRegion::init( varray.varray[botv] ); + getGridExtent( &extrema[0]->pwlArc->pts[0], &extrema[0]->pwlArc->pts[0] ); + + for( long quad=0; quad<varray.numquads; quad++ ) { + backend.surfgrid( uarray.uarray[0], + uarray.uarray[ulines-1], + ulines-1, + varray.vval[quad], + varray.vval[quad+1], + varray.voffset[quad+1] - varray.voffset[quad] ); + + for( long i=varray.voffset[quad]+1; i <= varray.voffset[quad+1]; i++ ) { + topv = botv++; + advance( topv - varray.voffset[quad], + botv - varray.voffset[quad], + varray.varray[botv] ); + if( i == vlines ) + getPts( extrema[2] ); + else + getPts( backend ); + getGridExtent(); + if( isolines ) { + outline(); + } else { + if( canTile() ) + coveAndTile(); + else + mesh(); + } + } + } +} + + +void +Slicer::outline( void ) +{ + GridTrimVertex upper, lower; + Hull::init( ); + + backend.bgnoutline(); + while( (nextupper( &upper )) ) { + if( upper.isGridVert() ) + backend.linevert( upper.g ); + else + backend.linevert( upper.t ); + } + backend.endoutline(); + + backend.bgnoutline(); + while( (nextlower( &lower )) ) { + if( lower.isGridVert() ) + backend.linevert( lower.g ); + else + backend.linevert( lower.t ); + } + backend.endoutline(); +} + + +void +Slicer::outline( Arc_ptr jarc ) +{ + jarc->markverts(); + + if( jarc->pwlArc->npts >= 2 ) { + backend.bgnoutline(); + for( int j = jarc->pwlArc->npts-1; j >= 0; j-- ) + backend.linevert( &(jarc->pwlArc->pts[j]) ); + backend.endoutline(); + } +} + + diff --git a/mesalib/src/glu/sgi/libnurbs/internals/slicer.h b/mesalib/src/glu/sgi/libnurbs/internals/slicer.h new file mode 100644 index 000000000..e1f5d22ff --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/slicer.h @@ -0,0 +1,84 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * slicer.h + * + */ + +#ifndef __gluslicer_h_ +#define __gluslicer_h_ + +#include "trimregion.h" +#include "mesher.h" +#include "coveandtiler.h" +#include "primitiveStream.h" +#include "rectBlock.h" + +class Backend; +class Arc; +class TrimVertex; + +class Slicer : public CoveAndTiler, public Mesher { +public: + Slicer( Backend & ); + ~Slicer( void ); + void slice( Arc_ptr ); + void slice_old( Arc_ptr); + void slice_new( Arc_ptr ); + void evalStream(primStream* ); + void evalRBArray(rectBlockArray* rbArray, gridWrap* grid); + + void outline( Arc_ptr ); + void setstriptessellation( REAL, REAL ); + void setisolines( int ); + + void set_ulinear(int ulinear_flag) + { + ulinear = ulinear_flag; + } + void set_vlinear(int vlinear_flag) + { + vlinear = vlinear_flag; + } +private: + Backend& backend; + REAL oneOverDu; + REAL du, dv; + int isolines; + + void outline( void ); + void initGridlines( void ); + void advanceGridlines( long ); + + int ulinear; //indicate whether uorder is 2 or not + int vlinear; //indicate whether vorder is 2 or not +}; +#endif /* __gluslicer_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/sorter.cc b/mesalib/src/glu/sgi/libnurbs/internals/sorter.cc new file mode 100644 index 000000000..7a7994149 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/sorter.cc @@ -0,0 +1,139 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * sorter.c++ + * + */ + +#include "glimports.h" +#include "sorter.h" +#include "mystdio.h" + +Sorter::Sorter( int _es ) +{ + es = _es; +} + +void +Sorter::qsort( void *a, int n ) +{ + qs1( (char *)a, ((char *)a)+n*es); +} + +int +Sorter::qscmp( char *, char * ) +{ + _glu_dprintf( "Sorter::qscmp: pure virtual called\n" ); + return 0; +} + + +void +Sorter::qsexc( char *, char * ) +{ + _glu_dprintf( "Sorter::qsexc: pure virtual called\n" ); +} + + +void +Sorter::qstexc( char *, char *, char * ) +{ + _glu_dprintf( "Sorter::qstexc: pure virtual called\n" ); +} + +void +Sorter::qs1( char *a, char *l ) +{ + char *i, *j; + char *lp, *hp; + int c; + unsigned int n; + +start: + if((n=l-a) <= (unsigned int)es) + return; + n = es * (n / (2*es)); + hp = lp = a+n; + i = a; + j = l-es; + while(1) { + if(i < lp) { + if((c = qscmp(i, lp)) == 0) { + qsexc(i, lp -= es); + continue; + } + if(c < 0) { + i += es; + continue; + } + } + +loop: + if(j > hp) { + if((c = qscmp(hp, j)) == 0) { + qsexc(hp += es, j); + goto loop; + } + if(c > 0) { + if(i == lp) { + qstexc(i, hp += es, j); + i = lp += es; + goto loop; + } + qsexc(i, j); + j -= es; + i += es; + continue; + } + j -= es; + goto loop; + } + + if(i == lp) { + if(lp-a >= l-hp) { + qs1(hp+es, l); + l = lp; + } else { + qs1(a, lp); + a = hp+es; + } + goto start; + } + + qstexc(j, lp -= es, i); + j = hp -= es; + } +} + diff --git a/mesalib/src/glu/sgi/libnurbs/internals/sorter.h b/mesalib/src/glu/sgi/libnurbs/internals/sorter.h new file mode 100644 index 000000000..57ea12129 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/sorter.h @@ -0,0 +1,51 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ +/* +*/ + +#ifndef __glusorter_h_ +#define __glusorter_h_ + +class Sorter { +public: + Sorter( int es ); + virtual ~Sorter() { /* silence warning*/ } + void qsort( void *a, int n ); + +protected: + virtual int qscmp( char *, char * ); + virtual void qsexc( char *i, char *j ); // i<-j, j<-i + virtual void qstexc( char *i, char *j, char *k ); // i<-k, k<-j, j<-i + +private: + void qs1( char *, char * ); + int es; +}; +#endif /* __glusorter_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/splitarcs.cc b/mesalib/src/glu/sgi/libnurbs/internals/splitarcs.cc new file mode 100644 index 000000000..1f79d543f --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/splitarcs.cc @@ -0,0 +1,293 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * splitarcs.c++ + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "mysetjmp.h" +#include "mystdio.h" +#include "subdivider.h" +#include "arcsorter.h" +#include "arc.h" +#include "bin.h" + +/* local preprocessor definitions */ +#define MAXARCS 10 + +/*---------------------------------------------------------------------------- + * Subdivider::split - split trim regions in source bin by line (param == value). + *---------------------------------------------------------------------------- + */ + +void +Subdivider::split( Bin& bin, Bin& left, Bin& right, int param, REAL value ) +{ + Bin intersections, unknown; + + partition( bin, left, intersections, right, unknown, param, value ); + + int count = intersections.numarcs(); + if( count % 2 ) { +#ifndef NDEBUG + left.show( "left" ); + intersections.show( "intersections" ); + right.show( "right" ); +#endif + ::mylongjmp( jumpbuffer, 29 ); + } + + Arc_ptr arclist[MAXARCS], *list; + if( count >= MAXARCS ) { + list = new Arc_ptr[count]; + } else { + list = arclist; + } + + Arc_ptr jarc, *last, *lptr; + for( last = list; (jarc=intersections.removearc()) != NULL; last++ ) + *last = jarc; + + if( param == 0 ) { /* sort into increasing t order */ + ArcSdirSorter sorter(*this); + sorter.qsort( list, count ); + + //::qsort ((void *)list, count, sizeof(Arc_ptr), (cmpfunc)compare_s); + for( lptr=list; lptr<last; lptr+=2 ) + check_s ( lptr[0], lptr[1] ); + for( lptr=list; lptr<last; lptr+=2 ) + join_s ( left, right, lptr[0], lptr[1] ); + for( lptr=list; lptr != last; lptr++ ) { + if( ((*lptr)->head()[0] <= value) && ((*lptr)->tail()[0] <= value) ) + left.addarc( *lptr ); + else + right.addarc( *lptr ); + } + } else { /* sort into decreasing s order */ + ArcTdirSorter sorter(*this); + sorter.qsort( list, count ); + //::qsort ((void *)list, count, sizeof(Arc_ptr), (cmpfunc)compare_t); + for( lptr=list; lptr<last; lptr+=2 ) + check_t ( lptr[0], lptr[1] ); + for( lptr=list; lptr<last; lptr+=2 ) + join_t ( left, right, lptr[0], lptr[1] ); + for( lptr=list; lptr != last; lptr++ ) { + if( ((*lptr)->head()[1] <= value) && ((*lptr)->tail()[1] <= value) ) + left.addarc( *lptr ); + else + right.addarc( *lptr ); + } + } + + if( list != arclist ) delete[] list; + unknown.adopt(); +} + + +void +Subdivider::check_s( Arc_ptr jarc1, Arc_ptr jarc2 ) +{ + assert( jarc1->check( ) != 0 ); + assert( jarc2->check( ) != 0 ); + assert( jarc1->next->check( ) != 0 ); + assert( jarc2->next->check( ) != 0 ); + assert( jarc1 != jarc2 ); + + /* XXX - if these assertions fail, it is due to user error or + undersampling */ + if( ! ( jarc1->tail()[0] < (jarc1)->head()[0] ) ) { +#ifndef NDEBUG + _glu_dprintf( "s difference %f\n", (jarc1)->tail()[0] - (jarc1)->head()[0] ); +#endif + ::mylongjmp( jumpbuffer, 28 ); + } + + if( ! ( jarc2->tail()[0] > (jarc2)->head()[0] ) ) { +#ifndef NDEBUG + _glu_dprintf( "s difference %f\n", (jarc2)->tail()[0] - (jarc2)->head()[0] ); +#endif + ::mylongjmp( jumpbuffer, 28 ); + } +} + +inline void +Subdivider::link( Arc_ptr jarc1, Arc_ptr jarc2, Arc_ptr up, Arc_ptr down ) +{ + up->nuid = down->nuid = 0; // XXX + + up->next = jarc2; + down->next = jarc1; + up->prev = jarc1->prev; + down->prev = jarc2->prev; + + down->next->prev = down; + up->next->prev = up; + down->prev->next = down; + up->prev->next = up; +} + +inline void +Subdivider::simple_link( Arc_ptr jarc1, Arc_ptr jarc2 ) +{ + Arc_ptr tmp = jarc2->prev; + jarc2->prev = jarc1->prev; + jarc1->prev = tmp; + jarc2->prev->next = jarc2; + jarc1->prev->next = jarc1; +} + + +/*---------------------------------------------------------------------------- + * join - add a pair of oppositely directed jordan arcs between two arcs + *---------------------------------------------------------------------------- + */ + +void +Subdivider::join_s( Bin& left, Bin& right, Arc_ptr jarc1, Arc_ptr jarc2 ) +{ + assert( jarc1->check( ) != 0); + assert( jarc2->check( ) != 0); + assert( jarc1 != jarc2 ); + + if( ! jarc1->getitail() ) + jarc1 = jarc1->next; + + if( ! jarc2->getitail() ) + jarc2 = jarc2->next; + + REAL s = jarc1->tail()[0]; + REAL t1 = jarc1->tail()[1]; + REAL t2 = jarc2->tail()[1]; + + if( t1 == t2 ) { + simple_link( jarc1, jarc2 ); + } else { + Arc_ptr newright = new(arcpool) Arc( arc_right, 0 ); + Arc_ptr newleft = new(arcpool) Arc( arc_left, 0 ); + assert( t1 < t2 ); + if( isBezierArcType() ) { + arctessellator.bezier( newright, s, s, t1, t2 ); + arctessellator.bezier( newleft, s, s, t2, t1 ); + } else { + arctessellator.pwl_right( newright, s, t1, t2, stepsizes[0] ); + arctessellator.pwl_left( newleft, s, t2, t1, stepsizes[2] ); + } + link( jarc1, jarc2, newright, newleft ); + left.addarc( newright ); + right.addarc( newleft ); + } + + assert( jarc1->check( ) != 0 ); + assert( jarc2->check( ) != 0 ); + assert( jarc1->next->check( ) != 0); + assert( jarc2->next->check( ) != 0); +} + +void +Subdivider::check_t( Arc_ptr jarc1, Arc_ptr jarc2 ) +{ + assert( jarc1->check( ) != 0 ); + assert( jarc2->check( ) != 0 ); + assert( jarc1->next->check( ) != 0 ); + assert( jarc2->next->check( ) != 0 ); + assert( jarc1 != jarc2 ); + + /* XXX - if these assertions fail, it is due to user error or + undersampling */ + if( ! ( jarc1->tail()[1] < (jarc1)->head()[1] ) ) { +#ifndef NDEBUG + _glu_dprintf( "t difference %f\n", jarc1->tail()[1] - (jarc1)->head()[1] ); +#endif + ::mylongjmp( jumpbuffer, 28 ); + } + + if( ! ( jarc2->tail()[1] > (jarc2)->head()[1] ) ) { +#ifndef NDEBUG + _glu_dprintf( "t difference %f\n", jarc2->tail()[1] - (jarc2)->head()[1] ); +#endif + ::mylongjmp( jumpbuffer, 28 ); + } +} + +/*---------------------------------------------------------------------------- + * join_t - add a pair of oppositely directed jordan arcs between two arcs + *---------------------------------------------------------------------------- + */ + +void +Subdivider::join_t( Bin& bottom, Bin& top, Arc_ptr jarc1, Arc_ptr jarc2 ) +{ + assert( jarc1->check( ) != 0 ); + assert( jarc2->check( ) != 0 ); + assert( jarc1->next->check( ) != 0 ); + assert( jarc2->next->check( ) != 0 ); + assert( jarc1 != jarc2 ); + + if( ! jarc1->getitail() ) + jarc1 = jarc1->next; + + if( ! jarc2->getitail() ) + jarc2 = jarc2->next; + + REAL s1 = jarc1->tail()[0]; + REAL s2 = jarc2->tail()[0]; + REAL t = jarc1->tail()[1]; + + if( s1 == s2 ) { + simple_link( jarc1, jarc2 ); + } else { + Arc_ptr newtop = new(arcpool) Arc( arc_top, 0 ); + Arc_ptr newbot = new(arcpool) Arc( arc_bottom, 0 ); + assert( s1 > s2 ); + if( isBezierArcType() ) { + arctessellator.bezier( newtop, s1, s2, t, t ); + arctessellator.bezier( newbot, s2, s1, t, t ); + } else { + arctessellator.pwl_top( newtop, t, s1, s2, stepsizes[1] ); + arctessellator.pwl_bottom( newbot, t, s2, s1, stepsizes[3] ); + } + link( jarc1, jarc2, newtop, newbot ); + bottom.addarc( newtop ); + top.addarc( newbot ); + } + + assert( jarc1->check( ) != 0 ); + assert( jarc2->check( ) != 0 ); + assert( jarc1->next->check( ) != 0 ); + assert( jarc2->next->check( ) != 0 ); +} + diff --git a/mesalib/src/glu/sgi/libnurbs/internals/subdivider.cc b/mesalib/src/glu/sgi/libnurbs/internals/subdivider.cc new file mode 100644 index 000000000..cc0b51470 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/subdivider.cc @@ -0,0 +1,910 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * subdivider.cxx + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "subdivider.h" +#include "arc.h" +#include "bezierarc.h" +#include "bin.h" +#include "renderhints.h" +#include "backend.h" +#include "mapdesc.h" +#include "quilt.h" +#include "patchlist.h" +#include "patch.h" +#include "nurbsconsts.h" +#include "trimvertpool.h" +#include "simplemath.h" + +#include "polyUtil.h" //for function area() + +//#define PARTITION_TEST +#ifdef PARTITION_TEST +#include "partitionY.h" +#include "monoTriangulation.h" +#include "dataTransform.h" +#include "monoChain.h" + +#endif + + +#define OPTIMIZE_UNTRIMED_CASE + + +Bin* +Subdivider::makePatchBoundary( const REAL *from, const REAL *to ) +{ + Bin* ret = new Bin(); + REAL smin = from[0]; + REAL smax = to[0]; + REAL tmin = from[1]; + REAL tmax = to[1]; + + pjarc = 0; + + Arc_ptr jarc = new(arcpool) Arc( arc_bottom, 0 ); + arctessellator.bezier( jarc, smin, smax, tmin, tmin ); + ret->addarc( jarc ); + pjarc = jarc->append( pjarc ); + + jarc = new(arcpool) Arc( arc_right, 0 ); + arctessellator.bezier( jarc, smax, smax, tmin, tmax ); + ret->addarc( jarc ); + pjarc = jarc->append( pjarc ); + + jarc = new(arcpool) Arc( arc_top, 0 ); + arctessellator.bezier( jarc, smax, smin, tmax, tmax ); + ret->addarc( jarc ); + pjarc = jarc->append( pjarc ); + + jarc = new(arcpool) Arc( arc_left, 0 ); + arctessellator.bezier( jarc, smin, smin, tmax, tmin ); + ret->addarc( jarc ); + jarc->append( pjarc ); + + assert( jarc->check() != 0 ); + return ret; +} + +/*--------------------------------------------------------------------------- + * Subdivider - construct a subdivider + *--------------------------------------------------------------------------- + */ + +Subdivider::Subdivider( Renderhints& r, Backend& b ) + : slicer( b ), + arctessellator( trimvertexpool, pwlarcpool ), + arcpool( sizeof( Arc), 1, "arcpool" ), + bezierarcpool( sizeof( BezierArc ), 1, "Bezarcpool" ), + pwlarcpool( sizeof( PwlArc ), 1, "Pwlarcpool" ), + renderhints( r ), + backend( b ) +{ +} + +void +Subdivider::setJumpbuffer( JumpBuffer *j ) +{ + jumpbuffer = j; +} + +/*--------------------------------------------------------------------------- + * clear - reset all state after possible error condition + *--------------------------------------------------------------------------- + */ + +void +Subdivider::clear( void ) +{ + trimvertexpool.clear(); + arcpool.clear(); + pwlarcpool.clear(); + bezierarcpool.clear(); +} + +/*--------------------------------------------------------------------------- + * ~Subdivider - destroy a subdivider + *--------------------------------------------------------------------------- + */ + +Subdivider::~Subdivider( void ) +{ +} + +/*--------------------------------------------------------------------------- + * addArc - add a bezier arc to a trim loop and to a bin + *--------------------------------------------------------------------------- + */ +void +Subdivider::addArc( REAL *cpts, Quilt *quilt, long _nuid ) +{ + BezierArc *bezierArc = new(bezierarcpool) BezierArc; + Arc *jarc = new(arcpool) Arc( arc_none, _nuid ); + jarc->pwlArc = 0; + jarc->bezierArc = bezierArc; + bezierArc->order = quilt->qspec->order; + bezierArc->stride = quilt->qspec->stride; + bezierArc->mapdesc = quilt->mapdesc; + bezierArc->cpts = cpts; + initialbin.addarc( jarc ); + pjarc = jarc->append( pjarc ); +} + +/*--------------------------------------------------------------------------- + * addArc - add a pwl arc to a trim loop and to a bin + *--------------------------------------------------------------------------- + */ + +void +Subdivider::addArc( int npts, TrimVertex *pts, long _nuid ) +{ + Arc *jarc = new(arcpool) Arc( arc_none, _nuid ); + jarc->pwlArc = new(pwlarcpool) PwlArc( npts, pts ); + initialbin.addarc( jarc ); + pjarc = jarc->append( pjarc ); +} + +void +Subdivider::beginQuilts( void ) +{ + qlist = 0; +} + +void +Subdivider::addQuilt( Quilt *quilt ) +{ + quilt->next = qlist; + qlist = quilt; +} + +/*--------------------------------------------------------------------------- + * drawSurfaces - main entry point for surface tessellation + *--------------------------------------------------------------------------- + */ + +void +Subdivider::drawSurfaces( long nuid ) +{ + renderhints.init( ); + + if (qlist == NULL) + { + //initialbin could be nonempty due to some errors + freejarcs(initialbin); + return; + } + + for( Quilt *q = qlist; q; q = q->next ) { + if( q->isCulled( ) == CULL_TRIVIAL_REJECT ) { + freejarcs( initialbin ); + return; + } + } + + + REAL from[2], to[2]; + qlist->getRange( from, to, spbrkpts, tpbrkpts ); +#ifdef OPTIMIZE_UNTRIMED_CASE + //perform optimization only when the samplng method is + //DOMAIN_DISTANCE and the display methdo is either + //fill or outline_polygon. + int optimize = (is_domain_distance_sampling && (renderhints.display_method != N_OUTLINE_PATCH)); +#endif + + if( ! initialbin.isnonempty() ) { +#ifdef OPTIMIZE_UNTRIMED_CASE + if(! optimize ) + { + + makeBorderTrim( from, to ); + } +#else + makeBorderTrim( from, to ); +#endif + } else { + REAL rate[2]; + qlist->findRates( spbrkpts, tpbrkpts, rate ); + + if( decompose( initialbin, min(rate[0], rate[1]) ) ) + mylongjmp( jumpbuffer, 31 ); + } + + backend.bgnsurf( renderhints.wiretris, renderhints.wirequads, nuid ); + +#ifdef PARTITION_TEST + if( initialbin.isnonempty() && spbrkpts.end-2 == spbrkpts.start && + tpbrkpts.end-2 == tpbrkpts.start) +{ + for(int i=spbrkpts.start; i<spbrkpts.end-1; i++){ + for(int j=tpbrkpts.start; j<tpbrkpts.end-1; j++){ + Real pta[2], ptb[2]; + pta[0] = spbrkpts.pts[i]; + ptb[0] = spbrkpts.pts[i+1]; + pta[1] = tpbrkpts.pts[j]; + ptb[1] = tpbrkpts.pts[j+1]; + qlist->downloadAll(pta, ptb, backend); + + directedLine *poly; + + { + + poly = bin_to_DLineLoops(initialbin); + + poly=poly->deleteDegenerateLinesAllPolygons(); + + sampledLine* retSampledLines; +//printf("before MC_partition\n"); + poly = MC_partitionY(poly, &retSampledLines); +//printf("after MC_partition\n"); + + } + + + { + primStream pStream(5000,5000); + directedLine* temp; + + for(temp=poly; temp != NULL; temp=temp->getNextPolygon()) + + monoTriangulation(temp, &pStream); + + slicer.evalStream(&pStream); + + } + //need to clean up space + } + } + freejarcs( initialbin ); + backend.endsurf(); + return; + + /* + printf("num_polygons=%i\n", poly->numPolygons()); + printf("num_edges=%i\n", poly->numEdgesAllPolygons()); + poly->writeAllPolygons("zloutputFile"); + return; + { + primStream pStream(20,20); + for(directedLine* tempD = poly; tempD != NULL; tempD = tempD->getNextPolygon()) + monoTriangulation(tempD, &pStream); + } + return; + */ +} +#endif //PARTITION_TEST + + +#ifdef OPTIMIZE_UNTRIMED_CASE + if( (!initialbin.isnonempty()) && optimize ) + { + int i,j; + int num_u_steps; + int num_v_steps; + for(i=spbrkpts.start; i<spbrkpts.end-1; i++){ + for(j=tpbrkpts.start; j<tpbrkpts.end-1; j++){ + Real pta[2], ptb[2]; + pta[0] = spbrkpts.pts[i]; + ptb[0] = spbrkpts.pts[i+1]; + pta[1] = tpbrkpts.pts[j]; + ptb[1] = tpbrkpts.pts[j+1]; + qlist->downloadAll(pta, ptb, backend); + + num_u_steps = (int) (domain_distance_u_rate * (ptb[0]-pta[0])); + num_v_steps = (int) (domain_distance_v_rate * (ptb[1]-pta[1])); + + if(num_u_steps <= 0) num_u_steps = 1; + if(num_v_steps <= 0) num_v_steps = 1; + + backend.surfgrid(pta[0], ptb[0], num_u_steps, + ptb[1], pta[1], num_v_steps); + backend.surfmesh(0,0,num_u_steps,num_v_steps); + + + + continue; + /* the following is left for reference purpose, don't delete + { + Bin* tempSource; + Patchlist patchlist(qlist, pta, ptb); + patchlist.getstepsize(); + + tempSource=makePatchBoundary(pta, ptb); + + tessellation(*tempSource, patchlist); + + render(*tempSource); + delete tempSource; + } + */ + } + } + } + else + subdivideInS( initialbin ); +#else + + subdivideInS( initialbin ); +#endif + + backend.endsurf(); + +} + +void +Subdivider::subdivideInS( Bin& source ) +{ + if( renderhints.display_method == N_OUTLINE_PARAM ) { + outline( source ); + freejarcs( source ); + } else { + setArcTypeBezier(); + setNonDegenerate(); + splitInS( source, spbrkpts.start, spbrkpts.end ); + } +} + + +/*--------------------------------------------------------------------------- + * splitInS - split a patch and a bin by an isoparametric line + *--------------------------------------------------------------------------- + */ + +void +Subdivider::splitInS( Bin& source, int start, int end ) +{ + if( source.isnonempty() ) { + if( start != end ) { + int i = start + (end - start) / 2; + Bin left, right; + split( source, left, right, 0, spbrkpts.pts[i] ); + splitInS( left, start, i ); + splitInS( right, i+1, end ); + } else { + if( start == spbrkpts.start || start == spbrkpts.end ) { + freejarcs( source ); + } else if( renderhints.display_method == N_OUTLINE_PARAM_S ) { + outline( source ); + freejarcs( source ); + } else { + setArcTypeBezier(); + setNonDegenerate(); + s_index = start; + splitInT( source, tpbrkpts.start, tpbrkpts.end ); + } + } + } +} + +/*--------------------------------------------------------------------------- + * splitInT - split a patch and a bin by an isoparametric line + *--------------------------------------------------------------------------- + */ + +void +Subdivider::splitInT( Bin& source, int start, int end ) +{ + if( source.isnonempty() ) { + if( start != end ) { + int i = start + (end - start) / 2; + Bin left, right; + split( source, left, right, 1, tpbrkpts.pts[i] ); + splitInT( left, start, i ); + splitInT( right, i+1, end ); + } else { + if( start == tpbrkpts.start || start == tpbrkpts.end ) { + freejarcs( source ); + } else if( renderhints.display_method == N_OUTLINE_PARAM_ST ) { + outline( source ); + freejarcs( source ); + } else { + t_index = start; + setArcTypeBezier(); + setDegenerate(); + + REAL pta[2], ptb[2]; + pta[0] = spbrkpts.pts[s_index-1]; + pta[1] = tpbrkpts.pts[t_index-1]; + + ptb[0] = spbrkpts.pts[s_index]; + ptb[1] = tpbrkpts.pts[t_index]; + qlist->downloadAll( pta, ptb, backend ); + + Patchlist patchlist( qlist, pta, ptb ); +/* +printf("-------samplingSplit-----\n"); +source.show("samplingSplit source"); +*/ + samplingSplit( source, patchlist, renderhints.maxsubdivisions, 0 ); + setNonDegenerate(); + setArcTypeBezier(); + } + } + } +} + +/*-------------------------------------------------------------------------- + * samplingSplit - recursively subdivide patch, cull check each subpatch + *-------------------------------------------------------------------------- + */ + +void +Subdivider::samplingSplit( + Bin& source, + Patchlist& patchlist, + int subdivisions, + int param ) +{ + if( ! source.isnonempty() ) return; + + if( patchlist.cullCheck() == CULL_TRIVIAL_REJECT ) { + freejarcs( source ); + return; + } + + patchlist.getstepsize(); + + if( renderhints.display_method == N_OUTLINE_PATCH ) { + tessellation( source, patchlist ); + outline( source ); + freejarcs( source ); + return; + } + + //patchlist.clamp(); + + tessellation( source, patchlist ); + + if( patchlist.needsSamplingSubdivision() && (subdivisions > 0) ) { + if( ! patchlist.needsSubdivision( 0 ) ) + param = 1; + else if( ! patchlist.needsSubdivision( 1 ) ) + param = 0; + else + param = 1 - param; + + Bin left, right; + REAL mid = ( patchlist.pspec[param].range[0] + + patchlist.pspec[param].range[1] ) * 0.5; + split( source, left, right, param, mid ); + Patchlist subpatchlist( patchlist, param, mid ); + samplingSplit( left, subpatchlist, subdivisions-1, param ); + samplingSplit( right, patchlist, subdivisions-1, param ); + } else { + setArcTypePwl(); + setDegenerate(); + nonSamplingSplit( source, patchlist, subdivisions, param ); + setDegenerate(); + setArcTypeBezier(); + } +} + +void +Subdivider::nonSamplingSplit( + Bin& source, + Patchlist& patchlist, + int subdivisions, + int param ) +{ + if( patchlist.needsNonSamplingSubdivision() && (subdivisions > 0) ) { + param = 1 - param; + + Bin left, right; + REAL mid = ( patchlist.pspec[param].range[0] + + patchlist.pspec[param].range[1] ) * 0.5; + split( source, left, right, param, mid ); + Patchlist subpatchlist( patchlist, param, mid ); + if( left.isnonempty() ) + if( subpatchlist.cullCheck() == CULL_TRIVIAL_REJECT ) + freejarcs( left ); + else + nonSamplingSplit( left, subpatchlist, subdivisions-1, param ); + if( right.isnonempty() ) + if( patchlist.cullCheck() == CULL_TRIVIAL_REJECT ) + freejarcs( right ); + else + nonSamplingSplit( right, patchlist, subdivisions-1, param ); + + } else { + // make bbox calls + patchlist.bbox(); + backend.patch( patchlist.pspec[0].range[0], patchlist.pspec[0].range[1], + patchlist.pspec[1].range[0], patchlist.pspec[1].range[1] ); + + if( renderhints.display_method == N_OUTLINE_SUBDIV ) { + outline( source ); + freejarcs( source ); + } else { + setArcTypePwl(); + setDegenerate(); + findIrregularS( source ); + monosplitInS( source, smbrkpts.start, smbrkpts.end ); + } + } +} + +/*-------------------------------------------------------------------------- + * tessellation - set tessellation of interior and boundary of patch + *-------------------------------------------------------------------------- + */ + +void +Subdivider::tessellation( Bin& bin, Patchlist &patchlist ) +{ + // tessellate unsampled trim curves + tessellate( bin, patchlist.pspec[1].sidestep[1], patchlist.pspec[0].sidestep[1], + patchlist.pspec[1].sidestep[0], patchlist.pspec[0].sidestep[0] ); + + // set interior sampling rates + slicer.setstriptessellation( patchlist.pspec[0].stepsize, patchlist.pspec[1].stepsize ); + + //added by zl: set the order which will be used in slicer.c++ + slicer.set_ulinear( (patchlist.get_uorder() == 2)); + slicer.set_vlinear( (patchlist.get_vorder() == 2)); + + // set boundary sampling rates + stepsizes[0] = patchlist.pspec[1].stepsize; + stepsizes[1] = patchlist.pspec[0].stepsize; + stepsizes[2] = patchlist.pspec[1].stepsize; + stepsizes[3] = patchlist.pspec[0].stepsize; +} + +/*--------------------------------------------------------------------------- + * monosplitInS - split a patch and a bin by an isoparametric line + *--------------------------------------------------------------------------- + */ + +void +Subdivider::monosplitInS( Bin& source, int start, int end ) +{ + if( source.isnonempty() ) { + if( start != end ) { + int i = start + (end - start) / 2; + Bin left, right; + split( source, left, right, 0, smbrkpts.pts[i] ); + monosplitInS( left, start, i ); + monosplitInS( right, i+1, end ); + } else { + if( renderhints.display_method == N_OUTLINE_SUBDIV_S ) { + outline( source ); + freejarcs( source ); + } else { + setArcTypePwl(); + setDegenerate(); + findIrregularT( source ); + monosplitInT( source, tmbrkpts.start, tmbrkpts.end ); + } + } + } +} + +/*--------------------------------------------------------------------------- + * monosplitInT - split a patch and a bin by an isoparametric line + *--------------------------------------------------------------------------- + */ + +void +Subdivider::monosplitInT( Bin& source, int start, int end ) +{ + if( source.isnonempty() ) { + if( start != end ) { + int i = start + (end - start) / 2; + Bin left, right; + split( source, left, right, 1, tmbrkpts.pts[i] ); + monosplitInT( left, start, i ); + monosplitInT( right, i+1, end ); + } else { + if( renderhints.display_method == N_OUTLINE_SUBDIV_ST ) { + outline( source ); + freejarcs( source ); + } else { +/* +printf("*******render\n"); +source.show("source\n"); +*/ + render( source ); + freejarcs( source ); + } + } + } +} + + +/*---------------------------------------------------------------------------- + * findIrregularS - determine points of non-monotonicity is s direction + *---------------------------------------------------------------------------- + */ + +void +Subdivider::findIrregularS( Bin& bin ) +{ + assert( bin.firstarc()->check() != 0 ); + + smbrkpts.grow( bin.numarcs() ); + + for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) { + REAL *a = jarc->prev->tail(); + REAL *b = jarc->tail(); + REAL *c = jarc->head(); + + if( b[1] == a[1] && b[1] == c[1] ) continue; + + //corrected code + if((b[1]<=a[1] && b[1] <= c[1]) || + (b[1]>=a[1] && b[1] >= c[1])) + { + //each arc (jarc, jarc->prev, jarc->next) is a + //monotone arc consisting of multiple line segements. + //it may happen that jarc->prev and jarc->next are the same, + //that is, jarc->prev and jarc form a closed loop. + //In such case, a and c will be the same. + if(a[0]==c[0] && a[1] == c[1]) + { + if(jarc->pwlArc->npts >2) + { + c = jarc->pwlArc->pts[jarc->pwlArc->npts-2].param; + } + else + { + assert(jarc->prev->pwlArc->npts>2); + a = jarc->prev->pwlArc->pts[jarc->prev->pwlArc->npts-2].param; + } + + } + if(area(a,b,c) < 0) + { + smbrkpts.add(b[0]); + } + + } + + /* old code, + if( b[1] <= a[1] && b[1] <= c[1] ) { + if( ! ccwTurn_tr( jarc->prev, jarc ) ) + smbrkpts.add( b[0] ); + } else if( b[1] >= a[1] && b[1] >= c[1] ) { + if( ! ccwTurn_tl( jarc->prev, jarc ) ) + smbrkpts.add( b[0] ); + } + */ + + } + + smbrkpts.filter(); +} + +/*---------------------------------------------------------------------------- + * findIrregularT - determine points of non-monotonicity in t direction + * where one arc is parallel to the s axis. + *---------------------------------------------------------------------------- + */ + +void +Subdivider::findIrregularT( Bin& bin ) +{ + assert( bin.firstarc()->check() != 0 ); + + tmbrkpts.grow( bin.numarcs() ); + + for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) { + REAL *a = jarc->prev->tail(); + REAL *b = jarc->tail(); + REAL *c = jarc->head(); + + if( b[0] == a[0] && b[0] == c[0] ) continue; + + if( b[0] <= a[0] && b[0] <= c[0] ) { + if( a[1] != b[1] && b[1] != c[1] ) continue; + if( ! ccwTurn_sr( jarc->prev, jarc ) ) + tmbrkpts.add( b[1] ); + } else if ( b[0] >= a[0] && b[0] >= c[0] ) { + if( a[1] != b[1] && b[1] != c[1] ) continue; + if( ! ccwTurn_sl( jarc->prev, jarc ) ) + tmbrkpts.add( b[1] ); + } + } + tmbrkpts.filter( ); +} + +/*----------------------------------------------------------------------------- + * makeBorderTrim - if no user input trimming data then create + * a trimming curve around the boundaries of the Quilt. The curve consists of + * four Jordan arcs, one for each side of the Quilt, connected, of course, + * head to tail. + *----------------------------------------------------------------------------- + */ + +void +Subdivider::makeBorderTrim( const REAL *from, const REAL *to ) +{ + REAL smin = from[0]; + REAL smax = to[0]; + REAL tmin = from[1]; + REAL tmax = to[1]; + + pjarc = 0; + + Arc_ptr jarc = new(arcpool) Arc( arc_bottom, 0 ); + arctessellator.bezier( jarc, smin, smax, tmin, tmin ); + initialbin.addarc( jarc ); + pjarc = jarc->append( pjarc ); + + jarc = new(arcpool) Arc( arc_right, 0 ); + arctessellator.bezier( jarc, smax, smax, tmin, tmax ); + initialbin.addarc( jarc ); + pjarc = jarc->append( pjarc ); + + jarc = new(arcpool) Arc( arc_top, 0 ); + arctessellator.bezier( jarc, smax, smin, tmax, tmax ); + initialbin.addarc( jarc ); + pjarc = jarc->append( pjarc ); + + jarc = new(arcpool) Arc( arc_left, 0 ); + arctessellator.bezier( jarc, smin, smin, tmax, tmin ); + initialbin.addarc( jarc ); + jarc->append( pjarc ); + + assert( jarc->check() != 0 ); +} + +/*---------------------------------------------------------------------------- + * render - renders all monotone regions in a bin and frees the bin + *---------------------------------------------------------------------------- + */ + +void +Subdivider::render( Bin& bin ) +{ + bin.markall(); + +#ifdef N_ISOLINE_S + slicer.setisolines( ( renderhints.display_method == N_ISOLINE_S ) ? 1 : 0 ); +#else + slicer.setisolines( 0 ); +#endif + + for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) { + if( jarc->ismarked() ) { + assert( jarc->check( ) != 0 ); + Arc_ptr jarchead = jarc; + do { + jarc->clearmark(); + jarc = jarc->next; + } while (jarc != jarchead); + slicer.slice( jarc ); + } + } +} + +/*--------------------------------------------------------------------------- + * outline - render the trimmed patch by outlining the boundary + *--------------------------------------------------------------------------- + */ + +void +Subdivider::outline( Bin& bin ) +{ + bin.markall(); + for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) { + if( jarc->ismarked() ) { + assert( jarc->check( ) != 0 ); + Arc_ptr jarchead = jarc; + do { + slicer.outline( jarc ); + jarc->clearmark(); + jarc = jarc->prev; + } while (jarc != jarchead); + } + } +} + +/*--------------------------------------------------------------------------- + * freejarcs - free all arcs in a bin + *--------------------------------------------------------------------------- + */ + +void +Subdivider::freejarcs( Bin& bin ) +{ + bin.adopt(); /* XXX - should not be necessary */ + + Arc_ptr jarc; + while( (jarc = bin.removearc()) != NULL ) { + if( jarc->pwlArc ) jarc->pwlArc->deleteMe( pwlarcpool ); jarc->pwlArc = 0; + if( jarc->bezierArc) jarc->bezierArc->deleteMe( bezierarcpool ); jarc->bezierArc = 0; + jarc->deleteMe( arcpool ); + } +} + +/*---------------------------------------------------------------------------- + * tessellate - tessellate all Bezier arcs in a bin + * 1) only accepts linear Bezier arcs as input + * 2) the Bezier arcs are stored in the pwlArc structure + * 3) only vertical or horizontal lines work + * -- should + * 1) represent Bezier arcs in BezierArc structure + * (this requires a multitude of changes to the code) + * 2) accept high degree Bezier arcs (hard) + * 3) map the curve onto the surface to determine tessellation + * 4) work for curves of arbitrary geometry + *---------------------------------------------------------------------------- + */ + + +void +Subdivider::tessellate( Bin& bin, REAL rrate, REAL trate, REAL lrate, REAL brate ) +{ + for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) { + if( jarc->isbezier( ) ) { + assert( jarc->pwlArc->npts == 2 ); + TrimVertex *pts = jarc->pwlArc->pts; + REAL s1 = pts[0].param[0]; + REAL t1 = pts[0].param[1]; + REAL s2 = pts[1].param[0]; + REAL t2 = pts[1].param[1]; + + jarc->pwlArc->deleteMe( pwlarcpool ); jarc->pwlArc = 0; + + switch( jarc->getside() ) { + case arc_left: + assert( s1 == s2 ); + arctessellator.pwl_left( jarc, s1, t1, t2, lrate ); + break; + case arc_right: + assert( s1 == s2 ); + arctessellator.pwl_right( jarc, s1, t1, t2, rrate ); + break; + case arc_top: + assert( t1 == t2 ); + arctessellator.pwl_top( jarc, t1, s1, s2, trate ); + break; + case arc_bottom: + assert( t1 == t2 ); + arctessellator.pwl_bottom( jarc, t1, s1, s2, brate ); + break; + case arc_none: + (void) abort(); + break; + } + assert( ! jarc->isbezier() ); + assert( jarc->check() != 0 ); + } + } +} diff --git a/mesalib/src/glu/sgi/libnurbs/internals/subdivider.h b/mesalib/src/glu/sgi/libnurbs/internals/subdivider.h new file mode 100644 index 000000000..4d5395181 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/subdivider.h @@ -0,0 +1,200 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * subdivider.h + * + */ + +#ifndef __glusubdivider_h_ +#define __glusubdivider_h_ + +#include "mysetjmp.h" +#include "bin.h" +#include "flist.h" +#include "slicer.h" +#include "arctess.h" +#include "trimvertex.h" +#include "trimvertpool.h" + +class Arc; +class Pool; +class Renderhints; +class Quilt; +class Patchlist; +class Curvelist; +struct JumpBuffer; + +class Subdivider { +public: + Subdivider( Renderhints&, Backend& ); + ~Subdivider( void ); + void clear( void ); + + void beginTrims( void ) {} + void beginLoop( void ); + void addArc( REAL *, Quilt *, long ); + void addArc( int, TrimVertex *, long ); + void endLoop( void ) {} + void endTrims( void ) {} + + void beginQuilts( void ); + void addQuilt( Quilt * ); + void endQuilts( void ) {} + + void drawCurves( void ); + void drawSurfaces( long ); + + int ccwTurn_sl( Arc_ptr, Arc_ptr ); + int ccwTurn_sr( Arc_ptr , Arc_ptr ); + int ccwTurn_tl( Arc_ptr , Arc_ptr ); + int ccwTurn_tr( Arc_ptr , Arc_ptr ); + + void setJumpbuffer( JumpBuffer * ); + + void set_domain_distance_u_rate(REAL u_rate) + { + domain_distance_u_rate = u_rate; + } + void set_domain_distance_v_rate(REAL v_rate) + { + domain_distance_v_rate = v_rate; + } + void set_is_domain_distance_sampling(int flag) + { + is_domain_distance_sampling = flag; + } + +private: + void classify_headonleft_s( Bin &, Bin &, Bin &, REAL ); + void classify_tailonleft_s( Bin &, Bin &, Bin &, REAL ); + void classify_headonright_s( Bin &, Bin &, Bin &, REAL ); + void classify_tailonright_s( Bin &, Bin &, Bin &, REAL ); + void classify_headonleft_t( Bin &, Bin &, Bin &, REAL ); + void classify_tailonleft_t( Bin &, Bin &, Bin &, REAL ); + void classify_headonright_t( Bin &, Bin &, Bin &, REAL ); + void classify_tailonright_t( Bin &, Bin &, Bin &, REAL ); + + enum dir { down, same, up, none }; + void tessellate( Arc_ptr, REAL ); + void monotonize( Arc_ptr , Bin & ); + int isMonotone( Arc_ptr ); + int decompose( Bin &, REAL ); + + + Slicer slicer; + ArcTessellator arctessellator; + Pool arcpool; + Pool bezierarcpool; + Pool pwlarcpool; + TrimVertexPool trimvertexpool; + + JumpBuffer* jumpbuffer; + Renderhints& renderhints; + Backend& backend; + + Bin initialbin; + Arc_ptr pjarc; + int s_index; + int t_index; + Quilt * qlist; + Flist spbrkpts; + Flist tpbrkpts; + Flist smbrkpts; + Flist tmbrkpts; + REAL stepsizes[4]; + int showDegenerate; + int isArcTypeBezier; + + void samplingSplit( Curvelist&, int ); + + void subdivideInS( Bin& ); + void splitInS( Bin&, int, int ); + void splitInT( Bin&, int, int ); + void samplingSplit( Bin&, Patchlist&, int, int ); + void nonSamplingSplit( Bin&, Patchlist&, int, int ); + void tessellation( Bin&, Patchlist& ); + void monosplitInS( Bin&, int, int ); + void monosplitInT( Bin&, int, int ); + + void outline( Bin & ); + void freejarcs( Bin & ); + void render( Bin & ); + void split( Bin &, Bin &, Bin &, int, REAL ); + void tessellate( Bin &, REAL, REAL, REAL, REAL ); + + inline void setDegenerate( void ) { showDegenerate = 1; } + inline void setNonDegenerate( void ) { showDegenerate = 0; } + inline int showingDegenerate( void ) { return showDegenerate; } + inline void setArcTypeBezier( void ) { isArcTypeBezier = 1; } + inline void setArcTypePwl( void ) { isArcTypeBezier = 0; } + inline int isBezierArcType( void ) { return isArcTypeBezier; } + + void makeBorderTrim( const REAL *, const REAL * ); + void split( Bin &, int, const REAL *, int, int ); + void partition( Bin &, Bin &, Bin &, Bin &, Bin &, int, REAL ); + void findIrregularS( Bin & ); + void findIrregularT( Bin & ); + + + inline int bbox( TrimVertex *, TrimVertex *, TrimVertex *, int ); + static int bbox( REAL, REAL, REAL, REAL, REAL, REAL ); + static int ccw( TrimVertex *, TrimVertex *, TrimVertex * ); + void join_s( Bin &, Bin &, Arc_ptr, Arc_ptr ); + void join_t( Bin &, Bin &, Arc_ptr , Arc_ptr ); + int arc_split( Arc_ptr , int, REAL, int ); + void check_s( Arc_ptr , Arc_ptr ); + void check_t( Arc_ptr , Arc_ptr ); + inline void link( Arc_ptr , Arc_ptr , Arc_ptr , Arc_ptr ); + inline void simple_link( Arc_ptr , Arc_ptr ); + + Bin* makePatchBoundary( const REAL *from, const REAL *to ); + + /*in domain distance method, the tessellation is controled by two numbers: + *GLU_U_STEP: number of u-segments per unit u length of domain + *GLU_V_STEP: number of v-segments per unit v length of domain + *These two numbers are normally stored in mapdesc->maxs(t)rate. + *I (ZL) put these two numbers here so that I can optimize the untrimmed + *case in the case of domain distance sampling. + *These two numbers are set by set_domain_distance_u_rate() and ..._v_..(). + */ + REAL domain_distance_u_rate; + REAL domain_distance_v_rate; + int is_domain_distance_sampling; +}; + +inline void +Subdivider::beginLoop( void ) +{ + pjarc = 0; +} + + +#endif /* __glusubdivider_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/tobezier.cc b/mesalib/src/glu/sgi/libnurbs/internals/tobezier.cc new file mode 100644 index 000000000..531f26bc7 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/tobezier.cc @@ -0,0 +1,687 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * tobezier.c++ + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "mystring.h" +#include "quilt.h" +#include "knotvector.h" + +/* local type definitions */ +struct Breakpt { /* breakpoints */ + Knot value; /* value */ + int multi; /* multiplicity */ + int def; /* deficit */ +}; + +struct Knotspec { /* knotvector format */ + long order; /* order of spline */ + Knot_ptr inkbegin; /* input knot sequence */ + Knot_ptr inkend; /* location after last knot */ + Knot_ptr outkbegin; /* in-process knot subsequence */ + Knot_ptr outkend; /* location after last knot */ + Knot_ptr kleft; /* */ + Knot_ptr kright; /* */ + Knot_ptr kfirst; /* */ + Knot_ptr klast; /* */ + Knot_ptr sbegin; /* conversion factor values */ + Breakpt * bbegin; /* in-process breakpoints */ + Breakpt * bend; /* last breakpoint */ + int ncoords; /* coordinates per control point */ + int prestride; /* stride between input points */ + int poststride; /* stride between output points */ + int preoffset; /* scaled point offset */ + int postoffset; /* scaled point offset */ + int prewidth; /* width of dimension */ + int postwidth; /* width of dimension */ + int istransformed; /* was dimension transformed */ + Knotspec * next; /* next knotspec */ + Knotspec * kspectotrans; /* knotspec in transformation direction */ + + Knotspec( void ); + ~Knotspec( void ); + void factors( void ); + void insert( REAL * ); + void preselect(); + void select( void ); + void copy( INREAL *, REAL * ); + void breakpoints( void ); + void knots( void ); + void transform( REAL * ); + void showpts( REAL * ); + + void pt_io_copy( REAL *, INREAL * ); + void pt_oo_copy( REAL *, REAL * ); + void pt_oo_sum( REAL*, REAL*, REAL*, Knot, Knot ); +}; + +struct Splinespec { /* a non-uniform tensor element */ + Splinespec( int ); + ~Splinespec(void); + Knotspec *kspec; /* format of each param. dir. */ + int dim; /* domain dimension */ + REAL * outcpts; /* Bezier control points */ + + void kspecinit( Knotvector & ); + void kspecinit( Knotvector &, Knotvector & ); + void select( void ); + void layout( long ); + void setupquilt( Quilt_ptr ); + void copy( INREAL * ); + void transform( void ); +}; + +/*----------------------------------------------------------------------------- + * Quilt::toBezier - convert from NURBS to rational Bezier + *----------------------------------------------------------------------------- + */ + +void +Quilt::toBezier( + Knotvector& knotvector, /* a knot vector */ + INREAL *ctlpts, /* input contol points */ + long ncoords ) /* number of coordinates per control point */ +{ + Splinespec spline( 1 ); + spline.kspecinit( knotvector ); + spline.select(); + spline.layout( ncoords ); + spline.setupquilt( this ); + spline.copy( ctlpts ); + spline.transform(); +} + +void +Quilt::toBezier( + Knotvector& sknotvector, /* a knot vector */ + Knotvector& tknotvector, /* a knot vector */ + INREAL *ctlpts, /* input contol points */ + long ncoords ) /* number of coordinates per control point */ +{ + Splinespec spline( 2 ); + spline.kspecinit( sknotvector, tknotvector ); + spline.select(); + spline.layout( ncoords ); + spline.setupquilt( this ); + spline.copy( ctlpts ); + spline.transform(); +} +Splinespec::Splinespec( int dimen ) +{ + dim = dimen; +} + +Splinespec::~Splinespec( void ) +{ + /* Note: do NOT delete 'outcpts' here since its address (not contents) + * is copied in 'cpts' in this file in function Splinespec::setupquilt(). + * This block of memory will eventually be deleted in file quilt.c++ in + * function Quilt::deleteMe() through 'cpts' so do NOT delete it here! + */ + Knotspec *ktrav= kspec; //start at beginning of list + while (ktrav != 0) { //any items to delete? + Knotspec *deleteThis= ktrav; //remember to delete this + ktrav= ktrav->next; //go to next item if any + delete deleteThis; //delete it + } +} /* ~Splinespec() */ + +/*----------------------------------------------------------------------------- + * Splinespec::kspecinit - initialize Splinespec structure + * + * Client: Quilt::toBezier + *----------------------------------------------------------------------------- + */ + +void +Splinespec::kspecinit( Knotvector& knotvector ) +{ + kspec = new Knotspec; + kspec->inkbegin = knotvector.knotlist; + kspec->inkend = knotvector.knotlist + knotvector.knotcount; + kspec->prestride = (int) knotvector.stride; + kspec->order = knotvector.order; + kspec->next = NULL; +} + +void +Splinespec::kspecinit( Knotvector& sknotvector, Knotvector& tknotvector ) +{ + kspec = new Knotspec; + Knotspec *tkspec = new Knotspec; + + kspec->inkbegin = sknotvector.knotlist; + kspec->inkend = sknotvector.knotlist + sknotvector.knotcount; + kspec->prestride = (int) sknotvector.stride; + kspec->order = sknotvector.order; + kspec->next = tkspec; + + tkspec->inkbegin = tknotvector.knotlist; + tkspec->inkend = tknotvector.knotlist + tknotvector.knotcount; + tkspec->prestride = (int) tknotvector.stride; + tkspec->order = tknotvector.order; + tkspec->next = NULL; +} + + +/*----------------------------------------------------------------------------- + * Splinespec::select - select the subsegments to copy + * + * Client: gl_quilt_to_bezier + *----------------------------------------------------------------------------- + */ + +void +Splinespec::select( ) +{ + for( Knotspec *knotspec = kspec; knotspec; knotspec = knotspec->next ) { + knotspec->preselect(); + knotspec->select(); + } +} + +/*----------------------------------------------------------------------------- + * Splinespec::layout - + * + * Client: gl_quilt_to_bezier + *----------------------------------------------------------------------------- + */ + +void +Splinespec::layout( long ncoords ) +{ + + long stride = ncoords; + for( Knotspec *knotspec = kspec; knotspec; knotspec=knotspec->next ) { + knotspec->poststride = (int) stride; + stride *= ((knotspec->bend-knotspec->bbegin)*knotspec->order + knotspec->postoffset); + knotspec->preoffset *= knotspec->prestride; + knotspec->prewidth *= knotspec->poststride; + knotspec->postwidth *= knotspec->poststride; + knotspec->postoffset *= knotspec->poststride; + knotspec->ncoords = (int) ncoords; + } + outcpts = new REAL[stride]; + assert( outcpts != 0 ); +} + +/*----------------------------------------------------------------------------- + * Splinespec::copy - copy the control points of current subobject + * + * Client: gl_quilt_to_bezier + *----------------------------------------------------------------------------- + */ + +void +Splinespec::copy( INREAL *incpts ) +{ + kspec->copy( incpts, outcpts ); +} + +/*----------------------------------------------------------------------------- + * Splinespec::setupquilt - assign all quilt variables from knotspec + * + * Client: gl_quilt_to_bezier + *----------------------------------------------------------------------------- + */ + +void +Splinespec::setupquilt( Quilt_ptr quilt ) +{ + Quiltspec_ptr qspec = quilt->qspec; + quilt->eqspec = qspec + dim; + for( Knotspec *knotspec = kspec; knotspec; knotspec=knotspec->next, qspec++ ) { + qspec->stride = knotspec->poststride; + qspec->width = knotspec->bend - knotspec->bbegin; + qspec->order = (int) knotspec->order; + qspec->offset = knotspec->postoffset; + qspec->index = 0; + qspec->bdry[0] = (knotspec->kleft == knotspec->kfirst) ? 1 : 0; + qspec->bdry[1] = (knotspec->kright == knotspec->klast) ? 1 : 0; + qspec->breakpoints = new Knot[qspec->width+1]; + Knot_ptr k = qspec->breakpoints; + for( Breakpt *bk = knotspec->bbegin; bk <= knotspec->bend; bk++ ) + *(k++) = bk->value; + } + quilt->cpts = outcpts; + quilt->next = 0; +} + +/*----------------------------------------------------------------------------- + * Splinespec::transform - convert a spline to Bezier format + * + * Client: gl_quilt_to_bezier + *----------------------------------------------------------------------------- + */ + +void +Splinespec::transform( void ) +{ + Knotspec *knotspec; + for( knotspec = kspec; knotspec; knotspec=knotspec->next ) + knotspec->istransformed = 0; + + for( knotspec = kspec; knotspec; knotspec=knotspec->next ) { + for( Knotspec *kspec2 = kspec; kspec2; kspec2=kspec2->next ) + kspec2->kspectotrans = knotspec; + kspec->transform( outcpts ); + knotspec->istransformed = 1; + } +} + + +/*----------------------------------------------------------------------------- + * Knotspec::Knotspec - constuct a knot spec + *----------------------------------------------------------------------------- + */ + +Knotspec::Knotspec( void ) +{ + bbegin = 0; + sbegin = 0; + outkbegin = 0; +} + +/*----------------------------------------------------------------------------- + * Knotspec::copy - copy the control points along minor direction + * + * Client: Splinespec::copy + *----------------------------------------------------------------------------- + */ + +void +Knotspec::copy( INREAL *inpt, REAL *outpt ) +{ + inpt = (INREAL *) (((char *) inpt) + preoffset); + + if( next ) { + for( REAL *lpt=outpt+prewidth; outpt != lpt; outpt += poststride ) { + next->copy( inpt, outpt ); + inpt = (INREAL *) (((char *) inpt) + prestride); + } + } else { + for( REAL *lpt=outpt+prewidth; outpt != lpt; outpt += poststride ) { + pt_io_copy( outpt, inpt ); + inpt = (INREAL *) (((char *) inpt) + prestride); + } + } +} + +/*----------------------------------------------------------------------------- + * Knotspec::showpts - print out points before transformation + * + * Client: Knotspec::select + *----------------------------------------------------------------------------- + */ +void +Knotspec::showpts( REAL *outpt ) +{ + if( next ) { + for( REAL *lpt=outpt+prewidth; outpt != lpt; outpt += poststride ) + next->showpts( outpt ); + } else { + for( REAL *lpt=outpt+prewidth; outpt != lpt; outpt += poststride ) + _glu_dprintf( "show %g %g %g\n", outpt[0], outpt[1], outpt[2] ); + } +} + +/*----------------------------------------------------------------------------- + * Knotspec::factors - precompute scale factors + * - overwrites knot vector, actual new knot vector is NOT produced + * + * Client: Knotspec::select + *----------------------------------------------------------------------------- + */ + +void +Knotspec::factors( void ) +{ + Knot *mid = (outkend - 1) - order + bend->multi; + Knot_ptr fptr = sbegin; + + for( Breakpt *bpt = bend; bpt >= bbegin; bpt-- ) { + mid -= bpt->multi; // last knot less than knot to insert + int def = bpt->def - 1; // number of knots to insert + if( def <= 0 ) continue; + Knot kv = bpt->value; // knot to insert + + Knot *kf = (mid-def) + (order-1); + for( Knot *kl = kf + def; kl != kf; kl-- ) { + Knot *kh, *kt; + for( kt=kl, kh=mid; kt != kf; kh--, kt-- ) + *(fptr++) = (kv - *kh) / (*kt - *kh); + *kl = kv; + } + } +} + +/*----------------------------------------------------------------------------- + * Knotspec::insert - convert subobject in direction of kspec into Bezier + * + * Client: Knotspec::transform + *----------------------------------------------------------------------------- + */ + +void +Knotspec::insert( REAL *p ) +{ + Knot_ptr fptr = sbegin; + REAL *srcpt = p + prewidth - poststride; + REAL *dstpt = p + postwidth + postoffset - poststride; + Breakpt *bpt = bend; + + for( REAL *pend = srcpt - poststride*bpt->def; srcpt != pend; pend +=poststride ) { + REAL *p1 = srcpt; + for( REAL *p2 = srcpt-poststride; p2 != pend; p1 = p2, p2 -= poststride ) { + pt_oo_sum( p1, p1, p2, *fptr, 1.0-*fptr ); + fptr++; + } + } + + for( --bpt; bpt >= bbegin; bpt-- ) { + + for( int multi = bpt->multi; multi > 0; multi-- ) { + pt_oo_copy( dstpt, srcpt ); + dstpt -= poststride; + srcpt -= poststride; + } + + for( REAL *pend = srcpt - poststride*bpt->def; srcpt != pend; pend +=poststride, dstpt-=poststride ) { + pt_oo_copy( dstpt, srcpt ); + REAL *p1 = srcpt; + + for( REAL *p2 = srcpt-poststride; p2 != pend; p1=p2, p2 -= poststride ) { + pt_oo_sum( p1, p1, p2, *fptr, 1.0-*fptr ); + fptr++; + } + } + } +} + +/*----------------------------------------------------------------------------- + * Knotspec::preselect - initialize kspec for processing + * + * Client: Splinespec::select + *----------------------------------------------------------------------------- + */ + +void +Knotspec::preselect( void ) +{ + Knot kval; + + /* position klast after last knot of "last" breakpoint */ + for( klast = inkend - order, kval = *klast; klast != inkend; klast++ ) + if( ! identical( *klast, kval ) ) break; + + /* position kfirst after last knot of "first" breakpoint */ + for( kfirst = inkbegin+order-1, kval= *kfirst; kfirst != inkend; kfirst++ ) + if( ! identical( *kfirst, kval ) ) break; + + /* compute multiplicity of first breakpoint */ + Knot_ptr k; + for( k = kfirst - 1; k >= inkbegin; k-- ) + if( ! identical( kval, *k ) ) break; + k++; + + /* allocate space for breakpoints - + use worst case estimate on number of breakpoints */ + + bbegin = new Breakpt[(klast - kfirst)+1]; + /* record multiplicity and value of first breakpoint */ + bbegin->multi = kfirst - k; + bbegin->value = kval; + bend = bbegin; + + kleft = kright = kfirst; +} + + +/*----------------------------------------------------------------------------- + * Knotspec::select - Knotspec::select segments and precompute scale factors + * + * Client: Splinespec::select + *----------------------------------------------------------------------------- + */ + +void +Knotspec::select( void ) +{ + breakpoints(); + knots(); + factors(); + + preoffset = kleft - (inkbegin + order); + postwidth = (int)((bend - bbegin) * order); + prewidth = (int)((outkend - outkbegin) - order); + postoffset = (bbegin->def > 1) ? (bbegin->def-1) : 0; +} + +/*----------------------------------------------------------------------------- + * Knotspec::breakpoints - compute breakpoints for knotspec + * + * Client: Knotspec::select + *----------------------------------------------------------------------------- + */ + +void +Knotspec::breakpoints( void ) +{ + Breakpt *ubpt = bbegin; + Breakpt *ubend = bend; + long nfactors = 0; + + ubpt->value = ubend->value; + ubpt->multi = ubend->multi; + + kleft = kright; + + for( ; kright != klast; kright++ ) { + if ( identical(*kright,ubpt->value) ) { + (ubpt->multi)++; + } else { + ubpt->def = (int) (order - ubpt->multi); + nfactors += (ubpt->def * (ubpt->def - 1)) / 2; + (++ubpt)->value = *kright; + ubpt->multi = 1; + } + } + ubpt->def = (int) (order - ubpt->multi); + nfactors += (ubpt->def * (ubpt->def - 1)) / 2; + + bend = ubpt; + + if( nfactors ) { + sbegin = new Knot[nfactors]; + } else { + sbegin = NULL; + } +} + + +/*----------------------------------------------------------------------------- + * Knotspec::knots - copy relevant subsequence of knots into temporary area + * + * Client: Knotspec::select + *----------------------------------------------------------------------------- + */ + +void +Knotspec::knots( void ) +{ + Knot_ptr inkpt = kleft - order; + Knot_ptr inkend = kright + bend->def; + + /* allocate space for knots and factors */ + outkbegin = new Knot[inkend-inkpt]; + Knot_ptr outkpt; + for( outkpt = outkbegin; inkpt != inkend; inkpt++, outkpt++ ) + *outkpt = *inkpt; + + outkend = outkpt; +} + + +/*----------------------------------------------------------------------------- + * Knotspec::transform - convert a spline along a given direction + * + * Client: Splienspec::transform + *----------------------------------------------------------------------------- + */ + +void +Knotspec::transform( REAL *p ) +{ + if( next ) { + if( this == kspectotrans ) { + next->transform( p ); + } else { + if( istransformed ) { + p += postoffset; + for( REAL *pend = p + postwidth; p != pend; p += poststride ) + next->transform( p ); + } else { + REAL *pend = p + prewidth; + for( ; p != pend; p += poststride ) + next->transform( p ); + } + } + } else { + if( this == kspectotrans ) { + insert( p ); + } else { + if( istransformed ) { + p += postoffset; + for( REAL *pend = p + postwidth; p != pend; p += poststride ) + kspectotrans->insert( p ); + } else { + REAL *pend = p + prewidth; + for( ; p != pend; p += poststride ) + kspectotrans->insert( p ); + } + } + } +} + +/*----------------------------------------------------------------------------- + * Knotspec::~Knotspec - free space alocated for knotspec + *----------------------------------------------------------------------------- + */ + +Knotspec::~Knotspec( void ) +{ + if( bbegin ) delete[] bbegin; + if( sbegin ) delete[] sbegin; + if( outkbegin ) delete[] outkbegin; +} + + +/*----------------------------------------------------------------------------- + * pt_io_copy - make internal copy of input cntrl pt. of x coords + *----------------------------------------------------------------------------- + */ + +void +Knotspec::pt_io_copy( REAL *topt, INREAL *frompt ) +{ + switch( ncoords ) { + case 4: + topt[3] = (REAL) frompt[3]; + case 3: + topt[2] = (REAL) frompt[2]; + case 2: + topt[1] = (REAL) frompt[1]; + case 1: + topt[0] = (REAL) frompt[0]; + break; + default: { + for( int i = 0; i < ncoords; i++ ) + *topt++ = (REAL) *frompt++; + } + } +} + +/*----------------------------------------------------------------------------- + * pt_oo_copy - make internal copy of internal cntrl pt. of x coords + *----------------------------------------------------------------------------- + */ + +void +Knotspec::pt_oo_copy( REAL *topt, REAL *frompt ) +{ + switch( ncoords ) { + case 4: + topt[3] = frompt[3]; + case 3: + topt[2] = frompt[2]; + case 2: + topt[1] = frompt[1]; + case 1: + topt[0] = frompt[0]; + break; + default: + memcpy( topt, frompt, ncoords * sizeof( REAL ) ); + } +} + +/*----------------------------------------------------------------------------- + * pt_oo_sum - compute affine combination of internal cntrl pts + *----------------------------------------------------------------------------- + */ + +void +Knotspec::pt_oo_sum( REAL *x, REAL *y, REAL *z, Knot a, Knot b ) +{ + switch( ncoords ) { + case 4: + x[3] = a * y[3] + b * z[3]; + case 3: + x[2] = a * y[2] + b * z[2]; + case 2: + x[1] = a * y[1] + b * z[1]; + case 1: + x[0] = a * y[0] + b * z[0]; + break; + default: { + for( int i = 0; i < ncoords; i++ ) + *x++ = a * *y++ + b * *z++; + } + } +} diff --git a/mesalib/src/glu/sgi/libnurbs/internals/trimline.cc b/mesalib/src/glu/sgi/libnurbs/internals/trimline.cc new file mode 100644 index 000000000..61f34cd38 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/trimline.cc @@ -0,0 +1,223 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * trimline.c++ + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "trimline.h" +#include "backend.h" + +Trimline::Trimline() +{ + size = 0; pts = 0; numverts = 0; + tinterp = &t; binterp = &b; +} + +Trimline::~Trimline() +{ + if( pts ) delete[] pts; +} + +void +Trimline::init( TrimVertex *v ) +{ + reset(); + grow(1); + append(v); +} + +inline void +Trimline::grow( long npts ) +{ + if( size < npts ) { + size = 2 * npts; + if( pts ) delete[] pts; + pts = new TrimVertex_p[size]; + } +} + +inline void +Trimline::append( TrimVertex *v ) +{ + assert( numverts != size ); + pts[numverts++] = v; +} + +void +Trimline::init( long npts, Arc_ptr jarc, long last ) +{ + jarcl.init( jarc, 0, last ); + grow( npts + 2 ); +} + +inline void +Trimline::swap() +{ + TrimVertex *tmp=tinterp; + tinterp=binterp; + binterp=tmp; +} + +void +Trimline::getNextPt() +{ + *binterp = *jarcl.getnextpt(); +} + +void +Trimline::getPrevPt() +{ + *binterp = *jarcl.getprevpt(); +} + +/*---------------------------------------------------------------------- + * getNextPts - make arrays of pointers to trim points on left and right + * hulls of trim strip. + *---------------------------------------------------------------------- + */ +void +Trimline::getNextPts( REAL vval, Backend& backend ) +{ + reset(); swap(); append( tinterp ); + assert( tinterp->param[1] >= vval ); + + register TrimVertex *p; + for( p=jarcl.getnextpt() ; p->param[1] >= vval; p=jarcl.getnextpt() ) { + append( p ); + } + + /* compute and copy pointer to final point on left hull */ + if( interpvert( last(), p, binterp, vval ) ) { + binterp->nuid = p->nuid; + backend.triangle( p, binterp, last() ); + append( binterp ); + } + jarcl.reverse(); + (void) jarcl.getprevpt(); /* reset jarcl to proper position */ + jarcl.reverse(); +} + +void +Trimline::getPrevPts( REAL vval, Backend& backend ) +{ + reset(); swap(); append( tinterp ); + assert( tinterp->param[1] >= vval ); + + register TrimVertex *q; + for( q=jarcl.getprevpt(); q->param[1] >= vval; q=jarcl.getprevpt() ) { + append( q ); + } + + /* compute and copy pointer to final point on right hull */ + if( interpvert( q, last(), binterp, vval ) ) { + binterp->nuid = q->nuid; + backend.triangle( last(), binterp, q ); + append( binterp ); + } + jarcl.reverse(); + (void) jarcl.getnextpt(); /* reset jarcl to proper position */ + jarcl.reverse(); +} + +void +Trimline::getNextPts( Arc_ptr botarc ) +{ + reset(); swap(); append( tinterp ); + +#ifndef NDEBUG + PwlArc *lastpwl = botarc->prev->pwlArc; + TrimVertex *lastpt1 = &lastpwl->pts[lastpwl->npts-1]; +#endif + TrimVertex *lastpt2 = botarc->pwlArc->pts; + register TrimVertex *p = jarcl.getnextpt(); + for( append( p ); p != lastpt2; append( p ) ) { + assert( p != lastpt1 ); + p = jarcl.getnextpt(); + } +} + +void +Trimline::getPrevPts( Arc_ptr botarc ) +{ + reset(); swap(); append( tinterp ); + + PwlArc *lastpwl = botarc->prev->pwlArc; + TrimVertex *lastpt1 = &lastpwl->pts[lastpwl->npts-1]; +#ifndef NDEBUG + TrimVertex *lastpt2 = botarc->pwlArc->pts; +#endif + + register TrimVertex *q = jarcl.getprevpt(); + for( append( q ); q != lastpt1; append( q ) ) { + assert( q != lastpt2 ); + q = jarcl.getprevpt(); + } +} + + +long +Trimline::interpvert( TrimVertex *a, TrimVertex *b, TrimVertex *c, REAL vval ) +{ + REAL denom = a->param[1] - b->param[1]; + + if(denom != 0) { + if( vval == a->param[1] ) { + c->param[0] = a->param[0]; + c->param[1] = a->param[1]; + c->nuid = a->nuid; + return 0; + } else if( vval == b->param[1] ) { + c->param[0] = b->param[0]; + c->param[1] = b->param[1]; + c->nuid = b->nuid; + return 0; + } else { + REAL r = (a->param[1] - vval)/denom; + c->param[0] = a->param[0] - r * (a->param[0] - b->param[0]); + c->param[1] = vval; + return 1; + } + } else { + c->param[0] = a->param[0]; + c->param[1] = a->param[1]; + c->nuid = a->nuid; + return 0; + } +} + diff --git a/mesalib/src/glu/sgi/libnurbs/internals/trimline.h b/mesalib/src/glu/sgi/libnurbs/internals/trimline.h new file mode 100644 index 000000000..ecc884284 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/trimline.h @@ -0,0 +1,103 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * trimline.h + * + */ + +#ifndef __glutrimline_h_ +#define __glutrimline_h_ + +class Arc; +class Backend; + +#include "trimvertex.h" +#include "jarcloc.h" + + +class Trimline { +private: + TrimVertex** pts; + long numverts; + long i; + long size; + Jarcloc jarcl; + TrimVertex t, b; + TrimVertex *tinterp, *binterp; + void reset( void ) { numverts = 0; } + inline void grow( long ); + inline void swap( void ); + inline void append( TrimVertex * ); + static long interpvert( TrimVertex *, TrimVertex *, TrimVertex *, REAL ); + + + +public: + Trimline(); + ~Trimline(); + void init( TrimVertex * ); + void init( long, Arc_ptr, long ); + void getNextPt( void ); + void getPrevPt( void ); + void getNextPts( REAL, Backend & ); + void getPrevPts( REAL, Backend & ); + void getNextPts( Arc_ptr ); + void getPrevPts( Arc_ptr ); + inline TrimVertex * next( void ); + inline TrimVertex * prev( void ); + inline TrimVertex * first( void ); + inline TrimVertex * last( void ); +}; + +inline TrimVertex * +Trimline::next( void ) +{ + if( i < numverts) return pts[i++]; else return 0; +} + +inline TrimVertex * +Trimline::prev( void ) +{ + if( i >= 0 ) return pts[i--]; else return 0; +} + +inline TrimVertex * +Trimline::first( void ) +{ + i = 0; return pts[i]; +} + +inline TrimVertex * +Trimline::last( void ) +{ + i = numverts; return pts[--i]; +} +#endif /* __glutrimline_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/trimregion.cc b/mesalib/src/glu/sgi/libnurbs/internals/trimregion.cc new file mode 100644 index 000000000..efe789356 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/trimregion.cc @@ -0,0 +1,114 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * trimregion.c++ + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "trimregion.h" +#include "backend.h" + +TrimRegion::TrimRegion( void ) +{ +} + +void +TrimRegion::setDu( REAL du ) +{ + oneOverDu = 1.0/du; +} + +void +TrimRegion::init( long npts, Arc_ptr extrema ) +{ + left.init( npts, extrema, extrema->pwlArc->npts - 1 ); + left.getNextPt(); + + right.init( npts, extrema, 0 ); + right.getPrevPt(); +} + +void +TrimRegion::getPts( Arc_ptr extrema ) +{ + left.getNextPts( extrema ); + right.getPrevPts( extrema ); +} + +void +TrimRegion::getPts( Backend &backend ) +{ + left.getNextPts( bot.vval, backend ); + right.getPrevPts( bot.vval, backend ); +} + +void +TrimRegion::getGridExtent( void ) +{ + getGridExtent( left.last(), right.last() ); +} + +void +TrimRegion::getGridExtent( TrimVertex *l, TrimVertex *r ) +{ + bot.ustart = (long) ((l->param[0] - uarray.uarray[0])*oneOverDu); + if( l->param[0] >= uarray.uarray[bot.ustart] ) bot.ustart++; +// if( l->param[0] > uarray.uarray[bot.ustart] ) bot.ustart++; + assert( l->param[0] <= uarray.uarray[bot.ustart] ); + assert( l->param[0] >= uarray.uarray[bot.ustart-1] ); + + bot.uend = (long) ((r->param[0] - uarray.uarray[0])*oneOverDu); + if( uarray.uarray[bot.uend] >= r->param[0] ) bot.uend--; +// if( uarray.uarray[bot.uend] > r->param[0] ) bot.uend--; + assert( r->param[0] >= uarray.uarray[bot.uend] ); + assert( r->param[0] <= uarray.uarray[bot.uend+1] ); +} + +int +TrimRegion::canTile( void ) +{ + TrimVertex *lf = left.first(); + TrimVertex *ll = left.last(); + TrimVertex *l = ( ll->param[0] > lf->param[0] ) ? ll : lf; + + TrimVertex *rf = right.first(); + TrimVertex *rl = right.last(); + TrimVertex *r = ( rl->param[0] < rf->param[0] ) ? rl : rf; + return (l->param[0] <= r->param[0]) ? 1 : 0; +} + diff --git a/mesalib/src/glu/sgi/libnurbs/internals/trimregion.h b/mesalib/src/glu/sgi/libnurbs/internals/trimregion.h new file mode 100644 index 000000000..ee15d7b98 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/trimregion.h @@ -0,0 +1,84 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * trimregion.h + * + */ + +#ifndef __glutrimregion_h_ +#define __glutrimregion_h_ + +#include "trimline.h" +#include "gridline.h" +#include "uarray.h" + +class Arc; +class Backend; + +class TrimRegion { +public: + TrimRegion(); + Trimline left; + Trimline right; + Gridline top; + Gridline bot; + Uarray uarray; + + void init( REAL ); + void advance( REAL, REAL, REAL ); + void setDu( REAL ); + void init( long, Arc_ptr ); + void getPts( Arc_ptr ); + void getPts( Backend & ); + void getGridExtent( TrimVertex *, TrimVertex * ); + void getGridExtent( void ); + int canTile( void ); +private: + REAL oneOverDu; +}; + +inline void +TrimRegion::init( REAL vval ) +{ + bot.vval = vval; +} + +inline void +TrimRegion::advance( REAL topVindex, REAL botVindex, REAL botVval ) +{ + top.vindex = (long) topVindex; + bot.vindex = (long) botVindex; + top.vval = bot.vval; + bot.vval = botVval; + top.ustart = bot.ustart; + top.uend = bot.uend; +} +#endif /* __glutrimregion_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/trimvertex.h b/mesalib/src/glu/sgi/libnurbs/internals/trimvertex.h new file mode 100644 index 000000000..2780b764a --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/trimvertex.h @@ -0,0 +1,63 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * trimvertex.h + * + */ + +#ifndef __glutrimvertex_h_ +#define __glutrimvertex_h_ + +#include "types.h" + +/*#define USE_OPTTT*/ + +class TrimVertex { /* a vertex on a trim curve */ +public: + REAL param[2]; /* parametric space coords */ +#ifdef USE_OPTTT + REAL cache_point[4]; //only when USE_OPTTT is on in slicer.c++ + REAL cache_normal[3]; +#endif + long nuid; +}; + +typedef class TrimVertex *TrimVertex_p; + +inline REAL +det3( TrimVertex *a, TrimVertex *b, TrimVertex *c ) +{ + return a->param[0] * (b->param[1]-c->param[1]) + + b->param[0] * (c->param[1]-a->param[1]) + + c->param[0] * (a->param[1]-b->param[1]); +} + +#endif /* __glutrimvertex_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/trimvertpool.cc b/mesalib/src/glu/sgi/libnurbs/internals/trimvertpool.cc new file mode 100644 index 000000000..3e5bd7038 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/trimvertpool.cc @@ -0,0 +1,119 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * trimvertexpool.c++ + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "mystring.h" +#include "trimvertex.h" +#include "trimvertpool.h" +#include "bufpool.h" + +/*---------------------------------------------------------------------------- + * TrimVertexPool::TrimVertexPool + *---------------------------------------------------------------------------- + */ +TrimVertexPool::TrimVertexPool( void ) + : pool( sizeof(TrimVertex)*3, 32, "Threevertspool" ) +{ + // initialize array of pointers to vertex lists + nextvlistslot = 0; + vlistsize = INIT_VERTLISTSIZE; + vlist = new TrimVertex_p[vlistsize]; +} + +/*---------------------------------------------------------------------------- + * TrimVertexPool::~TrimVertexPool + *---------------------------------------------------------------------------- + */ +TrimVertexPool::~TrimVertexPool( void ) +{ + // free all arrays of TrimVertices vertices + while( nextvlistslot ) { + delete [] vlist[--nextvlistslot]; + } + + // reallocate space for array of pointers to vertex lists + if( vlist ) delete[] vlist; +} + +/*---------------------------------------------------------------------------- + * TrimVertexPool::clear + *---------------------------------------------------------------------------- + */ +void +TrimVertexPool::clear( void ) +{ + // reinitialize pool of 3 vertex arrays + pool.clear(); + + // free all arrays of TrimVertices vertices + while( nextvlistslot ) { + delete [] vlist[--nextvlistslot]; + vlist[nextvlistslot] = 0; + } + + // reallocate space for array of pointers to vertex lists + if( vlist ) delete[] vlist; + vlist = new TrimVertex_p[vlistsize]; +} + + +/*---------------------------------------------------------------------------- + * TrimVertexPool::get - allocate a vertex list + *---------------------------------------------------------------------------- + */ +TrimVertex * +TrimVertexPool::get( int n ) +{ + TrimVertex *v; + if( n == 3 ) { + v = (TrimVertex *) pool.new_buffer(); + } else { + if( nextvlistslot == vlistsize ) { + vlistsize *= 2; + TrimVertex_p *nvlist = new TrimVertex_p[vlistsize]; + memcpy( nvlist, vlist, nextvlistslot * sizeof(TrimVertex_p) ); + if( vlist ) delete[] vlist; + vlist = nvlist; + } + v = vlist[nextvlistslot++] = new TrimVertex[n]; + } + return v; +} diff --git a/mesalib/src/glu/sgi/libnurbs/internals/trimvertpool.h b/mesalib/src/glu/sgi/libnurbs/internals/trimvertpool.h new file mode 100644 index 000000000..ebd3c04b1 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/trimvertpool.h @@ -0,0 +1,57 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * trimvertexpool.h + * + */ + +#ifndef __glutrimvertpool_h_ +#define __glutrimvertpool_h_ + +#include "bufpool.h" + +class TrimVertex; + +#define INIT_VERTLISTSIZE 200 + +class TrimVertexPool { +public: + TrimVertexPool( void ); + ~TrimVertexPool( void ); + void clear( void ); + TrimVertex * get( int ); +private: + Pool pool; + TrimVertex ** vlist; + int nextvlistslot; + int vlistsize; +}; +#endif /* __glutrimvertpool_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/types.h b/mesalib/src/glu/sgi/libnurbs/internals/types.h new file mode 100644 index 000000000..8b59625cf --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/types.h @@ -0,0 +1,47 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * types.h + * + */ + +#ifndef __glutypes_h_ +#define __glutypes_h_ + +//typedef double INREAL; +#define INREAL float +typedef float REAL; +typedef void (*Pfvv)( void ); +typedef void (*Pfvf)( float * ); +typedef int (*cmpfunc)(const void *, const void *); +typedef REAL Knot, *Knot_ptr;/* knot values */ + +#endif /* __glutypes_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/uarray.cc b/mesalib/src/glu/sgi/libnurbs/internals/uarray.cc new file mode 100644 index 000000000..f0e236437 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/uarray.cc @@ -0,0 +1,72 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * uarray.c++ + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "uarray.h" +#include "arc.h" + +Uarray::Uarray( void ) +{ + uarray = 0; + size = 0; +} + +Uarray::~Uarray( void ) +{ + if( uarray ) delete[] uarray; +} + +long +Uarray::init( REAL delta, Arc_ptr lo, Arc_ptr hi ) +{ + ulines = (long) ((hi->tail()[0] - lo->tail()[0])/delta) + 3; + if( size < ulines ) { + size = ulines * 2; + if( uarray ) delete[] uarray; + uarray = new REAL[size]; + assert( uarray != 0); + } + uarray[0] = lo->tail()[0] - delta/2.0; + for( long i = 1 ; i != ulines; i++ ) + uarray[i] = uarray[0] + i*delta; + return ulines; +} + diff --git a/mesalib/src/glu/sgi/libnurbs/internals/uarray.h b/mesalib/src/glu/sgi/libnurbs/internals/uarray.h new file mode 100644 index 000000000..cc6fae1b7 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/uarray.h @@ -0,0 +1,55 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * uarray.h + * + */ + +#ifndef __gluuarray_h_ +#define __gluuarray_h_ + +#include "types.h" + +class Arc; +typedef class Arc *Arc_ptr; + +class Uarray { +private: + long size; + long ulines; +public: + Uarray(); + ~Uarray(); + long init( REAL, Arc_ptr, Arc_ptr ); + REAL * uarray; +}; + +#endif /* __gluuarray_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/internals/varray.cc b/mesalib/src/glu/sgi/libnurbs/internals/varray.cc new file mode 100644 index 000000000..31cc73a9d --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/varray.cc @@ -0,0 +1,144 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * varray.c++ + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "varray.h" +#include "arc.h" +#include "simplemath.h" // glu_abs() + +#define TINY 0.0001 +inline long sgn( REAL x ) +{ + return (x < -TINY) ? -1 : ((x > TINY) ? 1 : 0 ); +} + + +Varray::Varray( void ) +{ + varray = 0; + size = 0; +} + +Varray::~Varray( void ) +{ + if( varray ) delete[] varray; +} + +inline void +Varray::update( Arc_ptr arc, long dir[2], REAL val ) +{ + register long ds = sgn(arc->tail()[0] - arc->prev->tail()[0]); + register long dt = sgn(arc->tail()[1] - arc->prev->tail()[1]); + + if( dir[0] != ds || dir[1] != dt ) { + dir[0] = ds; + dir[1] = dt; + append( val ); + } +} + +void +Varray::grow( long guess ) +{ + if( size < guess ) { + size = guess * 2; + if( varray ) delete[] varray; + varray = new REAL[size]; + assert( varray != 0 ); + } +} + +long +Varray::init( REAL delta, Arc_ptr toparc, Arc_ptr botarc ) +{ + Arc_ptr left = toparc->next; + Arc_ptr right = toparc; + long ldir[2], rdir[2]; + + ldir[0] = sgn( left->tail()[0] - left->prev->tail()[0] ); + ldir[1] = sgn( left->tail()[1] - left->prev->tail()[1] ); + rdir[0] = sgn( right->tail()[0] - right->prev->tail()[0] ); + rdir[1] = sgn( right->tail()[1] - right->prev->tail()[1] ); + + vval[0] = toparc->tail()[1]; + numquads = 0; + + while( 1 ) { + switch( sgn( left->tail()[1] - right->prev->tail()[1] ) ) { + case 1: + left = left->next; + update( left, ldir, left->prev->tail()[1] ); + break; + case -1: + right = right->prev; + update( right, rdir, right->tail()[1] ); + break; + case 0: + if( glu_abs(left->tail()[1] - botarc->tail()[1]) < TINY) goto end; + if( glu_abs(left->tail()[0]-right->prev->tail()[0]) < TINY && + glu_abs(left->tail()[1]-right->prev->tail()[1]) < TINY) goto end; + left = left->next; + break; + } + } + +end: + append( botarc->tail()[1] ); + + grow( ((long) ((vval[0] - vval[numquads])/delta)) + numquads + 2 ); + + long i, index = 0; + for( i=0; i<numquads; i++ ) { + voffset[i] = index; + varray[index++] = vval[i]; + REAL dist = vval[i] - vval[i+1]; + if( dist > delta ) { + long steps = ((long) (dist/delta)) +1; + float deltav = - dist / (REAL) steps; + for( long j=1; j<steps; j++ ) + varray[index++] = vval[i] + j * deltav; + } + } + voffset[i] = index; + varray[index] = vval[i]; + return index; +} + diff --git a/mesalib/src/glu/sgi/libnurbs/internals/varray.h b/mesalib/src/glu/sgi/libnurbs/internals/varray.h new file mode 100644 index 000000000..b12ff837c --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/internals/varray.h @@ -0,0 +1,68 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * varray.h + * + */ + +#ifndef __gluvarray_h_ +#define __gluvarray_h_ + +#include "types.h" + +class Arc; + +class Varray { +public: + Varray(); + ~Varray(); + long init( REAL, Arc *, Arc * ); + REAL * varray; + REAL vval[1000]; + long voffset[1000]; + long numquads; + +private: + long size; + inline void update( Arc *, long[2], REAL ); + void grow( long ); + inline void append( REAL ); +}; + +inline void +Varray::append( REAL v ) +{ + if( v != vval[numquads] ) + vval[++numquads] = v; +} + + +#endif /* __gluvarray_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/definitions.h b/mesalib/src/glu/sgi/libnurbs/nurbtess/definitions.h new file mode 100644 index 000000000..962921da1 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/definitions.h @@ -0,0 +1,40 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ +/* +*/ + +#ifndef _DEFINITIONS_H +#define _DEFINITIONS_H + +typedef float Real; +typedef int Int; +typedef Real Real2[2]; + +#endif diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/directedLine.cc b/mesalib/src/glu/sgi/libnurbs/nurbtess/directedLine.cc new file mode 100644 index 000000000..74450352d --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/directedLine.cc @@ -0,0 +1,848 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <math.h> +#include "glimports.h" +#include "zlassert.h" + +#include "quicksort.h" +#include "directedLine.h" +#include "polyDBG.h" + +#ifdef __WATCOMC__ +#pragma warning 726 10 +#endif + +//we must return the newLine +directedLine* directedLine::deleteChain(directedLine* begin, directedLine* end) +{ + if(begin->head()[0] == end->tail()[0] && + begin->head()[1] == end->tail()[1] + ) + { + directedLine *ret = begin->prev; + begin->prev->next = end->next; + end->next->prev = begin->prev; + delete begin->sline; + delete end->sline; + delete begin; + delete end; + + return ret; + } + + directedLine* newLine; + sampledLine* sline = new sampledLine(begin->head(), end->tail()); + newLine = new directedLine(INCREASING, sline); + directedLine *p = begin->prev; + directedLine *n = end->next; + p->next = newLine; + n->prev = newLine; + newLine->prev = p; + newLine->next = n; + + delete begin->sline; + delete end->sline; + delete begin; + delete end; + return newLine; +} + + +void directedLine::deleteSingleLine(directedLine* dline) +{ + //make sure that dline->prev->tail is the same as + //dline->next->head. This is for numerical erros. + //for example, if we delete a line which is almost degeneate + //within (epsilon), then we want to make that the polygon after deletion + //is still a valid polygon + + dline->next->head()[0] = dline->prev->tail()[0]; + dline->next->head()[1] = dline->prev->tail()[1]; + + dline->prev->next = dline->next; + dline->next->prev = dline->prev; + + delete dline; + +} + +static Int myequal(Real a[2], Real b[2]) +{ + /* + if(a[0]==b[0] && a[1] == b[1]) + return 1; + else + return 0; + */ + + + if(fabs(a[0]-b[0]) < 0.00001 && + fabs(a[1]-b[1]) < 0.00001) + return 1; + else + return 0; + +} + +directedLine* directedLine::deleteDegenerateLines() +{ + //if there is only one edge or two edges, don't do anything + if(this->next == this) + return this; + if(this->next == this->prev) + return this; + + //find a nondegenerate line + directedLine* temp; + directedLine* first = NULL; + if(! myequal(head(), tail())) + /* + if(head()[0] != tail()[0] || + head()[1] != tail()[1]) + */ + first = this; + else + { + for(temp = this->next; temp != this; temp = temp->next) + { + /* + if(temp->head()[0] != temp->tail()[0] || + temp->head()[1] != temp->tail()[1]) + */ + if(! myequal(temp->head(), temp->tail())) + { + first = temp; + break; + } + + } + } + + //if there are no non-degenerate lines, then we simply return NULL. + if(first == NULL) + { + deleteSinglePolygonWithSline(); + return NULL; + } + + directedLine* tempNext = NULL; + for(temp =first->next; temp != first; temp = tempNext) + { + tempNext = temp->getNext(); +/* + if(temp->head()[0] == temp->tail()[0] && + temp->head()[1] == temp->tail()[1]) +*/ + + if(myequal(temp->head(), temp->tail())) + deleteSingleLine(temp); + } + return first; +} + +directedLine* directedLine::deleteDegenerateLinesAllPolygons() +{ + directedLine* temp; + directedLine *tempNext = NULL; + directedLine* ret= NULL; + directedLine* retEnd = NULL; + for(temp=this; temp != NULL; temp = tempNext) + { + tempNext = temp->nextPolygon; + temp->nextPolygon = NULL; + if(ret == NULL) + { + ret = retEnd = temp->deleteDegenerateLines(); + + } + else + { + directedLine *newPolygon = temp->deleteDegenerateLines(); + if(newPolygon != NULL) + { + retEnd->nextPolygon = temp->deleteDegenerateLines(); + retEnd = retEnd->nextPolygon; + } + } + } + return ret; +} + +directedLine* directedLine::cutIntersectionAllPoly(int &cutOccur) +{ + directedLine* temp; + directedLine *tempNext = NULL; + directedLine* ret= NULL; + directedLine* retEnd = NULL; + cutOccur = 0; + for(temp=this; temp != NULL; temp = tempNext) + { + int eachCutOccur=0; + tempNext = temp->nextPolygon; + temp->nextPolygon = NULL; + if(ret == NULL) + { + + ret = retEnd = DBG_cutIntersectionPoly(temp, eachCutOccur); + if(eachCutOccur) + cutOccur = 1; + } + else + { + + retEnd->nextPolygon = DBG_cutIntersectionPoly(temp, eachCutOccur); + retEnd = retEnd->nextPolygon; + if(eachCutOccur) + cutOccur = 1; + } + } + return ret; +} + + +void directedLine::deleteSinglePolygonWithSline() +{ + directedLine *temp, *tempNext; + prev->next = NULL; + for(temp=this; temp != NULL; temp = tempNext) + { + tempNext = temp->next; + delete temp->sline; + delete temp; + } +} + +void directedLine::deletePolygonListWithSline() +{ + directedLine *temp, *tempNext; + for(temp=this; temp != NULL; temp=tempNext) + { + tempNext = temp->nextPolygon; + temp->deleteSinglePolygonWithSline(); + } +} + +void directedLine::deleteSinglePolygon() +{ + directedLine *temp, *tempNext; + prev->next = NULL; + for(temp=this; temp != NULL; temp = tempNext) + { + tempNext = temp->next; + delete temp; + } +} + +void directedLine::deletePolygonList() +{ + directedLine *temp, *tempNext; + for(temp=this; temp != NULL; temp=tempNext) + { + tempNext = temp->nextPolygon; + temp->deleteSinglePolygon(); + } +} + + +/*a loop by itself*/ +directedLine::directedLine(short dir, sampledLine* sl) +{ + direction = dir; + sline = sl; + next = this; + prev = this; + nextPolygon = NULL; +// prevPolygon = NULL; + rootBit = 0;/*important to initilzae to 0 meaning not root yet*/ + + rootLink = NULL; + +} + +void directedLine::init(short dir, sampledLine* sl) +{ + direction = dir; + sline = sl; +} + +directedLine::directedLine() +{ + next = this; + prev = this; + nextPolygon = NULL; + rootBit = 0;/*important to initilzae to 0 meaning not root yet*/ + rootLink = NULL; +} + +directedLine::~directedLine() +{ +} + +Real* directedLine::head() +{ + + return (direction==INCREASING)? (sline->get_points())[0] : (sline->get_points())[sline->get_npoints()-1]; +} + +/*inline*/ Real* directedLine::getVertex(Int i) +{ + return (direction==INCREASING)? (sline->get_points())[i] : (sline->get_points())[sline->get_npoints() - 1 -i]; +} + +Real* directedLine::tail() +{ + return (direction==DECREASING)? (sline->get_points())[0] : (sline->get_points())[sline->get_npoints()-1]; +} + + /*insert a new line between prev and this*/ +void directedLine::insert(directedLine* nl) +{ + nl->next = this; + nl->prev = prev; + prev->next = nl; + prev = nl; + nl->rootLink = this; /*assuming that 'this' is the root!!!*/ +} + +Int directedLine::numEdges() +{ + Int ret=0; + directedLine* temp; + if(next == this) return 1; + + ret = 1; + for(temp = next; temp != this; temp = temp->next) + ret++; + return ret; +} + +Int directedLine::numEdgesAllPolygons() +{ + Int ret=0; + directedLine* temp; + for(temp=this; temp!= NULL; temp=temp->nextPolygon) + { + ret += temp->numEdges(); + } + return ret; +} + +/*return 1 if the double linked list forms a polygon. + */ +short directedLine::isPolygon() +{ + directedLine* temp; + + /*a polygon contains at least 3 edges*/ + if(numEdges() <=2) return 0; + + /*check this edge*/ + if(! isConnected()) return 0; + + /*check all other edges*/ + for(temp=next; temp != this; temp = temp->next){ + if(!isConnected()) return 0; + } + return 1; +} + +/*check if the head of this edge is connected to + *the tail of the prev + */ +short directedLine::isConnected() +{ + if( (head()[0] == prev->tail()[0]) && (head()[1] == prev->tail()[1])) + return 1; + else + return 0; +} + +Int compV2InY(Real A[2], Real B[2]) +{ + if(A[1] < B[1]) return -1; + if(A[1] == B[1] && A[0] < B[0]) return -1; + if(A[1] == B[1] && A[0] == B[0]) return 0; + return 1; +} + +Int compV2InX(Real A[2], Real B[2]) +{ + if(A[0] < B[0]) return -1; + if(A[0] == B[0] && A[1] < B[1]) return -1; + if(A[0] == B[0] && A[1] == B[1]) return 0; + return 1; +} + +/*compare two vertices NOT lines! + *A vertex is the head of a directed line. + *(x_1, y_1) <= (x_2, y_2) if + *either y_1 < y_2 + *or y_1 == y_2 && x_1 < x_2. + *return -1 if this->head() <= nl->head(), + *return 1 otherwise + */ +Int directedLine::compInY(directedLine* nl) +{ + if(head()[1] < nl->head()[1]) return -1; + if(head()[1] == nl->head()[1] && head()[0] < nl->head()[0]) return -1; + return 1; +} + +/*compare two vertices NOT lines! + *A vertex is the head of a directed line. + *(x_1, y_1) <= (x_2, y_2) if + *either x_1 < x_2 + *or x_1 == x_2 && y_1 < y_2. + *return -1 if this->head() <= nl->head(), + *return 1 otherwise + */ +Int directedLine::compInX(directedLine* nl) +{ + if(head()[0] < nl->head()[0]) return -1; + if(head()[0] == nl->head()[0] && head()[1] < nl->head()[1]) return -1; + return 1; +} + +/*used by sort precedures + */ +static Int compInY2(directedLine* v1, directedLine* v2) +{ + return v1->compInY(v2); +} +#ifdef NOT_USED +static Int compInX(directedLine* v1, directedLine* v2) +{ + return v1->compInX(v2); +} +#endif + +/*sort all the vertices NOT the lines! + *a vertex is the head of a directed line + */ +directedLine** directedLine::sortAllPolygons() +{ + Int total_num_edges = 0; + directedLine** array = toArrayAllPolygons(total_num_edges); + quicksort( (void**)array, 0, total_num_edges-1, (Int (*)(void *, void *)) compInY2); + + return array; +} + +void directedLine::printSingle() +{ + if(direction == INCREASING) + printf("direction is INCREASING\n"); + else + printf("direction is DECREASING\n"); + printf("head=%f,%f)\n", head()[0], head()[1]); + sline->print(); +} + +/*print one polygon*/ +void directedLine::printList() +{ + directedLine* temp; + printSingle(); + for(temp = next; temp!=this; temp=temp->next) + temp->printSingle(); +} + +/*print all the polygons*/ +void directedLine::printAllPolygons() +{ + directedLine *temp; + for(temp = this; temp!=NULL; temp = temp->nextPolygon) + { + printf("polygon:\n"); + temp->printList(); + } +} + +/*insert this polygon into the head of the old polygon List*/ +directedLine* directedLine::insertPolygon(directedLine* oldList) +{ + /*this polygon is a root*/ + setRootBit(); + if(oldList == NULL) return this; + nextPolygon = oldList; +/* oldList->prevPolygon = this;*/ + return this; +} + +/*cutoff means delete. but we don't deallocate any space, + *so we use cutoff instead of delete + */ +directedLine* directedLine::cutoffPolygon(directedLine *p) +{ + directedLine* temp; + directedLine* prev_polygon = NULL; + if(p == NULL) return this; + + for(temp=this; temp != p; temp = temp->nextPolygon) + { + if(temp == NULL) + { + fprintf(stderr, "in cutoffPolygon, not found\n"); + exit(1); + } + prev_polygon = temp; + } + +/* prev_polygon = p->prevPolygon;*/ + + p->resetRootBit(); + if(prev_polygon == NULL) /*this is the one to cutoff*/ + return nextPolygon; + else { + prev_polygon->nextPolygon = p->nextPolygon; + return this; + } +} + +Int directedLine::numPolygons() +{ + if(nextPolygon == NULL) return 1; + else return 1+nextPolygon->numPolygons(); +} + + +/*let array[index ...] denote + *all the edges in this polygon + *return the next available index of array. + */ +Int directedLine::toArraySinglePolygon(directedLine** array, Int index) +{ + directedLine *temp; + array[index++] = this; + for(temp = next; temp != this; temp = temp->next) + { + array[index++] = temp; + } + return index; +} + +/*the space is allocated. The caller is responsible for + *deallocate the space. + *total_num_edges is set to be the total number of edges of all polygons + */ +directedLine** directedLine::toArrayAllPolygons(Int& total_num_edges) +{ + total_num_edges=numEdgesAllPolygons(); + directedLine** ret = (directedLine**) malloc(sizeof(directedLine*) * total_num_edges); + assert(ret); + + directedLine *temp; + Int index = 0; + for(temp=this; temp != NULL; temp=temp->nextPolygon) { + index = temp->toArraySinglePolygon(ret, index); + } + return ret; +} + +/*assume the polygon is a simple polygon, return + *the area enclosed by it. + *if thee order is counterclock wise, the area is positive. + */ +Real directedLine::polyArea() +{ + directedLine* temp; + Real ret=0.0; + Real x1,y1,x2,y2; + x1 = this->head()[0]; + y1 = this->head()[1]; + x2 = this->next->head()[0]; + y2 = this->next->head()[1]; + ret = -(x2*y1-x1*y2); + for(temp=this->next; temp!=this; temp = temp->next) + { + x1 = temp->head()[0]; + y1 = temp->head()[1]; + x2 = temp->next->head()[0]; + y2 = temp->next->head()[1]; + ret += -( x2*y1-x1*y2); + } + return Real(0.5)*ret; +} + +/*******************split or combine polygons begin********************/ +/*conect a diagonal of a single simple polygon or two simple polygons. + *If the two vertices v1 (head) and v2 (head) are in the same simple polygon, + *then we actually split the simple polygon into two polygons. + *If instead two vertices velong to two difference polygons, + *then we combine the two polygons into one polygon. + *It is upto the caller to decide whether this is a split or a + *combination. + * + *Case Split: + *split a single simple polygon into two simple polygons by + *connecting a diagonal (two vertices). + *v1, v2: the two vertices are the head() of the two directedLines. + * this routine generates one new sampledLine which is returned in + *generatedLine, + *and it generates two directedLines returned in ret_p1 and ret_p2. + *ret_p1 and ret_p2 are used as the entry to the two new polygons. + *Notice the caller should not deallocate the space of v2 and v2 after + *calling this function, since all of the edges are connected to + *ret_p1 or ret_p2. + * + *combine: + *combine two simpolygons into one by connecting one diagonal. + *the returned polygon is returned in ret_p1. + */ +/*ARGSUSED*/ +void directedLine::connectDiagonal(directedLine* v1, directedLine* v2, + directedLine** ret_p1, + directedLine** ret_p2, + sampledLine** generatedLine, + directedLine* polygonList ) +{ + sampledLine *nsline = new sampledLine(2); + + + + nsline->setPoint(0, v1->head()); + nsline->setPoint(1, v2->head()); + + + + /*the increasing line is from v1 head to v2 head*/ + directedLine* newLineInc = new directedLine(INCREASING, nsline); + + + + directedLine* newLineDec = new directedLine(DECREASING, nsline); + + + directedLine* v1Prev = v1->prev; + directedLine* v2Prev = v2->prev; + + v1 ->prev = newLineDec; + v2Prev ->next = newLineDec; + newLineDec->next = v1; + newLineDec->prev = v2Prev; + + v2 ->prev = newLineInc; + v1Prev ->next = newLineInc; + newLineInc->next = v2; + newLineInc->prev = v1Prev; + + *ret_p1 = newLineDec; + *ret_p2 = newLineInc; + *generatedLine = nsline; +} + +//see the function connectDiangle +/*ARGSUSED*/ +void directedLine::connectDiagonal_2slines(directedLine* v1, directedLine* v2, + directedLine** ret_p1, + directedLine** ret_p2, + directedLine* polygonList ) +{ + sampledLine *nsline = new sampledLine(2); + sampledLine *nsline2 = new sampledLine(2); + + nsline->setPoint(0, v1->head()); + nsline->setPoint(1, v2->head()); + nsline2->setPoint(0, v1->head()); + nsline2->setPoint(1, v2->head()); + + /*the increasing line is from v1 head to v2 head*/ + directedLine* newLineInc = new directedLine(INCREASING, nsline); + + directedLine* newLineDec = new directedLine(DECREASING, nsline2); + + directedLine* v1Prev = v1->prev; + directedLine* v2Prev = v2->prev; + + v1 ->prev = newLineDec; + v2Prev ->next = newLineDec; + newLineDec->next = v1; + newLineDec->prev = v2Prev; + + v2 ->prev = newLineInc; + v1Prev ->next = newLineInc; + newLineInc->next = v2; + newLineInc->prev = v1Prev; + + *ret_p1 = newLineDec; + *ret_p2 = newLineInc; + +} + +Int directedLine::samePolygon(directedLine* v1, directedLine* v2) +{ + if(v1 == v2) return 1; + directedLine *temp; + for(temp = v1->next; temp != v1; temp = temp->next) + { + if(temp == v2) return 1; + } + return 0; +} + +directedLine* directedLine::findRoot() +{ + if(rootBit) return this; + directedLine* temp; + for(temp = next; temp != this; temp = temp->next) + if(temp -> rootBit ) return temp; + return NULL; /*should not happen*/ +} + +directedLine* directedLine::rootLinkFindRoot() +{ + directedLine* tempRoot; + directedLine* tempLink; + tempRoot = this; + tempLink = rootLink; + while(tempLink != NULL){ + tempRoot = tempLink; + tempLink = tempRoot->rootLink; + } + return tempRoot; +} + +/*******************split or combine polygons end********************/ + +/*****************IO stuff begin*******************/ + +/*format: + *#polygons + * #vertices + * vertices + * #vertices + * vertices + *... + */ +void directedLine::writeAllPolygons(char* filename) +{ + FILE* fp = fopen(filename, "w"); + assert(fp); + Int nPolygons = numPolygons(); + directedLine *root; + fprintf(fp, "%i\n", nPolygons); + for(root = this; root != NULL; root = root->nextPolygon) + { + directedLine *temp; + Int npoints=0; + npoints = root->get_npoints()-1; + for(temp = root->next; temp != root; temp=temp->next) + npoints += temp->get_npoints()-1; + fprintf(fp, "%i\n", npoints/*root->numEdges()*/); + + + for(Int i=0; i<root->get_npoints()-1; i++){ + fprintf(fp, "%f ", root->getVertex(i)[0]); + fprintf(fp, "%f ", root->getVertex(i)[1]); + } + + for(temp=root->next; temp != root; temp = temp->next) + { + for(Int i=0; i<temp->get_npoints()-1; i++){ + + fprintf(fp, "%f ", temp->getVertex(i)[0]); + fprintf(fp, "%f ", temp->getVertex(i)[1]); + } + fprintf(fp,"\n"); + } + fprintf(fp, "\n"); + } + fclose(fp); +} + +directedLine* readAllPolygons(char* filename) +{ + Int i,j; + FILE* fp = fopen(filename, "r"); + assert(fp); + Int nPolygons; + fscanf(fp, "%i", &nPolygons); + directedLine *ret = NULL; + + for(i=0; i<nPolygons; i++) + { + Int nEdges; + fscanf(fp, "%i", &nEdges); + Real vert[2][2]; + Real VV[2][2]; + /*the first two vertices*/ + fscanf(fp, "%f", &(vert[0][0])); + fscanf(fp, "%f", &(vert[0][1])); + fscanf(fp, "%f", &(vert[1][0])); + fscanf(fp, "%f", &(vert[1][1])); + VV[1][0] = vert[0][0]; + VV[1][1] = vert[0][1]; + sampledLine *sLine = new sampledLine(2, vert); + directedLine *thisPoly = new directedLine(INCREASING, sLine); +thisPoly->rootLinkSet(NULL); + + directedLine *dLine; + for(j=2; j<nEdges; j++) + { + vert[0][0]=vert[1][0]; + vert[0][1]=vert[1][1]; + fscanf(fp, "%f", &(vert[1][0])); + fscanf(fp, "%f", &(vert[1][1])); + sLine = new sampledLine(2,vert); + dLine = new directedLine(INCREASING, sLine); +dLine->rootLinkSet(thisPoly); + thisPoly->insert(dLine); + } + + VV[0][0]=vert[1][0]; + VV[0][1]=vert[1][1]; + sLine = new sampledLine(2,VV); + dLine = new directedLine(INCREASING, sLine); +dLine->rootLinkSet(thisPoly); + thisPoly->insert(dLine); + + ret = thisPoly->insertPolygon(ret); + } + fclose(fp); + return ret; +} + + + + + + + + diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/directedLine.h b/mesalib/src/glu/sgi/libnurbs/nurbtess/directedLine.h new file mode 100644 index 000000000..4ed0128ca --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/directedLine.h @@ -0,0 +1,171 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ +/* +*/ + +#ifndef _DIRECTEDLINE_H +#define _DIRECTEDLINE_H + +#include "definitions.h" +#include "sampledLine.h" + +enum {INCREASING, DECREASING}; + +class directedLine { + short direction; /*INCREASING or DECREASING*/ + sampledLine* sline; + directedLine* next; /*double linked list*/ + directedLine* prev; /*double linked list*/ + + /*in case we need a list of polygons each + *consisting of a double linked list + */ + directedLine* nextPolygon; + + /*optimization make cutoff polygon faster*/ +/* directedLine* prevPolygon;*/ + + Int rootBit; /*1 if this is a root of the polygon, set by setRootBit*/ + /*and reset by resetRootBit()*/ + + directedLine* rootLink; /*fast root-finding*/ + + + +public: + directedLine(short dir, sampledLine* sl); + directedLine(); + ~directedLine(); + + void init(short dir, sampledLine* sl); + + Real* head(); /*points[0] if INCREASING, points[n-1] otherwise*/ + Real* tail(); /*points[n-1] if INCREASING, points[0] otherwise*/ + Real* getVertex(Int i); /*points[i] if INCREASING, points[n-1-i] otherwise*/ + Int get_npoints() {return sline->get_npoints();} + directedLine* getPrev() {return prev;} + directedLine* getNext() {return next;} + directedLine* getNextPolygon() {return nextPolygon;} + sampledLine* getSampledLine() {return sline;} + + short getDirection(){return direction;} + void putDirection(short dir) {direction = dir;} + void putPrev(directedLine *p) {prev = p;} + void putNext(directedLine *p) {next = p;} + + /*insert a new line between prev and this*/ + void insert(directedLine* nl); + + /*delete all the polygons following the link: nextPolygon. + *notice that sampledLine is not deleted. The caller is + *responsible for that + */ + void deletePolygonList(); + void deleteSinglePolygon(); + + void deleteSinglePolygonWithSline(); //also delete sanmpled line + void deletePolygonListWithSline(); //also delete sanmpled line + + void deleteSingleLine(directedLine* dline); + directedLine* deleteDegenerateLines(); + directedLine* deleteDegenerateLinesAllPolygons(); + directedLine* cutIntersectionAllPoly(int& cutOccur); + + /*check to see if the list forms a closed polygon + *return 1 if yes + */ + short isPolygon(); + + Int compInY(directedLine* nl); + Int compInX(directedLine* nl); + + /*return an array of pointers. + *the + */ + directedLine** sortAllPolygons(); + + Int numEdges(); + Int numEdgesAllPolygons(); + Int numPolygons(); + + /*check if the head of this edge is connected to + *the tail of the prev + */ + short isConnected(); + + Real polyArea(); + + void printSingle(); + void printList(); + void printAllPolygons(); + void writeAllPolygons(char* filename); + + + /*insert a polygon: using nextPolygon*/ + directedLine* insertPolygon(directedLine* newpolygon); + directedLine* cutoffPolygon(directedLine *p); + + Int toArraySinglePolygon(directedLine** array, Int index); + directedLine** toArrayAllPolygons(Int& total_num_edges); + + void connectDiagonal(directedLine* v1, directedLine* v2, + directedLine** ret_p1, + directedLine** ret_p2, + sampledLine** generatedLine, directedLine* list); + + /*generate two slines + */ + void connectDiagonal_2slines(directedLine* v1, directedLine* v2, + directedLine** ret_p1, + directedLine** ret_p2, + directedLine* list); + + Int samePolygon(directedLine* v1, directedLine* v2); + void setRootBit() {rootBit = 1;} + void resetRootBit() {rootBit = 0;} + directedLine* findRoot(); + + void rootLinkSet(directedLine* r) {rootLink = r;} + directedLine* rootLinkFindRoot(); + + //the chain from begin to end is deleted (the space is deallocated) + //and a new edge(which connectes the head of begin and the tail of end) + // is inserted. The new polygon is returned. + //notice that "this" is arbitrary + directedLine* deleteChain(directedLine* begin, directedLine* end); +}; + +directedLine* readAllPolygons(char* filename); + +extern Int compV2InY(Real A[2], Real B[2]); +extern Int compV2InX(Real A[2], Real B[2]); + +#endif + diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/glimports.h b/mesalib/src/glu/sgi/libnurbs/nurbtess/glimports.h new file mode 100644 index 000000000..6e69feb40 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/glimports.h @@ -0,0 +1,42 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * glimports.h + * + */ + +#ifndef __gluimports_h_ +#define __gluimports_h_ + +#include "mystdlib.h" +#include "mystdio.h" + +#endif /* __gluimports_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/gridWrap.cc b/mesalib/src/glu/sgi/libnurbs/nurbtess/gridWrap.cc new file mode 100644 index 000000000..3c92039ba --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/gridWrap.cc @@ -0,0 +1,293 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include "gluos.h" +#include <stdlib.h> +#include <stdio.h> +#include <GL/gl.h> +#include "zlassert.h" +#include "gridWrap.h" + + +/*******************grid structure****************************/ +void gridWrap::print() +{ + printf("n_ulines = %i\n", n_ulines); + printf("n_vlines = %i\n", n_vlines); + printf("u_min=%f, umax=%f, vmin=%f, vmax=%f\n", u_min, u_max, v_min, v_max); +} + +gridWrap::gridWrap(Int nUlines, Real* uvals, + Int nVlines, Real* vvals) +{ + assert(nUlines>=2); + assert(nVlines>=2); + + is_uniform = 0; + n_ulines = nUlines; + n_vlines = nVlines; + u_min = uvals[0]; + u_max = uvals[nUlines-1]; + v_min = vvals[0]; + v_max = vvals[nVlines-1]; + u_values = (Real*) malloc(sizeof(Real) * n_ulines); + assert(u_values); + v_values = (Real*) malloc(sizeof(Real) * n_vlines); + assert(v_values); + + Int i; + for(i=0; i<n_ulines; i++) + u_values[i] = uvals[i]; + for(i=0; i<n_vlines; i++) + v_values[i] = vvals[i]; +} + +gridWrap::gridWrap(Int nUlines, Int nVlines, + Real uMin, Real uMax, + Real vMin, Real vMax + ) +{ + is_uniform = 1; + n_ulines = nUlines; + n_vlines = nVlines; + u_min = uMin; + u_max = uMax; + v_min = vMin; + v_max = vMax; + u_values = (Real*) malloc(sizeof(Real) * n_ulines); + assert(u_values); + v_values = (Real*) malloc(sizeof(Real) * n_vlines); + assert(v_values); + + Int i; + assert(nUlines>=2); + assert(nVlines>=2); + Real du = (uMax-uMin)/(nUlines-1); + Real dv = (vMax-vMin)/(nVlines-1); + + float tempu=uMin; + u_values[0] = tempu; + for(i=1; i<nUlines; i++) + { + tempu += du; + u_values[i] = tempu; + } + u_values[nUlines-1] = uMax; + + float tempv=vMin; + v_values[0] = tempv; + for(i=1; i<nVlines; i++) + { + tempv += dv; + v_values[i] = tempv; + } + v_values[nVlines-1] = vMax; +} + +gridWrap::~gridWrap() +{ + free(u_values); + free(v_values); +} + +void gridWrap::draw() +{ + int i,j; + glBegin(GL_POINTS); + for(i=0; i<n_ulines; i++) + for(j=0; j<n_vlines; j++) + glVertex2f(get_u_value(i), get_v_value(j)); + glEnd(); +} + +void gridWrap::outputFanWithPoint(Int v, Int uleft, Int uright, Real vert[2], primStream* pStream) +{ + Int i; + if(uleft >= uright) + return; //no triangles to output. + + pStream->begin(); + pStream->insert(vert); + + assert(vert[1] != v_values[v]); //don't output degenerate triangles + + if(vert[1] > v_values[v]) //vertex is above this grid line: notice the orientation + { + for(i=uleft; i<=uright; i++) + pStream->insert(u_values[i], v_values[v]); + } + else //vertex is below the grid line + { + for(i=uright; i>= uleft; i--) + pStream->insert(u_values[i], v_values[v]); + } + + pStream->end(PRIMITIVE_STREAM_FAN); +} + + + +/*each chain stores a number of consecutive + *V-lines within a grid. + *There is one grid vertex on each V-line. + * The total number of V-lines is: + * nVlines. + * with respect to the grid, the index of the first V-line is + * firstVlineIndex. + * So with respect to the grid, the index of the ith V-line is + * firstVlineIndex-i. + * the grid-index of the uline at the ith vline (recall that each vline has one grid point) + * is ulineIndices[i]. The u_value is cached in ulineValues[i], that is, + * ulineValues[i] = grid->get_u_value(ulineIndices[i]) + */ +gridBoundaryChain::gridBoundaryChain( + gridWrap* gr, + Int first_vline_index, + Int n_vlines, + Int* uline_indices, + Int* inner_indices + ) +: grid(gr), firstVlineIndex(first_vline_index), nVlines(n_vlines) +{ + ulineIndices = (Int*) malloc(sizeof(Int) * n_vlines); + assert(ulineIndices); + + innerIndices = (Int*) malloc(sizeof(Int) * n_vlines); + assert(innerIndices); + + vertices = (Real2*) malloc(sizeof(Real2) * n_vlines); + assert(vertices); + + + + Int i; + for(i=0; i<n_vlines; i++){ + ulineIndices[i] = uline_indices[i]; + innerIndices[i] = inner_indices[i]; + } + + for(i=0; i<n_vlines; i++){ + vertices[i][0] = gr->get_u_value(ulineIndices[i]); + vertices[i][1] = gr->get_v_value(first_vline_index-i); + } +} + +void gridBoundaryChain::draw() +{ + Int i; + glBegin(GL_LINE_STRIP); + for(i=0; i<nVlines; i++) + { + glVertex2fv(vertices[i]); + } + glEnd(); +} + +void gridBoundaryChain::drawInner() +{ + Int i; + for(i=1; i<nVlines; i++) + { + glBegin(GL_LINE_STRIP); + glVertex2f(grid->get_u_value(innerIndices[i]), get_v_value(i-1) ); + glVertex2f(grid->get_u_value(innerIndices[i]), get_v_value(i) ); + glEnd(); + } +} + +Int gridBoundaryChain::lookfor(Real v, Int i1, Int i2) +{ + Int mid; + while(i1 < i2-1) + { + mid = (i1+i2)/2; + if(v > vertices[mid][1]) + { + i2 = mid; + } + else + i1 = mid; + } + return i1; +} + +/*output the fan of the right end between grid line i-1 and grid line i*/ +void gridBoundaryChain::rightEndFan(Int i, primStream* pStream) +{ + Int j; + if(getUlineIndex(i) > getUlineIndex(i-1)) + { + pStream->begin(); + pStream->insert(get_vertex(i-1)); + for(j=getUlineIndex(i-1); j<= getUlineIndex(i); j++) + pStream->insert(grid->get_u_value(j), get_v_value(i)); + pStream->end(PRIMITIVE_STREAM_FAN); + } + else if(getUlineIndex(i) < getUlineIndex(i-1)) + { + pStream->begin(); + pStream->insert(get_vertex(i)); + for(j=getUlineIndex(i-1); j>= getUlineIndex(i); j--) + pStream->insert(grid->get_u_value(j), get_v_value(i-1)); + pStream->end(PRIMITIVE_STREAM_FAN); + } + //otherside, the two are equal, so there is no fan to output +} + + +/*output the fan of the left end between grid line i-1 and grid line i*/ +void gridBoundaryChain::leftEndFan(Int i, primStream* pStream) +{ + Int j; + if(getUlineIndex(i) < getUlineIndex(i-1)) + { + pStream->begin(); + pStream->insert(get_vertex(i-1)); + for(j=getUlineIndex(i); j<= getUlineIndex(i-1); j++) + pStream->insert(grid->get_u_value(j), get_v_value(i)); + pStream->end(PRIMITIVE_STREAM_FAN); + } + else if(getUlineIndex(i) > getUlineIndex(i-1)) + { + pStream->begin(); + pStream->insert(get_vertex(i)); + for(j=getUlineIndex(i); j>= getUlineIndex(i-1); j--) + pStream->insert(grid->get_u_value(j), get_v_value(i-1)); + pStream->end(PRIMITIVE_STREAM_FAN); + } + /*otherwisem, the two are equal, so there is no fan to outout*/ +} diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/gridWrap.h b/mesalib/src/glu/sgi/libnurbs/nurbtess/gridWrap.h new file mode 100644 index 000000000..b6428484f --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/gridWrap.h @@ -0,0 +1,137 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ +/* +*/ + +#ifndef _GRIDWRAP_H +#define _GRIDWRAP_H + +#include <stdio.h> +#include "definitions.h" + +#include "primitiveStream.h" +#include "zlassert.h" + +class gridWrap{ + Int n_ulines; + Int n_vlines; + Real u_min, u_max; + Real v_min, v_max; + + /*cache the coordinate values for efficiency. + *these are redundant information when + *the grid is uniform. + */ + Real* u_values; /*size is n_ulines*/ + Real* v_values; /*size is n_vlines*/ + + Int is_uniform; + +public: + //uniform grid constructor + gridWrap(Int nUlines, Int nVlines, + Real uMin, Real uMax, + Real vMin, Real vMax + ); + + //nonuniform grid constructor. + gridWrap(Int nUlines, Real *uvals, + Int nVlines, Real *vvlas + ); + ~gridWrap(); + + void print(); + Int get_n_ulines() {return n_ulines;} + Int get_n_vlines() {return n_vlines;} + Real get_u_min() {return u_min;} + Real get_u_max() {return u_max;} + Real get_v_min() {return v_min;} + Real get_v_max() {return v_max;} + + Real get_u_value(Int i) + { + assert(i<n_ulines); + /*if(i>=n_ulines){printf("ERROR, n_ulines=%i,i=%i\n",n_ulines,i);exit(0);}*/ + return u_values[i];} + Real get_v_value(Int j) {return v_values[j];} + + Real* get_u_values() {return u_values;} + Real* get_v_values() {return v_values;} + + void outputFanWithPoint(Int v, Int uleft, Int uright, + Real vert[2], primStream* pStream); + + void draw(); + + Int isUniform() {return is_uniform;} +}; + +class gridBoundaryChain{ + gridWrap* grid; + Int firstVlineIndex; + Int nVlines; + Int* ulineIndices; /*each v line has a boundary*/ + Int* innerIndices; /*the segment of the vertical gridline from */ + /*(innerIndices[i], i) to (innerIndices[i+1], i-1) */ + /*is inside the polygon: i=1,...,nVlines-1*/ + + Real2* vertices; /*one grid point at each grid V-line, cached for efficiency*/ + +public: + gridBoundaryChain(gridWrap* gr, Int first_vline_index, Int n_vlines, Int* uline_indices, Int* inner_indices); + + ~gridBoundaryChain() + { + free(innerIndices); + free(ulineIndices); + free(vertices); + } + + /*i indexes the vlines in this chain. + */ + Int getVlineIndex(Int i) {return firstVlineIndex-i;} + Int getUlineIndex(Int i) {return ulineIndices[i];} + Real get_u_value(Int i) {return vertices[i][0];} + Real get_v_value(Int i) {return vertices[i][1];} + Int get_nVlines() {return nVlines;} + Int getInnerIndex(Int i) {return innerIndices[i];} + Real getInner_u_value(Int i) {return grid->get_u_value(innerIndices[i]);} + + Real* get_vertex(Int i) {return vertices[i];} + gridWrap* getGrid() {return grid;} + void leftEndFan(Int i, primStream* pStream); + void rightEndFan(Int i, primStream* pStream); + + Int lookfor(Real v, Int i1, Int i2); //find i in [i1,i2] so that vertices[i][1]>= v > vertices[i+1][1] + void draw(); + void drawInner(); +}; + +#endif diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/monoChain.cc b/mesalib/src/glu/sgi/libnurbs/nurbtess/monoChain.cc new file mode 100644 index 000000000..814bf32fa --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/monoChain.cc @@ -0,0 +1,934 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include "gluos.h" +#include <stdlib.h> +#include <stdio.h> +#include <GL/gl.h> + +#include "glimports.h" +#include "zlassert.h" + +#include "monoChain.h" +#include "quicksort.h" +#include "searchTree.h" +#include "polyUtil.h" + +#ifndef max +#define max(a,b) ((a>b)? a:b) +#endif +#ifndef min +#define min(a,b) ((a>b)? b:a) +#endif + +extern Int isCusp(directedLine *v); +extern Int deleteRepeatDiagonals(Int num_diagonals, directedLine** diagonal_vertices, directedLine** new_vertices); + +//for debug purpose only +#if 0 // UNUSED +static void drawDiagonals(Int num_diagonals, directedLine** diagonal_vertices) +{ + Int i; + for(i=0; i<num_diagonals; i++) + { + glBegin(GL_LINE); + glVertex2fv(diagonal_vertices[2*i]->head()); + glVertex2fv(diagonal_vertices[2*i+1]->head()); + glEnd(); + } +} +#endif + +/*given (x_1, y_1) and (x_2, y_2), and y + *return x such that (x,y) is on the line + */ +inline Real intersectHoriz(Real x1, Real y1, Real x2, Real y2, Real y) +{ + return ((y2==y1)? (x1+x2)*0.5 : x1 + ((y-y1)/(y2-y1)) * (x2-x1)); +} + +//compare the heads of the two chains +static int compChainHeadInY(monoChain* mc1, monoChain* mc2) +{ + return compV2InY(mc1->getHead()->head(), mc2->getHead()->head()); +} + +monoChain::monoChain(directedLine* cHead, directedLine* cTail) +{ + chainHead = cHead; + chainTail = cTail; + next = this; + prev = this; + + nextPolygon = NULL; + + //compute bounding box + directedLine* temp; + minX = maxX = chainTail->head()[0]; + minY = maxY = chainTail->head()[1]; + + for(temp=chainHead; temp!=cTail; temp = temp->getNext()) + { + if(temp->head()[0] < minX) + minX = temp->head()[0]; + if(temp->head()[0] > maxX) + maxX = temp->head()[0]; + + if(temp->head()[1] < minY) + minY = temp->head()[1]; + if(temp->head()[1] > maxY) + maxY = temp->head()[1]; + } + + //check whether the chain is increasing or decreasing + if(chainHead->compInY(chainTail) <0) + isIncrease = 1; + else + isIncrease = 0; + + //initilize currrent, this is used for accelerating search + if(isIncrease) + current = chainHead; + else + current = chainTail; + + isKey = 0; +} + +//insert a new line between prev and this +void monoChain::insert(monoChain* nc) +{ + nc->next = this; + nc->prev = prev; + prev->next = nc; + prev = nc; +} + +void monoChain::deleteLoop() +{ + monoChain *temp, *tempNext; + prev->next = NULL; + for(temp=this; temp != NULL; temp = tempNext) + { + tempNext = temp->next; + delete temp; + } +} + +void monoChain::deleteLoopList() +{ + monoChain *temp, *tempNext; + for(temp=this; temp != NULL; temp = tempNext) + { + tempNext = temp->nextPolygon; + temp->deleteLoop(); + } +} + +Int monoChain::toArraySingleLoop(monoChain** array, Int index) +{ + monoChain *temp; + array[index++] = this; + for(temp = next; temp != this; temp = temp->next) + { + array[index++] = temp; + } + return index; +} + +monoChain** monoChain::toArrayAllLoops(Int& num_chains) +{ + num_chains = numChainsAllLoops(); + monoChain **ret = (monoChain**) malloc(sizeof(monoChain*) * num_chains); + assert(ret); + monoChain *temp; + Int index = 0; + for(temp = this; temp != NULL; temp=temp->nextPolygon){ + index = temp->toArraySingleLoop(ret, index); + } + return ret; +} + +Int monoChain::numChainsSingleLoop() +{ + Int ret=0; + monoChain* temp; + if(next == this) return 1; + ret = 1; + for(temp=next; temp != this; temp = temp->next) + ret++; + return ret; +} + +Int monoChain::numChainsAllLoops() +{ + Int ret=0; + monoChain *temp; + for(temp =this; temp != NULL; temp = temp->nextPolygon) + ret += temp->numChainsSingleLoop(); + return ret; +} + +//update 'current' +Real monoChain::chainIntersectHoriz(Real y) +{ + directedLine* temp; + if(isIncrease) + { + for(temp= current; temp != chainTail; temp = temp->getNext()) + { + if(temp->head()[1] > y) + break; + } + current = temp->getPrev(); + } + else + { + for(temp = current; temp != chainHead; temp = temp->getPrev()) + { + if(temp->head()[1] > y) + break; + } + current = temp->getNext(); + } + return intersectHoriz(current->head()[0], current->head()[1], current->tail()[0], current->tail()[1], y); +} + +monoChain* directedLineLoopToMonoChainLoop(directedLine* loop) +{ + directedLine *temp; + monoChain *ret=NULL; + + //find the first cusp + directedLine *prevCusp=NULL; + directedLine *firstCusp; + + if(isCusp(loop)) + prevCusp = loop; + else + { + for(temp = loop->getNext(); temp != loop; temp = temp->getNext()) + if(isCusp(temp)) + break; + prevCusp = temp; + } + firstCusp = prevCusp; +//printf("first cusp is (%f,%f), (%f,%f), (%f,%f)\n", prevCusp->getPrev()->head()[0], prevCusp->getPrev()->head()[1], prevCusp->head()[0], prevCusp->head()[1], prevCusp->tail()[0], prevCusp->tail()[1]); + + for(temp = prevCusp->getNext(); temp != loop; temp = temp->getNext()) + { + if(isCusp(temp)) + { +//printf("the cusp is (%f,%f), (%f,%f), (%f,%f)\n", temp->getPrev()->head()[0], temp->getPrev()->head()[1], temp->head()[0], temp->head()[1], temp->tail()[0], temp->tail()[1]); + if(ret == NULL) + { + ret = new monoChain(prevCusp, temp); + } + else + ret->insert(new monoChain(prevCusp, temp)); + prevCusp = temp; + } + } + ret->insert(new monoChain(prevCusp, firstCusp)); + + return ret; +} + +monoChain* directedLineLoopListToMonoChainLoopList(directedLine* list) +{ + directedLine* temp; + monoChain* mc; + monoChain* mcEnd; + mc = directedLineLoopToMonoChainLoop(list); + mcEnd = mc; + for(temp = list->getNextPolygon(); temp != NULL; temp = temp->getNextPolygon()) + { + monoChain *newLoop = directedLineLoopToMonoChainLoop(temp); + mcEnd->setNextPolygon(newLoop); + mcEnd = newLoop; + } + return mc; +} + +/*compare two edges of a polygon. + *edge A < edge B if there is a horizontal line so that the intersection + *with A is to the left of the intersection with B. + *This function is used in sweepY for the dynamic search tree insertion to + *order the edges. + * Implementation: (x_1,y_1) and (x_2, y_2) + */ +static Int compEdges(directedLine *e1, directedLine *e2) +{ + Real* head1 = e1->head(); + Real* tail1 = e1->tail(); + Real* head2 = e2->head(); + Real* tail2 = e2->tail(); +/* + Real h10 = head1[0]; + Real h11 = head1[1]; + Real t10 = tail1[0]; + Real t11 = tail1[1]; + Real h20 = head2[0]; + Real h21 = head2[1]; + Real t20 = tail2[0]; + Real t21 = tail2[1]; +*/ + Real e1_Ymax, e1_Ymin, e2_Ymax, e2_Ymin; +/* + if(h11>t11) { + e1_Ymax= h11; + e1_Ymin= t11; + } + else{ + e1_Ymax = t11; + e1_Ymin = h11; + } + + if(h21>t21) { + e2_Ymax= h21; + e2_Ymin= t21; + } + else{ + e2_Ymax = t21; + e2_Ymin = h21; + } +*/ + + if(head1[1]>tail1[1]) { + e1_Ymax= head1[1]; + e1_Ymin= tail1[1]; + } + else{ + e1_Ymax = tail1[1]; + e1_Ymin = head1[1]; + } + + if(head2[1]>tail2[1]) { + e2_Ymax= head2[1]; + e2_Ymin= tail2[1]; + } + else{ + e2_Ymax = tail2[1]; + e2_Ymin = head2[1]; + } + + + /*Real e1_Ymax = max(head1[1], tail1[1]);*/ /*max(e1->head()[1], e1->tail()[1]);*/ + /*Real e1_Ymin = min(head1[1], tail1[1]);*/ /*min(e1->head()[1], e1->tail()[1]);*/ + /*Real e2_Ymax = max(head2[1], tail2[1]);*/ /*max(e2->head()[1], e2->tail()[1]);*/ + /*Real e2_Ymin = min(head2[1], tail2[1]);*/ /*min(e2->head()[1], e2->tail()[1]);*/ + + Real Ymax = min(e1_Ymax, e2_Ymax); + Real Ymin = max(e1_Ymin, e2_Ymin); + + Real y = 0.5*(Ymax + Ymin); + +/* Real x1 = intersectHoriz(e1->head()[0], e1->head()[1], e1->tail()[0], e1->tail()[1], y); + Real x2 = intersectHoriz(e2->head()[0], e2->head()[1], e2->tail()[0], e2->tail()[1], y); +*/ +/* + Real x1 = intersectHoriz(h10, h11, t10, t11, y); + Real x2 = intersectHoriz(h20, h21, t20, t21, y); +*/ + Real x1 = intersectHoriz(head1[0], head1[1], tail1[0], tail1[1], y); + Real x2 = intersectHoriz(head2[0], head2[1], tail2[0], tail2[1], y); + + if(x1<= x2) return -1; + else return 1; +} + +Int compChains(monoChain* mc1, monoChain* mc2) +{ + Real y; + assert(mc1->isKey || mc2->isKey); + if(mc1->isKey) + y = mc1->keyY; + else + y = mc2->keyY; + directedLine *d1 = mc1->find(y); + directedLine *d2 = mc2->find(y); + mc2->find(y); +// Real x1 = mc1->chainIntersectHoriz(y); +// Real x2 = mc2->chainIntersectHoriz(y); + return compEdges(d1, d2); +} + +//this function modifies current for efficiency +directedLine* monoChain::find(Real y) +{ + directedLine *ret; + directedLine *temp; + assert(current->head()[1] <= y); + if(isIncrease) + { + assert(chainTail->head()[1] >=y); + for(temp=current; temp!=chainTail; temp = temp->getNext()) + { + if(temp->head()[1] > y) + break; + } + current = temp->getPrev(); + ret = current; + } + else + { + for(temp=current; temp != chainHead; temp = temp->getPrev()) + { + if(temp->head()[1] > y) + break; + } + current = temp->getNext(); + ret = temp; + } + return ret; +} + +void monoChain::printOneChain() +{ + directedLine* temp; + for(temp = chainHead; temp != chainTail; temp = temp->getNext()) + { + printf("(%f,%f) ", temp->head()[0], temp->head()[1]); + } + printf("(%f,%f) \n", chainTail->head()[0], chainTail->head()[1]); +} + +void monoChain::printChainLoop() +{ + monoChain* temp; + this->printOneChain(); + for(temp = next; temp != this; temp = temp->next) + { + temp->printOneChain(); + } + printf("\n"); +} + +void monoChain::printAllLoops() +{ + monoChain* temp; + for(temp=this; temp != NULL; temp = temp->nextPolygon) + temp->printChainLoop(); +} + +//return 1 if error occures +Int MC_sweepY(Int nVertices, monoChain** sortedVertices, sweepRange** ret_ranges) +{ + Int i; + Real keyY; + Int errOccur=0; +//printf("enter MC_sweepY\n"); +//printf("nVertices=%i\n", nVertices); + /*for each vertex in the sorted list, update the binary search tree. + *and store the range information for each vertex. + */ + treeNode* searchTree = NULL; +//printf("nVertices=%i\n", nVertices); + for(i=0; i<nVertices; i++) + { + monoChain* vert = sortedVertices[i]; + keyY = vert->getHead()->head()[1]; //the sweep line + directedLine *dline = vert->getHead(); + directedLine *dlinePrev = dline->getPrev(); + if(isBelow(dline, dline) && isBelow(dline, dlinePrev)) + { +//printf("case 1\n"); + //this<v and prev < v + //delete both edges + vert->isKey = 1; + vert->keyY = keyY; + treeNode* thisNode = TreeNodeFind(searchTree, vert, (Int (*) (void *, void *))compChains); + vert->isKey = 0; + + vert->getPrev()->isKey = 1; + vert->getPrev()->keyY = keyY; + treeNode* prevNode = TreeNodeFind(searchTree, vert->getPrev(), (Int (*) (void *, void *))compChains); + vert->getPrev()->isKey = 0; + + if(cuspType(dline) == 1)//interior cusp + { + + treeNode* leftEdge = TreeNodePredecessor(prevNode); + treeNode* rightEdge = TreeNodeSuccessor(thisNode); + if(leftEdge == NULL || rightEdge == NULL) + { + errOccur = 1; + goto JUMP_HERE; + } + + directedLine* leftEdgeDline = ((monoChain* ) leftEdge->key)->find(keyY); + + + + directedLine* rightEdgeDline = ((monoChain* ) rightEdge->key)->find(keyY); + + ret_ranges[i] = sweepRangeMake(leftEdgeDline, 1, rightEdgeDline, 1); + } + else /*exterior cusp*/ + { + ret_ranges[i] = sweepRangeMake( dline, 1, dlinePrev, 1); + } + + searchTree = TreeNodeDeleteSingleNode(searchTree, thisNode); + searchTree = TreeNodeDeleteSingleNode(searchTree, prevNode); + + } + else if(isAbove(dline, dline) && isAbove(dline, dlinePrev)) + { +//printf("case 2\n"); + //insert both edges + treeNode* thisNode = TreeNodeMake(vert); + treeNode* prevNode = TreeNodeMake(vert->getPrev()); + + vert->isKey = 1; + vert->keyY = keyY; + searchTree = TreeNodeInsert(searchTree, thisNode, (Int (*) (void *, void *))compChains); + vert->isKey = 0; + + vert->getPrev()->isKey = 1; + vert->getPrev()->keyY = keyY; + searchTree = TreeNodeInsert(searchTree, prevNode, (Int (*) (void *, void *))compChains); + vert->getPrev()->isKey = 0; + + if(cuspType(dline) == 1) //interior cusp + { +//printf("cuspType is 1\n"); + treeNode* leftEdge = TreeNodePredecessor(thisNode); + treeNode* rightEdge = TreeNodeSuccessor(prevNode); + if(leftEdge == NULL || rightEdge == NULL) + { + errOccur = 1; + goto JUMP_HERE; + } +//printf("leftEdge is %i, rightEdge is %i\n", leftEdge, rightEdge); + directedLine* leftEdgeDline = ((monoChain*) leftEdge->key)->find(keyY); + directedLine* rightEdgeDline = ((monoChain*) rightEdge->key)->find(keyY); + ret_ranges[i] = sweepRangeMake( leftEdgeDline, 1, rightEdgeDline, 1); + } + else //exterior cusp + { +//printf("cuspType is not 1\n"); + ret_ranges[i] = sweepRangeMake(dlinePrev, 1, dline, 1); + } + } + else + { +//printf("%i,%i\n", isAbove(dline, dline), isAbove(dline, dlinePrev)); + errOccur = 1; + goto JUMP_HERE; + + fprintf(stderr, "error in MC_sweepY\n"); + exit(1); + } + } + + JUMP_HERE: + //finally clean up space: delete the search tree + TreeNodeDeleteWholeTree(searchTree); + return errOccur; +} + +void MC_findDiagonals(Int total_num_edges, monoChain** sortedVertices, + sweepRange** ranges, Int& num_diagonals, + directedLine** diagonal_vertices) +{ + Int i,j,k; + k=0; + //reset 'current' of all the monoChains + for(i=0; i<total_num_edges; i++) + sortedVertices[i]->resetCurrent(); + + for(i=0; i<total_num_edges; i++) + { + directedLine* vert = sortedVertices[i]->getHead(); + directedLine* thisEdge = vert; + directedLine* prevEdge = vert->getPrev(); + if(isBelow(vert, thisEdge) && isBelow(vert, prevEdge) && compEdges(prevEdge, thisEdge)<0) + { + //this is an upward interior cusp + diagonal_vertices[k++] = vert; + + directedLine* leftEdge = ranges[i]->left; + directedLine* rightEdge = ranges[i]->right; + + directedLine* leftVert = leftEdge; + directedLine* rightVert = rightEdge->getNext(); + assert(leftVert->head()[1] >= vert->head()[1]); + assert(rightVert->head()[1] >= vert->head()[1]); + directedLine* minVert = (leftVert->head()[1] <= rightVert->head()[1])?leftVert:rightVert; + Int found = 0; + for(j=i+1; j<total_num_edges; j++) + { + if(sortedVertices[j]->getHead()->head()[1] > minVert->head()[1]) + break; + + if(sweepRangeEqual(ranges[i], ranges[j])) + { + found = 1; + break; + } + } + + if(found) + diagonal_vertices[k++] = sortedVertices[j]->getHead(); + else + diagonal_vertices[k++] = minVert; + } + else if(isAbove(vert, thisEdge) && isAbove(vert, prevEdge) && compEdges(prevEdge, thisEdge)>0) + { + //downward interior cusp + diagonal_vertices[k++] = vert; + directedLine* leftEdge = ranges[i]->left; + directedLine* rightEdge = ranges[i]->right; + directedLine* leftVert = leftEdge->getNext(); + directedLine* rightVert = rightEdge; + assert(leftVert->head()[1] <= vert->head()[1]); + assert(rightVert->head()[1] <= vert->head()[1]); + directedLine* maxVert = (leftVert->head()[1] > rightVert->head()[1])? leftVert:rightVert; + Int found=0; + for(j=i-1; j>=0; j--) + { + if(sortedVertices[j]->getHead()->head()[1] < maxVert->head()[1]) + break; + if(sweepRangeEqual(ranges[i], ranges[j])) + { + found = 1; + break; + } + } + if(found) + diagonal_vertices[k++] = sortedVertices[j]->getHead(); + else + diagonal_vertices[k++] = maxVert; + } + } + num_diagonals = k/2; +} + + + + +directedLine* MC_partitionY(directedLine *polygons, sampledLine **retSampledLines) +{ +//printf("enter mc_partitionY\n"); + Int total_num_chains = 0; + monoChain* loopList = directedLineLoopListToMonoChainLoopList(polygons); + monoChain** array = loopList->toArrayAllLoops(total_num_chains); + + if(total_num_chains<=2) //there is just one single monotone polygon + { + loopList->deleteLoopList(); + free(array); + *retSampledLines = NULL; + return polygons; + } + +//loopList->printAllLoops(); +//printf("total_num_chains=%i\n", total_num_chains); + quicksort( (void**)array, 0, total_num_chains-1, (Int (*)(void*, void*))compChainHeadInY); +//printf("after quicksort\n"); + + sweepRange** ranges = (sweepRange**)malloc(sizeof(sweepRange*) * (total_num_chains)); + assert(ranges); + + if(MC_sweepY(total_num_chains, array, ranges)) + { + loopList->deleteLoopList(); + free(array); + *retSampledLines = NULL; + return NULL; + } +//printf("after MC_sweepY\n"); + + + Int num_diagonals; + /*number diagonals is < total_num_edges*total_num_edges*/ + directedLine** diagonal_vertices = (directedLine**) malloc(sizeof(directedLine*) * total_num_chains*2/*total_num_edges*/); + assert(diagonal_vertices); + +//printf("before call MC_findDiagonales\n"); + + MC_findDiagonals(total_num_chains, array, ranges, num_diagonals, diagonal_vertices); +//printf("after call MC_findDia, num_diagnla=%i\n", num_diagonals); + + directedLine* ret_polygons = polygons; + sampledLine* newSampledLines = NULL; + Int i,k; + + num_diagonals=deleteRepeatDiagonals(num_diagonals, diagonal_vertices, diagonal_vertices); + + + +//drawDiagonals(num_diagonals, diagonal_vertices); +//printf("diagoanls are \n"); +//for(i=0; i<num_diagonals; i++) +// { +// printf("(%f,%f)\n", diagonal_vertices[2*i]->head()[0], diagonal_vertices[2*i]->head()[1]); +// printf("**(%f,%f)\n", diagonal_vertices[2*i+1]->head()[0], diagonal_vertices[2*i+1]->head()[1]); +// } + + Int *removedDiagonals=(Int*)malloc(sizeof(Int) * num_diagonals); + for(i=0; i<num_diagonals; i++) + removedDiagonals[i] = 0; +// printf("first pass\n"); + + + for(i=0,k=0; i<num_diagonals; i++,k+=2) + { + + + directedLine* v1=diagonal_vertices[k]; + directedLine* v2=diagonal_vertices[k+1]; + directedLine* ret_p1; + directedLine* ret_p2; + + /*we ahve to determine whether v1 and v2 belong to the same polygon before + *their structure are modified by connectDiagonal(). + */ +/* + directedLine *root1 = v1->findRoot(); + directedLine *root2 = v2->findRoot(); + assert(root1); + assert(root2); +*/ + +directedLine* root1 = v1->rootLinkFindRoot(); +directedLine* root2 = v2->rootLinkFindRoot(); + + if(root1 != root2) + { + + removedDiagonals[i] = 1; + sampledLine* generatedLine; + + + + v1->connectDiagonal(v1,v2, &ret_p1, &ret_p2, &generatedLine, ret_polygons); + + + + newSampledLines = generatedLine->insert(newSampledLines); +/* + ret_polygons = ret_polygons->cutoffPolygon(root1); + + ret_polygons = ret_polygons->cutoffPolygon(root2); + ret_polygons = ret_p1->insertPolygon(ret_polygons); +root1->rootLinkSet(ret_p1); +root2->rootLinkSet(ret_p1); +ret_p1->rootLinkSet(NULL); +ret_p2->rootLinkSet(ret_p1); +*/ + ret_polygons = ret_polygons->cutoffPolygon(root2); + + + +root2->rootLinkSet(root1); +ret_p1->rootLinkSet(root1); +ret_p2->rootLinkSet(root1); + + /*now that we have connected the diagonal v1 and v2, + *we have to check those unprocessed diagonals which + *have v1 or v2 as an end point. Notice that the head of v1 + *has the same coodinates as the head of v2->prev, and the head of + *v2 has the same coordinate as the head of v1->prev. + *Suppose these is a diagonal (v1, x). If (v1,x) is still a valid + *diagonal, then x should be on the left hand side of the directed line: *v1->prev->head -- v1->head -- v1->tail. Otherwise, (v1,x) should be + *replaced by (v2->prev, x), that is, x is on the left of + * v2->prev->prev->head, v2->prev->head, v2->prev->tail. + */ + Int ii, kk; + for(ii=0, kk=0; ii<num_diagonals; ii++, kk+=2) + if( removedDiagonals[ii]==0) + { + directedLine* d1=diagonal_vertices[kk]; + directedLine* d2=diagonal_vertices[kk+1]; + /*check d1, and replace diagonal_vertices[kk] if necessary*/ + if(d1 == v1) { + /*check if d2 is to left of v1->prev->head:v1->head:v1->tail*/ + if(! pointLeft2Lines(v1->getPrev()->head(), + v1->head(), v1->tail(), d2->head())) + { +/* + assert(pointLeft2Lines(v2->getPrev()->getPrev()->head(), + v2->getPrev()->head(), + v2->getPrev()->tail(), d2->head())); +*/ + diagonal_vertices[kk] = v2->getPrev(); + } + } + if(d1 == v2) { + /*check if d2 is to left of v2->prev->head:v2->head:v2->tail*/ + if(! pointLeft2Lines(v2->getPrev()->head(), + v2->head(), v2->tail(), d2->head())) + { +/* + assert(pointLeft2Lines(v1->getPrev()->getPrev()->head(), + v1->getPrev()->head(), + v1->getPrev()->tail(), d2->head())); +*/ + diagonal_vertices[kk] = v1->getPrev(); + } + } + /*check d2 and replace diagonal_vertices[k+1] if necessary*/ + if(d2 == v1) { + /*check if d1 is to left of v1->prev->head:v1->head:v1->tail*/ + if(! pointLeft2Lines(v1->getPrev()->head(), + v1->head(), v1->tail(), d1->head())) + { +/* assert(pointLeft2Lines(v2->getPrev()->getPrev()->head(), + v2->getPrev()->head(), + v2->getPrev()->tail(), d1->head())); +*/ + diagonal_vertices[kk+1] = v2->getPrev(); + } + } + if(d2 == v2) { + /*check if d1 is to left of v2->prev->head:v2->head:v2->tail*/ + if(! pointLeft2Lines(v2->getPrev()->head(), + v2->head(), v2->tail(), d1->head())) + { +/* assert(pointLeft2Lines(v1->getPrev()->getPrev()->head(), + v1->getPrev()->head(), + v1->getPrev()->tail(), d1->head())); +*/ + diagonal_vertices[kk+1] = v1->getPrev(); + } + } + } +}/*end if (root1 not equal to root 2)*/ +} + + /*second pass, now all diagoals should belong to the same polygon*/ +//printf("second pass: \n"); + +// for(i=0; i<num_diagonals; i++) +// printf("%i ", removedDiagonals[i]); + + + for(i=0,k=0; i<num_diagonals; i++, k += 2) + if(removedDiagonals[i] == 0) + { + + + directedLine* v1=diagonal_vertices[k]; + directedLine* v2=diagonal_vertices[k+1]; + + + + directedLine* ret_p1; + directedLine* ret_p2; + + /*we ahve to determine whether v1 and v2 belong to the same polygon before + *their structure are modified by connectDiagonal(). + */ + directedLine *root1 = v1->findRoot(); +/* + directedLine *root2 = v2->findRoot(); + + + + assert(root1); + assert(root2); + assert(root1 == root2); + */ + sampledLine* generatedLine; + + + + v1->connectDiagonal(v1,v2, &ret_p1, &ret_p2, &generatedLine, ret_polygons); + newSampledLines = generatedLine->insert(newSampledLines); + + ret_polygons = ret_polygons->cutoffPolygon(root1); + + ret_polygons = ret_p1->insertPolygon(ret_polygons); + + ret_polygons = ret_p2->insertPolygon(ret_polygons); + + + + for(Int j=i+1; j<num_diagonals; j++) + { + if(removedDiagonals[j] ==0) + { + + directedLine* temp1=diagonal_vertices[2*j]; + directedLine* temp2=diagonal_vertices[2*j+1]; + if(temp1==v1 || temp1==v2 || temp2==v1 || temp2==v2) + if(! temp1->samePolygon(temp1, temp2)) + { + /*if temp1 and temp2 are in different polygons, + *then one of them must be v1 or v2. + */ + + + + assert(temp1==v1 || temp1 == v2 || temp2==v1 || temp2 ==v2); + if(temp1==v1) + { + diagonal_vertices[2*j] = v2->getPrev(); + } + if(temp2==v1) + { + diagonal_vertices[2*j+1] = v2->getPrev(); + } + if(temp1==v2) + { + diagonal_vertices[2*j] = v1->getPrev(); + } + if(temp2==v2) + { + diagonal_vertices[2*j+1] = v1->getPrev(); + } + } + } + } + + } + + + //clean up + loopList->deleteLoopList(); + free(array); + free(ranges); + free(diagonal_vertices); + free(removedDiagonals); + + *retSampledLines = newSampledLines; + return ret_polygons; +} + + diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/monoChain.h b/mesalib/src/glu/sgi/libnurbs/nurbtess/monoChain.h new file mode 100644 index 000000000..999f16319 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/monoChain.h @@ -0,0 +1,103 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ +/* +*/ + +#ifndef _MONO_CHAIN_H +#define _MONO_CHAIN_H + +#include "directedLine.h" +#include "partitionY.h" + +class monoChain; + +class monoChain{ + directedLine* chainHead; + directedLine* chainTail; + monoChain* next; + monoChain* prev; + monoChain* nextPolygon; //a list of polygons + + //cached informatin + //bounding box + Real minX, maxX, minY, maxY; + Int isIncrease; + + //for efficiently comparing two chains + + directedLine* current; + +public: + monoChain(directedLine* cHead, directedLine* cTail); + ~monoChain() {} + + inline void setNext(monoChain* n) {next = n;} + inline void setPrev(monoChain* p) {prev = p;} + inline void setNextPolygon(monoChain* np) {nextPolygon = np;} + inline monoChain* getNext() {return next;} + inline monoChain* getPrev() {return prev;} + inline directedLine* getHead() {return chainHead;} + inline directedLine* getTail() {return chainTail;} + + inline void resetCurrent() { current = ((isIncrease==1)? chainHead:chainTail);} + + void deleteLoop(); + void deleteLoopList(); + + //insert a new chain between prev and this + void insert(monoChain* nc); + + Int numChainsSingleLoop(); + Int numChainsAllLoops(); + monoChain** toArrayAllLoops(Int& num_chains); + Int toArraySingleLoop(monoChain** array, Int index); + + Int isKey; + Real keyY; //the current horizotal line + Real chainIntersectHoriz(Real y); //updates current incrementally for efficiency + directedLine* find(Real y);//find dline so that y intersects dline. + + void printOneChain(); + void printChainLoop(); + void printAllLoops(); + +}; + +monoChain* directedLineLoopToMonoChainLoop(directedLine* loop); +monoChain* directedLineLoopListToMonoChainLoopList(directedLine* list); +Int MC_sweepY(Int nVertices, monoChain** sortedVertices, sweepRange** ret_ranges); + +void MC_findDiagonals(Int total_num_edges, monoChain** sortedVertices, + sweepRange** ranges, Int& num_diagonals, + directedLine** diagonal_vertices); + +directedLine* MC_partitionY(directedLine *polygons, sampledLine **retSampledLines); + +#endif diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/monoPolyPart.cc b/mesalib/src/glu/sgi/libnurbs/nurbtess/monoPolyPart.cc new file mode 100644 index 000000000..8391205bf --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/monoPolyPart.cc @@ -0,0 +1,299 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* + *monoPolyPart.C + * + *To partition a v-monotone polygon into some uv-monotone polygons. + *The algorithm is different from the general monotone partition algorithm. + *while the general monotone partition algorithm works for this special case, + *but it is more expensive (O(nlogn)). The algorithm implemented here takes + *advantage of the fact that the input is a v-monotone polygon and it is + *conceptually simpler and computationally cheaper (a linear time algorithm). + *The algorithm is described in Zicheng Liu's paper + * "Quality-Oriented Linear Time Tessellation". + */ + +#include <stdlib.h> +#include <stdio.h> +#include "directedLine.h" +#include "monoPolyPart.h" + +/*a vertex is u_maximal if both of its two neightbors are to the left of this + *vertex + */ +static Int is_u_maximal(directedLine* v) +{ + if (compV2InX(v->getPrev()->head(), v->head()) == -1 && + compV2InX(v->getNext()->head(), v->head()) == -1) + return 1; + else + return 0; +} + +/*a vertex is u_minimal if both of its two neightbors are to the right of this + *vertex + */ +static Int is_u_minimal(directedLine* v) +{ + if (compV2InX(v->getPrev()->head(), v->head()) == 1 && + compV2InX(v->getNext()->head(), v->head()) == 1) + return 1; + else + return 0; +} + +/*poly: a v-monotone polygon + *return: a linked list of uv-monotone polygons. + */ +directedLine* monoPolyPart(directedLine* polygon) +{ + //handle special cases: + if(polygon == NULL) + return NULL; + if(polygon->getPrev() == polygon) + return polygon; + if(polygon->getPrev() == polygon->getNext()) + return polygon; + if(polygon->getPrev()->getPrev() == polygon->getNext()) + return polygon; + + //find the top and bottom vertexes + directedLine *tempV, *topV, *botV; + topV = botV = polygon; + for(tempV = polygon->getNext(); tempV != polygon; tempV = tempV->getNext()) + { + if(compV2InY(topV->head(), tempV->head())<0) { + topV = tempV; + } + if(compV2InY(botV->head(), tempV->head())>0) { + botV = tempV; + } + } + + //initilization + directedLine *A, *B, *C, *D, *G, *H; + //find A:the first u_maximal vertex on the left chain + //and C: the left most vertex between top and A + A = NULL; + C = topV; + for(tempV=topV->getNext(); tempV != botV; tempV = tempV->getNext()) + { + if(tempV->head()[0] < C->head()[0]) + C = tempV; + + if(is_u_maximal(tempV)) + { + A = tempV; + break; + } + } + if(A == NULL) + { + A = botV; + if(A->head()[0] < C->head()[0]) + C = A; + } + + //find B: the first u_minimal vertex on the right chain + //and D: the right most vertex between top and B + B = NULL; + D = topV; + for(tempV=topV->getPrev(); tempV != botV; tempV = tempV->getPrev()) + { + if(tempV->head()[0] > D->head()[0]) + D = tempV; + if(is_u_minimal(tempV)) + { + B = tempV; + break; + } + } + if(B == NULL) + { + B = botV; + if(B->head()[0] > D->head()[0]) + D = B; + } + + //error checking XXX + if(C->head()[0] >= D->head()[0]) + return polygon; + + //find G on the left chain that is right above B + for(tempV=topV; compV2InY(tempV->head(), B->head()) == 1; tempV=tempV->getNext()); + G = tempV->getPrev(); + //find H on the right chain that is right above A + for(tempV=topV; compV2InY(tempV->head(), A->head()) == 1; tempV = tempV->getPrev()); + H = tempV->getNext(); + + //Main Loop + directedLine* ret = NULL; + directedLine* currentPolygon = polygon; + while(1) + { + //if both B and D are equal to botV, then this polygon is already + //u-monotone + if(A == botV && B == botV) + { + ret = currentPolygon->insertPolygon(ret); + return ret; + } + else //not u-monotone + { + directedLine *ret_p1, *ret_p2; + if(compV2InY(A->head(),B->head()) == 1) //A is above B + { + directedLine* E = NULL; + for(tempV = C; tempV != D; tempV = tempV->getPrev()) + { + if(tempV->head()[0] >= A->head()[0]) + { + E = tempV; + break; + } + } + + if(E == NULL) + E = D; + if(E->head()[0]> H->head()[0]) + E = H; + //connect AE and output polygon ECA + polygon->connectDiagonal_2slines(A, E, + &ret_p1, + &ret_p2, + NULL); + ret = ret_p2->insertPolygon(ret); + currentPolygon = ret_p1; + + if(E == D) + D = ret_p1; + if(E == H) + H = ret_p1; + if(G->head()[1] >= A->head()[1]) + G = A; + //update A to be the next u-maxiaml vertex on left chain + //and C the leftmost vertex between the old A and the new A + C = A; + for(tempV = A->getNext(); tempV != botV; tempV = tempV->getNext()) + { + + if(tempV->head()[0] < C->head()[0]) + C = tempV; + if(is_u_maximal(tempV)) + { + A = tempV; + break; + } + } + + if(tempV == botV) + { + A = botV; + if(botV->head()[0] < C->head()[0]) + C = botV; + } + //update H + + if(A == botV) + H = botV; + else + { + for(tempV = H; compV2InY(tempV->head(), A->head()) == 1; tempV = tempV->getPrev()); + H = tempV->getNext(); + } + + } + else //A is below B + { + + directedLine* F = NULL; + for(tempV = D; tempV != C; tempV = tempV->getNext()) + { + if(tempV->head()[0] <= B->head()[0]) + { + F = tempV; + break; + } + } + if(F == NULL) + F = C; + if(F->head()[0] < G->head()[0]) + F = G; + + //connect FB + polygon->connectDiagonal_2slines(F, B, + &ret_p1, + &ret_p2, + NULL); + ret = ret_p2->insertPolygon(ret); + currentPolygon = ret_p1; + B = ret_p1; + if(H ->head()[1] >= B->head()[1]) + H = ret_p1; + + //update B to be the next u-minimal vertex on right chain + //and D the rightmost vertex between the old B and the new B + D = B; + for(tempV = B->getPrev(); tempV != botV; tempV = tempV->getPrev()) + { + if(tempV->head()[0] > D->head()[0]) + D = tempV; + if(is_u_minimal(tempV)) + { + B = tempV; + break; + } + } + if(tempV == botV) + { + B = botV; + if(botV->head()[0] > D->head()[0]) + D = botV; + } + //update G + if(B == botV) + G = botV; + else + { + for(tempV = G; compV2InY(tempV->head(), B->head()) == 1; tempV = tempV->getNext()); + G = tempV->getPrev(); + } + } //end of A is below B + } //end not u-monotone + } //end of main loop +} + + + diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/monoPolyPart.h b/mesalib/src/glu/sgi/libnurbs/nurbtess/monoPolyPart.h new file mode 100644 index 000000000..6877a59c2 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/monoPolyPart.h @@ -0,0 +1,41 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ +/* + *monoPolyPart.h + */ + +#ifndef _MONO_POLY_PART_H +#define _MONO_POLY_PART_H + +class directedLine; + +directedLine* monoPolyPart(directedLine* polygon); + +#endif diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/monoTriangulation.cc b/mesalib/src/glu/sgi/libnurbs/nurbtess/monoTriangulation.cc new file mode 100644 index 000000000..8e8d49dda --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/monoTriangulation.cc @@ -0,0 +1,1482 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include <stdlib.h> +#include <stdio.h> +#include "gluos.h" +#include "glimports.h" +#include "zlassert.h" + +#include "monoTriangulation.h" +#include "polyUtil.h" /*for area*/ +#include "partitionX.h" +#include "monoPolyPart.h" + + + +extern directedLine* polygonConvert(directedLine* polygon); + +/*poly is NOT deleted + */ +void monoTriangulationOpt(directedLine* poly, primStream* pStream) +{ + Int n_cusps; + Int n_edges = poly->numEdges(); + directedLine** cusps = (directedLine**) malloc(sizeof(directedLine*)*n_edges); + assert(cusps); + findInteriorCuspsX(poly, n_cusps, cusps); + if(n_cusps ==0) //u monotine + { + monoTriangulationFun(poly, compV2InX, pStream); + } + else if(n_cusps == 1) // one interior cusp + { + directedLine* new_polygon = polygonConvert(cusps[0]); + directedLine* other = findDiagonal_singleCuspX(new_polygon); + //<other> should NOT be null unless there are self-intersecting + //trim curves. In that case, we don't want to core dump, instead, + //we triangulate anyway, and print out error message. + if(other == NULL) + { + monoTriangulationFun(poly, compV2InX, pStream); + } + else + { + directedLine* ret_p1; + directedLine* ret_p2; + + new_polygon->connectDiagonal_2slines(new_polygon, other, + &ret_p1, + &ret_p2, + new_polygon); + + monoTriangulationFun(ret_p1, compV2InX, pStream); + monoTriangulationFun(ret_p2, compV2InX, pStream); + + ret_p1->deleteSinglePolygonWithSline(); + ret_p2->deleteSinglePolygonWithSline(); + } + } + else + { + //we need a general partitionX funtion (supposed to be in partitionX.C, + //not implemented yet. XXX + monoTriangulationFun(poly, compV2InY, pStream); + } + + free(cusps); +} + +void monoTriangulationRecOpt(Real* topVertex, Real* botVertex, + vertexArray* left_chain, Int left_current, + vertexArray* right_chain, Int right_current, + primStream* pStream) +{ + Int i,j; + Int n_left = left_chain->getNumElements(); + Int n_right = right_chain->getNumElements(); + if(left_current>= n_left-1 || + right_current>= n_right-1) + { + monoTriangulationRec(topVertex, botVertex, left_chain, left_current, + right_chain, right_current, pStream); + return; + } + //now both left and right have at least two vertices each. + Real left_v = left_chain->getVertex(left_current)[1]; + Real right_v = right_chain->getVertex(right_current)[1]; + + if(left_v <= right_v) //first left vertex is below right + { + //find the last vertex of right which is above or equal to left + for(j=right_current; j<=n_right-1; j++) + { + if(right_chain->getVertex(j)[1] < left_v) + break; + } + monoTriangulationRecGen(topVertex, left_chain->getVertex(left_current), + left_chain, left_current, left_current, + right_chain, right_current, j-1, + pStream); + monoTriangulationRecOpt(right_chain->getVertex(j-1), + botVertex, + left_chain, left_current, + right_chain, j, + pStream); + } + else //first right vertex is strictly below left + { + //find the last vertex of left which is strictly above right + for(i=left_current; i<=n_left-1; i++) + { + if(left_chain->getVertex(i)[1] <= right_v) + break; + } + monoTriangulationRecGen(topVertex, right_chain->getVertex(right_current), + left_chain, left_current, i-1, + right_chain, right_current, right_current, + pStream); + monoTriangulationRecOpt(left_chain->getVertex(i-1), + botVertex, + left_chain, i, + right_chain, right_current, + pStream); + } +} + + +void monoTriangulationRecGenTBOpt(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, Int inc_end, + vertexArray* dec_chain, Int dec_current, Int dec_end, + primStream* pStream) +{ + pStream->triangle(topVertex, inc_chain->getVertex(inc_current), dec_chain->getVertex(dec_current)); + +/*printf("**(%f,%f)\n", inc_chain->getArray()[0][0],inc_chain->getArray()[0][1]);*/ + triangulateXYMonoTB(inc_end-inc_current+1, inc_chain->getArray()+inc_current, dec_end-dec_current+1, dec_chain->getArray()+dec_current, pStream); + + pStream->triangle(botVertex, dec_chain->getVertex(dec_end), inc_chain->getVertex(inc_end)); +} + + +/*n_left>=1 + *n_right>=1 + *the strip is going top to bottom. compared to the funtion + * triangulateXYmono() + */ +void triangulateXYMonoTB(Int n_left, Real** leftVerts, + Int n_right, Real** rightVerts, + primStream* pStream) +{ + + + Int i,j,k,l; + Real* topMostV; + + assert(n_left>=1 && n_right>=1); + if(leftVerts[0][1] >= rightVerts[0][1]) + { + i=1; + j=0; + topMostV = leftVerts[0]; + } + else + { + i=0; + j=1; + topMostV = rightVerts[0]; + } + + while(1) + { + if(i >= n_left) /*case1: no more in left*/ + { + + if(j<n_right-1) /*at least two vertices in right*/ + { + pStream->begin(); + pStream->insert(topMostV); + for(k=n_right-1; k>=j; k--) + pStream->insert(rightVerts[j]); + + pStream->end(PRIMITIVE_STREAM_FAN); + + } + + break; + } + else if(j>= n_right) /*case2: no more in right*/ + { + + if(i<n_left-1) /*at least two vertices in left*/ + { + pStream->begin(); + pStream->insert(topMostV); + + for(k=i; k<n_left; k++) + pStream->insert(leftVerts[k]); + + pStream->end(PRIMITIVE_STREAM_FAN); + } + + break; + } + else /* case3: neither is empty, plus the topMostV, there is at least one triangle to output*/ + { + + if(leftVerts[i][1] >= rightVerts[j][1]) + { + pStream->begin(); + pStream->insert(rightVerts[j]); /*the origin of this fan*/ + + pStream->insert(topMostV); + + /*find the last k>=i such that + *leftverts[k][1] >= rightverts[j][1] + */ + k=i; + while(k<n_left) + { + if(leftVerts[k][1] < rightVerts[j][1]) + break; + k++; + } + k--; + for(l=i; l<=k; l++) + { + pStream->insert(leftVerts[l]); + } + + pStream->end(PRIMITIVE_STREAM_FAN); + //update i for next loop + i = k+1; + topMostV = leftVerts[k]; + + } + else /*leftVerts[i][1] < rightVerts[j][1]*/ + { + pStream->begin(); + pStream->insert(leftVerts[i]);/*the origion of this fan*/ + + /*find the last k>=j such that + *rightverts[k][1] > leftverts[i][1]*/ + k=j; + while(k< n_right) + { + if(rightVerts[k][1] <= leftVerts[i][1]) + break; + k++; + } + k--; + + for(l=k; l>= j; l--) + pStream->insert(rightVerts[l]); + + pStream->insert(topMostV); + pStream->end(PRIMITIVE_STREAM_FAN); + j=k+1; + topMostV = rightVerts[j-1]; + } + } + } +} + +static int chainConvex(vertexArray* inc_chain, Int inc_current, Int inc_end) +{ + Int i; + //if there are no more than 2 vertices, return 1 + if(inc_current >= inc_end-1) return 1; + for(i=inc_current; i<= inc_end-2; i++) + { + if(area(inc_chain->getVertex(i), inc_chain->getVertex(i+1), inc_chain->getVertex(i+2)) <0) + return 0; + } + return 1; +} + +static int chainConcave(vertexArray* dec_chain, Int dec_current, Int dec_end) +{ + Int i; + //if there are no more than 2 vertices, return 1 + if(dec_current >= dec_end -1) return 1; + for(i=dec_current; i<=dec_end-2; i++) + { + if(area(dec_chain->getVertex(i), dec_chain->getVertex(i+1), dec_chain->getVertex(i+2)) >0) + return 0; + } + return 1; +} + +void monoTriangulationRecGenInU(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, Int inc_end, + vertexArray* dec_chain, Int dec_current, Int dec_end, + primStream* pStream) +{ + +} + +void monoTriangulationRecGenOpt(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, Int inc_end, + vertexArray* dec_chain, Int dec_current, Int dec_end, + primStream* pStream) +{ + Int i; + //copy this to a polygon: directedLine Lioop + sampledLine* sline; + directedLine* dline; + directedLine* poly; + + if(inc_current <= inc_end) //at least one vertex in inc_chain + { + sline = new sampledLine(topVertex, inc_chain->getVertex(inc_current)); + poly = new directedLine(INCREASING, sline); + for(i=inc_current; i<=inc_end-1; i++) + { + sline = new sampledLine(inc_chain->getVertex(i), inc_chain->getVertex(i+1)); + dline = new directedLine(INCREASING, sline); + poly->insert(dline); + } + sline = new sampledLine(inc_chain->getVertex(inc_end), botVertex); + dline = new directedLine(INCREASING, sline); + poly->insert(dline); + } + else //inc_chian is empty + { + sline = new sampledLine(topVertex, botVertex); + dline = new directedLine(INCREASING, sline); + poly = dline; + } + + assert(poly != NULL); + + if(dec_current <= dec_end) //at least on vertex in dec_Chain + { + sline = new sampledLine(botVertex, dec_chain->getVertex(dec_end)); + dline = new directedLine(INCREASING, sline); + poly->insert(dline); + for(i=dec_end; i>dec_current; i--) + { + sline = new sampledLine(dec_chain->getVertex(i), dec_chain->getVertex(i-1)); + dline = new directedLine(INCREASING, sline); + poly->insert(dline); + } + sline = new sampledLine(dec_chain->getVertex(dec_current), topVertex); + dline = new directedLine(INCREASING, sline); + poly->insert(dline); + } + else //dec_chain is empty + { + sline = new sampledLine(botVertex, topVertex); + dline = new directedLine(INCREASING, sline); + poly->insert(dline); + } + + { + Int n_cusps; + Int n_edges = poly->numEdges(); + directedLine** cusps = (directedLine**) malloc(sizeof(directedLine*)*n_edges); + assert(cusps); + findInteriorCuspsX(poly, n_cusps, cusps); + + if(n_cusps ==0) //u monotine + { + monoTriangulationFun(poly, compV2InX, pStream); + } + else if(n_cusps == 1) // one interior cusp + { + directedLine* new_polygon = polygonConvert(cusps[0]); + directedLine* other = findDiagonal_singleCuspX(new_polygon); + //<other> should NOT be null unless there are self-intersecting + //trim curves. In that case, we don't want to core dump, instead, + //we triangulate anyway, and print out error message. + if(other == NULL) + { + monoTriangulationFun(poly, compV2InX, pStream); + } + else + { + directedLine* ret_p1; + directedLine* ret_p2; + + new_polygon->connectDiagonal_2slines(new_polygon, other, + &ret_p1, + &ret_p2, + new_polygon); + + monoTriangulationFun(ret_p1, compV2InX, pStream); + monoTriangulationFun(ret_p2, compV2InX, pStream); + + ret_p1->deleteSinglePolygonWithSline(); + ret_p2->deleteSinglePolygonWithSline(); + } + } + else + { + //we need a general partitionX funtion (supposed to be in partitionX.C, + //not implemented yet. XXX + //monoTriangulationFun(poly, compV2InY, pStream); + + directedLine* new_polygon = polygonConvert(poly); + directedLine* list = monoPolyPart(new_polygon); + for(directedLine* temp = list; temp != NULL; temp = temp->getNextPolygon()) + { + monoTriangulationFun(temp, compV2InX, pStream); + } + //clean up + list->deletePolygonListWithSline(); + + } + + free(cusps); + /* + if(numInteriorCuspsX(poly) == 0) //is u monotone + monoTriangulationFun(poly, compV2InX, pStream); + else //it is not u motone + monoTriangulationFun(poly, compV2InY, pStream); + */ + //clean up space + poly->deleteSinglePolygonWithSline(); + return; + } + + //apparently the following code is not reachable, + //it is for test purpose + if(inc_current > inc_end || dec_current>dec_end) + { + monoTriangulationRecGen(topVertex, botVertex, inc_chain, inc_current, inc_end, + dec_chain, dec_current, dec_end, + pStream); + return; + } + + + if( + area(dec_chain->getVertex(dec_current), + topVertex, + inc_chain->getVertex(inc_current)) >=0 + && chainConvex(inc_chain, inc_current, inc_end) + && chainConcave(dec_chain, dec_current, dec_end) + && area(inc_chain->getVertex(inc_end), botVertex, dec_chain->getVertex(dec_end)) >=0 + ) + { + monoTriangulationRecFunGen(topVertex, botVertex, + inc_chain, inc_current, inc_end, + dec_chain, dec_current, dec_end, + compV2InX, pStream); + } + else + { + monoTriangulationRecGen(topVertex, botVertex, inc_chain, inc_current, inc_end, + dec_chain, dec_current, dec_end, + pStream); + } +} + +/*if inc_current>inc_end, then inc_chain has no points to be considered + *same for dec_chain + */ +void monoTriangulationRecGen(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, Int inc_end, + vertexArray* dec_chain, Int dec_current, Int dec_end, + primStream* pStream) +{ + Real** inc_array ; + Real** dec_array ; + Int i; + + if(inc_current > inc_end && dec_current>dec_end) + return; + else if(inc_current>inc_end) /*no more vertices on inc_chain*/ + { + dec_array = dec_chain->getArray(); + reflexChain rChain(100,0); + /*put the top vertex into the reflex chain*/ + rChain.processNewVertex(topVertex, pStream); + /*process all the vertices on the dec_chain*/ + for(i=dec_current; i<=dec_end; i++){ + rChain.processNewVertex(dec_array[i], pStream); + } + /*process the bottom vertex*/ + rChain.processNewVertex(botVertex, pStream); + } + else if(dec_current> dec_end) /*no more vertices on dec_chain*/ + { + inc_array = inc_chain->getArray(); + + reflexChain rChain(100,1); + /*put the top vertex into the reflex chain*/ + rChain.processNewVertex(topVertex, pStream); + /*process all the vertices on the inc_chain*/ + for(i=inc_current; i<=inc_end; i++){ + rChain.processNewVertex(inc_array[i], pStream); + } + /*process the bottom vertex*/ + rChain.processNewVertex(botVertex, pStream); + } + else /*neither chain is empty*/ + { + inc_array = inc_chain -> getArray(); + dec_array = dec_chain -> getArray(); + + /*if top of inc_chain is 'lower' than top of dec_chain, process all the + *vertices on the dec_chain which are higher than top of inc_chain + */ + if(compV2InY(inc_array[inc_current], dec_array[dec_current]) <= 0) + { + + reflexChain rChain(100, 0); + rChain.processNewVertex(topVertex, pStream); + for(i=dec_current; i<=dec_end; i++) + { + if(compV2InY(inc_array[inc_current], dec_array[i]) <= 0) + rChain.processNewVertex(dec_array[i], pStream); + else + break; + } + rChain.outputFan(inc_array[inc_current], pStream); + monoTriangulationRecGen(dec_array[i-1], botVertex, + inc_chain, inc_current, inc_end, + dec_chain, i, dec_end, + pStream); + } + else /*compV2InY(inc_array[inc_current], dec_array[dec_current]) > 0*/ + { + + reflexChain rChain(100, 1); + rChain.processNewVertex(topVertex, pStream); + for(i=inc_current; i<=inc_end; i++) + { + if(compV2InY(inc_array[i], dec_array[dec_current]) >0) + rChain.processNewVertex(inc_array[i], pStream); + else + break; + } + rChain.outputFan(dec_array[dec_current], pStream); + monoTriangulationRecGen(inc_array[i-1], botVertex, + inc_chain, i, inc_end, + dec_chain, dec_current,dec_end, + pStream); + } + }/*end case neither is empty*/ +} + +void monoTriangulationFun(directedLine* monoPolygon, Int (*compFun)(Real*, Real*), primStream* pStream) +{ + Int i; + /*find the top vertex, bottom vertex, inccreasing chain, and decreasing chain, + *then call monoTriangulationRec + */ + directedLine* tempV; + directedLine* topV; + directedLine* botV; + topV = botV = monoPolygon; + for(tempV = monoPolygon->getNext(); tempV != monoPolygon; tempV = tempV->getNext()) + { + if(compFun(topV->head(), tempV->head())<0) { + topV = tempV; + } + if(compFun(botV->head(), tempV->head())>0) { + botV = tempV; + } + } + + /*creat increase and decrease chains*/ + vertexArray inc_chain(20); /*this is a dynamic array*/ + for(i=1; i<=topV->get_npoints()-2; i++) { /*the first vertex is the top vertex which doesn't belong to inc_chain*/ + inc_chain.appendVertex(topV->getVertex(i)); + } + for(tempV = topV->getNext(); tempV != botV; tempV = tempV->getNext()) + { + for(i=0; i<=tempV->get_npoints()-2; i++){ + inc_chain.appendVertex(tempV->getVertex(i)); + } + } + + vertexArray dec_chain(20); + for(tempV = topV->getPrev(); tempV != botV; tempV = tempV->getPrev()) + { + for(i=tempV->get_npoints()-2; i>=0; i--){ + dec_chain.appendVertex(tempV->getVertex(i)); + } + } + for(i=botV->get_npoints()-2; i>=1; i--){ + dec_chain.appendVertex(tempV->getVertex(i)); + } + + if (!(0 == inc_chain.getNumElements() && 0 == dec_chain.getNumElements())) { + monoTriangulationRecFun(topV->head(), botV->head(), &inc_chain, 0, + &dec_chain, 0, compFun, pStream); + } +} + +void monoTriangulation(directedLine* monoPolygon, primStream* pStream) +{ + Int i; + /*find the top vertex, bottom vertex, inccreasing chain, and decreasing chain, + *then call monoTriangulationRec + */ + directedLine* tempV; + directedLine* topV; + directedLine* botV; + topV = botV = monoPolygon; + for(tempV = monoPolygon->getNext(); tempV != monoPolygon; tempV = tempV->getNext()) + { + if(compV2InY(topV->head(), tempV->head())<0) { + topV = tempV; + } + if(compV2InY(botV->head(), tempV->head())>0) { + botV = tempV; + } + } + /*creat increase and decrease chains*/ + vertexArray inc_chain(20); /*this is a dynamic array*/ + for(i=1; i<=topV->get_npoints()-2; i++) { /*the first vertex is the top vertex which doesn't belong to inc_chain*/ + inc_chain.appendVertex(topV->getVertex(i)); + } + for(tempV = topV->getNext(); tempV != botV; tempV = tempV->getNext()) + { + for(i=0; i<=tempV->get_npoints()-2; i++){ + inc_chain.appendVertex(tempV->getVertex(i)); + } + } + + vertexArray dec_chain(20); + for(tempV = topV->getPrev(); tempV != botV; tempV = tempV->getPrev()) + { + for(i=tempV->get_npoints()-2; i>=0; i--){ + dec_chain.appendVertex(tempV->getVertex(i)); + } + } + for(i=botV->get_npoints()-2; i>=1; i--){ + dec_chain.appendVertex(tempV->getVertex(i)); + } + + monoTriangulationRec(topV->head(), botV->head(), &inc_chain, 0, &dec_chain, 0, pStream); + +} + +/*the chain could be increasing or decreasing, although we use the + * name inc_chain. + *the argument is_increase_chain indicates whether this chain + *is increasing (left chain in V-monotone case) or decreaing (right chain + *in V-monotone case). + */ +void monoTriangulation2(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_smallIndex, + Int inc_largeIndex, + Int is_increase_chain, + primStream* pStream) +{ + assert( inc_chain != NULL); + Real** inc_array ; + + if(inc_smallIndex > inc_largeIndex) + return; //no triangles + if(inc_smallIndex == inc_largeIndex) + { + if(is_increase_chain) + pStream->triangle(inc_chain->getVertex(inc_smallIndex), botVertex, topVertex); + else + pStream->triangle(inc_chain->getVertex(inc_smallIndex), topVertex, botVertex); + return; + } + Int i; + + if(is_increase_chain && botVertex[1] == inc_chain->getVertex(inc_largeIndex)[1]) + { + pStream->triangle(botVertex, inc_chain->getVertex(inc_largeIndex-1), + inc_chain->getVertex(inc_largeIndex)); + monoTriangulation2(topVertex, botVertex, inc_chain, inc_smallIndex, + inc_largeIndex-1, + is_increase_chain, + pStream); + return; + } + else if( (!is_increase_chain) && topVertex[1] == inc_chain->getVertex(inc_smallIndex)[1]) + { + pStream->triangle(topVertex, inc_chain->getVertex(inc_smallIndex+1), + inc_chain->getVertex(inc_smallIndex)); + monoTriangulation2(topVertex, botVertex, inc_chain, inc_smallIndex+1, + inc_largeIndex, is_increase_chain, pStream); + return ; + } + + inc_array = inc_chain->getArray(); + + reflexChain rChain(20,is_increase_chain); /*1 means the chain is increasing*/ + + rChain.processNewVertex(topVertex, pStream); + + for(i=inc_smallIndex; i<=inc_largeIndex; i++){ + rChain.processNewVertex(inc_array[i], pStream); + } + rChain.processNewVertex(botVertex, pStream); + +} + +/*if compFun == compV2InY, top to bottom: V-monotone + *if compFun == compV2InX, right to left: U-monotone + */ +void monoTriangulationRecFunGen(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, Int inc_end, + vertexArray* dec_chain, Int dec_current, Int dec_end, + Int (*compFun)(Real*, Real*), + primStream* pStream) +{ + assert( inc_chain != NULL && dec_chain != NULL); + assert( ! (inc_current> inc_end && + dec_current> dec_end)); + /* + Int inc_nVertices; + Int dec_nVertices; + */ + Real** inc_array ; + Real** dec_array ; + Int i; + assert( ! ( (inc_chain==NULL) && (dec_chain==NULL))); + + if(inc_current> inc_end) /*no more vertices on inc_chain*/ + { + + dec_array = dec_chain->getArray(); + reflexChain rChain(20,0); + /*put the top vertex into the reflex chain*/ + rChain.processNewVertex(topVertex, pStream); + /*process all the vertices on the dec_chain*/ + for(i=dec_current; i<=dec_end; i++){ + rChain.processNewVertex(dec_array[i], pStream); + } + /*process the bottom vertex*/ + rChain.processNewVertex(botVertex, pStream); + + } + else if(dec_current> dec_end) /*no more vertices on dec_chain*/ + { + inc_array = inc_chain->getArray(); + reflexChain rChain(20,1); + /*put the top vertex into the reflex chain*/ + rChain.processNewVertex(topVertex, pStream); + /*process all the vertices on the inc_chain*/ + for(i=inc_current; i<=inc_end; i++){ + rChain.processNewVertex(inc_array[i], pStream); + } + /*process the bottom vertex*/ + rChain.processNewVertex(botVertex, pStream); + } + else /*neither chain is empty*/ + { + inc_array = inc_chain -> getArray(); + dec_array = dec_chain -> getArray(); + + /*if top of inc_chain is 'lower' than top of dec_chain, process all the + *vertices on the dec_chain which are higher than top of inc_chain + */ + if(compFun(inc_array[inc_current], dec_array[dec_current]) <= 0) + { + + reflexChain rChain(20, 0); + rChain.processNewVertex(topVertex, pStream); + for(i=dec_current; i<=dec_end; i++) + { + if(compFun(inc_array[inc_current], dec_array[i]) <= 0) + rChain.processNewVertex(dec_array[i], pStream); + else + break; + } + rChain.outputFan(inc_array[inc_current], pStream); + monoTriangulationRecFunGen(dec_array[i-1], botVertex, + inc_chain, inc_current, inc_end, + dec_chain, i, dec_end, + compFun, + pStream); + } + else /*compFun(inc_array[inc_current], dec_array[dec_current]) > 0*/ + { + + reflexChain rChain(20, 1); + rChain.processNewVertex(topVertex, pStream); + for(i=inc_current; i<=inc_end; i++) + { + if(compFun(inc_array[i], dec_array[dec_current]) >0) + rChain.processNewVertex(inc_array[i], pStream); + else + break; + } + rChain.outputFan(dec_array[dec_current], pStream); + monoTriangulationRecFunGen(inc_array[i-1], botVertex, + inc_chain, i,inc_end, + dec_chain, dec_current,dec_end, + compFun, + pStream); + } + }/*end case neither is empty*/ +} + +/*if compFun == compV2InY, top to bottom: V-monotone + *if compFun == compV2InX, right to left: U-monotone + */ +void monoTriangulationRecFun(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, + vertexArray* dec_chain, Int dec_current, + Int (*compFun)(Real*, Real*), + primStream* pStream) +{ + assert( inc_chain != NULL && dec_chain != NULL); + assert( ! (inc_current>=inc_chain->getNumElements() && + dec_current>=dec_chain->getNumElements())); + Int inc_nVertices; + Int dec_nVertices; + Real** inc_array ; + Real** dec_array ; + Int i; + assert( ! ( (inc_chain==NULL) && (dec_chain==NULL))); + + if(inc_current>=inc_chain->getNumElements()) /*no more vertices on inc_chain*/ + { + + dec_array = dec_chain->getArray(); + dec_nVertices = dec_chain->getNumElements(); + reflexChain rChain(20,0); + /*put the top vertex into the reflex chain*/ + rChain.processNewVertex(topVertex, pStream); + /*process all the vertices on the dec_chain*/ + for(i=dec_current; i<dec_nVertices; i++){ + rChain.processNewVertex(dec_array[i], pStream); + } + /*process the bottom vertex*/ + rChain.processNewVertex(botVertex, pStream); + + } + else if(dec_current>= dec_chain->getNumElements()) /*no more vertices on dec_chain*/ + { + inc_array = inc_chain->getArray(); + inc_nVertices= inc_chain->getNumElements(); + reflexChain rChain(20,1); + /*put the top vertex into the reflex chain*/ + rChain.processNewVertex(topVertex, pStream); + /*process all the vertices on the inc_chain*/ + for(i=inc_current; i<inc_nVertices; i++){ + rChain.processNewVertex(inc_array[i], pStream); + } + /*process the bottom vertex*/ + rChain.processNewVertex(botVertex, pStream); + } + else /*neither chain is empty*/ + { + inc_array = inc_chain -> getArray(); + dec_array = dec_chain -> getArray(); + inc_nVertices= inc_chain->getNumElements(); + dec_nVertices= dec_chain->getNumElements(); + /*if top of inc_chain is 'lower' than top of dec_chain, process all the + *vertices on the dec_chain which are higher than top of inc_chain + */ + if(compFun(inc_array[inc_current], dec_array[dec_current]) <= 0) + { + + reflexChain rChain(20, 0); + rChain.processNewVertex(topVertex, pStream); + for(i=dec_current; i<dec_nVertices; i++) + { + if(compFun(inc_array[inc_current], dec_array[i]) <= 0) + rChain.processNewVertex(dec_array[i], pStream); + else + break; + } + rChain.outputFan(inc_array[inc_current], pStream); + monoTriangulationRecFun(dec_array[i-1], botVertex, + inc_chain, inc_current, + dec_chain, i, + compFun, + pStream); + } + else /*compFun(inc_array[inc_current], dec_array[dec_current]) > 0*/ + { + + reflexChain rChain(20, 1); + rChain.processNewVertex(topVertex, pStream); + for(i=inc_current; i<inc_nVertices; i++) + { + if(compFun(inc_array[i], dec_array[dec_current]) >0) + rChain.processNewVertex(inc_array[i], pStream); + else + break; + } + rChain.outputFan(dec_array[dec_current], pStream); + monoTriangulationRecFun(inc_array[i-1], botVertex, + inc_chain, i, + dec_chain, dec_current, + compFun, + pStream); + } + }/*end case neither is empty*/ +} + + +void monoTriangulationRec(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, + vertexArray* dec_chain, Int dec_current, + primStream* pStream) +{ + assert( inc_chain != NULL && dec_chain != NULL); + assert( ! (inc_current>=inc_chain->getNumElements() && + dec_current>=dec_chain->getNumElements())); + Int inc_nVertices; + Int dec_nVertices; + Real** inc_array ; + Real** dec_array ; + Int i; + assert( ! ( (inc_chain==NULL) && (dec_chain==NULL))); + + if(inc_current>=inc_chain->getNumElements()) /*no more vertices on inc_chain*/ + { + + dec_array = dec_chain->getArray(); + dec_nVertices = dec_chain->getNumElements(); + reflexChain rChain(20,0); + /*put the top vertex into the reflex chain*/ + rChain.processNewVertex(topVertex, pStream); + /*process all the vertices on the dec_chain*/ + for(i=dec_current; i<dec_nVertices; i++){ + rChain.processNewVertex(dec_array[i], pStream); + } + /*process the bottom vertex*/ + rChain.processNewVertex(botVertex, pStream); + + } + else if(dec_current>= dec_chain->getNumElements()) /*no more vertices on dec_chain*/ + { + inc_array = inc_chain->getArray(); + inc_nVertices= inc_chain->getNumElements(); + reflexChain rChain(20,1); + /*put the top vertex into the reflex chain*/ + rChain.processNewVertex(topVertex, pStream); + /*process all the vertices on the inc_chain*/ + for(i=inc_current; i<inc_nVertices; i++){ + rChain.processNewVertex(inc_array[i], pStream); + } + /*process the bottom vertex*/ + rChain.processNewVertex(botVertex, pStream); + } + else /*neither chain is empty*/ + { + inc_array = inc_chain -> getArray(); + dec_array = dec_chain -> getArray(); + inc_nVertices= inc_chain->getNumElements(); + dec_nVertices= dec_chain->getNumElements(); + /*if top of inc_chain is 'lower' than top of dec_chain, process all the + *vertices on the dec_chain which are higher than top of inc_chain + */ + if(compV2InY(inc_array[inc_current], dec_array[dec_current]) <= 0) + { + + reflexChain rChain(20, 0); + rChain.processNewVertex(topVertex, pStream); + for(i=dec_current; i<dec_nVertices; i++) + { + if(compV2InY(inc_array[inc_current], dec_array[i]) <= 0) + rChain.processNewVertex(dec_array[i], pStream); + else + break; + } + rChain.outputFan(inc_array[inc_current], pStream); + monoTriangulationRec(dec_array[i-1], botVertex, + inc_chain, inc_current, + dec_chain, i, + pStream); + } + else /*compV2InY(inc_array[inc_current], dec_array[dec_current]) > 0*/ + { + + reflexChain rChain(20, 1); + rChain.processNewVertex(topVertex, pStream); + for(i=inc_current; i<inc_nVertices; i++) + { + if(compV2InY(inc_array[i], dec_array[dec_current]) >0) + rChain.processNewVertex(inc_array[i], pStream); + else + break; + } + rChain.outputFan(dec_array[dec_current], pStream); + monoTriangulationRec(inc_array[i-1], botVertex, + inc_chain, i, + dec_chain, dec_current, + pStream); + } + }/*end case neither is empty*/ +} + + + +/* the name here assumes that the polygon is Y-monotone, but + *this function also works for X-monotone polygons. + * a monotne polygon consists of two extrem verteices: topVertex and botVertex, and + *two monotone chains: inc_chain, and dec_chain. The edges of the increasing chain (inc_chain) + *is ordered by following pointer: next, while the edges of the decreasing chain (dec_chain) + *is ordered by following pointer: prev + * inc_index index the vertex which is the toppest of the inc_chain which we are handling currently. + * dec_index index the vertex which is the toppest of the dec_chain which we are handling currently. + */ +void monoTriangulationRec(directedLine* inc_chain, Int inc_index, + directedLine* dec_chain, Int dec_index, + directedLine* topVertex, Int top_index, + directedLine* botVertex, + primStream* pStream) +{ + Int i; + directedLine *temp, *oldtemp = NULL; + Int tempIndex, oldtempIndex = 0; + + assert(inc_chain != NULL && dec_chain != NULL); + + if(inc_chain == botVertex) { + reflexChain rChain(20, 0); + rChain.processNewVertex(topVertex->getVertex(top_index), pStream); + for(i=dec_index; i< dec_chain->get_npoints(); i++){ + rChain.processNewVertex(dec_chain->getVertex(i), pStream); + } + for(temp = dec_chain->getPrev(); temp != botVertex; temp = temp->getPrev()) + { + for(i=0; i<temp->get_npoints(); i++){ + rChain.processNewVertex(temp->getVertex(i), pStream); + } + } + } + else if(dec_chain==botVertex) { + reflexChain rChain(20, 1); + rChain.processNewVertex(topVertex->getVertex(top_index), pStream); + for(i=inc_index; i< inc_chain->get_npoints(); i++){ + rChain.processNewVertex(inc_chain->getVertex(i), pStream); + } + for(temp = inc_chain->getPrev(); temp != botVertex; temp = temp->getNext()) + { + for(i=0; i<temp->get_npoints(); i++){ + rChain.processNewVertex(temp->getVertex(i), pStream); + } + } + } + else /*neither reached the bottom*/{ + if(compV2InY(inc_chain->getVertex(inc_index), dec_chain->getVertex(dec_index)) <=0) { + reflexChain rChain(20, 0); + rChain.processNewVertex(topVertex -> getVertex(top_index), pStream); + temp = dec_chain; + tempIndex = dec_index; + while( compV2InY(inc_chain->getVertex(inc_index), temp->getVertex(tempIndex))<=0) { + oldtemp = temp; + oldtempIndex = tempIndex; + rChain.processNewVertex(temp->getVertex(tempIndex), pStream); + + if(tempIndex == temp->get_npoints()-1){ + tempIndex = 0; + temp = temp->getPrev(); + } + else{ + tempIndex++; + } + } + rChain.outputFan(inc_chain->getVertex(inc_index), pStream); + monoTriangulationRec(inc_chain, inc_index, temp, tempIndex, oldtemp, oldtempIndex, botVertex, pStream); + } + else /* >0*/ { + reflexChain rChain(20, 1); + rChain.processNewVertex(topVertex -> getVertex(top_index), pStream); + temp = inc_chain; + tempIndex = inc_index; + while( compV2InY(temp->getVertex(tempIndex), dec_chain->getVertex(dec_index))>0){ + oldtemp = temp; + oldtempIndex = tempIndex; + rChain.processNewVertex(temp->getVertex(tempIndex), pStream); + + if(tempIndex == temp->get_npoints()-1){ + tempIndex = 0; + temp = temp->getNext(); + } + else{ + tempIndex++; + } + } + rChain.outputFan(dec_chain->getVertex(dec_index), pStream); + monoTriangulationRec(temp, tempIndex, dec_chain, dec_index, oldtemp, oldtempIndex, botVertex, pStream); + } + } /*end case neither reached the bottom*/ +} + +/***************************vertexArray begin here**********************************/ +vertexArray::vertexArray(Real2* vertices, Int nVertices) +{ + Int i; + size = index = nVertices; + array = (Real**) malloc(sizeof(Real*) * nVertices); + assert(array); + for(i=0; i<nVertices; i++) + { + array[i] = vertices[i]; + array[i] = vertices[i]; + } +} + +vertexArray::vertexArray(Int s) +{ + size = s; + array = (Real**) malloc(sizeof(Real*) * s); + assert(array); + index = 0; +} + +vertexArray::~vertexArray() +{ + free(array); +} + +void vertexArray::appendVertex(Real* ptr) +{ + Int i; + if(index >= size){ + Real** temp = (Real**) malloc(sizeof(Real*) * (2*size +1)); + assert(temp); + for(i=0; i<index; i++) + temp[i] = array[i]; + free(array); + array = temp; + size = 2*size+1; + } + array[index++] = ptr; +} + +void vertexArray::print() +{ + printf("vertex Array:index=%i, size=%i\n", index, size); + for(Int i=0; i<index; i++) + { + printf("(%f,%f) ", array[i][0], array[i][1]); + } + printf("\n"); +} + +/*find the first i such that array[i][1] >= v + * and array[i+1][1] <v + * if index == 0 (the array is empty, return -1. + * if v is above all, return -1. + * if v is below all, return index-1. + */ +Int vertexArray::findIndexAbove(Real v) +{ + Int i; + if(index == 0) + return -1; + else if(array[0][1] < v) + return -1; + else + { + for(i=1; i<index; i++) + { + if(array[i][1] < v) + break; + } + return i-1; + } +} + +/*find the first i<=endIndex such that array[i][1] <= v + * and array[i-1][1] > v + *if sartIndex>endIndex, then return endIndex+1. + *otherwise, startIndex<=endIndex, it is assumed that + * 0<=startIndex<=endIndex<index. + * if v is below all, return endIndex+1 + * if v is above all, return startIndex. + */ +Int vertexArray::findIndexBelowGen(Real v, Int startIndex, Int endIndex) +{ + Int i; + if(startIndex > endIndex) + return endIndex+1; + else if(array[endIndex][1] > v) + return endIndex+1; + else //now array[endIndex][1] <= v + { + for(i=endIndex-1; i>=startIndex; i--) + { + if(array[i][1] > v) + break; + } + return i+1; + } +} + +/*find the first i<=endIndex such that array[i-1][1] >= v + * and array[i][1] < v + *if sartIndex>endIndex, then return endIndex+1. + *otherwise, startIndex<=endIndex, it is assumed that + * 0<=startIndex<=endIndex<index. + * if v is below or equal to all, return endIndex+1 + * if v is strictly above all, return startIndex. + */ +Int vertexArray::findIndexStrictBelowGen(Real v, Int startIndex, Int endIndex) +{ + Int i; + if(startIndex > endIndex) + return endIndex+1; + else if(array[endIndex][1] >= v) + return endIndex+1; + else //now array[endIndex][1] < v + { + for(i=endIndex-1; i>=startIndex; i--) + { + if(array[i][1] >= v) + break; + } + return i+1; + } +} + +/*find the first i>startIndex such that array[i-1][1] > v + * and array[i][1] >=v + *if sartIndex>endIndex, then return startIndex-1. + *otherwise, startIndex<=endIndex, it is assumed that + * 0<=startIndex<=endIndex<index. + * if v is strictly above all, return startIndex-1 + * if v is strictly below all, return endIndex. + */ +Int vertexArray::findIndexFirstAboveEqualGen(Real v, Int startIndex, Int endIndex) +{ + + Int i; + if(startIndex > endIndex) + return startIndex-1; + else if(array[startIndex][1] < v) + return startIndex-1; + else //now array[startIndex][1] >= v + { + + for(i=startIndex; i<=endIndex; i++) + { + if(array[i][1] <= v) + break; + } + if(i>endIndex) // v is strictly below all + return endIndex; + else if(array[i][1] == v) + return i; + else + return i-1; + } + +} + + +/*find the first i>=startIndex such that array[i][1] >= v + * and array[i+1][1] <v + *if sartIndex>endIndex, then return startIndex-1. + *otherwise, startIndex<=endIndex, it is assumed that + * 0<=startIndex<=endIndex<index. + * if v is above all, return startIndex-1 + * if v is below all, return endIndex. + */ +Int vertexArray::findIndexAboveGen(Real v, Int startIndex, Int endIndex) +{ + Int i; + if(startIndex > endIndex) + return startIndex-1; + else if(array[startIndex][1] < v) + return startIndex-1; + else //now array[startIndex][1] >= v + { + for(i=startIndex+1; i<=endIndex; i++) + { + if(array[i][1] < v) + break; + } + return i-1; + } +} + +Int vertexArray::findDecreaseChainFromEnd(Int begin, Int end) +{ + Int i = end; + Real prevU = array[i][0]; + Real thisU; + for(i=end-1; i>=begin; i--){ + thisU = array[i][0]; + if(thisU < prevU) + prevU = thisU; + else + break; + } + return i; +} + +//if(V(start) == v, return start, other wise return the +//last i so that V(i)==v +Int vertexArray::skipEqualityFromStart(Real v, Int start, Int end) +{ + Int i; + if(array[start][1] != v) + return start; + //now array[start][1] == v + for(i=start+1; i<= end; i++) + if(array[i][1] != v) + break; + return i-1; +} + + +/***************************vertexArray end****************************************/ + + + +/***************************relfex chain stuff begin here*****************************/ + +reflexChain::reflexChain(Int size, Int is_increasing) +{ + queue = (Real2*) malloc(sizeof(Real2) * size); + assert(queue); + index_queue = 0; + size_queue = size; + isIncreasing = is_increasing; +} + +reflexChain::~reflexChain() +{ + free(queue); +} + +/*put (u,v) at the end of the queue + *pay attention to space + */ +void reflexChain::insert(Real u, Real v) +{ + Int i; + if(index_queue >= size_queue) { + Real2 *temp = (Real2*) malloc(sizeof(Real2) * (2*size_queue+1)); + assert(temp); + + /*copy*/ + for(i=0; i<index_queue; i++){ + temp[i][0] = queue[i][0]; + temp[i][1] = queue[i][1]; + } + + free(queue); + queue = temp; + size_queue = 2*size_queue + 1; + } + + queue[index_queue][0] = u; + queue[index_queue][1] = v; + index_queue ++; +} + +void reflexChain::insert(Real v[2]) +{ + insert(v[0], v[1]); +} + +/* +static Real area(Real A[2], Real B[2], Real C[2]) +{ + Real Bx, By, Cx, Cy; + Bx = B[0] - A[0]; + By = B[1] - A[1]; + Cx = C[0] - A[0]; + Cy = C[1] - A[1]; + return Bx*Cy - Cx*By; +} +*/ + +/*the chain is reflex, and the vertex v is + *on the other side of the chain, so that + *we can outout the fan with v as the + *the center + */ +void reflexChain::outputFan(Real v[2], primStream* pStream) +{ + Int i; + pStream->begin(); + pStream->insert(v); + if(isIncreasing) { + for(i=0; i<index_queue; i++) + pStream->insert(queue[i]); + } + else { + for(i=index_queue-1; i>=0; i--) + pStream->insert(queue[i]); + } + pStream->end(PRIMITIVE_STREAM_FAN); +} + +void reflexChain::processNewVertex(Real v[2], primStream* pStream) +{ + Int i,j,k; + Int isReflex; + /*if there are at most one vertex in the queue, then simply insert + */ + if(index_queue <=1){ + insert(v); + return; + } + + /*there are at least two vertices in the queue*/ + j=index_queue-1; + + for(i=j; i>=1; i--) { + if(isIncreasing) { + isReflex = (area(queue[i-1], queue[i], v) <= 0.0); + } + else /*decreasing*/{ + isReflex = (area(v, queue[i], queue[i-1]) <= 0.0); + } + if(isReflex) { + break; + } + } + + /* + *if i<j then vertices: i+1--j are convex + * output triangle fan: + * v, and queue[i], i+1, ..., j + */ + if(i<j) + { + pStream->begin(); + pStream->insert(v); + if(isIncreasing) { + for(k=i; k<=j; k++) + pStream->insert(queue[k]); + } + else { + for(k=j; k>=i; k--) + pStream->insert(queue[k]); + } + + pStream->end(PRIMITIVE_STREAM_FAN); + } + + /*delete vertices i+1--j from the queue*/ + index_queue = i+1; + /*finally insert v at the end of the queue*/ + insert(v); + +} + +void reflexChain::print() +{ + Int i; + printf("reflex chain: isIncreasing=%i\n", isIncreasing); + for(i=0; i<index_queue; i++) { + printf("(%f,%f) ", queue[i][0], queue[i][1]); + } + printf("\n"); +} diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/monoTriangulation.h b/mesalib/src/glu/sgi/libnurbs/nurbtess/monoTriangulation.h new file mode 100644 index 000000000..f78b8f402 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/monoTriangulation.h @@ -0,0 +1,184 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ +/* +*/ + +#ifndef _MONO_TRIANGULATION_H +#define _MONO_TRIANGULATION_H + +#include "definitions.h" +#include "primitiveStream.h" +#include "directedLine.h" +#include "arc.h" + +class Backend; + +class reflexChain{ + Real2 *queue; + /*the order of the polygon vertices: either q[0],q[1].., or + * q[n-1], q[n-2], ..., q[0] + *this order determines the interior of the polygon, so it + *also used to determines whether a chain is reflex or convex + */ + Int isIncreasing; + Int index_queue; + Int size_queue; /*allocated size*/ + +public: + reflexChain(Int size, Int isIncreasing); + ~reflexChain(); + + void insert(Real u, Real v); + void insert(Real v[2]); + + void processNewVertex(Real v[2], primStream* pStream); + void outputFan(Real v[2], primStream* pStream); + + void processNewVertex(Real v[2], Backend* backend); + void outputFan(Real v[2], Backend* backend); + + void print(); +}; + +/*dynamic array of pointers to reals. + *Intended to store an array of (u,v). + *Notice that it doesn't allocate or dealocate the space + *for the (u,v) themselfs. So it assums that someone else + *is taking care of them, while this class only plays with + *the pointers. + */ +class vertexArray{ + Real** array; + Int index; + Int size; +public: + vertexArray(Int s); + vertexArray(Real vertices[][2], Int nVertices); + ~vertexArray(); + void appendVertex(Real* ptr); /*the content (pointed by ptr is NOT copied*/ + Real* getVertex(Int i) {return array[i];} + Real** getArray() {return array;} + Int getNumElements() {return index;} + Int findIndexAbove(Real v); + Int findIndexAboveGen(Real v, Int startIndex, Int EndIndex); + Int findIndexBelowGen(Real v, Int startIndex, Int EndIndex); + Int findIndexStrictBelowGen(Real v, Int startIndex, Int EndIndex); + Int findIndexFirstAboveEqualGen(Real v, Int startIndex, Int endIndex); + Int skipEqualityFromStart(Real v, Int start, Int end); + //return i such that fron [i+1, end] is strictly U-monotone (left to right + Int findDecreaseChainFromEnd(Int begin, Int end); + void print(); +}; + +void monoTriangulation(directedLine* monoPolygon, primStream* pStream); + +void monoTriangulationRec(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, + vertexArray* dec_chain, Int dec_current, + primStream* pStream); + +void monoTriangulationRec(directedLine* inc_chain, Int inc_index, + directedLine* dec_chain, Int dec_index, + directedLine* topVertex, Int top_index, + directedLine* botVertex, + primStream* pStream); + +/*the chain could be increasing or decreasing, although we use the + * name inc_chain. + *the argument is_increase_chain indicates whether this chain + *is increasing (left chain in V-monotone case) or decreaing (right chain + *in V-monotone case). + */ +void monoTriangulation2(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_smallIndex, + Int inc_largeIndex, + Int is_increase_chain, + primStream* pStream); +void monoTriangulationRecGen(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, Int inc_end, + vertexArray* dec_chain, Int dec_current, Int dec_end, + primStream* pStream); + +void monoTriangulationRecGenOpt(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, Int inc_end, + vertexArray* dec_chain, Int dec_current, Int dec_end, + primStream* pStream); + +void triangulateXYMonoTB(Int n_left, Real** leftVerts, + Int n_right, Real** rightVerts, + primStream* pStream); + +void monoTriangulationRecGenTBOpt(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, Int inc_end, + vertexArray* dec_chain, Int dec_current, Int dec_end, + primStream* pStream); + +void monoTriangulationRecOpt(Real* topVertex, Real* botVertex, + vertexArray* left_chain, Int left_current, + vertexArray* right_chain, Int right_current, + primStream* pStream); + +void monoTriangulationRecFunGen(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, Int inc_end, + vertexArray* dec_chain, Int dec_current, Int dec_end, + Int (*compFun)(Real*, Real*), + primStream* pStream); + +void monoTriangulationRecFun(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, + vertexArray* dec_chain, Int dec_current, + Int (*compFun)(Real*, Real*), + primStream* pStream); +void monoTriangulationFun(directedLine* monoPolygon, + Int (*compFun)(Real*, Real*), primStream* pStream); + + + + +void monoTriangulationRec(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, + vertexArray* dec_chain, Int dec_current, + Backend* backend); + +void monoTriangulationFunBackend(Arc_ptr loop, Int (*compFun)(Real*, Real*), Backend* backend); + +void monoTriangulationRecFunBackend(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, + vertexArray* dec_chain, Int dec_current, + Int (*compFun)(Real*, Real*), + Backend* backend); + +void monoTriangulationOpt(directedLine* poly, primStream* pStream); + +#endif + + + + diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/mystdio.h b/mesalib/src/glu/sgi/libnurbs/nurbtess/mystdio.h new file mode 100644 index 000000000..a394e0ff9 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/mystdio.h @@ -0,0 +1,60 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * mystdio.h + * + */ + +#ifndef __glumystdio_h_ +#define __glumystdio_h_ + +#ifdef STANDALONE +inline void _glu_dprintf( char *, ... ) { } +#endif + +#ifdef LIBRARYBUILD +#ifndef NDEBUG +#include <stdio.h> +#define _glu_dprintf printf +#else +inline void _glu_dprintf( char *, ... ) { } +#endif +#endif + +#ifdef GLBUILD +inline void _glu_dprintf( char *, ... ) { } +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#endif /* __glumystdio_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/mystdlib.h b/mesalib/src/glu/sgi/libnurbs/nurbtess/mystdlib.h new file mode 100644 index 000000000..ab7a3b273 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/mystdlib.h @@ -0,0 +1,57 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +/* + * mystdlib.h + * + */ + +#ifndef __glumystdlib_h_ +#define __glumystdlib_h_ + +#ifdef STANDALONE +typedef unsigned int size_t; +extern "C" void abort( void ); +extern "C" void * malloc( size_t ); +extern "C" void free( void * ); +#endif + +#ifdef LIBRARYBUILD +#include <stdlib.h> +#endif + +#ifdef GLBUILD +typedef unsigned int size_t; +extern "C" void abort( void ); +extern "C" void * malloc( size_t ); +extern "C" void free( void * ); +#endif + +#endif /* __glumystdlib_h_ */ diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/partitionX.cc b/mesalib/src/glu/sgi/libnurbs/nurbtess/partitionX.cc new file mode 100644 index 000000000..e25e30b0f --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/partitionX.cc @@ -0,0 +1,162 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include <stdlib.h> +#include <stdio.h> + +#include "partitionX.h" + +#define CONCAVITY_ZERO 1.0e-6 //this number is used to test whether a vertex is concave (refelx) + //or not. The test needs to compute the area of the three adjacent + //vertices to see if the are is positive or negative. + +Int isCuspX(directedLine *v) +{ + //if v->prev <= v && v->next <= v + //|| v->prev >= v && v->next >= v + Real* T = v->head(); + Real* P = v->getPrev()->head(); + Real* N = v->getNext()->head(); + if( + (compV2InX(T,P) != -1 && + compV2InX(T,N) != -1 + ) || + (compV2InX(T,P) != 1 && + compV2InX(T,N) != 1 + ) + ) + return 1; + else + return 0; +} + +Int isReflexX(directedLine* v) +{ + Real* A = v->getPrev()->head(); + Real* B = v->head(); + Real* C = v->tail(); + Real Bx,By, Cx, Cy; + //scale them in case they are too small + Bx = 10*(B[0] - A[0]); + By = 10*(B[1] - A[1]); + Cx = 10*(C[0] - A[0]); + Cy = 10*(C[1] - A[1]); + + if(Bx*Cy - Cx*By < -CONCAVITY_ZERO) return 1; + else return 0; +} + + +/*return + *0: not-cusp + *1: interior cusp + *2: exterior cusp + */ +Int cuspTypeX(directedLine *v) +{ + if(! isCuspX(v)) return 0; + else + { +//printf("isCusp,%f,%f\n", v->head()[0], v->head()[1]); + if(isReflexX(v)) + { +// printf("isReflex\n"); + return 1; + } + else + { +// printf("not isReflex\n"); + return 2; + } + } +} + +Int numInteriorCuspsX(directedLine *polygon) +{ + directedLine *temp; + int ret = 0; + if(cuspTypeX(polygon) == 1) + ret++; + for(temp = polygon->getNext(); temp != polygon; temp = temp->getNext()) + if(cuspTypeX(temp) == 1) + ret++; + return ret; +} + + +void findInteriorCuspsX(directedLine *polygon, Int& ret_n_interior_cusps, + directedLine** ret_interior_cusps) +{ + directedLine *temp; + ret_n_interior_cusps = 0; + if(cuspTypeX(polygon) == 1) + { + ret_interior_cusps[ret_n_interior_cusps++] = polygon; + } + for(temp = polygon->getNext(); temp != polygon; temp = temp->getNext()) + if(cuspTypeX(temp) == 1) + { + ret_interior_cusps[ret_n_interior_cusps++] = temp; + } +} + +directedLine* findDiagonal_singleCuspX(directedLine* cusp) +{ + directedLine* temp; + Int is_minimal = ((compV2InX(cusp->head(), cusp->tail()) == -1)? 1:0); + + if(is_minimal) + for(temp = cusp->getNext(); temp != cusp; temp = temp->getNext()) + { + if(compV2InX(cusp->head(), temp->head()) == 1) + { + return temp; + } + } + else //is maxmal + for(temp = cusp->getNext(); temp != cusp; temp = temp->getNext()) + { + if(compV2InX(cusp->head(), temp->head()) == -1) + { + return temp; + } + } + return NULL; +} + + + diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/partitionX.h b/mesalib/src/glu/sgi/libnurbs/nurbtess/partitionX.h new file mode 100644 index 000000000..69f2b2df2 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/partitionX.h @@ -0,0 +1,54 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ +/* +*/ + +#ifndef _PARTITIONX_H +#define _PARTITIONX_H + +#include "directedLine.h" + +Int isCuspX(directedLine *v); +Int isReflexX(directedLine *v); +Int cuspTypeX(directedLine *v); + +//assuming the array of ret_interior_cusps has been allocated +void findInteriorCuspsX(directedLine* polygon, Int& ret_n_interior_cusps, + directedLine** ret_interior_cusps); + +Int numInteriorCuspsX(directedLine* polygon); + +/*a single polygon with a single cusp + *return the diagonal vertex corresponding to this cusp + */ +directedLine* findDiagonal_singleCuspX(directedLine* cusp); + +#endif + diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/partitionY.cc b/mesalib/src/glu/sgi/libnurbs/nurbtess/partitionY.cc new file mode 100644 index 000000000..297c62997 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/partitionY.cc @@ -0,0 +1,836 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <time.h> + +#include "zlassert.h" +#include "partitionY.h" +#include "searchTree.h" +#include "quicksort.h" +#include "polyUtil.h" + + +#define max(a,b) ((a>b)? a:b) +#define min(a,b) ((a>b)? b:a) + + +/*retrurn + *-1: if A < B (Ya<Yb) || (Ya==Yb) + * 0: if A == B + * 1: if A>B + */ +static Int compVertInY(Real A[2], Real B[2]) +{ + if( (A[1] < B[1]) || (A[1]==B[1] && A[0]<B[0])) + return -1; + else if + ( A[1] == B[1] && A[0] == B[0]) return 0; + else + return 1; +} + +/*v is a vertex: the head of en edge, + *e is an edge, + *return 1 if e is below v: assume v1 and v2 are the two endpoints of e: + * v1<= v, v2<=v. + */ +Int isBelow(directedLine *v, directedLine *e) +{ + Real* vert = v->head(); + if( compVertInY(e->head(), vert) != 1 + && compVertInY(e->tail(), vert) != 1 + ) + return 1; + else + return 0; +} + +/*v is a vertex: the head of en edge, + *e is an edge, + *return 1 if e is below v: assume v1 and v2 are the two endpoints of e: + * v1>= v, v2>=v. + */ +Int isAbove(directedLine *v, directedLine *e) +{ + Real* vert = v->head(); + if( compVertInY(e->head(), vert) != -1 + && compVertInY(e->tail(), vert) != -1 + ) + return 1; + else + return 0; +} + +Int isCusp(directedLine *v) +{ + Real *A=v->getPrev()->head(); + Real *B=v->head(); + Real *C=v->tail(); + if(A[1] < B[1] && B[1] < C[1]) + return 0; + else if(A[1] > B[1] && B[1] > C[1]) + return 0; + else if(A[1] < B[1] && C[1] < B[1]) + return 1; + else if(A[1] > B[1] && C[1] > B[1]) + return 1; + + if(isAbove(v, v) && isAbove(v, v->getPrev()) || + isBelow(v, v) && isBelow(v, v->getPrev())) + return 1; + else + return 0; +} + +/*crossproduct is strictly less than 0*/ +Int isReflex(directedLine *v) +{ + Real* A = v->getPrev()->head(); + Real* B = v->head(); + Real* C = v->tail(); + Real Bx,By, Cx, Cy; + Bx = B[0] - A[0]; + By = B[1] - A[1]; + Cx = C[0] - A[0]; + Cy = C[1] - A[1]; + + if(Bx*Cy - Cx*By < 0) return 1; + else return 0; +} + + /*return + *0: not-cusp + *1: interior cusp + *2: exterior cusp + */ +Int cuspType(directedLine *v) +{ + if(! isCusp(v)) return 0; + else if(isReflex(v)) return 1; + else + return 2; +} + +sweepRange* sweepRangeMake(directedLine* left, Int leftType, + directedLine* right, Int rightType) +{ + sweepRange* ret = (sweepRange*)malloc(sizeof(sweepRange)); + assert(ret); + ret->left = left; + ret->leftType = leftType; + ret->right = right; + ret->rightType = rightType; + return ret; +} + +void sweepRangeDelete(sweepRange* range) +{ + free(range); +} + +Int sweepRangeEqual(sweepRange* src1, sweepRange* src2) +{ + Int leftEqual; + Int rightEqual; + + + /*The case when both are vertices should not happen*/ + assert(! (src1->leftType == 0 && src2->leftType == 0)); + if(src1->leftType == 0 && src2->leftType == 1){ + if(src1->left == src2->left || + src1->left->getPrev() == src2->left + ) + leftEqual = 1; + else + leftEqual = 0; + } + else if(src1->leftType == 1 && src2->leftType == 1){ + if(src1->left == src2->left) + leftEqual = 1; + else + leftEqual = 0; + } + else /*src1->leftType == 1 && src2->leftType == 0*/{ + if(src1->left == src2->left || + src1->left == src2->left->getPrev() + ) + leftEqual = 1; + else + leftEqual = 0; + } + + /*the same thing for right*/ + /*The case when both are vertices should not happen*/ + assert(! (src1->rightType == 0 && src2->rightType == 0)); + if(src1->rightType == 0 && src2->rightType == 1){ + if(src1->right == src2->right || + src1->right->getPrev() == src2->right + ) + rightEqual = 1; + else + rightEqual = 0; + } + else if(src1->rightType == 1 && src2->rightType == 1){ + if(src1->right == src2->right) + rightEqual = 1; + else + rightEqual = 0; + } + else /*src1->rightType == 1 && src2->rightType == 0*/{ + if(src1->right == src2->right || + src1->right == src2->right->getPrev() + ) + rightEqual = 1; + else + rightEqual = 0; + } + + return (leftEqual == 1 || rightEqual == 1); +} + +/*given (x_1, y_1) and (x_2, y_2), and y + *return x such that (x,y) is on the line + */ +inline/*static*/ Real intersectHoriz(Real x1, Real y1, Real x2, Real y2, Real y) +{ + return ((y2==y1)? (x1+x2)*Real(0.5) : x1 + ((y-y1)/(y2-y1)) * (x2-x1)); +/* + if(y2 == y1) return (x1+x2)*0.5; + else return x1 + ((y-y1)/(y2-y1)) * (x2-x1); +*/ +} + +/*compare two edges of a polygon. + *edge A < edge B if there is a horizontal line so that the intersection + *with A is to the left of the intersection with B. + *This function is used in sweepY for the dynamic search tree insertion to + *order the edges. + * Implementation: (x_1,y_1) and (x_2, y_2) + */ +static Int compEdges(directedLine *e1, directedLine *e2) +{ + Real* head1 = e1->head(); + Real* tail1 = e1->tail(); + Real* head2 = e2->head(); + Real* tail2 = e2->tail(); +/* + Real h10 = head1[0]; + Real h11 = head1[1]; + Real t10 = tail1[0]; + Real t11 = tail1[1]; + Real h20 = head2[0]; + Real h21 = head2[1]; + Real t20 = tail2[0]; + Real t21 = tail2[1]; +*/ + Real e1_Ymax, e1_Ymin, e2_Ymax, e2_Ymin; +/* + if(h11>t11) { + e1_Ymax= h11; + e1_Ymin= t11; + } + else{ + e1_Ymax = t11; + e1_Ymin = h11; + } + + if(h21>t21) { + e2_Ymax= h21; + e2_Ymin= t21; + } + else{ + e2_Ymax = t21; + e2_Ymin = h21; + } +*/ + + if(head1[1]>tail1[1]) { + e1_Ymax= head1[1]; + e1_Ymin= tail1[1]; + } + else{ + e1_Ymax = tail1[1]; + e1_Ymin = head1[1]; + } + + if(head2[1]>tail2[1]) { + e2_Ymax= head2[1]; + e2_Ymin= tail2[1]; + } + else{ + e2_Ymax = tail2[1]; + e2_Ymin = head2[1]; + } + + + /*Real e1_Ymax = max(head1[1], tail1[1]);*/ /*max(e1->head()[1], e1->tail()[1]);*/ + /*Real e1_Ymin = min(head1[1], tail1[1]);*/ /*min(e1->head()[1], e1->tail()[1]);*/ + /*Real e2_Ymax = max(head2[1], tail2[1]);*/ /*max(e2->head()[1], e2->tail()[1]);*/ + /*Real e2_Ymin = min(head2[1], tail2[1]);*/ /*min(e2->head()[1], e2->tail()[1]);*/ + + Real Ymax = min(e1_Ymax, e2_Ymax); + Real Ymin = max(e1_Ymin, e2_Ymin); + + Real y = Real(0.5)*(Ymax + Ymin); + +/* Real x1 = intersectHoriz(e1->head()[0], e1->head()[1], e1->tail()[0], e1->tail()[1], y); + Real x2 = intersectHoriz(e2->head()[0], e2->head()[1], e2->tail()[0], e2->tail()[1], y); +*/ +/* + Real x1 = intersectHoriz(h10, h11, t10, t11, y); + Real x2 = intersectHoriz(h20, h21, t20, t21, y); +*/ + Real x1 = intersectHoriz(head1[0], head1[1], tail1[0], tail1[1], y); + Real x2 = intersectHoriz(head2[0], head2[1], tail2[0], tail2[1], y); + + if(x1<= x2) return -1; + else return 1; +} + +/*used by sort precedures + */ +static Int compInY(directedLine* v1, directedLine* v2) +{ + return v1->compInY(v2); +} + +void findDiagonals(Int total_num_edges, directedLine** sortedVertices, sweepRange** ranges, Int& num_diagonals, directedLine** diagonal_vertices) +{ + Int i,j,k; + + k=0; + + for(i=0; i<total_num_edges; i++) + { + directedLine* vert =sortedVertices[i]; + directedLine* thisEdge = vert; + directedLine* prevEdge = vert->getPrev(); +/* +printf("find i=%i\n", i); +printf("the vertex is\n"); +vert->printSingle(); +*/ + if(isBelow(vert, thisEdge) && isBelow(vert, prevEdge) && compEdges(prevEdge, thisEdge)<0) + { + /*this is an upward interior cusp*/ + diagonal_vertices[k++] = vert; + + for(j=i+1; j<total_num_edges; j++) + if(sweepRangeEqual(ranges[i], ranges[j])) + { + diagonal_vertices[k++] = sortedVertices[j]; + break; + } + assert(j<total_num_edges); + + + } + else if(isAbove(vert, thisEdge) && isAbove(vert, prevEdge) && compEdges(prevEdge, thisEdge)>0) + { + /*this is an downward interior cusp*/ + diagonal_vertices[k++] = vert; + for(j=i-1; j>=0; j--) + if(sweepRangeEqual(ranges[i], ranges[j])) + { + diagonal_vertices[k++] = sortedVertices[j]; + break; + } +/* printf("j=%i\n", j);*/ + assert(j>=0); + + + + } + } + num_diagonals = k/2; +} + +/*get rid of repeated diagonlas so that each diagonal appears only once in the array + */ +Int deleteRepeatDiagonals(Int num_diagonals, directedLine** diagonal_vertices, directedLine** new_vertices) +{ + Int i,k; + Int j,l; + Int index; + index=0; + for(i=0,k=0; i<num_diagonals; i++, k+=2) + { + Int isRepeated=0; + /*check the diagonla (diagonal_vertice[k], diagonal_vertices[k+1]) + *is repeated or not + */ + for(j=0,l=0; j<index; j++, l+=2) + { + if( + (diagonal_vertices[k] == new_vertices[l] && + diagonal_vertices[k+1] == new_vertices[l+1] + ) + || + ( + diagonal_vertices[k] == new_vertices[l+1] && + diagonal_vertices[k+1] == new_vertices[l] + ) + ) + { + isRepeated=1; + break; + } + } + if(! isRepeated) + { + new_vertices[index+index] = diagonal_vertices[k]; + new_vertices[index+index+1] = diagonal_vertices[k+1]; + index++; + } + } + return index; +} + +/*for debug only*/ +directedLine** DBGfindDiagonals(directedLine *polygons, Int& num_diagonals) +{ + Int total_num_edges = 0; + directedLine** array = polygons->toArrayAllPolygons(total_num_edges); + quicksort( (void**)array, 0, total_num_edges-1, (Int (*)(void*, void*)) compInY); + sweepRange** ranges = (sweepRange**) malloc(sizeof(sweepRange*) * total_num_edges); + assert(ranges); + + sweepY(total_num_edges, array, ranges); + + directedLine** diagonal_vertices = (directedLine**) malloc(sizeof(directedLine*) * total_num_edges); + assert(diagonal_vertices); + findDiagonals(total_num_edges, array, ranges, num_diagonals, diagonal_vertices); + + num_diagonals=deleteRepeatDiagonals(num_diagonals, diagonal_vertices, diagonal_vertices); + return diagonal_vertices; + +} + + +/*partition into Y-monotone polygons*/ +directedLine* partitionY(directedLine *polygons, sampledLine **retSampledLines) +{ + Int total_num_edges = 0; + directedLine** array = polygons->toArrayAllPolygons(total_num_edges); + + quicksort( (void**)array, 0, total_num_edges-1, (Int (*)(void*, void*)) compInY); + + sweepRange** ranges = (sweepRange**) malloc(sizeof(sweepRange*) * (total_num_edges)); + assert(ranges); + + + + sweepY(total_num_edges, array, ranges); + + + + /*the diagonal vertices are stored as: + *v0-v1: 1st diagonal + *v2-v3: 2nd diagonal + *v5-v5: 3rd diagonal + *... + */ + + + Int num_diagonals; + /*number diagonals is < total_num_edges*total_num_edges*/ + directedLine** diagonal_vertices = (directedLine**) malloc(sizeof(directedLine*) * total_num_edges*2/*total_num_edges*/); + assert(diagonal_vertices); + + + + findDiagonals(total_num_edges, array, ranges, num_diagonals, diagonal_vertices); + + + + directedLine* ret_polygons = polygons; + sampledLine* newSampledLines = NULL; + Int i,k; + +num_diagonals=deleteRepeatDiagonals(num_diagonals, diagonal_vertices, diagonal_vertices); + + + + Int *removedDiagonals=(Int*)malloc(sizeof(Int) * num_diagonals); + for(i=0; i<num_diagonals; i++) + removedDiagonals[i] = 0; + + + + + + for(i=0,k=0; i<num_diagonals; i++,k+=2) + { + + + directedLine* v1=diagonal_vertices[k]; + directedLine* v2=diagonal_vertices[k+1]; + directedLine* ret_p1; + directedLine* ret_p2; + + /*we ahve to determine whether v1 and v2 belong to the same polygon before + *their structure are modified by connectDiagonal(). + */ +/* + directedLine *root1 = v1->findRoot(); + directedLine *root2 = v2->findRoot(); + assert(root1); + assert(root2); +*/ + +directedLine* root1 = v1->rootLinkFindRoot(); +directedLine* root2 = v2->rootLinkFindRoot(); + + if(root1 != root2) + { + + removedDiagonals[i] = 1; + sampledLine* generatedLine; + + + + v1->connectDiagonal(v1,v2, &ret_p1, &ret_p2, &generatedLine, ret_polygons); + + + + newSampledLines = generatedLine->insert(newSampledLines); +/* + ret_polygons = ret_polygons->cutoffPolygon(root1); + + ret_polygons = ret_polygons->cutoffPolygon(root2); + ret_polygons = ret_p1->insertPolygon(ret_polygons); +root1->rootLinkSet(ret_p1); +root2->rootLinkSet(ret_p1); +ret_p1->rootLinkSet(NULL); +ret_p2->rootLinkSet(ret_p1); +*/ + ret_polygons = ret_polygons->cutoffPolygon(root2); + + + +root2->rootLinkSet(root1); +ret_p1->rootLinkSet(root1); +ret_p2->rootLinkSet(root1); + + /*now that we have connected the diagonal v1 and v2, + *we have to check those unprocessed diagonals which + *have v1 or v2 as an end point. Notice that the head of v1 + *has the same coodinates as the head of v2->prev, and the head of + *v2 has the same coordinate as the head of v1->prev. + *Suppose these is a diagonal (v1, x). If (v1,x) is still a valid + *diagonal, then x should be on the left hand side of the directed line: *v1->prev->head -- v1->head -- v1->tail. Otherwise, (v1,x) should be + *replaced by (v2->prev, x), that is, x is on the left of + * v2->prev->prev->head, v2->prev->head, v2->prev->tail. + */ + Int ii, kk; + for(ii=0, kk=0; ii<num_diagonals; ii++, kk+=2) + if( removedDiagonals[ii]==0) + { + directedLine* d1=diagonal_vertices[kk]; + directedLine* d2=diagonal_vertices[kk+1]; + /*check d1, and replace diagonal_vertices[kk] if necessary*/ + if(d1 == v1) { + /*check if d2 is to left of v1->prev->head:v1->head:v1->tail*/ + if(! pointLeft2Lines(v1->getPrev()->head(), + v1->head(), v1->tail(), d2->head())) + { +/* + assert(pointLeft2Lines(v2->getPrev()->getPrev()->head(), + v2->getPrev()->head(), + v2->getPrev()->tail(), d2->head())); +*/ + diagonal_vertices[kk] = v2->getPrev(); + } + } + if(d1 == v2) { + /*check if d2 is to left of v2->prev->head:v2->head:v2->tail*/ + if(! pointLeft2Lines(v2->getPrev()->head(), + v2->head(), v2->tail(), d2->head())) + { +/* + assert(pointLeft2Lines(v1->getPrev()->getPrev()->head(), + v1->getPrev()->head(), + v1->getPrev()->tail(), d2->head())); +*/ + diagonal_vertices[kk] = v1->getPrev(); + } + } + /*check d2 and replace diagonal_vertices[k+1] if necessary*/ + if(d2 == v1) { + /*check if d1 is to left of v1->prev->head:v1->head:v1->tail*/ + if(! pointLeft2Lines(v1->getPrev()->head(), + v1->head(), v1->tail(), d1->head())) + { +/* assert(pointLeft2Lines(v2->getPrev()->getPrev()->head(), + v2->getPrev()->head(), + v2->getPrev()->tail(), d1->head())); +*/ + diagonal_vertices[kk+1] = v2->getPrev(); + } + } + if(d2 == v2) { + /*check if d1 is to left of v2->prev->head:v2->head:v2->tail*/ + if(! pointLeft2Lines(v2->getPrev()->head(), + v2->head(), v2->tail(), d1->head())) + { +/* assert(pointLeft2Lines(v1->getPrev()->getPrev()->head(), + v1->getPrev()->head(), + v1->getPrev()->tail(), d1->head())); +*/ + diagonal_vertices[kk+1] = v1->getPrev(); + } + } + } +}/*end if (root1 not equal to root 2)*/ +} + + /*second pass, now all diagoals should belong to the same polygon*/ + + + + for(i=0,k=0; i<num_diagonals; i++, k += 2) + if(removedDiagonals[i] == 0) + { + + + directedLine* v1=diagonal_vertices[k]; + directedLine* v2=diagonal_vertices[k+1]; + + + + directedLine* ret_p1; + directedLine* ret_p2; + + /*we ahve to determine whether v1 and v2 belong to the same polygon before + *their structure are modified by connectDiagonal(). + */ + directedLine *root1 = v1->findRoot(); +/* + directedLine *root2 = v2->findRoot(); + + + + assert(root1); + assert(root2); + assert(root1 == root2); + */ + sampledLine* generatedLine; + + + + v1->connectDiagonal(v1,v2, &ret_p1, &ret_p2, &generatedLine, ret_polygons); + newSampledLines = generatedLine->insert(newSampledLines); + + ret_polygons = ret_polygons->cutoffPolygon(root1); + + ret_polygons = ret_p1->insertPolygon(ret_polygons); + + ret_polygons = ret_p2->insertPolygon(ret_polygons); + + + + for(Int j=i+1; j<num_diagonals; j++) + { + if(removedDiagonals[j] ==0) + { + + directedLine* temp1=diagonal_vertices[2*j]; + directedLine* temp2=diagonal_vertices[2*j+1]; + if(temp1==v1 || temp1==v2 || temp2==v1 || temp2==v2) + if(! temp1->samePolygon(temp1, temp2)) + { + /*if temp1 and temp2 are in different polygons, + *then one of them must be v1 or v2. + */ + + + + assert(temp1==v1 || temp1 == v2 || temp2==v1 || temp2 ==v2); + if(temp1==v1) + { + diagonal_vertices[2*j] = v2->getPrev(); + } + if(temp2==v1) + { + diagonal_vertices[2*j+1] = v2->getPrev(); + } + if(temp1==v2) + { + diagonal_vertices[2*j] = v1->getPrev(); + } + if(temp2==v2) + { + diagonal_vertices[2*j+1] = v1->getPrev(); + } + } + } + } + + } + + /*clean up spaces*/ + free(array); + free(ranges); + free(diagonal_vertices); + free(removedDiagonals); + + *retSampledLines = newSampledLines; + return ret_polygons; +} + +/*given a set of simple polygons where the interior + *is decided by left-hand principle, + *return a range (sight) for each vertex. This is called + *Trapezoidalization. + */ +void sweepY(Int nVertices, directedLine** sortedVertices, sweepRange** ret_ranges) +{ + Int i; + /*for each vertex in the sorted list, update the binary search tree. + *and store the range information for each vertex. + */ + treeNode* searchTree = NULL; + for(i=0; i<nVertices;i++) + { + + directedLine* vert = sortedVertices[i]; + + directedLine* thisEdge = vert; + directedLine* prevEdge = vert->getPrev(); + + if(isBelow(vert, thisEdge) && isAbove(vert, prevEdge)) + { + + /*case 1: this < v < prev + *the polygon is going down at v, the interior is to + *the right hand side. + * find the edge to the right of thisEdge for right range. + * delete thisEdge + * insert prevEdge + */ + treeNode* thisNode = TreeNodeFind(searchTree, thisEdge, ( Int (*) (void *, void *))compEdges); + assert(thisNode); + + treeNode* succ = TreeNodeSuccessor(thisNode); + assert(succ); + searchTree = TreeNodeDeleteSingleNode(searchTree, thisNode); + searchTree = TreeNodeInsert(searchTree, TreeNodeMake(prevEdge), ( Int (*) (void *, void *))compEdges); + + + ret_ranges[i] = sweepRangeMake(vert, 0, (directedLine*) (succ->key), 1); + + } + else if(isAbove(vert, thisEdge) && isBelow(vert, prevEdge)) + { + + /*case 2: this > v > prev + *the polygon is going up at v, the interior is to + *the left hand side. + * find the edge to the left of thisEdge for left range. + * delete prevEdge + * insert thisEdge + */ + treeNode* prevNode = TreeNodeFind(searchTree, prevEdge, ( Int (*) (void *, void *))compEdges); + assert(prevNode); + treeNode* pred = TreeNodePredecessor(prevNode); + searchTree = TreeNodeDeleteSingleNode(searchTree, prevNode); + searchTree = TreeNodeInsert(searchTree, TreeNodeMake(thisEdge), ( Int (*) (void *, void *))compEdges); + ret_ranges[i] = sweepRangeMake((directedLine*)(pred->key), 1, vert, 0); + } + else if(isAbove(vert, thisEdge) && isAbove(vert, prevEdge)) + { + + /*case 3: insert both edges*/ + treeNode* thisNode = TreeNodeMake(thisEdge); + treeNode* prevNode = TreeNodeMake(prevEdge); + searchTree = TreeNodeInsert(searchTree, thisNode, ( Int (*) (void *, void *))compEdges); + searchTree = TreeNodeInsert(searchTree, prevNode, ( Int (*) (void *, void *))compEdges); + if(compEdges(thisEdge, prevEdge)<0) /*interior cusp*/ + { + + treeNode* leftEdge = TreeNodePredecessor(thisNode); + treeNode* rightEdge = TreeNodeSuccessor(prevNode); + ret_ranges[i] = sweepRangeMake( (directedLine*) leftEdge->key, 1, + (directedLine*) rightEdge->key, 1 + ); + } + else /*exterior cusp*/ + { + + ret_ranges[i] = sweepRangeMake( prevEdge, 1, thisEdge, 1); + } + } + else if(isBelow(vert, thisEdge) && isBelow(vert, prevEdge)) + { + + /*case 4: delete both edges*/ + treeNode* thisNode = TreeNodeFind(searchTree, thisEdge, ( Int (*) (void *, void *))compEdges); + treeNode* prevNode = TreeNodeFind(searchTree, prevEdge, ( Int (*) (void *, void *))compEdges); + if(compEdges(thisEdge, prevEdge)>0) /*interior cusp*/ + { + treeNode* leftEdge = TreeNodePredecessor(prevNode); + treeNode* rightEdge = TreeNodeSuccessor(thisNode); + ret_ranges[i] = sweepRangeMake( (directedLine*) leftEdge->key, 1, + (directedLine*) rightEdge->key, 1 + ); + } + else /*exterior cusp*/ + { + ret_ranges[i] = sweepRangeMake( thisEdge, 1, prevEdge, 1); + } + searchTree = TreeNodeDeleteSingleNode(searchTree, thisNode); + searchTree = TreeNodeDeleteSingleNode(searchTree, prevNode); + } + else + { + fprintf(stderr,"error in partitionY.C, invalid case\n"); + printf("vert is\n"); + vert->printSingle(); + printf("thisEdge is\n"); + thisEdge->printSingle(); + printf("prevEdge is\n"); + prevEdge->printSingle(); + + exit(1); + } + } + + /*finaly clean up space: delete the search tree*/ + TreeNodeDeleteWholeTree(searchTree); +} diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/partitionY.h b/mesalib/src/glu/sgi/libnurbs/nurbtess/partitionY.h new file mode 100644 index 000000000..8dda409de --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/partitionY.h @@ -0,0 +1,97 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ +/* + *partitionY.h: + *partition a polygon into a Y-monotone polygon: + * A polygon is Y-monotone if the boundary can be split into two polygon chains + *A and B such that each chain is Y-monotonic that is the intersection of any + *horizontal line intersects each chain has at most one connected componenets + * (empty, single point or a single line). + * + * A vertex is a cusp if both its ajacent vertices are either at or above v, + *or both at or below v. In addition, at least one of the ajacent verteces is + *strictly below or above v. + * A vertex is a relex vertex if the internals angle is strictly greater than + *180. In other words, if the the signed area is negative: + *(x1, y1), (x2, y2), (x3, y3) are the three vertices along a polygon, the + *order is such that left hand side is inside the polygon. Then (x2,y2) is + *reflex if: + * (x2-x1, y2-y1) cross (x3-x1, y3-y1) <0. + *A vertex is an interior cusp if it is a cusp and a reflex. + *A vertex is an exterior cusp if it is a cusp but not a reflex. + * + */ + +#ifndef _PARTITIONY_H +#define _PARTITIONY_H + +#include "directedLine.h" + +/*whether an edge is below a vertex*/ +Int isBelow(directedLine *v, directedLine *e); + +/*whether an edge is above a vertex*/ +Int isAbove(directedLine *v, directedLine *e); + +/*not-cusp, + *inerior cusp + *exterior cusp + */ +Int cuspType(directedLine *v); + +/*used in trapezoidalization*/ +typedef struct sweepRange{ + directedLine *left; + Int leftType; /*either a vertex (leftType=0) or an edge (leftType =1) */ + directedLine *right; + Int rightType; /*either a vertex (rightType=0) or an edge (rightType =1) */ +} sweepRange; + +sweepRange* sweepRangeMake(directedLine* left, Int leftType, + directedLine* right, Int rightType); + +void sweepRangeDelete(sweepRange* range); +Int sweepRangeEqual(sweepRange* sr1, sweepRange* sr2); + +/*given a set of simple polygons where the interior + *is decided by left-hand principle, + *return a range (sight) for each vertex. This is called + *Trapezoidalization. + */ +void sweepY(Int nVertices, directedLine **sortedVerteces, sweepRange** ret_ranges); + + +directedLine* partitionY(directedLine *polygons, sampledLine **retSampledLines); + +void findDiagonals(Int total_num_edges, directedLine** sortedVertices, sweepRange** ranges, Int& num_diagonals, directedLine** diagonal_vertices); + +directedLine** DBGfindDiagonals(directedLine *polygons, Int& num_diagonals); + +#endif diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/polyDBG.cc b/mesalib/src/glu/sgi/libnurbs/nurbtess/polyDBG.cc new file mode 100644 index 000000000..4d04df73f --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/polyDBG.cc @@ -0,0 +1,734 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <math.h> +#include "zlassert.h" +#include "polyDBG.h" + +#ifdef __WATCOMC__ +#pragma warning 14 10 +#pragma warning 391 10 +#pragma warning 726 10 +#endif + +static Real area(Real A[2], Real B[2], Real C[2]) +{ + Real Bx, By, Cx, Cy; + Bx = B[0] - A[0]; + By = B[1] - A[1]; + Cx = C[0] - A[0]; + Cy = C[1] - A[1]; + return Bx*Cy - Cx*By; +} + +Int DBG_isConvex(directedLine *poly) +{ + directedLine* temp; + if(area(poly->head(), poly->tail(), poly->getNext()->tail()) < 0.00000) + return 0; + for(temp = poly->getNext(); temp != poly; temp = temp->getNext()) + { + if(area(temp->head(), temp->tail(), temp->getNext()->tail()) < 0.00000) + return 0; + } + return 1; +} + +Int DBG_is_U_monotone(directedLine* poly) +{ + Int n_changes = 0; + Int prev_sign; + Int cur_sign; + directedLine* temp; + cur_sign = compV2InX(poly->tail(), poly->head()); + + n_changes = (compV2InX(poly->getPrev()->tail(), poly->getPrev()->head()) + != cur_sign); + + for(temp = poly->getNext(); temp != poly; temp = temp->getNext()) + { + prev_sign = cur_sign; + cur_sign = compV2InX(temp->tail(), temp->head()); + + if(cur_sign != prev_sign) + n_changes++; + } + + if(n_changes ==2) return 1; + else return 0; +} + +/*if u-monotone, and there is a long horizontal edge*/ +Int DBG_is_U_direction(directedLine* poly) +{ +/* + if(! DBG_is_U_monotone(poly)) + return 0; +*/ + Int V_count = 0; + Int U_count = 0; + directedLine* temp; + if( fabs(poly->head()[0] - poly->tail()[0]) <= fabs(poly->head()[1]-poly->tail()[1])) + V_count += poly->get_npoints(); + else + U_count += poly->get_npoints(); + /* + else if(poly->head()[1] == poly->tail()[1]) + U_count += poly->get_npoints(); + */ + for(temp = poly->getNext(); temp != poly; temp = temp->getNext()) + { + if( fabs(temp->head()[0] - temp->tail()[0]) <= fabs(temp->head()[1]-temp->tail()[1])) + V_count += temp->get_npoints(); + else + U_count += temp->get_npoints(); + /* + if(temp->head()[0] == temp->tail()[0]) + V_count += temp->get_npoints(); + else if(temp->head()[1] == temp->tail()[1]) + U_count += temp->get_npoints(); + */ + } + + if(U_count > V_count) return 1; + else return 0; +} + +/*given two line segments, determine whether + *they intersect each other or not. + *return 1 if they do, + *return 0 otherwise + */ +Int DBG_edgesIntersect(directedLine* l1, directedLine* l2) +{ + if(l1->getNext() == l2) + { + if(area(l1->head(), l1->tail(), l2->tail()) == 0) //colinear + { + if( (l1->tail()[0] - l1->head()[0])*(l2->tail()[0]-l2->head()[0]) + + (l1->tail()[1] - l1->head()[1])*(l2->tail()[1]-l2->head()[1]) >=0) + return 0; //not intersect + else + return 1; + } + //else we use the normal code + } + else if(l1->getPrev() == l2) + { + if(area(l2->head(), l2->tail(), l1->tail()) == 0) //colinear + { + if( (l2->tail()[0] - l2->head()[0])*(l1->tail()[0]-l1->head()[0]) + + (l2->tail()[1] - l2->head()[1])*(l1->tail()[1]-l1->head()[1]) >=0) + return 0; //not intersect + else + return 1; + } + //else we use the normal code + } + else //the two edges are not connected + { + if((l1->head()[0] == l2->head()[0] && + l1->head()[1] == l2->head()[1]) || + (l1->tail()[0] == l2->tail()[0] && + l1->tail()[1] == l2->tail()[1])) + return 1; + + } + + + if( + ( + area(l1->head(), l1->tail(), l2->head()) + * + area(l1->head(), l1->tail(), l2->tail()) + < 0 + ) + && + ( + area(l2->head(), l2->tail(), l1->head()) + *area(l2->head(), l2->tail(), l1->tail()) + < 0 + ) + ) + return 1; + else + return 0; +} + +/*whether AB and CD intersect + *return 1 if they do + *retur 0 otheriwse + */ +Int DBG_edgesIntersectGen(Real A[2], Real B[2], Real C[2], Real D[2]) +{ + if( + ( + area(A, B, C) * area(A,B,D) <0 + ) + && + ( + area(C,D,A) * area(C,D,B) < 0 + ) + ) + return 1; + else + return 0; +} + +/*determien whether (A,B) interesect chain[start] to [end] + */ +Int DBG_intersectChain(vertexArray* chain, Int start, Int end, Real A[2], Real B[2]) +{ + Int i; + for(i=start; i<=end-2; i++) + if(DBG_edgesIntersectGen(chain->getVertex(i), chain->getVertex(i+1), A, B)) + return 1; + + return 0; +} + +/*determine whether a polygon intersect itself or not + *return 1 is it does, + * 0 otherwise + */ +Int DBG_polygonSelfIntersect(directedLine* poly) +{ + directedLine* temp1; + directedLine* temp2; + temp1=poly; + for(temp2=temp1->getNext(); temp2 != temp1; temp2=temp2->getNext()) + { + if(DBG_edgesIntersect(temp1, temp2)) + { + return 1; + } + + } + + for(temp1=poly->getNext(); temp1 != poly; temp1 = temp1->getNext()) + for(temp2=temp1->getNext(); temp2 != temp1; temp2=temp2->getNext()) + { + if(DBG_edgesIntersect(temp1, temp2)) + { + return 1; + } + } + return 0; +} + +/*check whether a line segment intersects a polygon + */ +Int DBG_edgeIntersectPoly(directedLine* edge, directedLine* poly) +{ + directedLine* temp; + if(DBG_edgesIntersect(edge, poly)) + return 1; + for(temp=poly->getNext(); temp != poly; temp=temp->getNext()) + if(DBG_edgesIntersect(edge, temp)) + return 1; + return 0; +} + +/*check whether two polygons intersect + */ +Int DBG_polygonsIntersect(directedLine* p1, directedLine* p2) +{ + directedLine* temp; + if(DBG_edgeIntersectPoly(p1, p2)) + return 1; + for(temp=p1->getNext(); temp!= p1; temp = temp->getNext()) + if(DBG_edgeIntersectPoly(temp, p2)) + return 1; + return 0; +} + +/*check whether there are polygons intersecting each other in + *a list of polygons + */ +Int DBG_polygonListIntersect(directedLine* pList) +{ + directedLine *temp; + for(temp=pList; temp != NULL; temp = temp->getNextPolygon()) + if(DBG_polygonSelfIntersect(temp)) + return 1; + directedLine* temp2; + for(temp=pList; temp!=NULL; temp=temp->getNextPolygon()) + { + for(temp2=temp->getNextPolygon(); temp2 != NULL; temp2=temp2->getNextPolygon()) + if(DBG_polygonsIntersect(temp, temp2)) + return 1; + } + + return 0; +} + + +Int DBG_isCounterclockwise(directedLine* poly) +{ + return (poly->polyArea() > 0); +} + +/*ray: v0 with direction (dx,dy). + *edge: v1-v2. + * the extra point v10[2] is given for the information at + *v1. Basically this edge is connectd to edge + * v10-v1. If v1 is on the ray, + * then we need v10 to determine whether this ray intersects + * the edge or not (that is, return 1 or return 0). + * If v1 is on the ray, then if v2 and v10 are on the same side of the ray, + * we return 0, otherwise return 1. + *For v2, if v2 is on the ray, we always return 0. + *Notice that v1 and v2 are not symmetric. So the edge is directed!!! + * The purpose for this convention is such that: a point is inside a polygon + * if and only if it intersets with odd number of edges. + */ +Int DBG_rayIntersectEdge(Real v0[2], Real dx, Real dy, Real v10[2], Real v1[2], Real v2[2]) +{ +/* +if( (v1[1] >= v0[1] && v2[1]<= v0[1] ) + ||(v2[1] >= v0[1] && v1[1]<= v0[1] ) + ) + printf("rayIntersectEdge, *********\n"); +*/ + + Real denom = (v2[0]-v1[0])*(-dy) - (v2[1]-v1[1]) * (-dx); + Real nomRay = (v2[0]-v1[0]) * (v0[1] - v1[1]) - (v2[1]-v1[1])*(v0[0]-v1[0]); + Real nomEdge = (v0[0]-v1[0]) * (-dy) - (v0[1]-v1[1])*(-dx); + + + /*if the ray is parallel to the edge, return 0: not intersect*/ + if(denom == 0.0) + return 0; + + /*if v0 is on the edge, return 0: not intersect*/ + if(nomRay == 0.0) + return 0; + + /*if v1 is on the positive ray, and the neighbor of v1 crosses the ray + *return 1: intersect + */ + if(nomEdge == 0) + { /*v1 is on the positive or negative ray*/ + +/* + printf("v1 is on the ray\n"); +*/ + + if(dx*(v1[0]-v0[0])>=0 && dy*(v1[1]-v0[1])>=0) /*v1 on positive ray*/ + { + if(area(v0, v1, v10) * area(v0, v1, v2) >0) + return 0; + else + return 1; + } + else /*v1 on negative ray*/ + return 0; + } + + /*if v2 is on the ray, always return 0: not intersect*/ + if(nomEdge == denom) { +/* printf("v2 is on the ray\n");*/ + return 0; + } + + /*finally */ + if(denom*nomRay>0 && denom*nomEdge>0 && nomEdge/denom <=1.0) + return 1; + return 0; +} + + +/*return the number of intersections*/ +Int DBG_rayIntersectPoly(Real v0[2], Real dx, Real dy, directedLine* poly) +{ + directedLine* temp; + Int count=0; + if(DBG_rayIntersectEdge(v0, dx, dy, poly->getPrev()->head(), poly->head(), poly->tail())) + count++; + + for(temp=poly->getNext(); temp != poly; temp = temp->getNext()) + if(DBG_rayIntersectEdge(v0, dx, dy, temp->getPrev()->head(), temp->head(), temp->tail())) + count++; +/*printf("ray intersect poly: count=%i\n", count);*/ + return count; +} + +Int DBG_pointInsidePoly(Real v[2], directedLine* poly) +{ +/* +printf("enter pointInsidePoly , v=(%f,%f)\n", v[0], v[1]); +printf("the polygon is\n"); +poly->printList(); +*/ + /*for debug purpose*/ + assert( (DBG_rayIntersectPoly(v,1,0,poly) % 2 ) + == (DBG_rayIntersectPoly(v,1,Real(0.1234), poly) % 2 ) + ); + if(DBG_rayIntersectPoly(v, 1, 0, poly) % 2 == 1) + return 1; + else + return 0; +} + +/*return the number of polygons which contain thie polygon + * as a subset + */ +Int DBG_enclosingPolygons(directedLine* poly, directedLine* list) +{ + directedLine* temp; + Int count=0; +/* +printf("%i\n", DBG_pointInsidePoly(poly->head(), + list->getNextPolygon() + ->getNextPolygon() + ->getNextPolygon() + ->getNextPolygon() +)); +*/ + + for(temp = list; temp != NULL; temp = temp->getNextPolygon()) + { + if(poly != temp) + if(DBG_pointInsidePoly(poly->head(), temp)) + count++; +/* printf("count=%i\n", count);*/ + } + return count; +} + +void DBG_reverse(directedLine* poly) +{ + if(poly->getDirection() == INCREASING) + poly->putDirection(DECREASING); + else + poly->putDirection(INCREASING); + + directedLine* oldNext = poly->getNext(); + poly->putNext(poly->getPrev()); + poly->putPrev(oldNext); + + directedLine* temp; + for(temp=oldNext; temp!=poly; temp = oldNext) + { + if(temp->getDirection() == INCREASING) + temp->putDirection(DECREASING); + else + temp->putDirection(INCREASING); + + oldNext = temp->getNext(); + temp->putNext(temp->getPrev()); + temp->putPrev(oldNext); + } + printf("reverse done\n"); +} + +Int DBG_checkConnectivity(directedLine *polygon) +{ + if(polygon == NULL) return 1; + directedLine* temp; + if(polygon->head()[0] != polygon->getPrev()->tail()[0] || + polygon->head()[1] != polygon->getPrev()->tail()[1]) + return 0; + for(temp=polygon->getNext(); temp != polygon; temp=temp->getNext()) + { + if(temp->head()[0] != temp->getPrev()->tail()[0] || + temp->head()[1] != temp->getPrev()->tail()[1]) + return 0; + } + return 1; +} + +/*print out error message. + *If it cannot modify the polygon list to make it satify the + *requirements, return 1. + *otherwise modify the polygon list, and return 0 + */ +Int DBG_check(directedLine *polyList) +{ + directedLine* temp; + if(polyList == NULL) return 0; + + /*if there are intersections, print out error message + */ + if(DBG_polygonListIntersect(polyList)) + { + fprintf(stderr, "DBG_check: there are self intersections, don't know to modify the polygons\n"); + return 1; + } + + /*check the connectivity of each polygon*/ + for(temp = polyList; temp!= NULL; temp = temp ->getNextPolygon()) + { + if(! DBG_checkConnectivity(temp)) + { + fprintf(stderr, "DBG_check, polygon not connected\n"); + return 1; + } + } + + /*check the orientation of each polygon*/ + for(temp = polyList; temp!= NULL; temp = temp ->getNextPolygon()) + { + + + Int correctDir; + + if( DBG_enclosingPolygons(temp, polyList) % 2 == 0) + correctDir = 1; /*counterclockwise*/ + else + correctDir = 0; /*clockwise*/ + + Int actualDir = DBG_isCounterclockwise(temp); + + if(correctDir != actualDir) + { + fprintf(stderr, "DBG_check: polygon with incorrect orientations. reversed\n"); + + DBG_reverse(temp); + } + + } + return 0; +} + +/**************handle self intersections*****************/ +//determine whether e interects [begin, end] or not +static directedLine* DBG_edgeIntersectChainD(directedLine *e, + directedLine *begin, directedLine *end) +{ + directedLine *temp; + for(temp=begin; temp != end; temp = temp->getNext()) + { + if(DBG_edgesIntersect(e, temp)) + return temp; + } + if(DBG_edgesIntersect(e, end)) + return end; + return NULL; +} + +//given a polygon, cut the edges off and finally obtain a +//a polygon without intersections. The cut-off edges are +//dealloated. The new polygon is returned. +directedLine* DBG_cutIntersectionPoly(directedLine *polygon, int& cutOccur) +{ + directedLine *begin, *end, *next; + begin = polygon; + end = polygon; + cutOccur = 0; + while( (next = end->getNext()) != begin) + { + directedLine *interc = NULL; + if( (interc = DBG_edgeIntersectChainD(next, begin, end))) + { + int fixed = 0; + if(DBG_edgesIntersect(next, interc->getNext())) + { + //trying to fix it + Real buf[2]; + int i; + Int n=5; + buf[0] = interc->tail()[0]; + buf[1] = interc->tail()[1]; + + for(i=1; i<n; i++) + { + Real r = ((Real)i) / ((Real) n); + Real u = (1-r) * interc->head()[0] + r * interc->tail()[0]; + Real v = (1-r) * interc->head()[1] + r * interc->tail()[1]; + interc->tail()[0] = interc->getNext()->head()[0] = u; + interc->tail()[1] = interc->getNext()->head()[1] = v; + if( (! DBG_edgesIntersect(next, interc)) && + (! DBG_edgesIntersect(next, interc->getNext()))) + break; //we fixed it + } + if(i==n) // we didn't fix it + { + fixed = 0; + //back to original + interc->tail()[0] = interc->getNext()->head()[0] = buf[0]; + interc->tail()[1] = interc->getNext()->head()[1] = buf[1]; + } + else + { + fixed = 1; + } + } + if(fixed == 0) + { + cutOccur = 1; + begin->deleteSingleLine(next); + + if(begin != end) + { + if(DBG_polygonSelfIntersect(begin)) + { + directedLine* newEnd = end->getPrev(); + begin->deleteSingleLine(end); + end = newEnd; + } + } + } + else + { + end = end->getNext(); + } + } + else + { + end = end->getNext(); + } + } + return begin; +} + +//given a polygon, cut the edges off and finally obtain a +//a polygon without intersections. The cut-off edges are +//dealloated. The new polygon is returned. +#if 0 // UNUSED +static directedLine* DBG_cutIntersectionPoly_notwork(directedLine *polygon) +{ + directedLine *crt;//current polygon + directedLine *begin; + directedLine *end; + directedLine *temp; + crt = polygon; + int find=0; + while(1) + { +//printf("loop\n"); + //if there are less than 3 edges, we should stop + if(crt->getPrev()->getPrev() == crt) + return NULL; + + if(DBG_edgesIntersect(crt, crt->getNext()) || + (crt->head()[0] == crt->getNext()->tail()[0] && + crt->head()[1] == crt->getNext()->tail()[1]) + ) + { + find = 1; + crt=crt->deleteChain(crt, crt->getNext()); + } + else + { + //now we know crt and crt->getNext do not intersect + begin = crt; + end = crt->getNext(); +//printf("begin=(%f,%f)\n", begin->head()[0], begin->head()[1]); +//printf("end=(%f,%f)\n", end->head()[0], end->head()[1]); + for(temp=end->getNext(); temp!=begin; temp= temp->getNext()) + { +//printf("temp=(%f,%f)\n", temp->head()[0], temp->head()[1]); + directedLine *intersect = DBG_edgeIntersectChainD(temp, begin, end); + if(intersect != NULL) + { + crt = crt->deleteChain(intersect, temp); + find=1; + break; //the for loop + } + else + { + end = temp; + } + } + } + if(find == 0) + return crt; + else + find = 0; //go to next loop +} +} +#endif + +directedLine* DBG_cutIntersectionAllPoly(directedLine* list) +{ + directedLine* temp; + directedLine* tempNext=NULL; + directedLine* ret = NULL; + int cutOccur=0; + for(temp=list; temp != NULL; temp = tempNext) + { + directedLine *left; + tempNext = temp->getNextPolygon(); + + left = DBG_cutIntersectionPoly(temp, cutOccur); + if(left != NULL) + ret=left->insertPolygon(ret); + } + return ret; +} + +sampledLine* DBG_collectSampledLinesAllPoly(directedLine *polygonList) +{ + directedLine *temp; + sampledLine* tempHead = NULL; + sampledLine* tempTail = NULL; + sampledLine* cHead = NULL; + sampledLine* cTail = NULL; + + if(polygonList == NULL) + return NULL; + + DBG_collectSampledLinesPoly(polygonList, cHead, cTail); + + assert(cHead); + assert(cTail); + for(temp = polygonList->getNextPolygon(); temp != NULL; temp = temp->getNextPolygon()) + { + DBG_collectSampledLinesPoly(temp, tempHead, tempTail); + cTail->insert(tempHead); + cTail = tempTail; + } + return cHead; +} + +void DBG_collectSampledLinesPoly(directedLine *polygon, sampledLine*& retHead, sampledLine*& retTail) +{ + directedLine *temp; + retHead = NULL; + retTail = NULL; + if(polygon == NULL) + return; + + retHead = retTail = polygon->getSampledLine(); + for(temp = polygon->getNext(); temp != polygon; temp=temp->getNext()) + { + retHead = temp->getSampledLine()->insert(retHead); + } +} diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/polyDBG.h b/mesalib/src/glu/sgi/libnurbs/nurbtess/polyDBG.h new file mode 100644 index 000000000..74843d888 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/polyDBG.h @@ -0,0 +1,68 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ +/* +*/ + +#ifndef _POLYDBG_H +#define _POLYDBG_H + +#include "definitions.h" +#include "directedLine.h" +#include "monoTriangulation.h" + +Int DBG_edgesIntersectGen(Real A[2], Real B[2], Real C[2], Real D[2]); +Int DBG_intersectChain(vertexArray* chain, Int start, Int end, Real A[2], Real B[2]); + + +Int DBG_edgesIntersect(directedLine* l1, directedLine* l2); +Int DBG_polygonSelfIntersect(directedLine* poly); +Int DBG_edgeIntersectPoly(directedLine* edge, directedLine* poly); +Int DBG_polygonsIntersect(directedLine* p1, directedLine* p2); +Int DBG_polygonListIntersect(directedLine* pList); + +Int DBG_isCounterclockwise(directedLine* poly); +Int DBG_rayIntersectEdge(Real v0[2], Real dx, Real dy, Real v10[2], Real v1[2], Real v2[2]); +Int DBG_pointInsidePoly(Real v[2], directedLine* poly); +Int DBG_enclosingPolygons(directedLine* poly, directedLine* list); +void DBG_reverse(directedLine* poly); +Int DBG_check(directedLine *polyList); + +Int DBG_isConvex(directedLine *poly); +Int DBG_is_U_direction(directedLine *poly); +Int DBG_is_U_monotone(directedLine* poly); + +directedLine* DBG_cutIntersectionAllPoly(directedLine* list); +directedLine* DBG_cutIntersectionPoly(directedLine *polygon, int& cutOccur); + +sampledLine* DBG_collectSampledLinesAllPoly(directedLine *polygonList); + +void DBG_collectSampledLinesPoly(directedLine *polygon, sampledLine*& retHead, sampledLine*& retTail); + +#endif diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/polyUtil.cc b/mesalib/src/glu/sgi/libnurbs/nurbtess/polyUtil.cc new file mode 100644 index 000000000..f9a27f402 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/polyUtil.cc @@ -0,0 +1,90 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include <stdlib.h> +#include <stdio.h> + +#include "polyUtil.h" + +Real area(Real A[2], Real B[2], Real C[2]) +{ + Real Bx, By, Cx, Cy; + Bx = B[0] - A[0]; + By = B[1] - A[1]; + Cx = C[0] - A[0]; + Cy = C[1] - A[1]; + return Bx*Cy - Cx*By; + +/* return (B[0]-A[0])*(C[1]-A[1]) - (C[0]-A[0])*(B[1]-A[1]);*/ +} + +/*given a directed line A->B, and a point P, + *determine whether P is to the left of AB. + *the line A->B (imagine it has beedn extended both + *end to the infinity) divides the plan into two + *half planes. When we walk from A to B, one + *half is to the left and the other half is to the right. + *return 1 if P is to the left. + *if P is on AB, 0 is returned. + */ +Int pointLeftLine(Real A[2], Real B[2], Real P[2]) +{ + if(area(A, B, P) >0) return 1; + else return 0; +} + +/*given two directed line: A -> B -> C, and another point P. + *determine whether P is to the left hand side of A->B->C. + *Think of BA and BC extended as two rays. So that the plane is + * divided into two parts. One part is to the left we walk from A + *to B and to C, the other part is to the right. + * In order for P to be the left, P must be either to the left + *of + */ +Int pointLeft2Lines(Real A[2], Real B[2], Real C[2], Real P[2]) +{ + Int C_left_AB = (area(A, B, C)>0); + Int P_left_AB = (area(A, B, P)>0); + Int P_left_BC = (area(B, C, P)>0); + + if(C_left_AB) + { + return (P_left_AB && P_left_BC); + } + else + return (P_left_AB || P_left_BC); +} diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/polyUtil.h b/mesalib/src/glu/sgi/libnurbs/nurbtess/polyUtil.h new file mode 100644 index 000000000..1ca2ebcc0 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/polyUtil.h @@ -0,0 +1,47 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ +/* +*/ + +#ifndef _POLYUTIL_H +#define _POLYUTIL_H + +#include "definitions.h" +#ifdef __cplusplus +extern "C" { +#endif +Real area(Real A[2], Real B[2], Real C[2]); + +Int pointLeftLine(Real A[2], Real B[2], Real P[2]); +Int pointLeft2Lines(Real A[2], Real B[2], Real C[2], Real P[2]); +#ifdef __cplusplus +} +#endif +#endif diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/primitiveStream.cc b/mesalib/src/glu/sgi/libnurbs/nurbtess/primitiveStream.cc new file mode 100644 index 000000000..26d05342f --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/primitiveStream.cc @@ -0,0 +1,190 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include "gluos.h" +#include <stdlib.h> +#include <stdio.h> +#include <assert.h> +#include <GL/gl.h> + +#include "primitiveStream.h" + +Int primStream::num_triangles() +{ + Int i; + Int ret=0; + for(i=0; i<index_lengths; i++) + { + ret += lengths[i]-2; + } + return ret; +} + + + +/*the begining of inserting a new primitive. + *reset counter to be 0. + */ +void primStream::begin() +{ + counter = 0; +} + +void primStream::insert(Real u, Real v) +{ + /*if the space cannot hold u and v, + *we have to expand the array + */ + if(index_vertices+1 >= size_vertices) { + Real* temp = (Real*) malloc (sizeof(Real) * (2*size_vertices + 2)); + assert(temp); + + /*copy*/ + for(Int i=0; i<index_vertices; i++) + temp[i] = vertices[i]; + + free(vertices); + vertices = temp; + size_vertices = 2*size_vertices + 2; + } + + vertices[index_vertices++] = u; + vertices[index_vertices++] = v; + counter++; +} + +/*the end of a primitive. + *increase index_lengths + */ +void primStream::end(Int type) +{ + Int i; + /*if there is no vertex in this primitive, + *nothing needs to be done + */ + if(counter == 0) return ; + + if(index_lengths >= size_lengths){ + Int* temp = (Int*) malloc(sizeof(Int) * (2*size_lengths + 2)); + assert(temp); + Int* tempTypes = (Int*) malloc(sizeof(Int) * (2*size_lengths + 2)); + assert(tempTypes); + + /*copy*/ + for(i=0; i<index_lengths; i++){ + temp[i] = lengths[i]; + tempTypes[i] = types[i]; + } + + free(lengths); + free(types); + lengths = temp; + types = tempTypes; + size_lengths = 2*size_lengths + 2; + } + lengths[index_lengths] = counter; + types[index_lengths] = type; + index_lengths++; +} + +void primStream::print() +{ + Int i,j,k; + printf("index_lengths=%i,size_lengths=%i\n", index_lengths, size_lengths); + printf("index_vertices=%i,size_vertices=%i\n", index_vertices, size_vertices); + k=0; + for(i=0; i<index_lengths; i++) + { + if(types[i] == PRIMITIVE_STREAM_FAN) + printf("primitive-FAN:\n"); + else + printf("primitive-STRIP:\n"); + for(j=0; j<lengths[i]; j++) + { + printf("(%f,%f) ", vertices[k], vertices[k+1]); + k += 2; + } + printf("\n"); + } +} + +primStream::primStream(Int sizeLengths, Int sizeVertices) +{ + lengths = (Int*)malloc (sizeof(Int) * sizeLengths); + assert(lengths); + types = (Int*)malloc (sizeof(Int) * sizeLengths); + assert(types); + + vertices = (Real*) malloc(sizeof(Real) * sizeVertices); + assert(vertices); + + index_lengths = 0; + index_vertices = 0; + size_lengths = sizeLengths; + size_vertices = sizeVertices; +} + +primStream::~primStream() +{ + free(lengths); + free(types); + free(vertices); +} + +void primStream::draw() +{ + Int i,j,k; + k=0; + for(i=0; i<index_lengths; i++) + { + switch(types[i]){ + case PRIMITIVE_STREAM_FAN: + glBegin(GL_TRIANGLE_FAN); + break; + case PRIMITIVE_STREAM_STRIP: + glBegin(GL_TRIANGLE_STRIP); + break; + } + + for(j=0; j<lengths[i]; j++){ + glVertex2fv(vertices+k); + k += 2; + } + glEnd(); + } +} + diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/primitiveStream.h b/mesalib/src/glu/sgi/libnurbs/nurbtess/primitiveStream.h new file mode 100644 index 000000000..b4174f146 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/primitiveStream.h @@ -0,0 +1,109 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ +/* +*/ + +/*we do not use the constans GL_... so that this file is independent of + *<GL/gl.h> + */ + +#ifndef _PRIMITIVE_STREAM_H +#define _PRIMITIVE_STREAM_H + +enum {PRIMITIVE_STREAM_FAN, PRIMITIVE_STREAM_STRIP}; + +#include "definitions.h" + +class primStream { + Int *lengths; /*length[i]=number of vertices of ith primitive*/ + Int *types; /*each primive has a type: FAN or STREAM*/ + Real *vertices; /*the size >= 2 * num_vertices, each vertex (u,v)*/ + + /*the following size information are used for dynamic arrays*/ + Int index_lengths; /*the current available entry*/ + Int size_lengths; /*the allocated size of the array: lengths*/ + Int index_vertices; + Int size_vertices; + + /*the vertex is inserted one by one. counter is used to + *count the number of vertices which have been inserted so far in + *the current primitive + */ + Int counter; + +public: + primStream(Int sizeLengths, Int sizeVertices); + ~primStream(); + + Int get_n_prims() //num of primitives + { + return index_lengths; + } + Int get_type(Int i) //the type of ith primitive + { + return types[i]; + } + Int get_length(Int i) //the length of the ith primitive + { + return lengths[i]; + } + Real* get_vertices() {return vertices;} + + /*the begining of inserting a new primitive. + *reset counter to be 0. + */ + void begin(); + void insert(Real u, Real v); + void insert(Real v[2]) {insert(v[0], v[1]);} + void end(Int type); + + Int num_triangles(); + + void triangle(Real A[2], Real B[2], Real C[2]) + { + begin(); + insert(A); + insert(B); + insert(C); + end(PRIMITIVE_STREAM_FAN); + } + void print(); + void draw(); /*using GL to draw the primitives*/ +}; + + + + + + + + +#endif + diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/quicksort.cc b/mesalib/src/glu/sgi/libnurbs/nurbtess/quicksort.cc new file mode 100644 index 000000000..9d0b290b3 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/quicksort.cc @@ -0,0 +1,77 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include <stdlib.h> +#include <stdio.h> + + +static void swap(void *v[], int i, int j) +{ + void *temp; + temp = v[i]; + v[i] = v[j]; + v[j] = temp; +} + +/*as an example to use this function to + *sort integers, you need to supply the function + *int comp(int *i1, int *i2) + *{ + * if( *i1 < * i2) return -1; + * else return 1; + *} + *and an array of pointers to integers: + * int *v[100] (allocate space for where each v[i] points to). + *then you can call: + * quicksort( (void**)v, left, right, (int (*)(void *, void *))comp) + */ +void quicksort(void *v[], int left, int right, + int (*comp) (void *, void *)) +{ + int i, last; + if(left >= right) /*do nothing if array contains */ + return; /*fewer than two elements*/ + + swap(v, left, (left+right)/2); + last = left; + for(i=left+1; i<=right; i++) + if((*comp)(v[i], v[left])<0) + swap(v, ++last, i); + swap(v, left, last); + quicksort(v, left, last-1, comp); + quicksort(v, last+1, right, comp); +} diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/quicksort.h b/mesalib/src/glu/sgi/libnurbs/nurbtess/quicksort.h new file mode 100644 index 000000000..3a8dcd6a2 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/quicksort.h @@ -0,0 +1,42 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ +/* +*/ + +#ifndef _QUICKSORT_H +#define _QUICKSORT_H + +#include <stdlib.h> +#include <stdio.h> + +void quicksort(void *v[], int left, int right, + int (*comp) (void *, void *)); + +#endif diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/rectBlock.cc b/mesalib/src/glu/sgi/libnurbs/nurbtess/rectBlock.cc new file mode 100644 index 000000000..f457b1573 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/rectBlock.cc @@ -0,0 +1,196 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include "gluos.h" +#include <stdlib.h> +#include <stdio.h> +#include "glimports.h" +#include "zlassert.h" +#include <GL/gl.h> + +#include "rectBlock.h" + +rectBlock::rectBlock(gridBoundaryChain* left, gridBoundaryChain* right, Int beginVline, Int endVline) +{ + Int i; + + + upGridLineIndex = left->getVlineIndex(beginVline); + + lowGridLineIndex = left->getVlineIndex(endVline); + + Int n = upGridLineIndex-lowGridLineIndex+1; //number of grid lines + leftIndices = (Int*) malloc(sizeof(Int) * n); + assert(leftIndices); + rightIndices = (Int*) malloc(sizeof(Int) * n); + assert(rightIndices); + for(i=0; i<n; i++) + { + + leftIndices[i] = left->getInnerIndex(i+beginVline); + rightIndices[i] = right->getInnerIndex(i+beginVline); + } +} + + +rectBlock::~rectBlock() +{ + free(leftIndices); + free(rightIndices); +} + +void rectBlock::print() +{ + Int i; + printf("block:\n"); + for(i=upGridLineIndex; i >= lowGridLineIndex; i--) + { + printf("gridline %i, (%i,%i)\n", i, leftIndices[upGridLineIndex-i], rightIndices[upGridLineIndex-i]); + } +} + + + +void rectBlock::draw(Real* u_values, Real* v_values) +{ + Int i,j,k; + //upgrid line to bot grid line +#ifdef DEBUG +printf("upGridLineIndex=%i, lowGridLineIndex=%i\n", upGridLineIndex, lowGridLineIndex); +#endif + for(k=0, i=upGridLineIndex; i > lowGridLineIndex; i--, k++) + { + glBegin(GL_QUAD_STRIP); + + for(j=leftIndices[k+1]; j<= rightIndices[k+1]; j++) + { + glVertex2f(u_values[j], v_values[i]); + glVertex2f(u_values[j], v_values[i-1]); + } + glEnd(); + } +} + + +Int rectBlock::num_quads() +{ + Int ret=0; + Int k,i; + for(k=0, i=upGridLineIndex; i>lowGridLineIndex; i--, k++) + { + ret += (rightIndices[k+1]-leftIndices[k+1]); + } + return ret; +} + +Int rectBlockArray::num_quads() +{ + Int ret=0; + for(Int i=0; i<n_elements; i++) + ret += array[i]->num_quads(); + return ret; +} + +rectBlockArray::rectBlockArray(Int s) +{ + Int i; + n_elements = 0; + size = s; + array = (rectBlock**) malloc(sizeof(rectBlock*) * s); + assert(array); +//initialization + for(i=0; i<s; i++) + array[i] = NULL; +} + +rectBlockArray::~rectBlockArray() +{ + Int i; + for(i=0; i<size; i++) + { + if(array[i] != NULL) + delete array[i]; + } + free(array); +} + +//put to the end of the array, check the size +void rectBlockArray::insert(rectBlock* newBlock) +{ + Int i; + if(n_elements == size) //full + { + rectBlock** temp = (rectBlock**) malloc(sizeof(rectBlock) * (2*size+1)); + assert(temp); + //initialization + for(i=0; i<2*size+1; i++) + temp[i] = NULL; + + for(i=0; i<n_elements; i++) + temp[i] = array[i]; + + free(array); + array = temp; + size = 2*size + 1; + } + + array[n_elements++] = newBlock; +} + +void rectBlockArray::print() +{ + Int i; + for(i=0; i<n_elements; i++) + array[i]->print(); +} + +void rectBlockArray::draw(Real* u_values, Real* v_values) +{ + Int i; + for(i=0; i<n_elements; i++) + array[i]->draw(u_values, v_values); +} + + + + + + + + + + diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/rectBlock.h b/mesalib/src/glu/sgi/libnurbs/nurbtess/rectBlock.h new file mode 100644 index 000000000..8dbd7eb81 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/rectBlock.h @@ -0,0 +1,82 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ +/* +*/ + +#ifndef _RECTBLOCK_H +#define _RECTBLOCK_H + +#include "definitions.h" +#include "gridWrap.h" + +class rectBlock{ + Int upGridLineIndex; + Int lowGridLineIndex; + Int* leftIndices; //up to bottome + Int* rightIndices; //up to bottom +public: + //the arrays are copies. + rectBlock(gridBoundaryChain* left, gridBoundaryChain* right, Int beginVline, Int endVline); + ~rectBlock(); //free the two arrays + + Int get_upGridLineIndex() {return upGridLineIndex;} + Int get_lowGridLineIndex() {return lowGridLineIndex;} + Int* get_leftIndices() {return leftIndices;} + Int* get_rightIndices() {return rightIndices;} + + Int num_quads(); + + void print(); + void draw(Real* u_values, Real* v_values); +}; + + +class rectBlockArray{ + rectBlock** array; + Int n_elements; + Int size; +public: + rectBlockArray(Int s); + ~rectBlockArray();//delete avarything including the blocks + + Int get_n_elements() {return n_elements;} + rectBlock* get_element(Int i) {return array[i];} + void insert(rectBlock* newBlock); //only take the pointer, not ther cotent + + Int num_quads(); + + void print(); + void draw(Real* u_values, Real* v_values); +}; + + + +#endif + diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleComp.cc b/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleComp.cc new file mode 100644 index 000000000..861c71bb3 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleComp.cc @@ -0,0 +1,371 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include <stdlib.h> +#include <stdio.h> +#include "glimports.h" +#include "sampleComp.h" +#include "sampleCompTop.h" +#include "sampleCompBot.h" +#include "sampleCompRight.h" + + + +#define max(a,b) ((a>b)? a:b) +#define min(a,b) ((a>b)? b:a) + +void sampleConnectedComp(Real* topVertex, Real* botVertex, + vertexArray* leftChain, + Int leftStartIndex, Int leftEndIndex, + vertexArray* rightChain, + Int rightStartIndex, Int rightEndIndex, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridIndex1, Int gridIndex2, + Int up_leftCornerWhere, + Int up_leftCornerIndex, + Int up_rightCornerWhere, + Int up_rightCornerIndex, + Int down_leftCornerWhere, + Int down_leftCornerIndex, + Int down_rightCornerWhere, + Int down_rightCornerIndex, + primStream* pStream, + rectBlockArray* rbArray + ) +{ + + sampleCompLeft(topVertex, botVertex, + leftChain, + leftStartIndex, leftEndIndex, + rightChain, + rightStartIndex, rightEndIndex, + leftGridChain, + gridIndex1, + gridIndex2, + up_leftCornerWhere, + up_leftCornerIndex, + down_leftCornerWhere, + down_leftCornerIndex, + pStream); + + + sampleCompRight(topVertex, botVertex, + leftChain, + leftStartIndex, leftEndIndex, + rightChain, + rightStartIndex, + rightEndIndex, + rightGridChain, + gridIndex1, gridIndex2, + up_rightCornerWhere, + up_rightCornerIndex, + down_rightCornerWhere, + down_rightCornerIndex, + pStream); + + + sampleCompTop(topVertex, + leftChain, + leftStartIndex, + rightChain, + rightStartIndex, + leftGridChain, + rightGridChain, + gridIndex1, + up_leftCornerWhere, + up_leftCornerIndex, + up_rightCornerWhere, + up_rightCornerIndex, + pStream); + + sampleCompBot(botVertex, + leftChain, + leftEndIndex, + rightChain, + rightEndIndex, + leftGridChain, + rightGridChain, + gridIndex2, + down_leftCornerWhere, + down_leftCornerIndex, + down_rightCornerWhere, + down_rightCornerIndex, + pStream); + + + //the center + + rbArray->insert(new rectBlock(leftGridChain, rightGridChain, gridIndex1, gridIndex2)); + + +} + +/*notice that we need rightChain because the + *corners could be on the rightChain. + *here comp means component. + */ +void sampleCompLeft(Real* topVertex, Real* botVertex, + vertexArray* leftChain, + Int leftStartIndex, Int leftEndIndex, + vertexArray* rightChain, + Int rightStartIndex, Int rightEndIndex, + gridBoundaryChain* leftGridChain, + Int gridIndex1, Int gridIndex2, + Int up_leftCornerWhere, + Int up_leftCornerIndex, + Int down_leftCornerWhere, + Int down_leftCornerIndex, + primStream* pStream) +{ + /*find out whether there is a trim vertex which is + *inbetween the top and bot grid lines or not. + */ + Int midIndex1; + Int midIndex2; + Int gridMidIndex1 = 0, gridMidIndex2 = 0; + //midIndex1: array[i] <= v, array[i-1] > v + //midIndex2: array[i] >= v, array[i+1] < v + // v(gridMidIndex1) >= v(midindex1) > v(gridMidIndex1+1) + // v(gridMidIndex2-1) >= v(midIndex2) > v(gridMidIndex2) ?? + midIndex1 = leftChain->findIndexBelowGen( + leftGridChain->get_v_value(gridIndex1), + leftStartIndex, + leftEndIndex); + + midIndex2 = -1; /*initilization*/ + if(midIndex1<= leftEndIndex && gridIndex1<gridIndex2) + if(leftChain->getVertex(midIndex1)[1] >= leftGridChain->get_v_value(gridIndex2)) + { + midIndex2 = leftChain->findIndexAboveGen( + leftGridChain->get_v_value(gridIndex2), + midIndex1, //midIndex1 <= midIndex2. + leftEndIndex); + gridMidIndex1 = leftGridChain->lookfor(leftChain->getVertex(midIndex1)[1], + gridIndex1, gridIndex2); + gridMidIndex2 = 1+leftGridChain->lookfor(leftChain->getVertex(midIndex2)[1], + gridMidIndex1, gridIndex2); + } + + + /*to interprete the corner information*/ + Real* cornerTop; + Real* cornerBot; + Int cornerLeftStart; + Int cornerLeftEnd; + Int cornerRightUpEnd; + Int cornerRightDownStart; + if(up_leftCornerWhere == 0) /*left corner is on left chain*/ + { + cornerTop = leftChain->getVertex(up_leftCornerIndex); + cornerLeftStart = up_leftCornerIndex+1; + cornerRightUpEnd = -1; /*no right*/ + } + else if(up_leftCornerWhere == 1) /*left corner is on top*/ + { + cornerTop = topVertex; + cornerLeftStart = leftStartIndex; + cornerRightUpEnd = -1; /*no right*/ + } + else /*left corner is on right chain*/ + { + cornerTop = topVertex; + cornerLeftStart = leftStartIndex; + cornerRightUpEnd = up_leftCornerIndex; + } + + if(down_leftCornerWhere == 0) /*left corner is on left chain*/ + { + cornerBot = leftChain->getVertex(down_leftCornerIndex); + cornerLeftEnd = down_leftCornerIndex-1; + cornerRightDownStart = rightEndIndex+1; /*no right*/ + } + else if(down_leftCornerWhere == 1) /*left corner is on bot*/ + { + cornerBot = botVertex; + cornerLeftEnd = leftEndIndex; + cornerRightDownStart = rightEndIndex+1; /*no right*/ + } + else /*left corner is on the right chian*/ + { + cornerBot = botVertex; + cornerLeftEnd = leftEndIndex; + cornerRightDownStart = down_leftCornerIndex; + } + + + + + /*sample*/ + if(midIndex2 >= 0) /*there is a trim point inbewteen grid lines*/ + { + + sampleLeftSingleTrimEdgeRegionGen(cornerTop, leftChain->getVertex(midIndex1), + leftChain, + cornerLeftStart, + midIndex1-1, + leftGridChain, + gridIndex1, + gridMidIndex1, + rightChain, + rightStartIndex, + cornerRightUpEnd, + 0, //no right down section + -1, + pStream); + + sampleLeftSingleTrimEdgeRegionGen(leftChain->getVertex(midIndex2), + cornerBot, + leftChain, + midIndex2+1, + cornerLeftEnd, + leftGridChain, + gridMidIndex2, + gridIndex2, + rightChain, + 0, //no right up section + -1, + cornerRightDownStart, + rightEndIndex, + pStream); + + + sampleLeftStripRecF(leftChain, + midIndex1, + midIndex2, + leftGridChain, + gridMidIndex1, + gridMidIndex2, + pStream); + } + else + { + sampleLeftSingleTrimEdgeRegionGen(cornerTop, cornerBot, + leftChain, + cornerLeftStart, + cornerLeftEnd, + leftGridChain, + gridIndex1, + gridIndex2, + rightChain, + rightStartIndex, + cornerRightUpEnd, + cornerRightDownStart, + rightEndIndex, + pStream); + } +} + +void sampleLeftSingleTrimEdgeRegionGen(Real topVert[2], Real botVert[2], + vertexArray* leftChain, + Int leftStart, + Int leftEnd, + gridBoundaryChain* gridChain, + Int gridBeginIndex, + Int gridEndIndex, + vertexArray* rightChain, + Int rightUpBegin, + Int rightUpEnd, + Int rightDownBegin, + Int rightDownEnd, + primStream* pStream) +{ + Int i,j,k; + + /*creat an array to store all the up and down secments of the right chain, + *and the left end grid points + * + *although vertex array is a dynamic array, but to gain efficiency, + *it is better to initiliza the exact array size + */ + vertexArray vArray(gridEndIndex-gridBeginIndex+1 + + max(0,rightUpEnd - rightUpBegin+1)+ + max(0,rightDownEnd - rightDownBegin+1)); + + /*append the vertices on the up section of thr right chain*/ + for(i=rightUpBegin; i<= rightUpEnd; i++) + vArray.appendVertex(rightChain->getVertex(i)); + + /*append the vertices of the left extremal grid points, + *and at the same time, perform triangulation for the stair cases + */ + vArray.appendVertex(gridChain->get_vertex(gridBeginIndex)); + + for(k=1, i=gridBeginIndex+1; i<=gridEndIndex; i++, k++) + { + vArray.appendVertex(gridChain->get_vertex(i)); + + /*output the fan of the grid points of the (i)th and (i-1)th grid line. + */ + if(gridChain->getUlineIndex(i) < gridChain->getUlineIndex(i-1)) + { + pStream->begin(); + pStream->insert(gridChain->get_vertex(i-1)); + for(j=gridChain->getUlineIndex(i); j<= gridChain->getUlineIndex(i-1); j++) + pStream->insert(gridChain->getGrid()->get_u_value(j), gridChain->get_v_value(i)); + pStream->end(PRIMITIVE_STREAM_FAN); + } + else if(gridChain->getUlineIndex(i) > gridChain->getUlineIndex(i-1)) + { + pStream->begin(); + pStream->insert(gridChain->get_vertex(i)); + for(j=gridChain->getUlineIndex(i); j>= gridChain->getUlineIndex(i-1); j--) + pStream->insert(gridChain->getGrid()->get_u_value(j), gridChain->get_v_value(i-1)); + pStream->end(PRIMITIVE_STREAM_FAN); + } + /*otherwisem, the two are equal, so there is no fan to outout*/ + } + + /*then append all the vertices on the down section of the right chain*/ + for(i=rightDownBegin; i<= rightDownEnd; i++) + vArray.appendVertex(rightChain->getVertex(i)); + + monoTriangulationRecGen(topVert, botVert, + leftChain, leftStart, leftEnd, + &vArray, 0, vArray.getNumElements()-1, + pStream); + +} + + + + + + + + + diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleComp.h b/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleComp.h new file mode 100644 index 000000000..a3c179025 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleComp.h @@ -0,0 +1,86 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ +/* +*/ + +#ifndef _SAMPLECOMP_H +#define _SAMPLECOMP_H + +#include "sampleMonoPoly.h" +#include "rectBlock.h" + +void sampleConnectedComp(Real* topVertex, Real* botVertex, + vertexArray* leftChain, + Int leftStartIndex, Int botLeftIndex, + vertexArray* rightChain, + Int rightStartIndex, Int botRightIndex, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridIndex1, Int gridIndex2, + Int up_leftCornerWhere, + Int up_leftCornerIndex, + Int up_rightCornerWhere, + Int up_rightCornerIndex, + Int down_leftCornerWhere, + Int down_leftCornerIndex, + Int down_rightCornerWhere, + Int down_rightCornerIndex, + primStream* pStream, + rectBlockArray* rbArray + ); + +void sampleCompLeft(Real* topVertex, Real* botVertex, + vertexArray* leftChain, + Int leftStartIndex, Int leftEndIndex, + vertexArray* rightChain, + Int rightStartIndex, Int rightEndIndex, + gridBoundaryChain* leftGridChain, + Int gridIndex1, Int gridIndex2, + Int up_leftCornerWhere, + Int up_leftCornerIndex, + Int down_leftCornerWhere, + Int down_leftCornerIndex, + primStream* pStream); + +void sampleLeftSingleTrimEdgeRegionGen(Real topVert[2], Real botVert[2], + vertexArray* leftChain, + Int leftStart, + Int leftEnd, + gridBoundaryChain* gridChain, + Int gridBegindex, + Int gridEndIndex, + vertexArray* rightChain, + Int rightUpBegin, + Int rightUpEnd, + Int rightDownBegin, + Int rightDownEnd, + primStream* pStream); + +#endif diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleCompBot.cc b/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleCompBot.cc new file mode 100644 index 000000000..e12f88bab --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleCompBot.cc @@ -0,0 +1,844 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include <stdlib.h> +#include <stdio.h> +#include "zlassert.h" +#include "sampleCompBot.h" +#include "sampleCompRight.h" + +#define max(a,b) ((a>b)? a:b) + +//return: index_mono, index_pass +//from [pass, mono] is strictly U-monotone +//from [corner, pass] is <u +// vertex[pass][0] >= u +//if everybost is <u, then pass = end+1. +//otherwise both mono and pass are meanng full and we have corner<=pass<=mono<=end +void findBotLeftSegment(vertexArray* leftChain, + Int leftEnd, + Int leftCorner, + Real u, + Int& ret_index_mono, + Int& ret_index_pass) +{ + Int i; + + assert(leftCorner <= leftEnd); + for(i=leftCorner; i<= leftEnd; i++) + if(leftChain->getVertex(i)[0] >= u) + break; + ret_index_pass = i; + if(ret_index_pass <= leftEnd) + { + for(i=ret_index_pass; i< leftEnd; i++) + { + if(leftChain->getVertex(i+1)[0] <= leftChain->getVertex(i)[0]) + break; + } + ret_index_mono = i; + } + +} + +void findBotRightSegment(vertexArray* rightChain, + Int rightEnd, + Int rightCorner, + Real u, + Int& ret_index_mono, + Int& ret_index_pass) +{ + Int i; + assert(rightCorner <= rightEnd); + for(i=rightCorner; i<= rightEnd; i++) + if(rightChain->getVertex(i)[0] <= u) + break; + + + + ret_index_pass = i; + + if(ret_index_pass <= rightEnd) + { + for(i=ret_index_pass; i< rightEnd; i++) + { + if(rightChain->getVertex(i+1)[0] >= rightChain->getVertex(i)[0]) + break; + } + ret_index_mono = i; + } +} + + +void sampleBotRightWithGridLinePost(Real* botVertex, + vertexArray* rightChain, + Int rightEnd, + Int segIndexMono, + Int segIndexPass, + Int rightCorner, + gridWrap* grid, + Int gridV, + Int leftU, + Int rightU, + primStream* pStream) +{ + //the possible section which is to the right of rightU + if(segIndexPass > rightCorner) //from corner to pass-1 is > u. + { + Real *tempBot; + if(segIndexPass <= rightEnd) //there is a point to the left of u + tempBot = rightChain->getVertex(segIndexPass); + else //nothing is to the left of u. + tempBot = botVertex; + Real tempTop[2]; + tempTop[0] = grid->get_u_value(rightU); + tempTop[1] = grid->get_v_value(gridV); + + monoTriangulation2(tempTop, tempBot, + rightChain, + rightCorner, + segIndexPass-1, + 0, // a decrease chain + pStream); + } + + //the possible section which is strictly Umonotone + if(segIndexPass <= rightEnd) //segIndex pass and mono exist + { + //if there are grid points which are to the left of botVertex + //then we should use botVertex to form a fan with these points to + //optimize the triangulation + int do_optimize = 1; + if(botVertex[0] <= grid->get_u_value(leftU)) + do_optimize = 0; + else + { + //we also have to make sure that botVertex is the left most vertex on the chain + int i; + for(i=segIndexMono; i<=rightEnd; i++) + if(rightChain->getVertex(i)[0] <= botVertex[0]) + { + do_optimize = 0; + break; + } + } + + if(do_optimize) + { + //find midU so that grid->get_u_value(midU) <= botVertex[0] + //and grid->get_u_value(midU) > botVertex[0] + int midU = leftU; + while(grid->get_u_value(midU) <= botVertex[0]) + { + midU++; + if(midU > rightU) + break; + } + midU--; + + grid->outputFanWithPoint(gridV, leftU, midU, botVertex, pStream); + stripOfFanRight(rightChain, segIndexMono, segIndexPass, grid, gridV, midU, rightU, pStream, 1); + Real tempTop[2]; + tempTop[0] = grid->get_u_value(midU); + tempTop[1] = grid->get_v_value(gridV); + monoTriangulation2(tempTop, botVertex, rightChain, segIndexMono, rightEnd, 0, pStream); + } + else //not optimize + { + stripOfFanRight(rightChain, segIndexMono, segIndexPass, grid, gridV, leftU, rightU, pStream, 1); + Real tempTop[2]; + tempTop[0] = grid->get_u_value(leftU); + tempTop[1] = grid->get_v_value(gridV); + monoTriangulation2(tempTop, botVertex, rightChain, segIndexMono, rightEnd, 0, pStream); + } + } + else //the botVertex forms a fan witht eh grid points + grid->outputFanWithPoint(gridV, leftU, rightU, botVertex, pStream); +} + +void sampleBotRightWithGridLine(Real* botVertex, + vertexArray* rightChain, + Int rightEnd, + Int rightCorner, + gridWrap* grid, + Int gridV, + Int leftU, + Int rightU, + primStream* pStream) +{ + //if right chaain is empty, then there is only one bot vertex with + //one grid line + if(rightEnd<rightCorner){ + grid->outputFanWithPoint(gridV, leftU, rightU, botVertex, pStream); + return; + } + + Int segIndexMono, segIndexPass; + findBotRightSegment(rightChain, + rightEnd, + rightCorner, + grid->get_u_value(rightU), + segIndexMono, + segIndexPass); + + sampleBotRightWithGridLinePost(botVertex, + rightChain, + rightEnd, + segIndexMono, + segIndexPass, + rightCorner, + grid, + gridV, + leftU, + rightU, + pStream); +} + + +void sampleBotLeftWithGridLinePost(Real* botVertex, + vertexArray* leftChain, + Int leftEnd, + Int segIndexMono, + Int segIndexPass, + Int leftCorner, + gridWrap* grid, + Int gridV, + Int leftU, + Int rightU, + primStream* pStream) +{ + + //the possible section which is to the left of leftU + if(segIndexPass > leftCorner) //at least leftCorner is to the left of leftU + { + Real *tempBot; + if(segIndexPass <= leftEnd) //from corner to pass-1 is <u + tempBot = leftChain->getVertex(segIndexPass); + else //nothing is to the rigth of u + tempBot = botVertex; + Real tempTop[2]; + tempTop[0] = grid->get_u_value(leftU); + tempTop[1] = grid->get_v_value(gridV); + monoTriangulation2(tempTop, tempBot, leftChain, leftCorner, segIndexPass-1, + 1, //a increase chain, + pStream); + } + //the possible section which is strictly Umonotone + if(segIndexPass <= leftEnd) //segIndexpass and mono exist + { + stripOfFanLeft(leftChain, segIndexMono, segIndexPass, grid, gridV, leftU, rightU, pStream, 1); + Real tempTop[2]; + tempTop[0] = grid->get_u_value(rightU); + tempTop[1] = grid->get_v_value(gridV); + + monoTriangulation2(tempTop, botVertex, leftChain, segIndexMono, leftEnd, + 1, //increase chain + pStream); + } + else //the botVertex forms a fan with the grid points + { + grid->outputFanWithPoint(gridV, leftU, rightU, botVertex, pStream); + } + +} + +void sampleBotLeftWithGridLine(Real* botVertex, + vertexArray* leftChain, + Int leftEnd, + Int leftCorner, + gridWrap* grid, + Int gridV, + Int leftU, + Int rightU, + primStream* pStream) +{ + + //if leftChain is empty, then there is only one botVertex with one grid line + if(leftEnd< leftCorner){ + grid->outputFanWithPoint(gridV, leftU, rightU, botVertex, pStream); + return; + } + + Int segIndexPass, segIndexMono; + findBotLeftSegment(leftChain, leftEnd, leftCorner, grid->get_u_value(leftU), segIndexMono, segIndexPass); + + sampleBotLeftWithGridLinePost(botVertex, + leftChain, + leftEnd, + segIndexMono, + segIndexPass, + leftCorner, + grid, + gridV, + leftU, rightU, pStream); +} + +//return 1 if separator exists, 0 otherwise +Int findBotSeparator(vertexArray* leftChain, + Int leftEnd, + Int leftCorner, + vertexArray* rightChain, + Int rightEnd, + Int rightCorner, + Int& ret_sep_left, + Int& ret_sep_right) +{ + Int oldLeftI, oldRightI, newLeftI, newRightI; + Int i,j,k; + Real leftMax /*= leftChain->getVertex(leftCorner)[0]*/; + Real rightMin /*= rightChain->getVertex(rightCorner)[0]*/; + if(leftChain->getVertex(leftCorner)[1] < rightChain->getVertex(rightCorner)[1])//leftlower + { + oldLeftI = leftCorner-1; + oldRightI = rightCorner; + leftMax = leftChain->getVertex(leftCorner)[0] - Real(1.0) ; //initilize to be left of leftCorner + rightMin = rightChain->getVertex(rightCorner)[0]; + } + else //rightlower + { + oldLeftI = leftCorner; + oldRightI = rightCorner-1; + leftMax = leftChain->getVertex(leftCorner)[0]; + rightMin = rightChain->getVertex(rightCorner)[0] + Real(1.0); + } + + //i: the current working leftChain Index + //j: the curent working right chian index + //if(left(i) is lower than right(j), then the two chains above right(j) are separated. + //else the two chains below left(i) are separated. + i = leftCorner; + j = rightCorner; + while(1) + { + newLeftI = oldLeftI; + newRightI = oldRightI; + if(i> leftEnd) //left chain is doen , go through remaining right chain + { + for(k=j+1; k<= rightEnd; k++) + { + if(rightChain->getVertex(k)[0] > leftMax) //no conflict + { + //update oldRightI if necessary + if(rightChain->getVertex(k)[0] < rightMin) + { + rightMin = rightChain->getVertex(k)[0]; + oldRightI = k; + } + } + else //there is a conflict + break; //the for-loop, above right(k+1) is separated: oldLeftI, oldRightI + } + break; //the while loop + } + else if(j > rightEnd) //right Chain is doen + { + for(k=i+1; k<= leftEnd; k++) + { + if(leftChain->getVertex(k)[0] < rightMin) //no conflict + { + //update oldLeftI if necessary + if(leftChain->getVertex(k)[0] > leftMax) + { + leftMax = leftChain->getVertex(k)[0]; + oldLeftI = k; + } + } + else //there is a conflict + break; //the for-loop, above left(k+1) is separated: oldLeftI, oldRightI + } + break; //the while loop + } + else if(leftChain->getVertex(i)[1] < rightChain->getVertex(j)[1]) //left lower + { + + if(leftChain->getVertex(i)[0] > leftMax) //update leftMax amd newLeftI + { + leftMax = leftChain->getVertex(i)[0]; + newLeftI = i; + } + for(k=j+1; k<= rightEnd; k++) //update rightMin and newRightI; + { + if(rightChain->getVertex(k)[1] < leftChain->getVertex(i)[1]) //right gets lower + break; + if(rightChain->getVertex(k)[0] < rightMin) + { + rightMin = rightChain->getVertex(k)[0]; + newRightI = k; + } + } + j = k; //next working j, since j will he lower than i in next loop + if(leftMax >= rightMin) //there is a conflict + break; + else //still no conflict + { + oldLeftI = newLeftI; + oldRightI = newRightI; + + } + } + else //right lower + { + if(rightChain->getVertex(j)[0] < rightMin) + { + rightMin = rightChain->getVertex(j)[0]; + newRightI = j; + } + for(k=i+1; k<= leftEnd; k++) + { + if(leftChain->getVertex(k)[1] < rightChain->getVertex(j)[1]) + break; + if(leftChain->getVertex(k)[0] > leftMax) + { + leftMax = leftChain->getVertex(k)[0]; + newLeftI = k; + } + } + i=k; //nexct working i, since i will be lower than j next loop + if(leftMax >= rightMin) //there is conflict + break; + else //still no conflict + { + oldLeftI = newLeftI; + oldRightI = newRightI; + } + } + }//end of while loop + //now oldLeftI and oldRight I are the desired separator index notice that they are not + //necessarily valid + if(oldLeftI < leftCorner || oldRightI < rightCorner) + return 0; //no separator + else + { + ret_sep_left = oldLeftI; + ret_sep_right = oldRightI; + return 1; + } +} + +void sampleCompBot(Real* botVertex, + vertexArray* leftChain, + Int leftEnd, + vertexArray* rightChain, + Int rightEnd, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridIndex, + Int down_leftCornerWhere, + Int down_leftCornerIndex, + Int down_rightCornerWhere, + Int down_rightCornerIndex, + primStream* pStream) +{ + + if(down_leftCornerWhere == 1 && down_rightCornerWhere == 1) //the bot is botVertex with possible grid points + { + + leftGridChain->getGrid()->outputFanWithPoint(leftGridChain->getVlineIndex(gridIndex), + leftGridChain->getUlineIndex(gridIndex), + rightGridChain->getUlineIndex(gridIndex), + botVertex, + pStream); + return; + } + else if(down_leftCornerWhere != 0) + { + + Real* tempBot; + Int tempRightEnd; + if(down_leftCornerWhere == 1){ + tempRightEnd = rightEnd; + tempBot = botVertex; + } + else + { + tempRightEnd = down_leftCornerIndex-1; + tempBot = rightChain->getVertex(down_leftCornerIndex); + } + + sampleBotRightWithGridLine(tempBot, + rightChain, + tempRightEnd, + down_rightCornerIndex, + rightGridChain->getGrid(), + leftGridChain->getVlineIndex(gridIndex), + leftGridChain->getUlineIndex(gridIndex), + rightGridChain->getUlineIndex(gridIndex), + pStream); + } + else if(down_rightCornerWhere != 2) + { + + Real* tempBot; + Int tempLeftEnd; + if(down_rightCornerWhere == 1){ + tempLeftEnd = leftEnd; + tempBot = botVertex; + } + else //right corner is on left chain + { + tempLeftEnd = down_rightCornerIndex-1; + tempBot = leftChain->getVertex(down_rightCornerIndex); + } + + + sampleBotLeftWithGridLine(tempBot, leftChain, tempLeftEnd, down_leftCornerIndex, + leftGridChain->getGrid(), + leftGridChain->getVlineIndex(gridIndex), + leftGridChain->getUlineIndex(gridIndex), + rightGridChain->getUlineIndex(gridIndex), + pStream); + + } + else //down_leftCornereWhere == 0, down_rightCornerwhere == 2 + { + sampleCompBotSimple(botVertex, + leftChain, + leftEnd, + rightChain, + rightEnd, + leftGridChain, + rightGridChain, + gridIndex, + down_leftCornerWhere, + down_leftCornerIndex, + down_rightCornerWhere, + down_rightCornerIndex, + pStream); + + return; + +#ifdef NOT_REACHABLE + //the following code is trying to do some optimization, but not quite working. so it is not reachable, but leave it here for reference + Int sep_left, sep_right; + if(findBotSeparator(leftChain, leftEnd, down_leftCornerIndex, + rightChain, rightEnd, down_rightCornerIndex, + sep_left, sep_right) + )//separator exiosts + { + + if(leftChain->getVertex(sep_left)[0] >= leftGridChain->get_u_value(gridIndex) && + rightChain->getVertex(sep_right)[0] <= rightGridChain->get_u_value(gridIndex)) + { + Int gridSep; + Int segLeftMono, segLeftPass, segRightMono, segRightPass; + findBotLeftSegment(leftChain, + sep_left, + down_leftCornerIndex, + leftGridChain->get_u_value(gridIndex), + segLeftMono, + segLeftPass); + findBotRightSegment(rightChain, + sep_right, + down_rightCornerIndex, + rightGridChain->get_u_value(gridIndex), + segRightMono, + segRightPass); + if(leftChain->getVertex(segLeftMono)[1] <= rightChain->getVertex(segRightMono)[1]) + { + gridSep = rightGridChain->getUlineIndex(gridIndex); + while(leftGridChain->getGrid()->get_u_value(gridSep) > leftChain->getVertex(segLeftMono)[0]) + gridSep--; + } + else + { + gridSep = leftGridChain->getUlineIndex(gridIndex); + while(leftGridChain->getGrid()->get_u_value(gridSep) < rightChain->getVertex(segRightMono)[0]) + gridSep++; + } + + sampleBotLeftWithGridLinePost(leftChain->getVertex(segLeftMono), + leftChain, + segLeftMono-1, + segLeftMono-1, + segLeftPass, + down_leftCornerIndex, + leftGridChain->getGrid(), + leftGridChain->getVlineIndex(gridIndex), + leftGridChain->getUlineIndex(gridIndex), + gridSep, + pStream); + sampleBotRightWithGridLinePost(rightChain->getVertex(segRightMono), + rightChain, + segRightMono-1, + segRightMono-1, + segRightPass, + down_rightCornerIndex, + rightGridChain->getGrid(), + rightGridChain->getVlineIndex(gridIndex), + gridSep, + rightGridChain->getUlineIndex(gridIndex), + pStream); + Real tempTop[2]; + tempTop[0] = leftGridChain->getGrid()->get_u_value(gridSep); + tempTop[1] = leftGridChain->get_v_value(gridIndex); + monoTriangulationRecGen(tempTop, botVertex, + leftChain, segLeftMono, leftEnd, + rightChain, segRightMono, rightEnd, + pStream); + }//end if both sides have vertices inside the gridboundary points + else if(leftChain->getVertex(sep_left)[0] >= leftGridChain->get_u_value(gridIndex)) //left n right out + + { + Int segLeftMono, segLeftPass; + findBotLeftSegment(leftChain, + sep_left, + down_leftCornerIndex, + leftGridChain->get_u_value(gridIndex), + segLeftMono, + segLeftPass); + assert(segLeftPass <= sep_left); //make sure there is a point to the right of u. + monoTriangulation2(leftGridChain->get_vertex(gridIndex), + leftChain->getVertex(segLeftPass), + leftChain, + down_leftCornerIndex, + segLeftPass-1, + 1, //a increase chain + pStream); + stripOfFanLeft(leftChain, segLeftMono, segLeftPass, + leftGridChain->getGrid(), + leftGridChain->getVlineIndex(gridIndex), + leftGridChain->getUlineIndex(gridIndex), + rightGridChain->getUlineIndex(gridIndex), + pStream,1 ); +/* + sampleBotLeftWithGridLinePost(leftChain->getVertex(segLeftMono), + leftChain, + segLeftMono-1, + segLeftMono-1, + segLeftPass, + down_leftCornerIndex, + leftGridChain->getGrid(), + leftGridChain->getVlineIndex(gridIndex), + leftGridChain->getUlineIndex(gridIndex), + rightGridChain->getUlineIndex(gridIndex), + pStream); +*/ + + monoTriangulationRecGen(rightGridChain->get_vertex(gridIndex), + botVertex, + leftChain, segLeftMono, leftEnd, + rightChain, down_rightCornerIndex, rightEnd, + pStream); + }//end left in right out + else if(rightChain->getVertex(sep_right)[0] <= rightGridChain->get_u_value(gridIndex))//left out right in + { + Int segRightMono, segRightPass; + findBotRightSegment(rightChain, sep_right, down_rightCornerIndex, + rightGridChain->get_u_value(gridIndex), + segRightMono, + segRightPass); + + assert(segRightPass <= sep_right); //make sure there is a point to the left of u. + monoTriangulation2(rightGridChain->get_vertex(gridIndex), + rightChain->getVertex(segRightPass), + rightChain, + down_rightCornerIndex, + segRightPass-1, + 0, // a decrease chain + pStream); + + stripOfFanRight(rightChain, segRightMono, segRightPass, + rightGridChain->getGrid(), + rightGridChain->getVlineIndex(gridIndex), + leftGridChain->getUlineIndex(gridIndex), + rightGridChain->getUlineIndex(gridIndex), + pStream, 1); + + + monoTriangulationRecGen(leftGridChain->get_vertex(gridIndex), + botVertex, + leftChain, down_leftCornerIndex, leftEnd, + rightChain, segRightMono, rightEnd, + pStream); + + }//end left out right in + else //left out, right out + { + sampleCompBotSimple(botVertex, + leftChain, + leftEnd, + rightChain, + rightEnd, + leftGridChain, + rightGridChain, + gridIndex, + down_leftCornerWhere, + down_leftCornerIndex, + down_rightCornerWhere, + down_rightCornerIndex, + pStream); + + }//end leftout right out + }//end if separator exists + else //no separator + { + + sampleCompBotSimple(botVertex, + leftChain, + leftEnd, + rightChain, + rightEnd, + leftGridChain, + rightGridChain, + gridIndex, + down_leftCornerWhere, + down_leftCornerIndex, + down_rightCornerWhere, + down_rightCornerIndex, + pStream); + } +#endif + }//end id 0 2 +}//end if the functin + + +void sampleCompBotSimple(Real* botVertex, + vertexArray* leftChain, + Int leftEnd, + vertexArray* rightChain, + Int rightEnd, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridIndex, + Int down_leftCornerWhere, + Int down_leftCornerIndex, + Int down_rightCornerWhere, + Int down_rightCornerIndex, + primStream* pStream) +{ + //the plan is to use monotriangulation algorithm. + Int i,k; + Real* ActualTop; + Real* ActualBot; + Int ActualLeftStart, ActualLeftEnd; + Int ActualRightStart, ActualRightEnd; + + //creat an array to store the points on the grid line + gridWrap* grid = leftGridChain->getGrid(); + Int gridV = leftGridChain->getVlineIndex(gridIndex); + Int gridLeftU = leftGridChain->getUlineIndex(gridIndex); + Int gridRightU = rightGridChain->getUlineIndex(gridIndex); + Real2* gridPoints = (Real2*) malloc(sizeof(Real2) * (gridRightU - gridLeftU +1)); + assert(gridPoints); + + for(k=0, i=gridRightU; i>= gridLeftU; i--, k++) + { + gridPoints[k][0] = grid->get_u_value(i); + gridPoints[k][1] = grid->get_v_value(gridV); + } + + if(down_rightCornerWhere != 0) //rightCorner is not on lef + ActualLeftEnd = leftEnd; + else + ActualLeftEnd = down_rightCornerIndex-1; //down_rightCornerIndex will be th actualBot + + if(down_leftCornerWhere != 0) //left corner is not on let chian + ActualLeftStart = leftEnd+1; //meaning that there is no actual left section + else + ActualLeftStart = down_leftCornerIndex; + + vertexArray ActualLeftChain(max(0, ActualLeftEnd - ActualLeftStart +1) + gridRightU - gridLeftU +1); + + for(i=0; i<gridRightU - gridLeftU +1 ; i++) + ActualLeftChain.appendVertex(gridPoints[i]); + for(i=ActualLeftStart; i<= ActualLeftEnd; i++) + ActualLeftChain.appendVertex(leftChain->getVertex(i)); + + //determine ActualRightStart + if(down_rightCornerWhere != 2) //right is not on right + ActualRightStart = rightEnd +1; //meaning no section on right + else + ActualRightStart = down_rightCornerIndex; + + //determine actualrightEnd + if(down_leftCornerWhere != 2) //left is not on right + { + + ActualRightEnd = rightEnd; + } + else //left corner is on right + { + ActualRightEnd = down_leftCornerIndex-1; //down_leftCornerIndex will be the bot + + } + + //actual bot + if(down_rightCornerWhere == 2) + { + if(down_leftCornerWhere == 2) + ActualBot = rightChain->getVertex(down_leftCornerIndex); + else + ActualBot = botVertex; + } + else if(down_rightCornerWhere == 1) //right corner bot + ActualBot = botVertex; + else //down_rightCornerWhere == 0 + ActualBot = leftChain->getVertex(down_rightCornerIndex); + + ActualTop = gridPoints[0]; +/* +printf("in bot simple, actual leftChain is \n"); +ActualLeftChain.print(); +printf("Actual Top = %f,%f\n", ActualTop[0],ActualTop[1]); +printf("Actual Bot = %f,%f\n", ActualBot[0],ActualBot[1]); +printf("Actual right start = %i, end=%i\n",ActualRightStart, ActualRightEnd); +*/ + if(rightChain->getVertex(ActualRightStart)[1] == ActualTop[1]) + monoTriangulationRecGenOpt(rightChain->getVertex(ActualRightStart), + ActualBot, + &ActualLeftChain, + 0, + ActualLeftChain.getNumElements()-1, + rightChain, + ActualRightStart+1, + ActualRightEnd, + pStream); + else + monoTriangulationRecGenOpt(ActualTop, ActualBot, + &ActualLeftChain, + 1, //the first one is the top vertex + ActualLeftChain.getNumElements()-1, + rightChain, + ActualRightStart, + ActualRightEnd, + pStream); + free(gridPoints); +} + + + + diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleCompBot.h b/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleCompBot.h new file mode 100644 index 000000000..7b982794c --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleCompBot.h @@ -0,0 +1,138 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ +/* +*/ + +#ifndef _SAMPLECOMPBOT_H +#define _SAMPLECOMPBOT_H + +#include "sampleMonoPoly.h" + +void findBotLeftSegment(vertexArray* leftChain, + Int leftEnd, + Int leftCorner, + Real u, + Int& ret_index_mono, + Int& ret_index_pass); + +void findBotRightSegment(vertexArray* rightChain, + Int rightEnd, + Int rightCorner, + Real u, + Int& ret_index_mono, + Int& ret_index_pass); + + +void sampleBotRightWithGridLinePost(Real* botVertex, + vertexArray* rightChain, + Int rightEnd, + Int segIndexMono, + Int segIndexPass, + Int rightCorner, + gridWrap* grid, + Int gridV, + Int leftU, + Int rightU, + primStream* pStream); + + +void sampleBotRightWithGridLine(Real* botVertex, + vertexArray* rightChain, + Int rightEnd, + Int rightCorner, + gridWrap* grid, + Int gridV, + Int leftU, + Int rightU, + primStream* pStream); + + +void sampleBotLeftWithGridLinePost(Real* botVertex, + vertexArray* leftChain, + Int leftEnd, + Int segIndexMono, + Int segIndexPass, + Int leftCorner, + gridWrap* grid, + Int gridV, + Int leftU, + Int rightU, + primStream* pStream); + + +void sampleBotLeftWithGridLine(Real* botVertex, + vertexArray* leftChain, + Int leftEnd, + Int leftCorner, + gridWrap* grid, + Int gridV, + Int leftU, + Int rightU, + primStream* pStream); + + +Int findBotSeparator(vertexArray* leftChain, + Int leftEnd, + Int leftCorner, + vertexArray* rightChain, + Int rightEnd, + Int rightCorner, + Int& ret_sep_left, + Int& ret_sep_right); + +void sampleCompBot(Real* botVertex, + vertexArray* leftChain, + Int leftEnd, + vertexArray* rightChain, + Int rightEnd, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridIndex, + Int down_leftCornerWhere, + Int down_leftCornerIndex, + Int down_rightCornerWhere, + Int down_rightCornerIndex, + primStream* pStream); + +void sampleCompBotSimple(Real* botVertex, + vertexArray* leftChain, + Int leftEnd, + vertexArray* rightChain, + Int rightEnd, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridIndex, + Int down_leftCornerWhere, + Int down_leftCornerIndex, + Int down_rightCornerWhere, + Int down_rightCornerIndex, + primStream* pStream); + +#endif diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleCompRight.cc b/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleCompRight.cc new file mode 100644 index 000000000..d01e50018 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleCompRight.cc @@ -0,0 +1,644 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include <stdlib.h> +#include <stdio.h> +#include "gluos.h" +#include "glimports.h" +#include "zlassert.h" +#include "sampleCompRight.h" + +#define max(a,b) ((a>b)? a:b) +#define min(a,b) ((a>b)? b:a) + + + +#ifdef NOT_TAKEOUT + +/*notice that we need leftChain because the + *corners could be on the leftChain. + */ +void sampleCompRight(Real* topVertex, Real* botVertex, + vertexArray* leftChain, + Int leftStartIndex, Int leftEndIndex, + vertexArray* rightChain, + Int rightStartIndex, Int rightEndIndex, + gridBoundaryChain* rightGridChain, + Int gridIndex1, Int gridIndex2, + Int up_rightCornerWhere, + Int up_rightCornerIndex, + Int down_rightCornerWhere, + Int down_rightCornerIndex, + primStream* pStream) +{ + /*find out whether there is a trim vertex which is + *inbetween the top and bot grid lines or not. + */ + Int midIndex1; + Int midIndex2; + Int gridMidIndex1 = 0, gridMidIndex2 = 0; + //midIndex1: array[i] <= v, array[i+1] > v + //midIndex2: array[i] >= v, array[i+1] < v + midIndex1 = rightChain->findIndexBelowGen(rightGridChain->get_v_value(gridIndex1), + rightStartIndex, + rightEndIndex); + midIndex2 = -1; //initilization + if(midIndex1 <= rightEndIndex && gridIndex1 < gridIndex2) + if(rightChain->getVertex(midIndex1)[1] >= rightGridChain->get_v_value(gridIndex2)) + { + //midIndex2 must exist: + midIndex2 = rightChain->findIndexAboveGen(rightGridChain->get_v_value(gridIndex2), + midIndex1, //midIndex1<=midIndex2 + rightEndIndex); + //find gridMidIndex1 so that either it=gridIndex1 when the gridline is + // at the same height as trim vertex midIndex1, or it is the last one + //which is strictly above midIndex1. + { + Real temp = rightChain->getVertex(midIndex1)[1]; + if(rightGridChain->get_v_value(gridIndex1) == temp) + gridMidIndex1 = gridIndex1; + else + { + gridMidIndex1 = gridIndex1; + while(rightGridChain->get_v_value(gridMidIndex1) > temp) + gridMidIndex1++; + gridMidIndex1--; + } + }//end of find gridMindIndex1 + //find gridMidIndex2 so that it is the (first one below or equal + //midIndex) last one above or equal midIndex2 + { + Real temp = rightChain->getVertex(midIndex2)[1]; + for(gridMidIndex2 = gridMidIndex1+1; gridMidIndex2 <= gridIndex2; gridMidIndex2++) + if(rightGridChain->get_v_value(gridMidIndex2) <= temp) + break; + + assert(gridMidIndex2 <= gridIndex2); + }//end of find gridMidIndex2 + } + + + + //to interprete the corner information + Real* cornerTop; + Real* cornerBot; + Int cornerRightStart; + Int cornerRightEnd; + Int cornerLeftUpEnd; + Int cornerLeftDownStart; + if(up_rightCornerWhere == 2) //right corner is on right chain + { + cornerTop = rightChain->getVertex(up_rightCornerIndex); + cornerRightStart = up_rightCornerIndex+1; + cornerLeftUpEnd = -1; //no left + } + else if(up_rightCornerWhere == 1) //right corner is on top + { + cornerTop = topVertex; + cornerRightStart = rightStartIndex; + cornerLeftUpEnd = -1; //no left + } + else //right corner is on left chain + { + cornerTop = topVertex; + cornerRightStart = rightStartIndex; + cornerLeftUpEnd = up_rightCornerIndex; + } + + if(down_rightCornerWhere == 2) //right corner is on right chan + { + cornerBot = rightChain->getVertex(down_rightCornerIndex); + cornerRightEnd = down_rightCornerIndex-1; + cornerLeftDownStart = leftEndIndex+1; //no left + } + else if (down_rightCornerWhere == 1) //right corner is at bot + { + cornerBot = botVertex; + cornerRightEnd = rightEndIndex; + cornerLeftDownStart = leftEndIndex+1; //no left + } + else //right corner is on the left chain + { + cornerBot = botVertex; + cornerRightEnd = rightEndIndex; + cornerLeftDownStart = down_rightCornerIndex; + } + + //sample + if(midIndex2 >= 0) //there is a trm point between grid lines + { + + sampleRightSingleTrimEdgeRegionGen(cornerTop, rightChain->getVertex(midIndex1), + rightChain, + cornerRightStart, + midIndex1-1, + rightGridChain, + gridIndex1, + gridMidIndex1, + leftChain, + leftStartIndex, + cornerLeftUpEnd, + 0, //no left down section, + -1, + pStream); + + sampleRightSingleTrimEdgeRegionGen(rightChain->getVertex(midIndex2), + cornerBot, + rightChain, + midIndex2+1, + cornerRightEnd, + rightGridChain, + gridMidIndex2, + gridIndex2, + leftChain, + 0, //no left up section + -1, + cornerLeftDownStart, + leftEndIndex, + pStream); + + sampleRightStripRecF(rightChain, + midIndex1, + midIndex2, + rightGridChain, + gridMidIndex1, + gridMidIndex2, + pStream); + + } + else + { + sampleRightSingleTrimEdgeRegionGen(cornerTop, cornerBot, + rightChain, + cornerRightStart, + cornerRightEnd, + rightGridChain, + gridIndex1, + gridIndex2, + leftChain, + leftStartIndex, + cornerLeftUpEnd, + cornerLeftDownStart, + leftEndIndex, + pStream); + } +} + +void sampleRightSingleTrimEdgeRegionGen(Real topVertex[2], Real botVertex[2], + vertexArray* rightChain, + Int rightStart, + Int rightEnd, + gridBoundaryChain* gridChain, + Int gridBeginIndex, + Int gridEndIndex, + vertexArray* leftChain, + Int leftUpBegin, + Int leftUpEnd, + Int leftDownBegin, + Int leftDownEnd, + primStream* pStream) +{ + Int i,k; + /*creat an array to store all the up and down secments of the left chain, + *and the right end grid points + * + *although vertex array is a dynamic array, but to gain efficiency, + *it is better to initiliza the exact array size + */ + vertexArray vArray(gridEndIndex-gridBeginIndex+1 + + max(0,leftUpEnd - leftUpBegin+1)+ + max(0,leftDownEnd - leftDownBegin+1)); + //append the vertices on the up section of the left chain + for(i=leftUpBegin; i<= leftUpEnd; i++) + vArray.appendVertex(leftChain->getVertex(i)); + + //append the vertices of the right extremal grid points, + //and at the same time, perform triangulation for the stair cases + vArray.appendVertex(gridChain->get_vertex(gridBeginIndex)); + + for(k=1, i=gridBeginIndex+1; i<= gridEndIndex; i++, k++) + { + vArray.appendVertex(gridChain->get_vertex(i)); + + //output the fan of the grid points of the (i)th and (i-1)th grid line. + gridChain->rightEndFan(i, pStream); + } + + //append all the vertices on the down section of the left chain + for(i=leftDownBegin; i<= leftDownEnd; i++) + vArray.appendVertex(leftChain->getVertex(i)); + monoTriangulationRecGen(topVertex, botVertex, + &vArray, 0, vArray.getNumElements()-1, + rightChain, rightStart, rightEnd, + pStream); +} + +void sampleRightSingleTrimEdgeRegion(Real upperVert[2], Real lowerVert[2], + gridBoundaryChain* gridChain, + Int beginIndex, + Int endIndex, + primStream* pStream) +{ + Int i,k; + vertexArray vArray(endIndex-beginIndex+1); + vArray.appendVertex(gridChain->get_vertex(beginIndex)); + for(k=1, i=beginIndex+1; i<= endIndex; i++, k++) + { + vArray.appendVertex(gridChain->get_vertex(i)); + //output the fan of the grid points of the (i)_th and i-1th gridLine + gridChain->rightEndFan(i, pStream); + } + monoTriangulation2(upperVert, lowerVert, &vArray, 0, endIndex-beginIndex, + 1, //increase chain (to the left) + pStream); +} + + +/*the gridlines from rightGridChainStartIndex to + *rightGridChainEndIndex are assumed to form a + *connected componenet + *the trm vertex of topRightIndex is assumed to be below + *or equal the first gridLine, and the trm vertex of + *botRightIndex is assumed to be above or equal the last gridline + **there could be multipe trm vertices equal to the last gridline, but + **only one could be equal to top gridline. shape: ____| (recall that + **for left chain recF, we allow shape: |---- + *if botRightIndex<topRightIndex, then no connected componenet exists, and + *no triangles are generated. + *Othewise, botRightIndex>= topRightIndex, there is at least one triangles to + *output + */ +void sampleRightStripRecF(vertexArray* rightChain, + Int topRightIndex, + Int botRightIndex, + gridBoundaryChain* rightGridChain, + Int rightGridChainStartIndex, + Int rightGridChainEndIndex, + primStream* pStream + ) +{ + + //sstop conditionL: if topRightIndex > botRightIndex, then stop + if(topRightIndex > botRightIndex) + return; + + //if there is only one grid line, return + if(rightGridChainStartIndex >= rightGridChainEndIndex) + return; + + + assert(rightChain->getVertex(topRightIndex)[1] <= rightGridChain->get_v_value(rightGridChainStartIndex) && + rightChain->getVertex(botRightIndex)[1] >= rightGridChain->get_v_value(rightGridChainEndIndex)); + + //firstfind the first trim vertex which is strictly below the second top + //grid line: index1. + Real secondGridChainV = rightGridChain->get_v_value(rightGridChainStartIndex+1); + Int index1 = topRightIndex; + while(rightChain->getVertex(index1)[1] >= secondGridChainV){ + index1++; + if(index1 > botRightIndex) + break; + } + //now rightChain->getVertex(index1-1)[1] >= secondGridChainV and + //rightChain->getVertex(index1)[1] < secondGridChainV and + //we should include index1-1 to perform a gridStep + index1--; + + //now we have rightChain->getVertex(index1)[1] >= secondGridChainV, and + //rightChain->getVertex(index1+1)[1] < secondGridChainV + sampleRightOneGridStep(rightChain, topRightIndex, index1, rightGridChain, rightGridChainStartIndex, pStream); + + //if rightChain->getVertex(index1)[1] ==secondGridChainV then we can + //recurvesively to the rest + if(rightChain->getVertex(index1)[1] == secondGridChainV) + { + + + sampleRightStripRecF(rightChain, index1, botRightIndex, rightGridChain, rightGridChainStartIndex+1, rightGridChainEndIndex, pStream); + } + else if(index1 < botRightIndex) + { + //otherwise, we have rightChain->getVertex(index1)[1] > secondV + //let the next trim vertex be nextTrimVertex, (which should be strictly + //below the second grid line). Find the last grid line index2 which is STRICTLY ABOVE + //nextTrimVertex. + //sample one trm edge region. + Real *uppervert, *lowervert; + uppervert = rightChain->getVertex(index1); + lowervert = rightChain->getVertex(index1+1); //okay since index1<botRightindex + Int index2 = rightGridChainStartIndex+1; + while(rightGridChain->get_v_value(index2) > lowervert[1]) + { + index2++; + if(index2 > rightGridChainEndIndex) + break; + } + index2--; + + sampleRightSingleTrimEdgeRegion(uppervert, lowervert, rightGridChain, rightGridChainStartIndex+1, index2, pStream); + + //recursion + sampleRightStripRecF(rightChain, index1+1, botRightIndex, rightGridChain, index2, rightGridChainEndIndex, pStream); + } +} + +//the degenerate case of sampleRightOneGridStep +void sampleRightOneGridStepNoMiddle(vertexArray* rightChain, + Int beginRightIndex, + Int endRightIndex, + gridBoundaryChain* rightGridChain, + Int rightGridChainStartIndex, + primStream* pStream) +{ + /*since there is no middle, there is at most one point which is on the + *second grid line, there could be multiple points on the first (top) + *grid line. + */ + rightGridChain->rightEndFan(rightGridChainStartIndex+1, pStream); + monoTriangulation2(rightGridChain->get_vertex(rightGridChainStartIndex), + rightGridChain->get_vertex(rightGridChainStartIndex+1), + rightChain, + beginRightIndex, + endRightIndex, + 0, //decrease chain + pStream); +} + +//sampling the right area in between two grid lines +//shape: _________| +void sampleRightOneGridStep(vertexArray* rightChain, + Int beginRightIndex, + Int endRightIndex, + gridBoundaryChain* rightGridChain, + Int rightGridChainStartIndex, + primStream* pStream) +{ + if(checkMiddle(rightChain, beginRightIndex, endRightIndex, + rightGridChain->get_v_value(rightGridChainStartIndex), + rightGridChain->get_v_value(rightGridChainStartIndex+1))<0) + { + sampleRightOneGridStepNoMiddle(rightChain, beginRightIndex, endRightIndex, rightGridChain, rightGridChainStartIndex, pStream); + return; + } + + //copy into a polygn + { + directedLine* poly = NULL; + sampledLine* sline; + directedLine* dline; + gridWrap* grid = rightGridChain->getGrid(); + float vert1[2]; + float vert2[2]; + Int i; + + Int innerInd = rightGridChain->getInnerIndex(rightGridChainStartIndex+1); + Int upperInd = rightGridChain->getUlineIndex(rightGridChainStartIndex); + Int lowerInd = rightGridChain->getUlineIndex(rightGridChainStartIndex+1); + Real upperV = rightGridChain->get_v_value(rightGridChainStartIndex); + Real lowerV = rightGridChain->get_v_value(rightGridChainStartIndex+1); + + //the upper gridline + vert1[1]=vert2[1]=upperV; + for(i=upperInd; + i>innerInd; + i--) + { + vert1[0]=grid->get_u_value(i); + vert2[0]=grid->get_u_value(i-1); + sline = new sampledLine(vert1, vert2); + dline = new directedLine(INCREASING, sline); + if(poly == NULL) + poly = dline; + else + poly->insert(dline); + } + + //the vertical grid line segment + vert1[0]=vert2[0] = grid->get_u_value(innerInd); + vert1[1]=upperV; + vert2[1]=lowerV; + sline=new sampledLine(vert1, vert2); + dline=new directedLine(INCREASING, sline); + if(poly == NULL) + poly = dline; + else + poly->insert(dline); + + //the lower grid line + vert1[1]=vert2[1]=lowerV; + for(i=innerInd; i<lowerInd; i++) + { + vert1[0] = grid->get_u_value(i); + vert2[0] = grid->get_u_value(i+1); + sline = new sampledLine(vert1, vert2); + dline = new directedLine(INCREASING, sline); + poly->insert(dline); + } + + //the edge connecting lower grid to right chain + vert1[0]=grid->get_u_value(lowerInd); + sline = new sampledLine(vert1, rightChain->getVertex(endRightIndex)); + dline = new directedLine(INCREASING, sline); + poly->insert(dline); + + + //the right Chain + for(i=endRightIndex; i>beginRightIndex; i--) + { + sline = new sampledLine(rightChain->getVertex(i), rightChain->getVertex(i-1)); + dline = new directedLine(INCREASING, sline); + poly->insert(dline); + } + + //the edge connecting right chain with upper grid + vert2[1]=upperV; + vert2[0]=grid->get_u_value(upperInd); + sline = new sampledLine(rightChain->getVertex(beginRightIndex), vert2); + dline = new directedLine(INCREASING, sline); + poly->insert(dline); + monoTriangulationOpt(poly, pStream); + //clean up + poly->deleteSinglePolygonWithSline(); + + return; + } + + //this following code cannot be reached, but leave it for debuggig purpose. + Int i; + //find the maximal U-monotone chain of beginRightIndex, beginRightIndex+1,... + i=beginRightIndex; + Real prevU = rightChain->getVertex(i)[0]; + for(i=beginRightIndex+1; i<= endRightIndex; i++){ + Real thisU = rightChain->getVertex(i)[0]; + if(thisU < prevU) + prevU = thisU; + else + break; + } + //from beginRightIndex to i-1 is strictly U-monotne + //if(i-1==beginRightIndex and the vertex of rightchain is on the first + //gridline, then we should use 2 vertices on the right chain. Of we only + //use one (begin), we would output degenrate triangles. + if(i-1 == beginRightIndex && rightChain->getVertex(beginRightIndex)[1] == rightGridChain->get_v_value(rightGridChainStartIndex)) + i++; + + Int j = endRightIndex -1; + if(rightGridChain->getInnerIndex(rightGridChainStartIndex+1) < rightGridChain->getUlineIndex(rightGridChainStartIndex+1)) + { + j = rightChain->findDecreaseChainFromEnd(i-1/*beginRightIndex*/, endRightIndex); + Int temp = endRightIndex; + //now from j+1 to end is strictly U-monotone. + //if j+1 is on the last grid line, then we wat to skip to the vertex + //whcih is strictly above the second grid line. This vertex must exist + //since there is a middle vertex + if(j+1 == endRightIndex) + { + while(rightChain->getVertex(j+1)[1] == rightGridChain->get_v_value(rightGridChainStartIndex+1)) + j--; + + monoTriangulation2(rightChain->getVertex(j+1), + rightGridChain->get_vertex(rightGridChainStartIndex+1), + rightChain, + j+2, + endRightIndex, + 0, //a decrease chain + pStream); + + temp = j+1; + } + + stripOfFanRight(rightChain, temp, j+1, rightGridChain->getGrid(), + rightGridChain->getVlineIndex(rightGridChainStartIndex+1), + rightGridChain->getInnerIndex(rightGridChainStartIndex+1), + rightGridChain->getUlineIndex(rightGridChainStartIndex+1), + pStream, + 0 //the grid line is below the trim line + ); + + } + + + stripOfFanRight(rightChain, i-1, beginRightIndex, rightGridChain->getGrid(), + rightGridChain->getVlineIndex(rightGridChainStartIndex), + rightGridChain->getInnerIndex(rightGridChainStartIndex+1), + rightGridChain->getUlineIndex(rightGridChainStartIndex), + pStream, + 1 //the grid line is above the trm lines + ); + + //monotone triangulate the remaining rightchain together with the + //two vertices on the two grid v-lines + Real vert[2][2]; + vert[0][0] = vert[1][0] = rightGridChain->getInner_u_value(rightGridChainStartIndex+1); + vert[0][1] = rightGridChain->get_v_value(rightGridChainStartIndex); + vert[1][1] = rightGridChain->get_v_value(rightGridChainStartIndex+1); + + monoTriangulation2(&vert[0][0], + &vert[1][0], + rightChain, + i-1, + j+1, + 0, ///a decreae chain + pStream); +} + +#endif + +void stripOfFanRight(vertexArray* rightChain, + Int largeIndex, + Int smallIndex, + gridWrap* grid, + Int vlineIndex, + Int ulineSmallIndex, + Int ulineLargeIndex, + primStream* pStream, + Int gridLineUp /*1 if the grid line is above the trim lines*/ + ) +{ + assert(largeIndex >= smallIndex); + + Real grid_v_value; + grid_v_value = grid->get_v_value(vlineIndex); + + Real2* trimVerts=(Real2*) malloc(sizeof(Real2)* (largeIndex-smallIndex+1)); + assert(trimVerts); + + + Real2* gridVerts=(Real2*) malloc(sizeof(Real2)* (ulineLargeIndex-ulineSmallIndex+1)); + assert(gridVerts); + + Int k,i; + if(! gridLineUp) /*trim line is above grid line, so trim vertices are going right when index increases*/ + for(k=0, i=smallIndex; i<=largeIndex; i++, k++) + { + trimVerts[k][0] = rightChain->getVertex(i)[0]; + trimVerts[k][1] = rightChain->getVertex(i)[1]; + } + else + for(k=0, i=largeIndex; i>=smallIndex; i--, k++) + { + trimVerts[k][0] = rightChain->getVertex(i)[0]; + trimVerts[k][1] = rightChain->getVertex(i)[1]; + } + + for(k=0, i=ulineSmallIndex; i<= ulineLargeIndex; i++, k++) + { + gridVerts[k][0] = grid->get_u_value(i); + gridVerts[k][1] = grid_v_value; + } + + if(gridLineUp) + triangulateXYMono( + ulineLargeIndex-ulineSmallIndex+1, gridVerts, + largeIndex-smallIndex+1, trimVerts, + pStream); + else + triangulateXYMono(largeIndex-smallIndex+1, trimVerts, + ulineLargeIndex-ulineSmallIndex+1, gridVerts, + pStream); + free(trimVerts); + free(gridVerts); +} + + + + + + + + + diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleCompRight.h b/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleCompRight.h new file mode 100644 index 000000000..4670b87ca --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleCompRight.h @@ -0,0 +1,117 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ +/* +*/ + +#ifndef _SAMPLECOMPRIGHT_H +#define _SAMPLECOMPRIGHT_H + +#define NOT_TAKEOUT + +#include "sampleMonoPoly.h" +void stripOfFanRight(vertexArray* rightChain, + Int largeIndex, + Int smallIndex, + gridWrap* grid, + Int vlineIndex, + Int ulineSmallIndex, + Int ulineLargeIndex, + primStream* pStream, + Int gridLineUp /*1 if grid line is above the trim lines */ + ); + +#ifdef NOT_TAKEOUT +void sampleRightStripRecF(vertexArray* rightChain, + Int topRightIndex, + Int botRightIndex, + gridBoundaryChain* rightGridChain, + Int rightGridChainStartIndex, + Int rightGridChainEndIndex, + primStream* pStream + ); +//the degenerate case of sampleRightOneGridStep +void sampleRightOneGridStepNoMiddle(vertexArray* rightChain, + Int beginRightIndex, + Int endRightIndex, + gridBoundaryChain* rightGridChain, + Int rightGridChainStartIndex, + primStream* pStream); +//sampling the right area in between two grid lines +//shape: _________| +void sampleRightOneGridStep(vertexArray* rightChain, + Int beginRightIndex, + Int endRightIndex, + gridBoundaryChain* rightGridChain, + Int rightGridChainStartIndex, + primStream* pStream); +void sampleRightSingleTrimEdgeRegion(Real upperVert[2], Real lowerVert[2], + gridBoundaryChain* gridChain, + Int beginIndex, + Int endIndex, + primStream* pStream); +//the degenerate case of sampleRightOneGridStep +void sampleRightOneGridStepNoMiddle(vertexArray* rightChain, + Int beginRightIndex, + Int endRightIndex, + gridBoundaryChain* rightGridChain, + Int rightGridChainStartIndex, + primStream* pStream); + +void sampleCompRight(Real* topVertex, Real* botVertex, + vertexArray* leftChain, + Int leftStartIndex, Int leftEndIndex, + vertexArray* rightChain, + Int rightStartIndex, Int rightEndIndex, + gridBoundaryChain* rightGridChain, + Int gridIndex1, Int gridIndex2, + Int up_leftCornerWhere, + Int up_leftCornerIndex, + Int down_leftCornerWhere, + Int down_leftCornerIndex, + primStream* pStream); + +void sampleRightSingleTrimEdgeRegionGen(Real topVert[2], Real botVert[2], + vertexArray* rightChain, + Int rightStart, + Int rightEnd, + gridBoundaryChain* gridChain, + Int gridBegindex, + Int gridEndIndex, + vertexArray* leftChain, + Int leftUpBegin, + Int leftUpEnd, + Int leftDownBegin, + Int leftDownEnd, + primStream* pStream); +#endif + +#endif + + diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleCompTop.cc b/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleCompTop.cc new file mode 100644 index 000000000..b7b929623 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleCompTop.cc @@ -0,0 +1,1030 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <math.h> +#include "zlassert.h" +#include "sampleCompTop.h" +#include "sampleCompRight.h" + +#define max(a,b) ((a>b)? a:b) + +//return : index_small, and index_large, +//from [small, large] is strictly U-monotne, +//from [large+1, end] is <u +//and vertex[large][0] is >= u +//if eveybody is <u, the large = start-1. +//otherwise both large and small are meaningful and we have start<=small<=large<=end +void findTopLeftSegment(vertexArray* leftChain, + Int leftStart, + Int leftEnd, + Real u, + Int& ret_index_small, + Int& ret_index_large + ) +{ + Int i; + assert(leftStart <= leftEnd); + for(i=leftEnd; i>= leftStart; i--) + { + if(leftChain->getVertex(i)[0] >= u) + break; + } + ret_index_large = i; + if(ret_index_large >= leftStart) + { + for(i=ret_index_large; i>leftStart; i--) + { + if(leftChain->getVertex(i-1)[0] <= leftChain->getVertex(i)[0]) + break; + } + ret_index_small = i; + } +} + +void findTopRightSegment(vertexArray* rightChain, + Int rightStart, + Int rightEnd, + Real u, + Int& ret_index_small, + Int& ret_index_large) +{ + Int i; + assert(rightStart<=rightEnd); + for(i=rightEnd; i>=rightStart; i--) + { + if(rightChain->getVertex(i)[0] <= u) + break; + } + ret_index_large = i; + if(ret_index_large >= rightStart) + { + for(i=ret_index_large; i>rightStart;i--) + { + if(rightChain->getVertex(i-1)[0] >= rightChain->getVertex(i)[0]) + break; + } + ret_index_small = i; + } +} + + +void sampleTopRightWithGridLinePost(Real* topVertex, + vertexArray* rightChain, + Int rightStart, + Int segIndexSmall, + Int segIndexLarge, + Int rightEnd, + gridWrap* grid, + Int gridV, + Int leftU, + Int rightU, + primStream* pStream) +{ + //the possible section which is to the right of rightU + if(segIndexLarge < rightEnd) + { + Real *tempTop; + if(segIndexLarge >= rightStart) + tempTop = rightChain->getVertex(segIndexLarge); + else + tempTop = topVertex; + Real tempBot[2]; + tempBot[0] = grid->get_u_value(rightU); + tempBot[1] = grid->get_v_value(gridV); +monoTriangulationRecGenOpt(tempTop, tempBot, + NULL, 1,0, + rightChain, segIndexLarge+1, rightEnd, + pStream); +/* + monoTriangulation2(tempTop, tempBot, + rightChain, + segIndexLarge+1, + rightEnd, + 0, //a decrease chian + pStream); +*/ + + } + + //the possible section which is strictly Umonotone + if(segIndexLarge >= rightStart) + { + stripOfFanRight(rightChain, segIndexLarge, segIndexSmall, grid, gridV, leftU, rightU, pStream, 0); + Real tempBot[2]; + tempBot[0] = grid->get_u_value(leftU); + tempBot[1] = grid->get_v_value(gridV); + monoTriangulation2(topVertex, tempBot, rightChain, rightStart, segIndexSmall, 0, pStream); + } + else //the topVertex forms a fan with the grid points + grid->outputFanWithPoint(gridV, leftU, rightU, topVertex, pStream); +} + +void sampleTopRightWithGridLine(Real* topVertex, + vertexArray* rightChain, + Int rightStart, + Int rightEnd, + gridWrap* grid, + Int gridV, + Int leftU, + Int rightU, + primStream* pStream + ) +{ + //if right chian is empty, then there is only one topVertex with one grid line + if(rightEnd < rightStart){ + grid->outputFanWithPoint(gridV, leftU, rightU, topVertex, pStream); + return; + } + + Int segIndexSmall, segIndexLarge; + findTopRightSegment(rightChain, + rightStart, + rightEnd, + grid->get_u_value(rightU), + segIndexSmall, + segIndexLarge + ); + sampleTopRightWithGridLinePost(topVertex, rightChain, + rightStart, + segIndexSmall, + segIndexLarge, + rightEnd, + grid, + gridV, + leftU, + rightU, + pStream); +} + + +void sampleTopLeftWithGridLinePost(Real* topVertex, + vertexArray* leftChain, + Int leftStart, + Int segIndexSmall, + Int segIndexLarge, + Int leftEnd, + gridWrap* grid, + Int gridV, + Int leftU, + Int rightU, + primStream* pStream) +{ + //the possible section which is to the left of leftU + + if(segIndexLarge < leftEnd) + { + Real *tempTop; + if(segIndexLarge >= leftStart) + tempTop = leftChain->getVertex(segIndexLarge); + else + tempTop = topVertex; + Real tempBot[2]; + tempBot[0] = grid->get_u_value(leftU); + tempBot[1] = grid->get_v_value(gridV); + + monoTriangulation2(tempTop, tempBot, + leftChain, + segIndexLarge+1, + leftEnd, + 1, //a increase chian + pStream); + } + + //the possible section which is strictly Umonotone + if(segIndexLarge >= leftStart) + { + //if there are grid points which are to the right of topV, + //then we should use topVertex to form a fan with these points to + //optimize the triangualtion + int do_optimize=1; + if(topVertex[0] >= grid->get_u_value(rightU)) + do_optimize = 0; + else + { + //we also have to make sure that topVertex are the right most vertex + //on the chain. + int i; + for(i=leftStart; i<=segIndexSmall; i++) + if(leftChain->getVertex(i)[0] >= topVertex[0]) + { + do_optimize = 0; + break; + } + } + + if(do_optimize) + { + //find midU so that grid->get_u_value(midU) >= topVertex[0] + //and grid->get_u_value(midU-1) < topVertex[0] + int midU=rightU; + while(grid->get_u_value(midU) >= topVertex[0]) + { + midU--; + if(midU < leftU) + break; + } + midU++; + + grid->outputFanWithPoint(gridV, midU, rightU, topVertex, pStream); + stripOfFanLeft(leftChain, segIndexLarge, segIndexSmall, grid, gridV, leftU, midU, pStream, 0); + Real tempBot[2]; + tempBot[0] = grid->get_u_value(midU); + tempBot[1] = grid->get_v_value(gridV); + monoTriangulation2(topVertex, tempBot, leftChain, leftStart, segIndexSmall, 1, pStream); + } + else //not optimize + { + + stripOfFanLeft(leftChain, segIndexLarge, segIndexSmall, grid, gridV, leftU, rightU, pStream, 0); + Real tempBot[2]; + tempBot[0] = grid->get_u_value(rightU); + tempBot[1] = grid->get_v_value(gridV); + monoTriangulation2(topVertex, tempBot, leftChain, leftStart, segIndexSmall, 1, pStream); + } + } + else //the topVertex forms a fan with the grid points + grid->outputFanWithPoint(gridV, leftU, rightU, topVertex, pStream); +} + + +void sampleTopLeftWithGridLine(Real* topVertex, + vertexArray* leftChain, + Int leftStart, + Int leftEnd, + gridWrap* grid, + Int gridV, + Int leftU, + Int rightU, + primStream* pStream + ) +{ + Int segIndexSmall, segIndexLarge; + //if left chain is empty, then there is only one top vertex with one grid + // line + if(leftEnd < leftStart) { + grid->outputFanWithPoint(gridV, leftU, rightU, topVertex, pStream); + return; + } + findTopLeftSegment(leftChain, + leftStart, + leftEnd, + grid->get_u_value(leftU), + segIndexSmall, + segIndexLarge + ); + sampleTopLeftWithGridLinePost(topVertex, + leftChain, + leftStart, + segIndexSmall, + segIndexLarge, + leftEnd, + grid, + gridV, + leftU, + rightU, + pStream); +} + + +//return 1 if saprator exits, 0 otherwise +Int findTopSeparator(vertexArray* leftChain, + Int leftStartIndex, + Int leftEndIndex, + vertexArray* rightChain, + Int rightStartIndex, + Int rightEndIndex, + Int& ret_sep_left, + Int& ret_sep_right) +{ + + Int oldLeftI, oldRightI, newLeftI, newRightI; + Int i,j,k; + Real leftMax /*= leftChain->getVertex(leftEndIndex)[0]*/; + Real rightMin /*= rightChain->getVertex(rightEndIndex)[0]*/; + if(leftChain->getVertex(leftEndIndex)[1] > rightChain->getVertex(rightEndIndex)[1]) //left higher + { + oldLeftI = leftEndIndex+1; + oldRightI = rightEndIndex; + leftMax = leftChain->getVertex(leftEndIndex)[0] - Real(1.0); //initilza to left of leftU + rightMin = rightChain->getVertex(rightEndIndex)[0]; + } + else + { + oldLeftI = leftEndIndex; + oldRightI = rightEndIndex+1; + leftMax = leftChain->getVertex(leftEndIndex)[0]; + rightMin = rightChain->getVertex(rightEndIndex)[0] + Real(1.0); + } + + //i: the current working leftChain index, + //j: the current working rightChain index, + //if left(i) is higher than right(j), then the two chains beloew right(j) are separated. + //else the two chains below left(i) are separeated. + i=leftEndIndex; + j=rightEndIndex; + while(1) + { + newLeftI = oldLeftI; + newRightI = oldRightI; + + if(i<leftStartIndex) //left chain is done, go through remining right chain. + { + for(k=j-1; k>= rightStartIndex; k--) + { + if(rightChain->getVertex(k)[0] > leftMax) //no conflict + { + //update oldRightI if necessary + if(rightChain->getVertex(k)[0] < rightMin) + { + rightMin = rightChain->getVertex(k)[0]; + oldRightI = k; + } + } + else //there is a conflict + break; //the for-loop. below right(k-1) is seperated: oldLeftI, oldRightI. + } + break; //the while loop + } + else if(j<rightStartIndex) //rightChain is done + { + for(k=i-1; k>= leftStartIndex; k--) + { + if(leftChain->getVertex(k)[0] < rightMin) //no conflict + { + //update oldLeftI if necessary + if(leftChain->getVertex(k)[0] > leftMax) + { + leftMax = leftChain->getVertex(k)[0]; + oldLeftI = k; + } + } + else //there is a conflict + break; //the for loop + } + break; //the while loop + } + else if(leftChain->getVertex(i)[1] > rightChain->getVertex(j)[1]) //left hgiher + { + if(leftChain->getVertex(i)[0] > leftMax) //update leftMax and newLeftI. + { + leftMax = leftChain->getVertex(i)[0]; + newLeftI = i; + } + for(k=j-1; k>= rightStartIndex; k--) //update rightMin and newRightI. + { + if(rightChain->getVertex(k)[1] > leftChain->getVertex(i)[1]) + break; + if(rightChain->getVertex(k)[0] < rightMin) + { + rightMin = rightChain->getVertex(k)[0]; + newRightI = k; + } + } + j = k; //next working j, since j will be higher than i in next loop + if(leftMax >= rightMin) //there is a conflict + break; + else //still no conflict + { + oldLeftI = newLeftI; + oldRightI = newRightI; + } + } + else //right higher + { + if(rightChain->getVertex(j)[0] < rightMin) + { + rightMin = rightChain->getVertex(j)[0]; + newRightI = j; + } + for(k=i-1; k>= leftStartIndex; k--) + { + if(leftChain->getVertex(k)[1] > rightChain->getVertex(j)[1]) + break; + if(leftChain->getVertex(k)[0] > leftMax) + { + leftMax = leftChain->getVertex(k)[0]; + newLeftI = k; + } + } + i = k; //next working i, since i will be higher than j next loop + + if(leftMax >= rightMin) //there is a conflict + break; + else //still no conflict + { + oldLeftI = newLeftI; + oldRightI = newRightI; + } + } + }//end of while loop + //now oldLeftI and oldRightI are the desired separeator index, notice that there are not necessarily valid + if(oldLeftI > leftEndIndex || oldRightI > rightEndIndex) + return 0; + else + { + ret_sep_left = oldLeftI; + ret_sep_right = oldRightI; + return 1; + } +} + + +void sampleCompTop(Real* topVertex, + vertexArray* leftChain, + Int leftStartIndex, + vertexArray* rightChain, + Int rightStartIndex, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridIndex1, + Int up_leftCornerWhere, + Int up_leftCornerIndex, + Int up_rightCornerWhere, + Int up_rightCornerIndex, + primStream* pStream) +{ + if(up_leftCornerWhere == 1 && up_rightCornerWhere == 1) //the top is topVertex with possible grid points + { + leftGridChain->getGrid()->outputFanWithPoint(leftGridChain->getVlineIndex(gridIndex1), + leftGridChain->getUlineIndex(gridIndex1), + rightGridChain->getUlineIndex(gridIndex1), + topVertex, + pStream); + return; + } + + else if(up_leftCornerWhere != 0) + { + Real* tempTop; + Int tempRightStart; + if(up_leftCornerWhere == 1){ + tempRightStart = rightStartIndex; + tempTop = topVertex; + } + else + { + tempRightStart = up_leftCornerIndex+1; + tempTop = rightChain->getVertex(up_leftCornerIndex); + } + sampleTopRightWithGridLine(tempTop, rightChain, tempRightStart, up_rightCornerIndex, + rightGridChain->getGrid(), + leftGridChain->getVlineIndex(gridIndex1), + leftGridChain->getUlineIndex(gridIndex1), + rightGridChain->getUlineIndex(gridIndex1), + pStream); + } + else if(up_rightCornerWhere != 2) + { + Real* tempTop; + Int tempLeftStart; + if(up_rightCornerWhere == 1) + { + tempLeftStart = leftStartIndex; + tempTop = topVertex; + } + else //0 + { + tempLeftStart = up_rightCornerIndex+1; + tempTop = leftChain->getVertex(up_rightCornerIndex); + } +/* + sampleTopLeftWithGridLine(tempTop, leftChain, tempLeftStart, up_leftCornerIndex, + leftGridChain->getGrid(), + leftGridChain->getVlineIndex(gridIndex1), + leftGridChain->getUlineIndex(gridIndex1), + rightGridChain->getUlineIndex(gridIndex1), + pStream); +*/ + sampleCompTopSimple(topVertex, + leftChain, + leftStartIndex, + rightChain, + rightStartIndex, + leftGridChain, + rightGridChain, + gridIndex1, + up_leftCornerWhere, + up_leftCornerIndex, + up_rightCornerWhere, + up_rightCornerIndex, + pStream); + } + else //up_leftCornerWhere == 0, up_rightCornerWhere == 2. + { + sampleCompTopSimple(topVertex, + leftChain, + leftStartIndex, + rightChain, + rightStartIndex, + leftGridChain, + rightGridChain, + gridIndex1, + up_leftCornerWhere, + up_leftCornerIndex, + up_rightCornerWhere, + up_rightCornerIndex, + pStream); + return; +#ifdef NOT_REACHABLE //code is not reachable, for test purpose only + //the following code is trying to do some optimization, but not quite working, also see sampleCompBot.C: + Int sep_left, sep_right; + if(findTopSeparator(leftChain, + leftStartIndex, + up_leftCornerIndex, + rightChain, + rightStartIndex, + up_rightCornerIndex, + sep_left, + sep_right) + ) //separator exists + { + + if( leftChain->getVertex(sep_left)[0] >= leftGridChain->get_u_value(gridIndex1) && + rightChain->getVertex(sep_right)[0] <= rightGridChain->get_u_value(gridIndex1)) + { + Int gridSep; + Int segLeftSmall, segLeftLarge, segRightSmall, segRightLarge; + Int valid=1; //whether the gridStep is valid or not. + findTopLeftSegment(leftChain, + sep_left, + up_leftCornerIndex, + leftGridChain->get_u_value(gridIndex1), + segLeftSmall, + segLeftLarge); + findTopRightSegment(rightChain, + sep_right, + up_rightCornerIndex, + rightGridChain->get_u_value(gridIndex1), + segRightSmall, + segRightLarge); + if(leftChain->getVertex(segLeftSmall)[1] >= rightChain->getVertex(segRightSmall)[1]) + { + gridSep = rightGridChain->getUlineIndex(gridIndex1); + while(leftGridChain->getGrid()->get_u_value(gridSep) > leftChain->getVertex(segLeftSmall)[0]) + gridSep--; + if(segLeftSmall<segLeftLarge) + if(leftGridChain->getGrid()->get_u_value(gridSep) < leftChain->getVertex(segLeftSmall+1)[0]) + { + valid = 0; + } + } + else + { + gridSep = leftGridChain->getUlineIndex(gridIndex1); + while(leftGridChain->getGrid()->get_u_value(gridSep) < rightChain->getVertex(segRightSmall)[0]) + gridSep++; + if(segRightSmall<segRightLarge) + if(leftGridChain->getGrid()->get_u_value(gridSep) > rightChain->getVertex(segRightSmall+1)[0]) + { + valid = 0; + } + } + + if(! valid) + { + sampleCompTopSimple(topVertex, + leftChain, + leftStartIndex, + rightChain, + rightStartIndex, + leftGridChain, + rightGridChain, + gridIndex1, + up_leftCornerWhere, + up_leftCornerIndex, + up_rightCornerWhere, + up_rightCornerIndex, + pStream); + } + else + { + sampleTopLeftWithGridLinePost(leftChain->getVertex(segLeftSmall), + leftChain, + segLeftSmall+1, + segLeftSmall+1, + segLeftLarge, + up_leftCornerIndex, + leftGridChain->getGrid(), + leftGridChain->getVlineIndex(gridIndex1), + leftGridChain->getUlineIndex(gridIndex1), + gridSep, + pStream); + sampleTopRightWithGridLinePost(rightChain->getVertex(segRightSmall), + rightChain, + segRightSmall+1, + segRightSmall+1, + segRightLarge, + up_rightCornerIndex, + leftGridChain->getGrid(), + leftGridChain->getVlineIndex(gridIndex1), + gridSep, + rightGridChain->getUlineIndex(gridIndex1), + pStream); + Real tempBot[2]; + tempBot[0] = leftGridChain->getGrid()->get_u_value(gridSep); + tempBot[1] = leftGridChain->get_v_value(gridIndex1); + monoTriangulationRecGen(topVertex, tempBot, + leftChain, leftStartIndex, segLeftSmall, + rightChain, rightStartIndex, segRightSmall, + pStream); + } + }//end if both sides have vetices inside the gridboundary points + else if(leftChain->getVertex(sep_left)[0] >= leftGridChain->get_u_value(gridIndex1)) //left is in, right is nout + { + + Int segLeftSmall, segLeftLarge; + findTopLeftSegment(leftChain, + sep_left, + up_leftCornerIndex, + leftGridChain->get_u_value(gridIndex1), + segLeftSmall, + segLeftLarge); + assert(segLeftLarge >= sep_left); + monoTriangulation2(leftChain->getVertex(segLeftLarge), + leftGridChain->get_vertex(gridIndex1), + leftChain, + segLeftLarge+1, + up_leftCornerIndex, + 1, //a increase chain, + pStream); + + stripOfFanLeft(leftChain, segLeftLarge, segLeftSmall, + leftGridChain->getGrid(), + leftGridChain->getVlineIndex(gridIndex1), + leftGridChain->getUlineIndex(gridIndex1), + rightGridChain->getUlineIndex(gridIndex1), + pStream, 0); + + + monoTriangulationRecGen(topVertex, rightGridChain->get_vertex(gridIndex1), + leftChain, leftStartIndex, segLeftSmall, + rightChain, rightStartIndex, up_rightCornerIndex, + pStream); + }//end left in right out + else if(rightChain->getVertex(sep_right)[0] <= rightGridChain->get_u_value(gridIndex1)) + { + Int segRightSmall, segRightLarge; + findTopRightSegment(rightChain, + sep_right, + up_rightCornerIndex, + rightGridChain->get_u_value(gridIndex1), + segRightSmall, + segRightLarge); + assert(segRightLarge>=sep_right); + monoTriangulation2(rightChain->getVertex(segRightLarge), + rightGridChain->get_vertex(gridIndex1), + rightChain, + segRightLarge+1, + up_rightCornerIndex, + 0, //a decrease chain + pStream); + stripOfFanRight(rightChain, segRightLarge, segRightSmall, + rightGridChain->getGrid(), + rightGridChain->getVlineIndex(gridIndex1), + leftGridChain->getUlineIndex(gridIndex1), + rightGridChain->getUlineIndex(gridIndex1), + pStream, 0); + + + monoTriangulationRecGen(topVertex, leftGridChain->get_vertex(gridIndex1), + leftChain, leftStartIndex, up_leftCornerIndex, + rightChain, rightStartIndex,segRightSmall, + pStream); + + }//end left out rigth in + else //left out , right out + { + + sampleCompTopSimple(topVertex, + leftChain, + leftStartIndex, + rightChain, + rightStartIndex, + leftGridChain, + rightGridChain, + gridIndex1, + up_leftCornerWhere, + up_leftCornerIndex, + up_rightCornerWhere, + up_rightCornerIndex, + pStream); + }//end leftout, right out + }//end if separator exixts. + else //no separator + { + + sampleCompTopSimple(topVertex, + leftChain, + leftStartIndex, + rightChain, + rightStartIndex, + leftGridChain, + rightGridChain, + gridIndex1, + up_leftCornerWhere, + up_leftCornerIndex, + up_rightCornerWhere, + up_rightCornerIndex, + pStream); + } +#endif + }//end if 0,2 +}//end if the function + + +static void sampleCompTopSimpleOpt(gridWrap* grid, + Int gridV, + Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, Int inc_end, + vertexArray* dec_chain, Int dec_current, Int dec_end, + primStream* pStream) +{ + if(gridV <= 0 || dec_end<dec_current || inc_end <inc_current) + { + monoTriangulationRecGenOpt(topVertex, botVertex, + inc_chain, inc_current, inc_end, + dec_chain, dec_current, dec_end, + pStream); + return; + } + if(grid->get_v_value(gridV+1) >= topVertex[1]) + { + monoTriangulationRecGenOpt(topVertex, botVertex, + inc_chain, inc_current, inc_end, + dec_chain, dec_current, dec_end, + pStream); + return; + } + Int i,j,k; + Real currentV = grid->get_v_value(gridV+1); + if(inc_chain->getVertex(inc_end)[1] <= currentV && + dec_chain->getVertex(dec_end)[1] < currentV) + { + //find i bottom up so that inc_chain[i]<= curentV and inc_chain[i-1] > currentV, + //find j botom up so that dec_chain[j] < currentV and dec_chain[j-1] >= currentV + for(i=inc_end; i >= inc_current; i--) + { + if(inc_chain->getVertex(i)[1] > currentV) + break; + } + i++; + for(j=dec_end; j >= dec_current; j--) + { + if(dec_chain->getVertex(j)[1] >= currentV) + break; + } + j++; + if(inc_chain->getVertex(i)[1] <= dec_chain->getVertex(j)[1]) + { + //find the k so that dec_chain[k][1] < inc_chain[i][1] + for(k=j; k<=dec_end; k++) + { + if(dec_chain->getVertex(k)[1] < inc_chain->getVertex(i)[1]) + break; + } + //we know that dec_chain[j][1] >= inc_chian[i][1] + //we know that dec_chain[k-1][1]>=inc_chain[i][1] + //we know that dec_chian[k][1] < inc_chain[i][1] + //find l in [j, k-1] so that dec_chain[l][0] 0 is closest to + // inc_chain[i] + int l; + Real tempI = Real(j); + Real tempMin = (Real)fabs(inc_chain->getVertex(i)[0] - dec_chain->getVertex(j)[0]); + for(l=j+1; l<= k-1; l++) + { + if(fabs(inc_chain->getVertex(i)[0] - dec_chain->getVertex(l)[0]) + <= tempMin) + { + tempMin = (Real)fabs(inc_chain->getVertex(i)[0] - dec_chain->getVertex(l)[0]); + tempI = (Real)l; + } + } + //inc_chain[i] and dec_chain[tempI] are connected. + monoTriangulationRecGenOpt(dec_chain->getVertex((int)tempI), + botVertex, + inc_chain, i, inc_end, + dec_chain, (int)(tempI+1), dec_end, + pStream); + //recursively do the rest + sampleCompTopSimpleOpt(grid, + gridV+1, + topVertex, inc_chain->getVertex(i), + inc_chain, inc_current, i-1, + dec_chain, dec_current, (int)tempI, + pStream); + } + else + { + //find the k so that inc_chain[k][1] <= dec_chain[j][1] + for(k=i; k<=inc_end; k++) + { + if(inc_chain->getVertex(k)[1] <= dec_chain->getVertex(j)[1]) + break; + } + //we know that inc_chain[i] > dec_chain[j] + //we know that inc_chain[k-1][1] > dec_chain[j][1] + //we know that inc_chain[k][1] <= dec_chain[j][1] + //so we find l between [i,k-1] so that + //inc_chain[l][0] is the closet to dec_chain[j][0] + int tempI = i; + int l; + Real tempMin = (Real)fabs(inc_chain->getVertex(i)[0] - dec_chain->getVertex(j)[0]); + for(l=i+1; l<=k-1; l++) + { + if(fabs(inc_chain->getVertex(l)[0] - dec_chain->getVertex(j)[0]) <= tempMin) + { + tempMin = (Real)fabs(inc_chain->getVertex(l)[0] - dec_chain->getVertex(j)[0]); + tempI = l; + } + } + + //inc_chain[tempI] and dec_chain[j] are connected + + monoTriangulationRecGenOpt(inc_chain->getVertex(tempI), + botVertex, + inc_chain, tempI+1, inc_end, + dec_chain, j, dec_end, + pStream); + + //recurvesily do the rest + sampleCompTopSimpleOpt(grid, gridV+1, + topVertex, dec_chain->getVertex(j), + inc_chain, inc_current, tempI, + dec_chain, dec_current, j-1, + pStream); + } + } + else //go to the next higher gridV + { + sampleCompTopSimpleOpt(grid, + gridV+1, + topVertex, botVertex, + inc_chain, inc_current, inc_end, + dec_chain, dec_current, dec_end, + pStream); + } +} + +void sampleCompTopSimple(Real* topVertex, + vertexArray* leftChain, + Int leftStartIndex, + vertexArray* rightChain, + Int rightStartIndex, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridIndex1, + Int up_leftCornerWhere, + Int up_leftCornerIndex, + Int up_rightCornerWhere, + Int up_rightCornerIndex, + primStream* pStream) +{ + //the plan is to use monotriangulation algortihm. + Int i,k; + Real* ActualTop; + Real* ActualBot; + Int ActualLeftStart, ActualLeftEnd; + Int ActualRightStart, ActualRightEnd; + + //creat an array to store the points on the grid line + gridWrap* grid = leftGridChain->getGrid(); + Int gridV = leftGridChain->getVlineIndex(gridIndex1); + Int gridLeftU = leftGridChain->getUlineIndex(gridIndex1); + Int gridRightU = rightGridChain->getUlineIndex(gridIndex1); + + Real2* gridPoints = (Real2*) malloc(sizeof(Real2) * (gridRightU - gridLeftU +1)); + assert(gridPoints); + + for(k=0, i=gridRightU; i>= gridLeftU; i--, k++) + { + gridPoints[k][0] = grid->get_u_value(i); + gridPoints[k][1] = grid->get_v_value(gridV); + } + + if(up_leftCornerWhere != 2) + ActualRightStart = rightStartIndex; + else + ActualRightStart = up_leftCornerIndex+1; //up_leftCornerIndex will be the ActualTop + + if(up_rightCornerWhere != 2) //right corner is not on right chain + ActualRightEnd = rightStartIndex-1; //meaning that there is no actual rigth section + else + ActualRightEnd = up_rightCornerIndex; + + vertexArray ActualRightChain(max(0, ActualRightEnd-ActualRightStart+1) + gridRightU-gridLeftU+1); + + for(i=ActualRightStart; i<= ActualRightEnd; i++) + ActualRightChain.appendVertex(rightChain->getVertex(i)); + for(i=0; i<gridRightU-gridLeftU+1; i++) + ActualRightChain.appendVertex(gridPoints[i]); + + //determine ActualLeftEnd + if(up_leftCornerWhere != 0) + ActualLeftEnd = leftStartIndex-1; + else + ActualLeftEnd = up_leftCornerIndex; + + if(up_rightCornerWhere != 0) + ActualLeftStart = leftStartIndex; + else + ActualLeftStart = up_rightCornerIndex+1; //up_rightCornerIndex will be the actual top + + if(up_leftCornerWhere == 0) + { + if(up_rightCornerWhere == 0) + ActualTop = leftChain->getVertex(up_rightCornerIndex); + else + ActualTop = topVertex; + } + else if(up_leftCornerWhere == 1) + ActualTop = topVertex; + else //up_leftCornerWhere == 2 + ActualTop = rightChain->getVertex(up_leftCornerIndex); + + ActualBot = gridPoints[gridRightU - gridLeftU]; + + + + + if(leftChain->getVertex(ActualLeftEnd)[1] == ActualBot[1]) + { +/* + monoTriangulationRecGenOpt(ActualTop, leftChain->getVertex(ActualLeftEnd), + leftChain, + ActualLeftStart, ActualLeftEnd-1, + &ActualRightChain, + 0, + ActualRightChain.getNumElements()-1, + pStream); +*/ + + sampleCompTopSimpleOpt(grid, gridV, + ActualTop, leftChain->getVertex(ActualLeftEnd), + leftChain, + ActualLeftStart, ActualLeftEnd-1, + &ActualRightChain, + 0, + ActualRightChain.getNumElements()-1, + pStream); + + } + else + { +/* + monoTriangulationRecGenOpt(ActualTop, ActualBot, leftChain, + ActualLeftStart, ActualLeftEnd, + &ActualRightChain, + 0, ActualRightChain.getNumElements()-2, //the last is the bot. + pStream); +*/ + + sampleCompTopSimpleOpt(grid, gridV, + ActualTop, ActualBot, leftChain, + ActualLeftStart, ActualLeftEnd, + &ActualRightChain, + 0, ActualRightChain.getNumElements()-2, //the last is the bot. + pStream); + + + } + + free(gridPoints); + +} + diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleCompTop.h b/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleCompTop.h new file mode 100644 index 000000000..95598d63a --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleCompTop.h @@ -0,0 +1,67 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ +/* +*/ + +#ifndef _SAMPLECOMPTOP_H +#define _SAMPLECOMPTOP_H + +#include "sampleMonoPoly.h" + +void sampleCompTop(Real* topVertex, + vertexArray* leftChain, + Int leftStartIndex, + vertexArray* rightChain, + Int rightStartIndex, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridIndex1, + Int up_leftCornerWhere, + Int up_leftCornerIndex, + Int up_rightCornerWhere, + Int up_rightCornerIndex, + primStream* pStream); + +void sampleCompTopSimple(Real* topVertex, + vertexArray* leftChain, + Int leftStartIndex, + vertexArray* rightChain, + Int rightStartIndex, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridIndex1, + Int up_leftCornerWhere, + Int up_leftCornerIndex, + Int up_rightCornerWhere, + Int up_rightCornerIndex, + primStream* pStream); + +#endif + diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleMonoPoly.cc b/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleMonoPoly.cc new file mode 100644 index 000000000..051f24108 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleMonoPoly.cc @@ -0,0 +1,2427 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include "gluos.h" +#include <stdlib.h> +#include <stdio.h> +#include <math.h> + +#ifndef max +#define max(a,b) ((a>b)? a:b) +#endif +#ifndef min +#define min(a,b) ((a>b)? b:a) +#endif + +#include <GL/gl.h> + +#include "glimports.h" +#include "zlassert.h" +#include "sampleMonoPoly.h" +#include "sampleComp.h" +#include "polyDBG.h" +#include "partitionX.h" + + +#define ZERO 0.00001 + +//#define MYDEBUG + +//#define SHORTEN_GRID_LINE +//see work/newtess/internal/test/problems + + +/*split a polygon so that each vertex correcpond to one edge + *the head of the first edge of the returned plygon must be the head of the first + *edge of the origianl polygon. This is crucial for the code in sampleMonoPoly function + */ + directedLine* polygonConvert(directedLine* polygon) +{ + int i; + directedLine* ret; + sampledLine* sline; + sline = new sampledLine(2); + sline->setPoint(0, polygon->getVertex(0)); + sline->setPoint(1, polygon->getVertex(1)); + ret=new directedLine(INCREASING, sline); + for(i=1; i<= polygon->get_npoints()-2; i++) + { + sline = new sampledLine(2); + sline->setPoint(0, polygon->getVertex(i)); + sline->setPoint(1, polygon->getVertex(i+1)); + ret->insert(new directedLine(INCREASING, sline)); + } + + for(directedLine *temp = polygon->getNext(); temp != polygon; temp = temp->getNext()) + { + for(i=0; i<= temp->get_npoints()-2; i++) + { + sline = new sampledLine(2); + sline->setPoint(0, temp->getVertex(i)); + sline->setPoint(1, temp->getVertex(i+1)); + ret->insert(new directedLine(INCREASING, sline)); + } + } + return ret; +} + +void triangulateConvexPolyVertical(directedLine* topV, directedLine* botV, primStream *pStream) +{ + Int i,j; + Int n_leftVerts; + Int n_rightVerts; + Real** leftVerts; + Real** rightVerts; + directedLine* tempV; + n_leftVerts = 0; + for(tempV = topV; tempV != botV; tempV = tempV->getNext()) + { + n_leftVerts += tempV->get_npoints(); + } + n_rightVerts=0; + for(tempV = botV; tempV != topV; tempV = tempV->getNext()) + { + n_rightVerts += tempV->get_npoints(); + } + + Real2* temp_leftVerts = (Real2 *) malloc(sizeof(Real2) * n_leftVerts); + assert(temp_leftVerts); + Real2* temp_rightVerts = (Real2 *) malloc(sizeof(Real2) * n_rightVerts); + assert(temp_rightVerts); + + leftVerts = (Real**) malloc(sizeof(Real2*) * n_leftVerts); + assert(leftVerts); + rightVerts = (Real**) malloc(sizeof(Real2*) * n_rightVerts); + assert(rightVerts); + for(i=0; i<n_leftVerts; i++) + leftVerts[i] = temp_leftVerts[i]; + for(i=0; i<n_rightVerts; i++) + rightVerts[i] = temp_rightVerts[i]; + + i=0; + for(tempV = topV; tempV != botV; tempV = tempV->getNext()) + { + for(j=1; j<tempV->get_npoints(); j++) + { + leftVerts[i][0] = tempV->getVertex(j)[0]; + leftVerts[i][1] = tempV->getVertex(j)[1]; + i++; + } + } + n_leftVerts = i; + i=0; + for(tempV = topV->getPrev(); tempV != botV->getPrev(); tempV = tempV->getPrev()) + { + for(j=tempV->get_npoints()-1; j>=1; j--) + { + rightVerts[i][0] = tempV->getVertex(j)[0]; + rightVerts[i][1] = tempV->getVertex(j)[1]; + i++; + } + } + n_rightVerts = i; + triangulateXYMonoTB(n_leftVerts, leftVerts, n_rightVerts, rightVerts, pStream); + free(leftVerts); + free(rightVerts); + free(temp_leftVerts); + free(temp_rightVerts); +} + +void triangulateConvexPolyHoriz(directedLine* leftV, directedLine* rightV, primStream *pStream) +{ + Int i,j; + Int n_lowerVerts; + Int n_upperVerts; + Real2 *lowerVerts; + Real2 *upperVerts; + directedLine* tempV; + n_lowerVerts=0; + for(tempV = leftV; tempV != rightV; tempV = tempV->getNext()) + { + n_lowerVerts += tempV->get_npoints(); + } + n_upperVerts=0; + for(tempV = rightV; tempV != leftV; tempV = tempV->getNext()) + { + n_upperVerts += tempV->get_npoints(); + } + lowerVerts = (Real2 *) malloc(sizeof(Real2) * n_lowerVerts); + assert(n_lowerVerts); + upperVerts = (Real2 *) malloc(sizeof(Real2) * n_upperVerts); + assert(n_upperVerts); + i=0; + for(tempV = leftV; tempV != rightV; tempV = tempV->getNext()) + { + for(j=0; j<tempV->get_npoints(); j++) + { + lowerVerts[i][0] = tempV->getVertex(j)[0]; + lowerVerts[i][1] = tempV->getVertex(j)[1]; + i++; + } + } + i=0; + for(tempV = leftV->getPrev(); tempV != rightV->getPrev(); tempV = tempV->getPrev()) + { + for(j=tempV->get_npoints()-1; j>=0; j--) + { + upperVerts[i][0] = tempV->getVertex(j)[0]; + upperVerts[i][1] = tempV->getVertex(j)[1]; + i++; + } + } + triangulateXYMono(n_upperVerts, upperVerts, n_lowerVerts, lowerVerts, pStream); + free(lowerVerts); + free(upperVerts); +} +void triangulateConvexPoly(directedLine* polygon, Int ulinear, Int vlinear, primStream* pStream) +{ + /*find left, right, top , bot + */ + directedLine* tempV; + directedLine* topV; + directedLine* botV; + directedLine* leftV; + directedLine* rightV; + topV = botV = polygon; + + for(tempV = polygon->getNext(); tempV != polygon; tempV = tempV->getNext()) + { + if(compV2InY(topV->head(), tempV->head())<0) { + + topV = tempV; + } + if(compV2InY(botV->head(), tempV->head())>0) { + + botV = tempV; + } + } + //find leftV + for(tempV = topV; tempV != botV; tempV = tempV->getNext()) + { + if(tempV->tail()[0] >= tempV->head()[0]) + break; + } + leftV = tempV; + //find rightV + for(tempV = botV; tempV != topV; tempV = tempV->getNext()) + { + if(tempV->tail()[0] <= tempV->head()[0]) + break; + } + rightV = tempV; + if(vlinear) + { + triangulateConvexPolyHoriz( leftV, rightV, pStream); + } + else if(ulinear) + { + triangulateConvexPolyVertical(topV, botV, pStream); + } + else + { + if(DBG_is_U_direction(polygon)) + { + triangulateConvexPolyHoriz( leftV, rightV, pStream); + } + else + triangulateConvexPolyVertical(topV, botV, pStream); + } +} + +/*for debug purpose*/ +void drawCorners( + Real* topV, Real* botV, + vertexArray* leftChain, + vertexArray* rightChain, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridIndex1, + Int gridIndex2, + Int leftCornerWhere, + Int leftCornerIndex, + Int rightCornerWhere, + Int rightCornerIndex, + Int bot_leftCornerWhere, + Int bot_leftCornerIndex, + Int bot_rightCornerWhere, + Int bot_rightCornerIndex) +{ + Real* leftCornerV; + Real* rightCornerV; + Real* bot_leftCornerV; + Real* bot_rightCornerV; + + if(leftCornerWhere == 1) + leftCornerV = topV; + else if(leftCornerWhere == 0) + leftCornerV = leftChain->getVertex(leftCornerIndex); + else + leftCornerV = rightChain->getVertex(leftCornerIndex); + + if(rightCornerWhere == 1) + rightCornerV = topV; + else if(rightCornerWhere == 0) + rightCornerV = leftChain->getVertex(rightCornerIndex); + else + rightCornerV = rightChain->getVertex(rightCornerIndex); + + if(bot_leftCornerWhere == 1) + bot_leftCornerV = botV; + else if(bot_leftCornerWhere == 0) + bot_leftCornerV = leftChain->getVertex(bot_leftCornerIndex); + else + bot_leftCornerV = rightChain->getVertex(bot_leftCornerIndex); + + if(bot_rightCornerWhere == 1) + bot_rightCornerV = botV; + else if(bot_rightCornerWhere == 0) + bot_rightCornerV = leftChain->getVertex(bot_rightCornerIndex); + else + bot_rightCornerV = rightChain->getVertex(bot_rightCornerIndex); + + Real topGridV = leftGridChain->get_v_value(gridIndex1); + Real topGridU1 = leftGridChain->get_u_value(gridIndex1); + Real topGridU2 = rightGridChain->get_u_value(gridIndex1); + Real botGridV = leftGridChain->get_v_value(gridIndex2); + Real botGridU1 = leftGridChain->get_u_value(gridIndex2); + Real botGridU2 = rightGridChain->get_u_value(gridIndex2); + + glBegin(GL_LINE_STRIP); + glVertex2fv(leftCornerV); + glVertex2f(topGridU1, topGridV); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(rightCornerV); + glVertex2f(topGridU2, topGridV); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(bot_leftCornerV); + glVertex2f(botGridU1, botGridV); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(bot_rightCornerV); + glVertex2f(botGridU2, botGridV); + glEnd(); + + +} + +void toVertexArrays(directedLine* topV, directedLine* botV, vertexArray& leftChain, vertexArray& rightChain) +{ + Int i; + directedLine* tempV; + for(i=1; i<=topV->get_npoints()-2; i++) { /*the first vertex is the top vertex which doesn't belong to inc_chain*/ + leftChain.appendVertex(topV->getVertex(i)); + } + for(tempV = topV->getNext(); tempV != botV; tempV = tempV->getNext()) + { + for(i=0; i<=tempV->get_npoints()-2; i++){ + leftChain.appendVertex(tempV->getVertex(i)); + } + } + + for(tempV = topV->getPrev(); tempV != botV; tempV = tempV->getPrev()) + { + for(i=tempV->get_npoints()-2; i>=0; i--){ + rightChain.appendVertex(tempV->getVertex(i)); + } + } + for(i=botV->get_npoints()-2; i>=1; i--){ + rightChain.appendVertex(tempV->getVertex(i)); + } +} + + +void findTopAndBot(directedLine* polygon, directedLine*& topV, directedLine*& botV) +{ + assert(polygon); + directedLine* tempV; + topV = botV = polygon; + for(tempV = polygon->getNext(); tempV != polygon; tempV = tempV->getNext()) + { + if(compV2InY(topV->head(), tempV->head())<0) { + topV = tempV; + } + if(compV2InY(botV->head(), tempV->head())>0) { + botV = tempV; + } + } +} + +void findGridChains(directedLine* topV, directedLine* botV, + gridWrap* grid, + gridBoundaryChain*& leftGridChain, + gridBoundaryChain*& rightGridChain) +{ + /*find the first(top) and the last (bottom) grid line which intersect the + *this polygon + */ + Int firstGridIndex; /*the index in the grid*/ + Int lastGridIndex; + + firstGridIndex = (Int) ((topV->head()[1] - grid->get_v_min()) / (grid->get_v_max() - grid->get_v_min()) * (grid->get_n_vlines()-1)); + + if(botV->head()[1] < grid->get_v_min()) + lastGridIndex = 0; + else + lastGridIndex = (Int) ((botV->head()[1] - grid->get_v_min()) / (grid->get_v_max() - grid->get_v_min()) * (grid->get_n_vlines()-1)) + 1; + + /*find the interval inside the polygon for each gridline*/ + Int *leftGridIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1)); + assert(leftGridIndices); + Int *rightGridIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1)); + assert(rightGridIndices); + Int *leftGridInnerIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1)); + assert(leftGridInnerIndices); + Int *rightGridInnerIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1)); + assert(rightGridInnerIndices); + + findLeftGridIndices(topV, firstGridIndex, lastGridIndex, grid, leftGridIndices, leftGridInnerIndices); + + findRightGridIndices(topV, firstGridIndex, lastGridIndex, grid, rightGridIndices, rightGridInnerIndices); + + leftGridChain = new gridBoundaryChain(grid, firstGridIndex, firstGridIndex-lastGridIndex+1, leftGridIndices, leftGridInnerIndices); + + rightGridChain = new gridBoundaryChain(grid, firstGridIndex, firstGridIndex-lastGridIndex+1, rightGridIndices, rightGridInnerIndices); + + free(leftGridIndices); + free(rightGridIndices); + free(leftGridInnerIndices); + free(rightGridInnerIndices); +} + +void findDownCorners(Real *botVertex, + vertexArray *leftChain, Int leftChainStartIndex, Int leftChainEndIndex, + vertexArray *rightChain, Int rightChainStartIndex, Int rightChainEndIndex, + Real v, + Real uleft, + Real uright, + Int& ret_leftCornerWhere, /*0: left chain, 1: topvertex, 2: rightchain*/ + Int& ret_leftCornerIndex, /*useful when ret_leftCornerWhere == 0 or 2*/ + Int& ret_rightCornerWhere, /*0: left chain, 1: topvertex, 2: rightchain*/ + Int& ret_rightCornerIndex /*useful when ret_leftCornerWhere == 0 or 2*/ + ) +{ +#ifdef MYDEBUG +printf("*************enter find donw corner\n"); +printf("finddownCorner: v=%f, uleft=%f, uright=%f\n", v, uleft, uright); +printf("(%i,%i,%i,%i)\n", leftChainStartIndex, leftChainEndIndex,rightChainStartIndex, rightChainEndIndex); +printf("left chain is\n"); +leftChain->print(); +printf("right chain is\n"); +rightChain->print(); +#endif + + assert(v > botVertex[1]); + Real leftGridPoint[2]; + leftGridPoint[0] = uleft; + leftGridPoint[1] = v; + Real rightGridPoint[2]; + rightGridPoint[0] = uright; + rightGridPoint[1] = v; + + Int i; + Int index1, index2; + + index1 = leftChain->findIndexBelowGen(v, leftChainStartIndex, leftChainEndIndex); + index2 = rightChain->findIndexBelowGen(v, rightChainStartIndex, rightChainEndIndex); + + if(index2 <= rightChainEndIndex) //index2 was found above + index2 = rightChain->skipEqualityFromStart(v, index2, rightChainEndIndex); + + if(index1>leftChainEndIndex && index2 > rightChainEndIndex) /*no point below v on left chain or right chain*/ + { + + /*the botVertex is the only vertex below v*/ + ret_leftCornerWhere = 1; + ret_rightCornerWhere = 1; + } + else if(index1>leftChainEndIndex ) /*index2 <= rightChainEndIndex*/ + { + + ret_rightCornerWhere = 2; /*on right chain*/ + ret_rightCornerIndex = index2; + + + Real tempMin = rightChain->getVertex(index2)[0]; + Int tempI = index2; + for(i=index2+1; i<= rightChainEndIndex; i++) + if(rightChain->getVertex(i)[0] < tempMin) + { + tempI = i; + tempMin = rightChain->getVertex(i)[0]; + } + + + //we consider whether we can use botVertex as left corner. First check + //if (leftGirdPoint, botVertex) interesects right chian or not. + if(DBG_intersectChain(rightChain, rightChainStartIndex,rightChainEndIndex, + leftGridPoint, botVertex)) + { + ret_leftCornerWhere = 2;//right + ret_leftCornerIndex = index2; //should use tempI??? + } + else if(botVertex[0] < tempMin) + ret_leftCornerWhere = 1; //bot + else + { + ret_leftCornerWhere = 2; //right + ret_leftCornerIndex = tempI; + } + } + else if(index2> rightChainEndIndex) /*index1<=leftChainEndIndex*/ + { + ret_leftCornerWhere = 0; /*left chain*/ + ret_leftCornerIndex = index1; + + /*find the vertex on the left chain with the maximum u, + *either this vertex or the botvertex can be used as the right corner + */ + + Int tempI; + //skip those points which are equal to v. (avoid degeneratcy) + for(tempI = index1; tempI <= leftChainEndIndex; tempI++) + if(leftChain->getVertex(tempI)[1] < v) + break; + if(tempI > leftChainEndIndex) + ret_rightCornerWhere = 1; + else + { + Real tempMax = leftChain->getVertex(tempI)[0]; + for(i=tempI; i<= leftChainEndIndex; i++) + if(leftChain->getVertex(i)[0] > tempMax) + { + tempI = i; + tempMax = leftChain->getVertex(i)[0]; + } + + + + //we consider whether we can use botVertex as a corner. So first we check + //whether (rightGridPoint, botVertex) interescts the left chain or not. + if(DBG_intersectChain(leftChain, leftChainStartIndex,leftChainEndIndex, + rightGridPoint, botVertex)) + { + ret_rightCornerWhere = 0; + ret_rightCornerIndex = index1; //should use tempI??? + } + else if(botVertex[0] > tempMax) + { + + ret_rightCornerWhere = 1; + } + else + { + ret_rightCornerWhere = 0; + ret_rightCornerIndex = tempI; + } + } + + } + else /*index1<=leftChainEndIndex and index2 <=rightChainEndIndex*/ + { + if(leftChain->getVertex(index1)[1] >= rightChain->getVertex(index2)[1]) /*left point above right point*/ + { + ret_leftCornerWhere = 0; /*on left chain*/ + ret_leftCornerIndex = index1; + + Real tempMax; + Int tempI; + + tempI = index1; + tempMax = leftChain->getVertex(index1)[0]; + + /*find the maximum u for all the points on the left above the right point index2*/ + for(i=index1+1; i<= leftChainEndIndex; i++) + { + if(leftChain->getVertex(i)[1] < rightChain->getVertex(index2)[1]) + break; + + if(leftChain->getVertex(i)[0]>tempMax) + { + tempI = i; + tempMax = leftChain->getVertex(i)[0]; + } + } + //we consider if we can use rightChain(index2) as right corner + //we check if (rightChain(index2), rightGidPoint) intersecs left chain or not. + if(DBG_intersectChain(leftChain, leftChainStartIndex,leftChainEndIndex, rightGridPoint, rightChain->getVertex(index2))) + { + ret_rightCornerWhere = 0; + ret_rightCornerIndex = index1; //should use tempI??? + } + else if(tempMax >= rightChain->getVertex(index2)[0] || + tempMax >= uright + ) + { + + ret_rightCornerWhere = 0; /*on left Chain*/ + ret_rightCornerIndex = tempI; + } + else + { + ret_rightCornerWhere = 2; /*on right chain*/ + ret_rightCornerIndex = index2; + } + } + else /*left below right*/ + { + ret_rightCornerWhere = 2; /*on the right*/ + ret_rightCornerIndex = index2; + + Real tempMin; + Int tempI; + + tempI = index2; + tempMin = rightChain->getVertex(index2)[0]; + + /*find the minimum u for all the points on the right above the left poitn index1*/ + for(i=index2+1; i<= rightChainEndIndex; i++) + { + if( rightChain->getVertex(i)[1] < leftChain->getVertex(index1)[1]) + break; + if(rightChain->getVertex(i)[0] < tempMin) + { + tempI = i; + tempMin = rightChain->getVertex(i)[0]; + } + } + + //we consider if we can use leftchain(index1) as left corner. + //we check if (leftChain(index1) intersects right chian or not + if(DBG_intersectChain(rightChain, rightChainStartIndex, rightChainEndIndex, leftGridPoint, leftChain->getVertex(index1))) + { + ret_leftCornerWhere = 2; + ret_leftCornerIndex = index2; //should use tempI??? + } + else if(tempMin <= leftChain->getVertex(index1)[0] || + tempMin <= uleft) + { + ret_leftCornerWhere = 2; /* on right chain*/ + ret_leftCornerIndex = tempI; + } + else + { + ret_leftCornerWhere = 0; /*on left chain*/ + ret_leftCornerIndex = index1; + } + } + } + +} + + +void findUpCorners(Real *topVertex, + vertexArray *leftChain, Int leftChainStartIndex, Int leftChainEndIndex, + vertexArray *rightChain, Int rightChainStartIndex, Int rightChainEndIndex, + Real v, + Real uleft, + Real uright, + Int& ret_leftCornerWhere, /*0: left chain, 1: topvertex, 2: rightchain*/ + Int& ret_leftCornerIndex, /*useful when ret_leftCornerWhere == 0 or 2*/ + Int& ret_rightCornerWhere, /*0: left chain, 1: topvertex, 2: rightchain*/ + Int& ret_rightCornerIndex /*useful when ret_leftCornerWhere == 0 or 2*/ + ) +{ +#ifdef MYDEBUG +printf("***********enter findUpCorners\n"); +#endif + + assert(v < topVertex[1]); + Real leftGridPoint[2]; + leftGridPoint[0] = uleft; + leftGridPoint[1] = v; + Real rightGridPoint[2]; + rightGridPoint[0] = uright; + rightGridPoint[1] = v; + + Int i; + Int index1, index2; + + index1 = leftChain->findIndexFirstAboveEqualGen(v, leftChainStartIndex, leftChainEndIndex); + + + index2 = rightChain->findIndexFirstAboveEqualGen(v, rightChainStartIndex, rightChainEndIndex); + + if(index2>= leftChainStartIndex) //index2 was found above + index2 = rightChain->skipEqualityFromStart(v, index2, rightChainEndIndex); + + if(index1<leftChainStartIndex && index2 <rightChainStartIndex) /*no point above v on left chain or right chain*/ + { + /*the topVertex is the only vertex above v*/ + ret_leftCornerWhere = 1; + ret_rightCornerWhere = 1; + } + else if(index1<leftChainStartIndex ) /*index2 >= rightChainStartIndex*/ + { + ret_rightCornerWhere = 2; /*on right chain*/ + ret_rightCornerIndex = index2; + + //find the minimum u on right top, either that, or top, or right[index2] is the left corner + Real tempMin = rightChain->getVertex(index2)[0]; + Int tempI = index2; + for(i=index2-1; i>=rightChainStartIndex; i--) + if(rightChain->getVertex(i)[0] < tempMin) + { + tempMin = rightChain->getVertex(i)[0]; + tempI = i; + } + //chech whether (leftGridPoint, top) intersects rightchai, + //if yes, use right corner as left corner + //if not, use top or right[tempI] as left corner + if(DBG_intersectChain(rightChain, rightChainStartIndex, rightChainEndIndex, + leftGridPoint, topVertex)) + { + ret_leftCornerWhere = 2; //rightChain + ret_leftCornerIndex = index2; + } + else if(topVertex[0] < tempMin) + ret_leftCornerWhere = 1; /*topvertex*/ + else + { + ret_leftCornerWhere = 2; //right chain + ret_leftCornerIndex = tempI; + } + + } + else if(index2< rightChainStartIndex) /*index1>=leftChainStartIndex*/ + { + ret_leftCornerWhere = 0; /*left chain*/ + ret_leftCornerIndex = index1; + + //find the maximum u on the left top section. either that or topvertex, or left[index1] is the right corner + Real tempMax = leftChain->getVertex(index1)[0]; + Int tempI = index1; + + for(i=index1-1; i>=leftChainStartIndex; i--){ + + if(leftChain->getVertex(i)[0] > tempMax) + { + + tempMax = leftChain->getVertex(i)[0]; + tempI = i; + } + } + //check whether (rightGridPoint, top) intersects leftChain or not + //if yes, we use leftCorner as the right corner + //if not, we use either top or left[tempI] as the right corner + if(DBG_intersectChain(leftChain, leftChainStartIndex,leftChainEndIndex, + rightGridPoint, topVertex)) + { + ret_rightCornerWhere = 0; //left chan + ret_rightCornerIndex = index1; + } + else if(topVertex[0] > tempMax) + ret_rightCornerWhere = 1;//topVertex + else + { + ret_rightCornerWhere = 0;//left chain + ret_rightCornerIndex = tempI; + } + } + else /*index1>=leftChainStartIndex and index2 >=rightChainStartIndex*/ + { + if(leftChain->getVertex(index1)[1] <= rightChain->getVertex(index2)[1]) /*left point below right point*/ + { + ret_leftCornerWhere = 0; /*on left chain*/ + ret_leftCornerIndex = index1; + + Real tempMax; + Int tempI; + + tempI = index1; + tempMax = leftChain->getVertex(index1)[0]; + + /*find the maximum u for all the points on the left below the right point index2*/ + for(i=index1-1; i>= leftChainStartIndex; i--) + { + if(leftChain->getVertex(i)[1] > rightChain->getVertex(index2)[1]) + break; + + if(leftChain->getVertex(i)[0]>tempMax) + { + tempI = i; + tempMax = leftChain->getVertex(i)[0]; + } + } + //chek whether (rightChain(index2), rightGridPoint) intersects leftchian or not + if(DBG_intersectChain(leftChain, leftChainStartIndex, leftChainEndIndex, rightGridPoint, rightChain->getVertex(index2))) + { + ret_rightCornerWhere = 0; + ret_rightCornerIndex = index1; + } + else if(tempMax >= rightChain->getVertex(index2)[0] || + tempMax >= uright) + { + ret_rightCornerWhere = 0; /*on left Chain*/ + ret_rightCornerIndex = tempI; + } + else + { + ret_rightCornerWhere = 2; /*on right chain*/ + ret_rightCornerIndex = index2; + } + } + else /*left above right*/ + { + ret_rightCornerWhere = 2; /*on the right*/ + ret_rightCornerIndex = index2; + + Real tempMin; + Int tempI; + + tempI = index2; + tempMin = rightChain->getVertex(index2)[0]; + + /*find the minimum u for all the points on the right below the left poitn index1*/ + for(i=index2-1; i>= rightChainStartIndex; i--) + { + if( rightChain->getVertex(i)[1] > leftChain->getVertex(index1)[1]) + break; + if(rightChain->getVertex(i)[0] < tempMin) + { + tempI = i; + tempMin = rightChain->getVertex(i)[0]; + } + } + //check whether (leftGRidPoint,left(index1)) interesect right chain + if(DBG_intersectChain(rightChain, rightChainStartIndex, rightChainEndIndex, + leftGridPoint, leftChain->getVertex(index1))) + { + ret_leftCornerWhere = 2; //right + ret_leftCornerIndex = index2; + } + else if(tempMin <= leftChain->getVertex(index1)[0] || + tempMin <= uleft) + { + ret_leftCornerWhere = 2; /* on right chain*/ + ret_leftCornerIndex = tempI; + } + else + { + ret_leftCornerWhere = 0; /*on left chain*/ + ret_leftCornerIndex = index1; + } + } + } +#ifdef MYDEBUG +printf("***********leave findUpCorners\n"); +#endif +} + +//return 1 if neck exists, 0 othewise +Int findNeckF(vertexArray *leftChain, Int botLeftIndex, + vertexArray *rightChain, Int botRightIndex, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridStartIndex, + Int& neckLeft, + Int& neckRight) +{ +/* +printf("enter findNeckF, botleft, botright=%i,%i,gstartindex=%i\n",botLeftIndex,botRightIndex,gridStartIndex); +printf("leftChain is\n"); +leftChain->print(); +printf("rightChain is\n"); +rightChain->print(); +*/ + + Int lowerGridIndex; //the grid below leftChain and rightChian vertices + Int i; + Int n_vlines = leftGridChain->get_nVlines(); + Real v; + if(botLeftIndex >= leftChain->getNumElements() || + botRightIndex >= rightChain->getNumElements()) + return 0; //no neck exists + + v=min(leftChain->getVertex(botLeftIndex)[1], rightChain->getVertex(botRightIndex)[1]); + + + + + for(i=gridStartIndex; i<n_vlines; i++) + if(leftGridChain->get_v_value(i) <= v && + leftGridChain->getUlineIndex(i)<= rightGridChain->getUlineIndex(i)) + break; + + lowerGridIndex = i; + + if(lowerGridIndex == n_vlines) //the two trm vertex are higher than all gridlines + return 0; + else + { + Int botLeft2, botRight2; +/* +printf("leftGridChain->get_v_)value=%f\n",leftGridChain->get_v_value(lowerGridIndex), botLeftIndex); +printf("leftChain->get_vertex(0)=(%f,%f)\n", leftChain->getVertex(0)[0],leftChain->getVertex(0)[1]); +printf("leftChain->get_vertex(1)=(%f,%f)\n", leftChain->getVertex(1)[0],leftChain->getVertex(1)[1]); +printf("leftChain->get_vertex(2)=(%f,%f)\n", leftChain->getVertex(2)[0],leftChain->getVertex(2)[1]); +*/ + botLeft2 = leftChain->findIndexFirstAboveEqualGen(leftGridChain->get_v_value(lowerGridIndex), botLeftIndex, leftChain->getNumElements()-1) -1 ; + +/* +printf("botLeft2=%i\n", botLeft2); +printf("leftChain->getNumElements=%i\n", leftChain->getNumElements()); +*/ + + botRight2 = rightChain->findIndexFirstAboveEqualGen(leftGridChain->get_v_value(lowerGridIndex), botRightIndex, rightChain->getNumElements()-1) -1; + if(botRight2 < botRightIndex) botRight2=botRightIndex; + + if(botLeft2 < botLeftIndex) botLeft2 = botLeftIndex; + + assert(botLeft2 >= botLeftIndex); + assert(botRight2 >= botRightIndex); + //find nectLeft so that it is th erightmost vertex on letChain + + Int tempI = botLeftIndex; + Real temp = leftChain->getVertex(tempI)[0]; + for(i=botLeftIndex+1; i<= botLeft2; i++) + if(leftChain->getVertex(i)[0] > temp) + { + temp = leftChain->getVertex(i)[0]; + tempI = i; + } + neckLeft = tempI; + + tempI = botRightIndex; + temp = rightChain->getVertex(tempI)[0]; + for(i=botRightIndex+1; i<= botRight2; i++) + if(rightChain->getVertex(i)[0] < temp) + { + temp = rightChain->getVertex(i)[0]; + tempI = i; + } + neckRight = tempI; + return 1; + } +} + + + +/*find i>=botLeftIndex,j>=botRightIndex so that + *(leftChain[i], rightChain[j]) is a neck. + */ +void findNeck(vertexArray *leftChain, Int botLeftIndex, + vertexArray *rightChain, Int botRightIndex, + Int& leftLastIndex, /*left point of the neck*/ + Int& rightLastIndex /*right point of the neck*/ + ) +{ + assert(botLeftIndex < leftChain->getNumElements() && + botRightIndex < rightChain->getNumElements()); + + /*now the neck exists for sure*/ + + if(leftChain->getVertex(botLeftIndex)[1] <= rightChain->getVertex(botRightIndex)[1]) //left below right + { + + leftLastIndex = botLeftIndex; + + /*find i so that rightChain[i][1] >= leftchainbotverte[1], and i+1< + */ + rightLastIndex=rightChain->findIndexAboveGen(leftChain->getVertex(botLeftIndex)[1], botRightIndex+1, rightChain->getNumElements()-1); + } + else //left above right + { + + rightLastIndex = botRightIndex; + + leftLastIndex = leftChain->findIndexAboveGen(rightChain->getVertex(botRightIndex)[1], + botLeftIndex+1, + leftChain->getNumElements()-1); + } +} + + + +void findLeftGridIndices(directedLine* topEdge, Int firstGridIndex, Int lastGridIndex, gridWrap* grid, Int* ret_indices, Int* ret_innerIndices) +{ + + Int i,k,isHoriz = 0; + Int n_ulines = grid->get_n_ulines(); + Real uMin = grid->get_u_min(); + Real uMax = grid->get_u_max(); + /* + Real vMin = grid->get_v_min(); + Real vMax = grid->get_v_max(); + */ + Real slop = 0.0, uinterc; + +#ifdef SHORTEN_GRID_LINE + //uintercBuf stores all the interction u value for each grid line + //notice that lastGridIndex<= firstGridIndex + Real *uintercBuf = (Real *) malloc (sizeof(Real) * (firstGridIndex-lastGridIndex+1)); + assert(uintercBuf); +#endif + + /*initialization to make vtail bigger than grid->...*/ + directedLine* dLine = topEdge; + Real vtail = grid->get_v_value(firstGridIndex) + 1.0; + Real tempMaxU = grid->get_u_min(); + + + /*for each grid line*/ + for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++) + { + + Real grid_v_value = grid->get_v_value(i); + + /*check whether this grid line is below the current trim edge.*/ + if(vtail > grid_v_value) + { + /*since the grid line is below the trim edge, we + *find the trim edge which will contain the trim line + */ + while( (vtail=dLine->tail()[1]) > grid_v_value){ + + tempMaxU = max(tempMaxU, dLine->tail()[0]); + dLine = dLine -> getNext(); + } + + if( fabs(dLine->head()[1] - vtail) < ZERO) + isHoriz = 1; + else + { + isHoriz = 0; + slop = (dLine->head()[0] - dLine->tail()[0]) / (dLine->head()[1]-vtail); + } + } + + if(isHoriz) + { + uinterc = max(dLine->head()[0], dLine->tail()[0]); + } + else + { + uinterc = slop * (grid_v_value - vtail) + dLine->tail()[0]; + } + + tempMaxU = max(tempMaxU, uinterc); + + if(uinterc < uMin && uinterc >= uMin - ZERO) + uinterc = uMin; + if(uinterc > uMax && uinterc <= uMax + ZERO) + uinterc = uMax; + +#ifdef SHORTEN_GRID_LINE + uintercBuf[k] = uinterc; +#endif + + assert(uinterc >= uMin && uinterc <= uMax); + if(uinterc == uMax) + ret_indices[k] = n_ulines-1; + else + ret_indices[k] = (Int)(((uinterc-uMin)/(uMax - uMin)) * (n_ulines-1)) + 1; + if(ret_indices[k] >= n_ulines) + ret_indices[k] = n_ulines-1; + + + ret_innerIndices[k] = (Int)(((tempMaxU-uMin)/(uMax - uMin)) * (n_ulines-1)) + 1; + + /*reinitialize tempMaxU for next grdiLine*/ + tempMaxU = uinterc; + } +#ifdef SHORTEN_GRID_LINE + //for each grid line, compare the left grid point with the + //intersection point. If the two points are too close, then + //we should move the grid point one grid to the right + //and accordingly we should update the inner index. + for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++) + { + //check gridLine i + //check ret_indices[k] + Real a = grid->get_u_value(ret_indices[k]-1); + Real b = grid->get_u_value(ret_indices[k]); + assert(uintercBuf[k] >= a && uintercBuf < b); + if( (b-uintercBuf[k]) <= 0.2 * (b-a)) //interc is very close to b + { + ret_indices[k]++; + } + + //check ret_innerIndices[k] + if(k>0) + { + if(ret_innerIndices[k] < ret_indices[k-1]) + ret_innerIndices[k] = ret_indices[k-1]; + if(ret_innerIndices[k] < ret_indices[k]) + ret_innerIndices[k] = ret_indices[k]; + } + } + //clean up + free(uintercBuf); +#endif +} + +void findRightGridIndices(directedLine* topEdge, Int firstGridIndex, Int lastGridIndex, gridWrap* grid, Int* ret_indices, Int* ret_innerIndices) +{ + + Int i,k; + Int n_ulines = grid->get_n_ulines(); + Real uMin = grid->get_u_min(); + Real uMax = grid->get_u_max(); + /* + Real vMin = grid->get_v_min(); + Real vMax = grid->get_v_max(); + */ + Real slop = 0.0, uinterc; + +#ifdef SHORTEN_GRID_LINE + //uintercBuf stores all the interction u value for each grid line + //notice that firstGridIndex >= lastGridIndex + Real *uintercBuf = (Real *) malloc (sizeof(Real) * (firstGridIndex-lastGridIndex+1)); + assert(uintercBuf); +#endif + + /*initialization to make vhead bigger than grid->v_value...*/ + directedLine* dLine = topEdge->getPrev(); + Real vhead = dLine->tail()[1]; + Real tempMinU = grid->get_u_max(); + + /*for each grid line*/ + for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++) + { + + Real grid_v_value = grid->get_v_value(i); + + + /*check whether this grid line is below the current trim edge.*/ + if(vhead >= grid_v_value) + { + /*since the grid line is below the tail of the trim edge, we + *find the trim edge which will contain the trim line + */ + while( (vhead=dLine->head()[1]) > grid_v_value){ + tempMinU = min(tempMinU, dLine->head()[0]); + dLine = dLine -> getPrev(); + } + + /*skip the equality in the case of degenerat case: horizontal */ + while(dLine->head()[1] == grid_v_value) + dLine = dLine->getPrev(); + + assert( dLine->tail()[1] != dLine->head()[1]); + slop = (dLine->tail()[0] - dLine->head()[0]) / (dLine->tail()[1]-dLine->head()[1]); + /* + if(dLine->tail()[1] == vhead) + isHoriz = 1; + else + { + isHoriz = 0; + slop = (dLine->tail()[0] - dLine->head()[0]) / (dLine->tail()[1]-vhead); + } + */ + } + uinterc = slop * (grid_v_value - dLine->head()[1]) + dLine->head()[0]; + + //in case unterc is outside of the grid due to floating point + if(uinterc < uMin) + uinterc = uMin; + else if(uinterc > uMax) + uinterc = uMax; + +#ifdef SHORTEN_GRID_LINE + uintercBuf[k] = uinterc; +#endif + + tempMinU = min(tempMinU, uinterc); + + assert(uinterc >= uMin && uinterc <= uMax); + + if(uinterc == uMin) + ret_indices[k] = 0; + else + ret_indices[k] = (int)ceil((((uinterc-uMin)/(uMax - uMin)) * (n_ulines-1))) -1; +/* +if(ret_indices[k] >= grid->get_n_ulines()) + { + printf("ERROR3\n"); + exit(0); +} +if(ret_indices[k] < 0) + { + printf("ERROR4\n"); + exit(0); +} +*/ + ret_innerIndices[k] = (int)ceil ((((tempMinU-uMin)/(uMax - uMin)) * (n_ulines-1))) -1; + + tempMinU = uinterc; + } +#ifdef SHORTEN_GRID_LINE + //for each grid line, compare the left grid point with the + //intersection point. If the two points are too close, then + //we should move the grid point one grid to the right + //and accordingly we should update the inner index. + for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++) + { + //check gridLine i + //check ret_indices[k] + Real a = grid->get_u_value(ret_indices[k]); + Real b = grid->get_u_value(ret_indices[k]+1); + assert(uintercBuf[k] > a && uintercBuf <= b); + if( (uintercBuf[k]-a) <= 0.2 * (b-a)) //interc is very close to a + { + ret_indices[k]--; + } + + //check ret_innerIndices[k] + if(k>0) + { + if(ret_innerIndices[k] > ret_indices[k-1]) + ret_innerIndices[k] = ret_indices[k-1]; + if(ret_innerIndices[k] > ret_indices[k]) + ret_innerIndices[k] = ret_indices[k]; + } + } + //clean up + free(uintercBuf); +#endif +} + + +void sampleMonoPoly(directedLine* polygon, gridWrap* grid, Int ulinear, Int vlinear, primStream* pStream, rectBlockArray* rbArray) +{ +/* +{ +grid->print(); +polygon->writeAllPolygons("zloutputFile"); +exit(0); +} +*/ + +if(grid->get_n_ulines() == 2 || + grid->get_n_vlines() == 2) +{ + if(ulinear && grid->get_n_ulines() == 2) + { + monoTriangulationFun(polygon, compV2InY, pStream); + return; + } + else if(DBG_isConvex(polygon) && polygon->numEdges() >=4) + { + triangulateConvexPoly(polygon, ulinear, vlinear, pStream); + return; + } + else if(vlinear || DBG_is_U_direction(polygon)) + { + Int n_cusps;//num interior cusps + Int n_edges = polygon->numEdges(); + directedLine** cusps = (directedLine**) malloc(sizeof(directedLine*) * n_edges); + assert(cusps); + findInteriorCuspsX(polygon, n_cusps, cusps); + + if(n_cusps == 0) //u_monotone + { + + monoTriangulationFun(polygon, compV2InX, pStream); + + free(cusps); + return; + } + else if(n_cusps == 1) //one interior cusp + { + + directedLine* new_polygon = polygonConvert(cusps[0]); + + directedLine* other = findDiagonal_singleCuspX( new_polygon); + + + + //<other> should NOT be null unless there are self-intersecting + //trim curves. In that case, we don't want to core dump, instead, + //we triangulate anyway, and print out error message. + if(other == NULL) + { + monoTriangulationFun(polygon, compV2InX, pStream); + free(cusps); + return; + } + + directedLine* ret_p1; + directedLine* ret_p2; + + new_polygon->connectDiagonal_2slines(new_polygon, other, + &ret_p1, + &ret_p2, + new_polygon); + + monoTriangulationFun(ret_p1, compV2InX, pStream); + monoTriangulationFun(ret_p2, compV2InX, pStream); + + ret_p1->deleteSinglePolygonWithSline(); + ret_p2->deleteSinglePolygonWithSline(); + + free(cusps); + return; + } + free(cusps); + } +} + + /*find the top and bottom of the polygon. It is supposed to be + *a V-monotone polygon + */ + + directedLine* tempV; + directedLine* topV; + directedLine* botV; + topV = botV = polygon; + + for(tempV = polygon->getNext(); tempV != polygon; tempV = tempV->getNext()) + { + if(compV2InY(topV->head(), tempV->head())<0) { + + topV = tempV; + } + if(compV2InY(botV->head(), tempV->head())>0) { + + botV = tempV; + } + } + + /*find the first(top) and the last (bottom) grid line which intersect the + *this polygon + */ + Int firstGridIndex; /*the index in the grid*/ + Int lastGridIndex; + firstGridIndex = (Int) ((topV->head()[1] - grid->get_v_min()) / (grid->get_v_max() - grid->get_v_min()) * (grid->get_n_vlines()-1)); + lastGridIndex = (Int) ((botV->head()[1] - grid->get_v_min()) / (grid->get_v_max() - grid->get_v_min()) * (grid->get_n_vlines()-1)) + 1; + + + /*find the interval inside the polygon for each gridline*/ + Int *leftGridIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1)); + assert(leftGridIndices); + Int *rightGridIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1)); + assert(rightGridIndices); + Int *leftGridInnerIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1)); + assert(leftGridInnerIndices); + Int *rightGridInnerIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1)); + assert(rightGridInnerIndices); + + findLeftGridIndices(topV, firstGridIndex, lastGridIndex, grid, leftGridIndices, leftGridInnerIndices); + + findRightGridIndices(topV, firstGridIndex, lastGridIndex, grid, rightGridIndices, rightGridInnerIndices); + + gridBoundaryChain leftGridChain(grid, firstGridIndex, firstGridIndex-lastGridIndex+1, leftGridIndices, leftGridInnerIndices); + + gridBoundaryChain rightGridChain(grid, firstGridIndex, firstGridIndex-lastGridIndex+1, rightGridIndices, rightGridInnerIndices); + + + +// leftGridChain.draw(); +// leftGridChain.drawInner(); +// rightGridChain.draw(); +// rightGridChain.drawInner(); + /*(1) determine the grid boundaries (left and right). + *(2) process polygon into two monotone chaines: use vertexArray + *(3) call sampleMonoPolyRec + */ + + /*copy the two chains into vertexArray datastructure*/ + Int i; + vertexArray leftChain(20); /*this is a dynamic array*/ + for(i=1; i<=topV->get_npoints()-2; i++) { /*the first vertex is the top vertex which doesn't belong to inc_chain*/ + leftChain.appendVertex(topV->getVertex(i)); + } + for(tempV = topV->getNext(); tempV != botV; tempV = tempV->getNext()) + { + for(i=0; i<=tempV->get_npoints()-2; i++){ + leftChain.appendVertex(tempV->getVertex(i)); + } + } + + vertexArray rightChain(20); + for(tempV = topV->getPrev(); tempV != botV; tempV = tempV->getPrev()) + { + for(i=tempV->get_npoints()-2; i>=0; i--){ + rightChain.appendVertex(tempV->getVertex(i)); + } + } + for(i=botV->get_npoints()-2; i>=1; i--){ + rightChain.appendVertex(tempV->getVertex(i)); + } + + sampleMonoPolyRec(topV->head(), + botV->head(), + &leftChain, + 0, + &rightChain, + 0, + &leftGridChain, + &rightGridChain, + 0, + pStream, + rbArray); + + + /*cleanup space*/ + free(leftGridIndices); + free(rightGridIndices); + free(leftGridInnerIndices); + free(rightGridInnerIndices); +} + +void sampleMonoPolyRec( + Real* topVertex, + Real* botVertex, + vertexArray* leftChain, + Int leftStartIndex, + vertexArray* rightChain, + Int rightStartIndex, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridStartIndex, + primStream* pStream, + rectBlockArray* rbArray) +{ + + /*find the first connected component, and the four corners. + */ + Int index1, index2; /*the first and last grid line of the first connected component*/ + + if(topVertex[1] <= botVertex[1]) + return; + + /*find i so that the grid line is below the top vertex*/ + Int i=gridStartIndex; + while (i < leftGridChain->get_nVlines()) + { + if(leftGridChain->get_v_value(i) < topVertex[1]) + break; + i++; + } + + /*find the first connected component starting with i*/ + /*find index1 so that left_uline_index <= right_uline_index, that is, this + *grid line contains at least one inner grid point + */ + index1=i; + int num_skipped_grid_lines=0; + while(index1 < leftGridChain->get_nVlines()) + { + if(leftGridChain->getUlineIndex(index1) <= rightGridChain->getUlineIndex(index1)) + break; + num_skipped_grid_lines++; + index1++; + } + + + + if(index1 >= leftGridChain->get_nVlines()) /*no grid line exists which has inner point*/ + { + /*stop recursion, ...*/ + /*monotone triangulate it...*/ +// printf("no grid line exists\n"); +/* + monoTriangulationRecOpt(topVertex, botVertex, leftChain, leftStartIndex, + rightChain, rightStartIndex, pStream); +*/ + +if(num_skipped_grid_lines <2) + { + monoTriangulationRecGenOpt(topVertex, botVertex, leftChain, leftStartIndex, + leftChain->getNumElements()-1, + rightChain, rightStartIndex, + rightChain->getNumElements()-1, + pStream); + } +else + { + //the optimum way to triangulate is top-down since this polygon + //is narrow-long. + monoTriangulationRec(topVertex, botVertex, leftChain, leftStartIndex, + rightChain, rightStartIndex, pStream); + } + +/* + monoTriangulationRec(topVertex, botVertex, leftChain, leftStartIndex, + rightChain, rightStartIndex, pStream); +*/ + +/* monoTriangulationRecGenTBOpt(topVertex, botVertex, + leftChain, leftStartIndex, leftChain->getNumElements()-1, + rightChain, rightStartIndex, rightChain->getNumElements()-1, + pStream);*/ + + + + } + else + { + + /*find index2 so that left_inner_index <= right_inner_index holds until index2*/ + index2=index1+1; + if(index2 < leftGridChain->get_nVlines()) + while(leftGridChain->getInnerIndex(index2) <= rightGridChain->getInnerIndex(index2)) + { + index2++; + if(index2 >= leftGridChain->get_nVlines()) + break; + } + + index2--; + + + + /*the neck*/ + Int neckLeftIndex; + Int neckRightIndex; + + /*the four corners*/ + Int up_leftCornerWhere; + Int up_leftCornerIndex; + Int up_rightCornerWhere; + Int up_rightCornerIndex; + Int down_leftCornerWhere; + Int down_leftCornerIndex; + Int down_rightCornerWhere; + Int down_rightCornerIndex; + + Real* tempBotVertex; /*the bottom vertex for this component*/ + Real* nextTopVertex=NULL; /*for the recursion*/ + Int nextLeftStartIndex=0; + Int nextRightStartIndex=0; + + /*find the points below the grid line index2 on both chains*/ + Int botLeftIndex = leftChain->findIndexStrictBelowGen( + leftGridChain->get_v_value(index2), + leftStartIndex, + leftChain->getNumElements()-1); + Int botRightIndex = rightChain->findIndexStrictBelowGen( + rightGridChain->get_v_value(index2), + rightStartIndex, + rightChain->getNumElements()-1); + /*if either botLeftIndex>= numelements, + * or botRightIndex >= numelemnet, + *then there is no neck exists. the bottom vertex is botVertex, + */ + if(! findNeckF(leftChain, botLeftIndex, rightChain, botRightIndex, + leftGridChain, rightGridChain, index2, neckLeftIndex, neckRightIndex)) + /* + if(botLeftIndex == leftChain->getNumElements() || + botRightIndex == rightChain->getNumElements()) + */ + { +#ifdef MYDEBUG + printf("neck NOT exists, botRightIndex=%i\n", botRightIndex); +#endif + + tempBotVertex = botVertex; + nextTopVertex = botVertex; + botLeftIndex = leftChain->getNumElements()-1; + botRightIndex = rightChain->getNumElements()-1; + } + else /*neck exists*/ + { +#ifdef MYDEBUG + printf("neck exists\n"); +#endif + + /* + findNeck(leftChain, botLeftIndex, + rightChain, botRightIndex, + neckLeftIndex, + neckRightIndex); + */ +#ifdef MYDEBUG +printf("neck is found, neckLeftIndex=%i, neckRightIndex=%i\n", neckLeftIndex, neckRightIndex); +glBegin(GL_LINES); +glVertex2fv(leftChain->getVertex(neckLeftIndex)); +glVertex2fv(rightChain->getVertex(neckRightIndex)); +glEnd(); +#endif + + if(leftChain->getVertex(neckLeftIndex)[1] <= rightChain->getVertex(neckRightIndex)[1]) + { + tempBotVertex = leftChain->getVertex(neckLeftIndex); + botLeftIndex = neckLeftIndex-1; + botRightIndex = neckRightIndex; + nextTopVertex = rightChain->getVertex(neckRightIndex); + nextLeftStartIndex = neckLeftIndex; + nextRightStartIndex = neckRightIndex+1; + } + else + { + tempBotVertex = rightChain->getVertex(neckRightIndex); + botLeftIndex = neckLeftIndex; + botRightIndex = neckRightIndex-1; + nextTopVertex = leftChain->getVertex(neckLeftIndex); + nextLeftStartIndex = neckLeftIndex+1; + nextRightStartIndex = neckRightIndex; + } + } + + findUpCorners(topVertex, + leftChain, + leftStartIndex, botLeftIndex, + rightChain, + rightStartIndex, botRightIndex, + leftGridChain->get_v_value(index1), + leftGridChain->get_u_value(index1), + rightGridChain->get_u_value(index1), + up_leftCornerWhere, + up_leftCornerIndex, + up_rightCornerWhere, + up_rightCornerIndex); + + findDownCorners(tempBotVertex, + leftChain, + leftStartIndex, botLeftIndex, + rightChain, + rightStartIndex, botRightIndex, + leftGridChain->get_v_value(index2), + leftGridChain->get_u_value(index2), + rightGridChain->get_u_value(index2), + down_leftCornerWhere, + down_leftCornerIndex, + down_rightCornerWhere, + down_rightCornerIndex); +#ifdef MYDEBUG + printf("find corners done, down_leftwhere=%i, down_righwhere=%i,\n",down_leftCornerWhere, down_rightCornerWhere ); + printf("find corners done, up_leftwhere=%i, up_righwhere=%i,\n",up_leftCornerWhere, up_rightCornerWhere ); + printf("find corners done, up_leftindex=%i, up_righindex=%i,\n",up_leftCornerIndex, up_rightCornerIndex ); + printf("find corners done, down_leftindex=%i, down_righindex=%i,\n",down_leftCornerIndex, down_rightCornerIndex ); +#endif + +/* + drawCorners(topVertex, + tempBotVertex, + leftChain, + rightChain, + leftGridChain, + rightGridChain, + index1, + index2, + up_leftCornerWhere, + up_leftCornerIndex, + up_rightCornerWhere, + up_rightCornerIndex, + down_leftCornerWhere, + down_leftCornerIndex, + down_rightCornerWhere, + down_rightCornerIndex); +*/ + + + sampleConnectedComp(topVertex, tempBotVertex, + leftChain, + leftStartIndex, botLeftIndex, + rightChain, + rightStartIndex, botRightIndex, + leftGridChain, + rightGridChain, + index1, index2, + up_leftCornerWhere, + up_leftCornerIndex, + up_rightCornerWhere, + up_rightCornerIndex, + down_leftCornerWhere, + down_leftCornerIndex, + down_rightCornerWhere, + down_rightCornerIndex, + pStream, + rbArray + ); + + /*recursion*/ + + sampleMonoPolyRec( + nextTopVertex, + botVertex, + leftChain, + nextLeftStartIndex, + rightChain, + nextRightStartIndex, + leftGridChain, + rightGridChain, + index2+1, + pStream, rbArray); + + + } + +} + +void sampleLeftStrip(vertexArray* leftChain, + Int topLeftIndex, + Int botLeftIndex, + gridBoundaryChain* leftGridChain, + Int leftGridChainStartIndex, + Int leftGridChainEndIndex, + primStream* pStream + ) +{ + assert(leftChain->getVertex(topLeftIndex)[1] > leftGridChain->get_v_value(leftGridChainStartIndex)); + assert(leftChain->getVertex(topLeftIndex+1)[1] <= leftGridChain->get_v_value(leftGridChainStartIndex)); + assert(leftChain->getVertex(botLeftIndex)[1] <= leftGridChain->get_v_value(leftGridChainEndIndex)); + assert(leftChain->getVertex(botLeftIndex-1)[1] > leftGridChain->get_v_value(leftGridChainEndIndex)); + + /* + *(1)find the last grid line which doesn'; pass below + * this first edge, sample this region: one trim edge and + * possily multiple grid lines. + */ + Real *upperVert, *lowerVert; /*the end points of the first trim edge*/ + upperVert = leftChain->getVertex(topLeftIndex); + lowerVert = leftChain->getVertex(topLeftIndex+1); + + Int index = leftGridChainStartIndex; + while(leftGridChain->get_v_value(index) >= lowerVert[1]){ + index++; + if(index > leftGridChainEndIndex) + break; + } + index--; + + sampleLeftSingleTrimEdgeRegion(upperVert, lowerVert, + leftGridChain, + leftGridChainStartIndex, + index, + pStream); + sampleLeftStripRec(leftChain, topLeftIndex+1, botLeftIndex, + leftGridChain, index, leftGridChainEndIndex, + pStream); + +} + +void sampleLeftStripRec(vertexArray* leftChain, + Int topLeftIndex, + Int botLeftIndex, + gridBoundaryChain* leftGridChain, + Int leftGridChainStartIndex, + Int leftGridChainEndIndex, + primStream* pStream + ) +{ + /*now top left trim vertex is below the top grid line. + */ + /*stop condition: if topLeftIndex >= botLeftIndex, then stop. + */ + if(topLeftIndex >= botLeftIndex) + return; + + /*find the last trim vertex which is above the second top grid line: + * index1. + *and sampleLeftOneGridStep(leftchain, topLeftIndex, index1, leftGridChain, + * leftGridChainStartIndex). + * index1 could be equal to topLeftIndex. + */ + Real secondGridChainV = leftGridChain->get_v_value(leftGridChainStartIndex+1); + assert(leftGridChainStartIndex < leftGridChainEndIndex); + Int index1 = topLeftIndex; + while(leftChain->getVertex(index1)[1] > secondGridChainV) + index1++; + index1--; + + sampleLeftOneGridStep(leftChain, topLeftIndex, index1, leftGridChain, leftGridChainStartIndex, pStream); + + + /* + * Let the next trim vertex be nextTrimVertIndex (which should be + * below the second grid line). + * Find the last grid line index2 which is above nextTrimVert. + * sampleLeftSingleTrimEdgeRegion(uppervert[2], lowervert[2], + * leftGridChain, leftGridChainStartIndex+1, index2). + */ + Real *uppervert, *lowervert; + uppervert = leftChain->getVertex(index1); + lowervert = leftChain->getVertex(index1+1); + Int index2 = leftGridChainStartIndex+1; + + while(leftGridChain->get_v_value(index2) >= lowervert[1]) + { + index2++; + if(index2 > leftGridChainEndIndex) + break; + } + index2--; + sampleLeftSingleTrimEdgeRegion(uppervert, lowervert, leftGridChain, leftGridChainStartIndex+1, index2, pStream); + + /* sampleLeftStripRec(leftChain, + nextTrimVertIndex, + botLeftIndex, + leftGridChain, + index2, + leftGridChainEndIndex + ) + * + */ + sampleLeftStripRec(leftChain, index1+1, botLeftIndex, leftGridChain, index2, leftGridChainEndIndex, pStream); + +} + + +/***************begin RecF***********************/ +/* the gridlines from leftGridChainStartIndex to + * leftGridChainEndIndex are assumed to form a + * connected component. + * the trim vertex of topLeftIndex is assumed to + * be below the first gridline, and the tim vertex + * of botLeftIndex is assumed to be above the last + * grid line. + * If botLeftIndex < topLeftIndex, then no connected componeent exists, and this funcion returns without + * outputing any triangles. + * Otherwise botLeftIndex >= topLeftIndex, there is at least one triangle to output. + */ +void sampleLeftStripRecF(vertexArray* leftChain, + Int topLeftIndex, + Int botLeftIndex, + gridBoundaryChain* leftGridChain, + Int leftGridChainStartIndex, + Int leftGridChainEndIndex, + primStream* pStream + ) +{ + /*now top left trim vertex is below the top grid line. + */ + /*stop condition: if topLeftIndex > botLeftIndex, then stop. + */ + if(topLeftIndex > botLeftIndex) + return; + + /*if there is only one grid Line, return.*/ + + if(leftGridChainStartIndex>=leftGridChainEndIndex) + return; + + + assert(leftChain->getVertex(topLeftIndex)[1] <= leftGridChain->get_v_value(leftGridChainStartIndex) && + leftChain->getVertex(botLeftIndex)[1] >= leftGridChain->get_v_value(leftGridChainEndIndex)); + + /*firs find the first trim vertex which is below or equal to the second top grid line: + * index1. + */ + Real secondGridChainV = leftGridChain->get_v_value(leftGridChainStartIndex+1); + + + Int index1 = topLeftIndex; + + while(leftChain->getVertex(index1)[1] > secondGridChainV){ + index1++; + if(index1>botLeftIndex) + break; + } + + /*now leftChain->getVertex(index-1)[1] > secondGridChainV and + * leftChain->getVertex(index)[1] <= secondGridChainV + *If equality holds, then we should include the vertex index1, otherwise we include only index1-1, to + *perform sampleOneGridStep. + */ + if(index1>botLeftIndex) + index1--; + else if(leftChain->getVertex(index1)[1] < secondGridChainV) + index1--; + + /*now we have leftChain->getVertex(index1)[1] >= secondGridChainV, and + * leftChain->getVertex(index1+1)[1] <= secondGridChainV + */ + + + sampleLeftOneGridStep(leftChain, topLeftIndex, index1, leftGridChain, leftGridChainStartIndex, pStream); + + + /*if leftChain->getVertex(index1)[1] == secondGridChainV, then we can recursively do the rest. + */ + if(leftChain->getVertex(index1)[1] == secondGridChainV) + { + + sampleLeftStripRecF(leftChain, index1, botLeftIndex,leftGridChain, leftGridChainStartIndex+1, leftGridChainEndIndex, pStream); + } + else if(index1 < botLeftIndex) + { + + /* Otherwise, we have leftChain->getVertex(index1)[1] > secondGridChainV, + * let the next trim vertex be nextTrimVertIndex (which should be strictly + * below the second grid line). + * Find the last grid line index2 which is above nextTrimVert. + * sampleLeftSingleTrimEdgeRegion(uppervert[2], lowervert[2], + * leftGridChain, leftGridChainStartIndex+1, index2). + */ + Real *uppervert, *lowervert; + uppervert = leftChain->getVertex(index1); + lowervert = leftChain->getVertex(index1+1); //okay since index1<botLeftIndex + Int index2 = leftGridChainStartIndex+1; + + + while(leftGridChain->get_v_value(index2) >= lowervert[1]) + { + index2++; + if(index2 > leftGridChainEndIndex) + break; + } + index2--; + + + sampleLeftSingleTrimEdgeRegion(uppervert, lowervert, leftGridChain, leftGridChainStartIndex+1, index2, pStream); + + /*recursion*/ + + sampleLeftStripRecF(leftChain, index1+1, botLeftIndex, leftGridChain, index2, leftGridChainEndIndex, pStream); + } + +} + +/***************End RecF***********************/ + +/*sample the left area in between one trim edge and multiple grid lines. + * all the grid lines should be in between the two end poins of the + *trim edge. + */ +void sampleLeftSingleTrimEdgeRegion(Real upperVert[2], Real lowerVert[2], + gridBoundaryChain* gridChain, + Int beginIndex, + Int endIndex, + primStream* pStream) +{ + Int i,j,k; + + vertexArray vArray(endIndex-beginIndex+1); + vArray.appendVertex(gridChain->get_vertex(beginIndex)); + + for(k=1, i=beginIndex+1; i<=endIndex; i++, k++) + { + vArray.appendVertex(gridChain->get_vertex(i)); + + /*output the fan of the grid points of the (i)th and (i-1)th grid line. + */ + if(gridChain->getUlineIndex(i) < gridChain->getUlineIndex(i-1)) + { + pStream->begin(); + pStream->insert(gridChain->get_vertex(i-1)); + for(j=gridChain->getUlineIndex(i); j<= gridChain->getUlineIndex(i-1); j++) + pStream->insert(gridChain->getGrid()->get_u_value(j), gridChain->get_v_value(i)); + pStream->end(PRIMITIVE_STREAM_FAN); + } + else if(gridChain->getUlineIndex(i) > gridChain->getUlineIndex(i-1)) + { + pStream->begin(); + pStream->insert(gridChain->get_vertex(i)); + for(j=gridChain->getUlineIndex(i); j>= gridChain->getUlineIndex(i-1); j--) + pStream->insert(gridChain->getGrid()->get_u_value(j), gridChain->get_v_value(i-1)); + pStream->end(PRIMITIVE_STREAM_FAN); + } + /*otherwisem, the two are equal, so there is no fan to outout*/ + } + + monoTriangulation2(upperVert, lowerVert, &vArray, 0, endIndex-beginIndex, + 0, /*decreasing chain*/ + pStream); +} + +/*return i, such that from begin to i-1 the chain is strictly u-monotone. + */ +Int findIncreaseChainFromBegin(vertexArray* chain, Int begin ,Int end) +{ + Int i=begin; + Real prevU = chain->getVertex(i)[0]; + Real thisU; + for(i=begin+1; i<=end; i++){ + thisU = chain->getVertex(i)[0]; + + if(prevU < thisU){ + prevU = thisU; + } + else + break; + } + return i; +} + +/*check whether there is a vertex whose v value is strictly + *inbetween vup vbelow + *if no middle exists return -1, else return the idnex. + */ +Int checkMiddle(vertexArray* chain, Int begin, Int end, + Real vup, Real vbelow) +{ + Int i; + for(i=begin; i<=end; i++) + { + if(chain->getVertex(i)[1] < vup && chain->getVertex(i)[1]>vbelow) + return i; + } + return -1; +} + +/*the degenerat case of sampleLeftOneGridStep*/ +void sampleLeftOneGridStepNoMiddle(vertexArray* leftChain, + Int beginLeftIndex, + Int endLeftIndex, + gridBoundaryChain* leftGridChain, + Int leftGridChainStartIndex, + primStream* pStream) +{ + /*since there is no middle, there is at most one point which is on the + *second grid line, there could be multiple points on the first (top) + *grid line. + */ + + leftGridChain->leftEndFan(leftGridChainStartIndex+1, pStream); + + monoTriangulation2(leftGridChain->get_vertex(leftGridChainStartIndex), + leftGridChain->get_vertex(leftGridChainStartIndex+1), + leftChain, + beginLeftIndex, + endLeftIndex, + 1, //is increase chain. + pStream); +} + + + +/*sampling the left area in between two grid lines. + */ +void sampleLeftOneGridStep(vertexArray* leftChain, + Int beginLeftIndex, + Int endLeftIndex, + gridBoundaryChain* leftGridChain, + Int leftGridChainStartIndex, + primStream* pStream + ) +{ + if(checkMiddle(leftChain, beginLeftIndex, endLeftIndex, + leftGridChain->get_v_value(leftGridChainStartIndex), + leftGridChain->get_v_value(leftGridChainStartIndex+1))<0) + + { + + sampleLeftOneGridStepNoMiddle(leftChain, beginLeftIndex, endLeftIndex, leftGridChain, leftGridChainStartIndex, pStream); + return; + } + + //copy into a polygon + { + directedLine* poly = NULL; + sampledLine* sline; + directedLine* dline; + gridWrap* grid = leftGridChain->getGrid(); + Real vert1[2]; + Real vert2[2]; + Int i; + + Int innerInd = leftGridChain->getInnerIndex(leftGridChainStartIndex+1); + Int upperInd = leftGridChain->getUlineIndex(leftGridChainStartIndex); + Int lowerInd = leftGridChain->getUlineIndex(leftGridChainStartIndex+1); + Real upperV = leftGridChain->get_v_value(leftGridChainStartIndex); + Real lowerV = leftGridChain->get_v_value(leftGridChainStartIndex+1); + + //the upper gridline + vert1[1] = vert2[1] = upperV; + for(i=innerInd; i>upperInd; i--) + { + vert1[0]=grid->get_u_value(i); + vert2[0]=grid->get_u_value(i-1); + sline = new sampledLine(vert1, vert2); + dline = new directedLine(INCREASING, sline); + if(poly == NULL) + poly = dline; + else + poly->insert(dline); + } + + //the edge connecting upper grid with left chain + vert1[0] = grid->get_u_value(upperInd); + vert1[1] = upperV; + sline = new sampledLine(vert1, leftChain->getVertex(beginLeftIndex)); + dline = new directedLine(INCREASING, sline); + if(poly == NULL) + poly = dline; + else + poly->insert(dline); + + //the left chain + for(i=beginLeftIndex; i<endLeftIndex; i++) + { + sline = new sampledLine(leftChain->getVertex(i), leftChain->getVertex(i+1)); + dline = new directedLine(INCREASING, sline); + poly->insert(dline); + } + + //the edge connecting left chain with lower gridline + vert2[0] = grid->get_u_value(lowerInd); + vert2[1] = lowerV; + sline = new sampledLine(leftChain->getVertex(endLeftIndex), vert2); + dline = new directedLine(INCREASING, sline); + poly->insert(dline); + + //the lower grid line + vert1[1] = vert2[1] = lowerV; + for(i=lowerInd; i<innerInd; i++) + { + vert1[0] = grid->get_u_value(i); + vert2[0] = grid->get_u_value(i+1); + sline = new sampledLine(vert1, vert2); + dline = new directedLine(INCREASING, sline); + poly->insert(dline); + } + + //the vertical grid line segement + vert1[0]=vert2[0] = grid->get_u_value(innerInd); + vert2[1]=upperV; + vert1[1]=lowerV; + sline=new sampledLine(vert1, vert2); + dline=new directedLine(INCREASING, sline); + poly->insert(dline); + monoTriangulationOpt(poly, pStream); + //cleanup + poly->deleteSinglePolygonWithSline(); + return; + } + + + + + + Int i; + if(1/*leftGridChain->getUlineIndex(leftGridChainStartIndex) >= + leftGridChain->getUlineIndex(leftGridChainStartIndex+1)*/ + ) /*the second grid line is beyond the first one to the left*/ + { + /*find the maximal U-monotone chain + * of endLeftIndex, endLeftIndex-1, ..., + */ + i=endLeftIndex; + Real prevU = leftChain->getVertex(i)[0]; + for(i=endLeftIndex-1; i>=beginLeftIndex; i--){ + Real thisU = leftChain->getVertex(i)[0]; + if( prevU < thisU){ + prevU = thisU; + } + else + break; + } + /*from endLeftIndex to i+1 is strictly U- monotone */ + /*if i+1==endLeftIndex and the vertex and leftchain is on the second gridline, then + *we should use 2 vertices on the leftchain. If we only use one (endLeftIndex), then we + *we would output degenerate triangles + */ + if(i+1 == endLeftIndex && leftChain->getVertex(endLeftIndex)[1] == leftGridChain->get_v_value(1+leftGridChainStartIndex)) + i--; + + Int j = beginLeftIndex/*endLeftIndex*/+1; + + + if(leftGridChain->getInnerIndex(leftGridChainStartIndex+1) > leftGridChain->getUlineIndex(leftGridChainStartIndex)) + { + j = findIncreaseChainFromBegin(leftChain, beginLeftIndex, i+1/*endLeftIndex*/); + + Int temp = beginLeftIndex; + /*now from begin to j-1 is strictly u-monotone*/ + /*if j-1 is on the first grid line, then we want to skip to the vertex which is strictly + *below the grid line. This vertexmust exist since there is a 'corner turn' inbetween the two grid lines + */ + if(j-1 == beginLeftIndex) + { + while(leftChain->getVertex(j-1)[1] == leftGridChain->get_v_value(leftGridChainStartIndex)) + j++; + + Real vert[2]; + vert[0] = leftGridChain->get_u_value(leftGridChainStartIndex); + vert[1] = leftGridChain->get_v_value(leftGridChainStartIndex); + + monoTriangulation2( + vert/*leftChain->getVertex(beginLeftIndex)*/, + leftChain->getVertex(j-1), + leftChain, + beginLeftIndex, + j-2, + 1, + pStream //increase chain + ); + + temp = j-1; + } + + stripOfFanLeft(leftChain, j-1, temp/*beginLeftIndex*/, leftGridChain->getGrid(), + leftGridChain->getVlineIndex(leftGridChainStartIndex), + leftGridChain->getUlineIndex(leftGridChainStartIndex), + leftGridChain->getInnerIndex(leftGridChainStartIndex+1), + pStream, + 1 /*the grid line is above the trim line*/ + ); + } + + stripOfFanLeft(leftChain, endLeftIndex, i+1, leftGridChain->getGrid(), + leftGridChain->getVlineIndex(leftGridChainStartIndex+1), + leftGridChain->getUlineIndex(leftGridChainStartIndex+1), + leftGridChain->getInnerIndex(leftGridChainStartIndex+1), + pStream, + 0 /*the grid line is below the trim lines*/ + ); + + /*monotone triangulate the remaining left chain togther with the + *two vertices on the two grid v-lines. + */ + Real vert[2][2]; + vert[0][0]=vert[1][0] = leftGridChain->getInner_u_value(leftGridChainStartIndex+1); + vert[0][1] = leftGridChain->get_v_value(leftGridChainStartIndex); + vert[1][1] = leftGridChain->get_v_value(leftGridChainStartIndex+1); + +// vertexArray right(vert, 2); + + monoTriangulation2( + &vert[0][0], /*top vertex */ + &vert[1][0], /*bottom vertex*/ + leftChain, + /*beginLeftIndex*/j-1, + i+1, + 1, /*an increasing chain*/ + pStream); + } + else /*the second one is shorter than the first one to the left*/ + { + /*find the maximal U-monotone chain of beginLeftIndex, beginLeftIndex+1,..., + */ + i=beginLeftIndex; + Real prevU = leftChain->getVertex(i)[0]; + for(i=beginLeftIndex+1; i<=endLeftIndex; i++){ + Real thisU = leftChain->getVertex(i)[0]; + + if(prevU < thisU){ + prevU = thisU; + } + else + break; + } + /*from beginLeftIndex to i-1 is strictly U-monotone*/ + + + stripOfFanLeft(leftChain, i-1, beginLeftIndex, leftGridChain->getGrid(), + leftGridChain->getVlineIndex(leftGridChainStartIndex), + leftGridChain->getUlineIndex(leftGridChainStartIndex), + leftGridChain->getUlineIndex(leftGridChainStartIndex+1), + pStream, + 1 /*the grid line is above the trim lines*/ + ); + /*monotone triangulate the remaining left chain together with the + *two vertices on the two grid v-lines. + */ + Real vert[2][2]; + vert[0][0]=vert[1][0] = leftGridChain->get_u_value(leftGridChainStartIndex+1); + vert[0][1] = leftGridChain->get_v_value(leftGridChainStartIndex); + vert[1][1] = leftGridChain->get_v_value(leftGridChainStartIndex+1); + + vertexArray right(vert, 2); + + monoTriangulation2( + &vert[0][0], //top vertex + &vert[1][0], //bottom vertex + leftChain, + i-1, + endLeftIndex, + 1, /*an increase chain*/ + pStream); + + } +} + +/*n_upper>=1 + *n_lower>=1 + */ +void triangulateXYMono(Int n_upper, Real upperVerts[][2], + Int n_lower, Real lowerVerts[][2], + primStream* pStream) +{ + Int i,j,k,l; + Real* leftMostV; + + assert(n_upper>=1 && n_lower>=1); + if(upperVerts[0][0] <= lowerVerts[0][0]) + { + i=1; + j=0; + leftMostV = upperVerts[0]; + } + else + { + i=0; + j=1; + leftMostV = lowerVerts[0]; + } + + while(1) + { + if(i >= n_upper) /*case1: no more in upper*/ + { + + if(j<n_lower-1) /*at least two vertices in lower*/ + { + pStream->begin(); + pStream->insert(leftMostV); + while(j<n_lower){ + pStream->insert(lowerVerts[j]); + j++; + } + pStream->end(PRIMITIVE_STREAM_FAN); + } + + break; + } + else if(j>= n_lower) /*case2: no more in lower*/ + { + + if(i<n_upper-1) /*at least two vertices in upper*/ + { + pStream->begin(); + pStream->insert(leftMostV); + + for(k=n_upper-1; k>=i; k--) + pStream->insert(upperVerts[k]); + + pStream->end(PRIMITIVE_STREAM_FAN); + } + + break; + } + else /* case3: neither is empty, plus the leftMostV, there is at least one triangle to output*/ + { + + if(upperVerts[i][0] <= lowerVerts[j][0]) + { + pStream->begin(); + pStream->insert(lowerVerts[j]); /*the origin of this fan*/ + + /*find the last k>=i such that + *upperverts[k][0] <= lowerverts[j][0] + */ + k=i; + while(k<n_upper) + { + if(upperVerts[k][0] > lowerVerts[j][0]) + break; + k++; + } + k--; + for(l=k; l>=i; l--)/*the reverse is for two-face lighting*/ + { + pStream->insert(upperVerts[l]); + } + pStream->insert(leftMostV); + + pStream->end(PRIMITIVE_STREAM_FAN); + //update i for next loop + i = k+1; + leftMostV = upperVerts[k]; + + } + else /*upperVerts[i][0] > lowerVerts[j][0]*/ + { + pStream->begin(); + pStream->insert(upperVerts[i]);/*the origion of this fan*/ + pStream->insert(leftMostV); + /*find the last k>=j such that + *lowerverts[k][0] < upperverts[i][0]*/ + k=j; + while(k< n_lower) + { + if(lowerVerts[k][0] >= upperVerts[i][0]) + break; + pStream->insert(lowerVerts[k]); + k++; + } + pStream->end(PRIMITIVE_STREAM_FAN); + j=k; + leftMostV = lowerVerts[j-1]; + } + } + } +} + + +void stripOfFanLeft(vertexArray* leftChain, + Int largeIndex, + Int smallIndex, + gridWrap* grid, + Int vlineIndex, + Int ulineSmallIndex, + Int ulineLargeIndex, + primStream* pStream, + Int gridLineUp /*1 if the grid line is above the trim lines*/ + ) +{ + assert(largeIndex >= smallIndex); + + Real grid_v_value; + grid_v_value = grid->get_v_value(vlineIndex); + + Real2* trimVerts=(Real2*) malloc(sizeof(Real2)* (largeIndex-smallIndex+1)); + assert(trimVerts); + + + Real2* gridVerts=(Real2*) malloc(sizeof(Real2)* (ulineLargeIndex-ulineSmallIndex+1)); + assert(gridVerts); + + Int k,i; + if(gridLineUp) /*trim line is below grid line, so trim vertices are going right when index increases*/ + for(k=0, i=smallIndex; i<=largeIndex; i++, k++) + { + trimVerts[k][0] = leftChain->getVertex(i)[0]; + trimVerts[k][1] = leftChain->getVertex(i)[1]; + } + else + for(k=0, i=largeIndex; i>=smallIndex; i--, k++) + { + trimVerts[k][0] = leftChain->getVertex(i)[0]; + trimVerts[k][1] = leftChain->getVertex(i)[1]; + } + + for(k=0, i=ulineSmallIndex; i<= ulineLargeIndex; i++, k++) + { + gridVerts[k][0] = grid->get_u_value(i); + gridVerts[k][1] = grid_v_value; + } + + if(gridLineUp) + triangulateXYMono( + ulineLargeIndex-ulineSmallIndex+1, gridVerts, + largeIndex-smallIndex+1, trimVerts, + pStream); + else + triangulateXYMono(largeIndex-smallIndex+1, trimVerts, + ulineLargeIndex-ulineSmallIndex+1, gridVerts, + pStream); + free(trimVerts); + free(gridVerts); +} + + + + + diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleMonoPoly.h b/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleMonoPoly.h new file mode 100644 index 000000000..3a5fa6c91 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/sampleMonoPoly.h @@ -0,0 +1,184 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ +/* +*/ + +#ifndef _SAMPLEMONOPOLY_H +#define _SAMPLEMONOPOLY_H + +#include "monoTriangulation.h" +#include "gridWrap.h" +#include "rectBlock.h" + + +void triangulateXYMono(Int n_upper, Real upperVerts[][2], + Int n_lower, Real lowerVerts[][2], + primStream* pStream); + +void stripOfFanLeft(vertexArray* leftChain, + Int largeIndex, + Int smallIndex, + gridWrap* grid, + Int vlineIndex, + Int ulineSmallIndex, + Int ulineLargeIndex, + primStream* pStream, + Int gridLineUp + ); +void sampleLeftOneGridStep(vertexArray* leftChain, + Int beginLeftIndex, + Int endLeftIndex, + gridBoundaryChain* leftGridChain, + Int leftGridChainStartIndex, + primStream* pStream + ); + +void sampleLeftSingleTrimEdgeRegion(Real upperVert[2], Real lowerVert[2], + gridBoundaryChain* gridChain, + Int beginIndex, + Int endIndex, + primStream* pStream); + +void sampleLeftStripRec(vertexArray* leftChain, + Int topLeftIndex, + Int botLeftIndex, + gridBoundaryChain* leftGridChain, + Int leftGridChainStartIndex, + Int leftGridChainEndIndex, + primStream* pStream + ); + +void sampleLeftStrip(vertexArray* leftChain, + Int topLeftIndex, + Int botLeftIndex, + gridBoundaryChain* leftGridChain, + Int leftGridChainStartIndex, + Int leftGridChainEndIndex, + primStream* pStream + ); + +void findLeftGridIndices(directedLine* topEdge, Int firstGridIndex, Int lastGridIndex, gridWrap* grid, Int* ret_indices, Int* ret_inner); + +void findRightGridIndices(directedLine* topEdge, Int firstGridIndex, Int lastGridIndex, gridWrap* grid, Int* ret_indices, Int* ret_inner); + +void sampleMonoPoly(directedLine* polygon, gridWrap* grid, Int ulinear, Int vlinear, primStream *pStream, rectBlockArray* rbArray); + +void sampleMonoPolyRec( + Real* topVertex, + Real* botVertex, + vertexArray* leftChain, + Int leftStartIndex, + vertexArray* rightChain, + Int rightStartIndex, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridStartIndex, + primStream* pStream, + rectBlockArray* rbArray + ); + +void sampleLeftStripRecF(vertexArray* leftChain, + Int topLeftIndex, + Int botLeftIndex, + gridBoundaryChain* leftGridChain, + Int leftGridChainStartIndex, + Int leftGridChainEndIndex, + primStream* pStream + ); + +void findUpCorners(Real *topVertex, + vertexArray *leftChain, + Int leftChainStartIndex, Int leftChainEndIndex, + vertexArray *rightChain, + Int rightChainStartIndex, Int rightChainEndIndex, + Real v, + Real uleft, + Real uright, + Int& ret_leftCornerWhere, + Int& ret_leftCornerIndex, + Int& ret_rightCornerWhere, + Int& ret_rightCornerIndex + ); +void findDownCorners(Real *botVertex, + vertexArray *leftChain, Int leftChainStartIndex, Int leftChainEndIndex, + vertexArray *rightChain, Int rightChainStartIndex, Int rightChainEndIndex, + Real v, + Real uleft, + Real uright, + Int& ret_leftCornerWhere, + Int& ret_leftCornerIndex, + Int& ret_rightCornerWhere, + Int& ret_rightCornerIndex + ); +void findNeck(vertexArray *leftChain, Int botLeftIndex, + vertexArray *rightChain, Int botRightIndex, + Int& leftLastIndex, /*left point of the neck*/ + Int& rightLastIndex /*right point of the neck*/ + ); + +Int findNeckF(vertexArray *leftChain, Int botLeftIndex, + vertexArray *rightChain, Int botRightIndex, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridStartIndex, + Int& neckLeft, + Int& neckRight); + +void findTopAndBot(directedLine* polygon, + directedLine*& topV, + directedLine*& botV); +void findGridChains(directedLine* top, directedLine* bot, + gridWrap* grid, + gridBoundaryChain*& leftGridChain, + gridBoundaryChain*& rightGridChain); +void toVertexArrays(directedLine* topV, directedLine* botV, vertexArray& leftChain, vertexArray& rightChain); + +void drawCorners( + Real* topV, Real* botV, + vertexArray* leftChain, + vertexArray* rightChain, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridIndex1, + Int gridIndex2, + Int leftCornerWhere, + Int leftCornerIndex, + Int rightCornerWhere, + Int rightCornerIndex, + Int bot_leftCornerWhere, + Int bot_leftCornerIndex, + Int bot_rightCornerWhere, + Int bot_rightCornerIndex); + +Int checkMiddle(vertexArray* chain, Int begin, Int end, + Real vup, Real vbelow); + +#endif + diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/sampledLine.cc b/mesalib/src/glu/sgi/libnurbs/nurbtess/sampledLine.cc new file mode 100644 index 000000000..6253a7c09 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/sampledLine.cc @@ -0,0 +1,179 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <math.h> //for fabs() +#include "glimports.h" +#include "zlassert.h" +#include "sampledLine.h" + +void sampledLine::setPoint(Int i, Real p[2]) +{ + points[i][0]=p[0]; + points[i][1]=p[1]; +} + + +/*insert this single line in front of the oldList*/ +sampledLine* sampledLine::insert(sampledLine *oldList) +{ + next = oldList; + return this; +} + +void sampledLine::deleteList() +{ + sampledLine *temp, *tempNext; + for(temp = this; temp != NULL; temp = tempNext) + { + tempNext = temp->next; + delete temp; + } +} + + +/*space of points[][2] is allocated*/ +sampledLine::sampledLine(Int n_points) +{ + npoints = n_points; + points = (Real2*) malloc(sizeof(Real2) * n_points); + assert(points); + next = NULL; +} + +/*space of points[][2] is allocated and + *points are copied + */ +sampledLine::sampledLine(Int n_points, Real2 pts[]) +{ + int i; + npoints = n_points; + points = (Real2*) malloc(sizeof(Real2) * n_points); + assert(points); + for(i=0; i<npoints; i++) { + points[i][0] = pts[i][0]; + points[i][1] = pts[i][1]; + } + next = NULL; +} + +sampledLine::sampledLine(Real pt1[2], Real pt2[2]) +{ + npoints = 2; + points = (Real2*) malloc(sizeof(Real2) * 2); + assert(points); + points[0][0] = pt1[0]; + points[0][1] = pt1[1]; + points[1][0] = pt2[0]; + points[1][1] = pt2[1]; + next = NULL; +} + +//needs tp call init to setup +sampledLine::sampledLine() +{ +} + +//warning: ONLY pointer is copies!!! +void sampledLine::init(Int n_points, Real2 *pts) +{ + npoints = n_points; + points = pts; +} + +/*points[] is dealocated + */ +sampledLine::~sampledLine() +{ + free(points); +} + +void sampledLine::print() +{ + int i; + printf("npoints=%i\n", npoints); + + for(i=0; i<npoints; i++){ + printf("(%f,%f)\n", points[i][0], points[i][1]); + } + +} + +void sampledLine::tessellate(Real u_reso, Real v_reso) +{ + int i; + + Int nu, nv, n; + nu = 1+(Int) (fabs((points[npoints-1][0] - points[0][0])) * u_reso); + nv = 1+(Int) (fabs((points[npoints-1][1] - points[0][1])) * v_reso); + + if(nu > nv) n = nu; + else + n = nv; + if(n<1) + n = 1; + //du dv could be negative + Real du = (points[npoints-1][0] - points[0][0])/n; + Real dv = (points[npoints-1][1] - points[0][1])/n; + Real2 *temp = (Real2*) malloc(sizeof(Real2) * (n+1)); + assert(temp); + + Real u,v; + for(i=0, u=points[0][0], v=points[0][1]; i<n; i++, u+=du, v+=dv) + { + temp[i][0] = u; + temp[i][1] = v; + } + temp[n][0] = points[npoints-1][0]; + temp[n][1] = points[npoints-1][1]; + + free(points); + + npoints = n+1; + points = temp; + +} + +void sampledLine::tessellateAll(Real u_reso, Real v_reso) +{ + sampledLine* temp; + for(temp = this; temp != NULL; temp = temp->next) + { + temp->tessellate(u_reso, v_reso); + } +} diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/sampledLine.h b/mesalib/src/glu/sgi/libnurbs/nurbtess/sampledLine.h new file mode 100644 index 000000000..2cc726948 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/sampledLine.h @@ -0,0 +1,71 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ +/* +*/ + +#ifndef _SAMPLEDLINE_H +#define _SAMPLEDLINE_H + +#include "definitions.h" + +class sampledLine{ + Int npoints; + Real2 *points; + +public: + sampledLine(Int n_points); + sampledLine(Int n_points, Real pts[][2]); + sampledLine(Real pt1[2], Real pt2[2]); + sampledLine(); //special, careful about memory + ~sampledLine(); + + void init(Int n_points, Real2 *pts);//special, careful about memory + + void setPoint(Int i, Real p[2]) ; + + sampledLine* insert(sampledLine *nline); + void deleteList(); + + Int get_npoints() {return npoints;} + Real2* get_points() {return points;} + + //u_reso is number of segments (may not be integer) per unit u + void tessellate(Real u_reso, Real v_reso);//n segments + void tessellateAll(Real u_reso, Real v_reso); + + void print(); + + sampledLine* next; +}; + + + + +#endif diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/searchTree.cc b/mesalib/src/glu/sgi/libnurbs/nurbtess/searchTree.cc new file mode 100644 index 000000000..1865755a4 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/searchTree.cc @@ -0,0 +1,282 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include <stdlib.h> +#include <stdio.h> +#include "zlassert.h" + +#include "searchTree.h" + +#define max(a,b) ((a>b)? a:b) + +treeNode* TreeNodeMake(void *key) +{ + treeNode *ret = (treeNode*) malloc(sizeof(treeNode)); + assert(ret); + ret->key = key; + ret->parent = NULL; + ret->left = NULL; + ret->right = NULL; + return ret; +} + +void TreeNodeDeleteSingleNode(treeNode* node) +{ + free(node); +} + +void TreeNodeDeleteWholeTree(treeNode* node) +{ + if(node == NULL) return; + TreeNodeDeleteWholeTree(node->left); + TreeNodeDeleteWholeTree(node->right); + TreeNodeDeleteSingleNode(node); +} + +void TreeNodePrint(treeNode* node, + void (*keyPrint) (void*)) +{ + if(node ==NULL) return; + TreeNodePrint(node->left, keyPrint); + keyPrint(node->key); + TreeNodePrint(node->right, keyPrint); +} + +int TreeNodeDepth(treeNode* root) +{ + if(root == NULL) return 0; + else{ + int leftdepth = TreeNodeDepth(root->left); + int rightdepth = TreeNodeDepth(root->right); + return 1 + max(leftdepth, rightdepth); + } +} + +/*return the node with the key. + *NULL is returned if not found + */ +treeNode* TreeNodeFind(treeNode* tree, void* key, + int (*compkey) (void*, void*)) +{ + if(tree == NULL) + return NULL; + if(key == tree->key) + return tree; + else if(compkey(key, tree->key) < 0) + return TreeNodeFind(tree->left, key, compkey); + else + return TreeNodeFind(tree->right, key, compkey); +} + + +treeNode* TreeNodeInsert(treeNode* root, treeNode* newnode, + int (*compkey) (void *, void *)) +{ + treeNode *y = NULL; + treeNode *x = root; + /*going down the tree from the root. + *x traces the path, y is the parent of x. + */ + while (x != NULL){ + y = x; + if(compkey(newnode->key,x->key) < 0) /*if newnode < x*/ + x = x->left; + else + x = x->right; + } + + /*now y has the property that + * if newnode < y, then y->left is NULL + * if newnode > y, then y->right is NULL. + *So we want to isnert newnode to be the child of y + */ + newnode->parent = y; + if(y == NULL) + return newnode; + else if( compkey(newnode->key, y->key) <0) + { + y->left = newnode; + } + else + { + y->right = newnode; + } + + return root; +} + +treeNode* TreeNodeDeleteSingleNode(treeNode* tree, treeNode* node) +{ + treeNode* y; + treeNode* x; + treeNode* ret; + if(node==NULL) return tree; + + if(node->left == NULL || node->right == NULL) { + + y = node; + if(y->left != NULL) + x = y->left; + else + x = y->right; + + if( x != NULL) + x->parent = y->parent; + + if(y->parent == NULL) /*y is the root which has at most one child x*/ + ret = x; + else /*y is not the root*/ + { + if(y == y->parent->left) + y->parent->left = x; + else + y->parent->right = x; + ret = tree; + } + } + else { /*node has two children*/ + + y = TreeNodeSuccessor(node); + assert(y->left == NULL); + + if(y == node->right) /*y is the right child if node*/ + { + y->parent = node->parent; + y->left = node->left; + node->left->parent = y; + + } + else /*y != node->right*/ + { + x = y->right; + if(x!= NULL) + x->parent = y->parent; + + assert(y->parent != NULL); + if(y == y->parent->left) + y->parent->left = x; + else + y->parent->right = x; + /*move y to the position of node*/ + y->parent = node->parent; + y->left = node->left; + y->right = node->right; + node->left->parent = y; + node->right->parent = y; + } + if(node->parent != NULL) { + if(node->parent->left == node) + node->parent->left = y; + else + node->parent->right = y; + ret = tree; /*the root if the tree doesn't change*/ + } + else /*node->parent is NULL: node is the root*/ + ret = y; + } + + /*finally free the node, and return the new root*/ + TreeNodeDeleteSingleNode(node); + return ret; +} + + +/*the minimum node in the tree rooted by node + */ +treeNode* TreeNodeMinimum(treeNode* node) +{ + treeNode* temp = node; + if(temp == NULL) return NULL; + while(temp->left != NULL) { + temp = temp->left; + } + return temp; +} + +/*the maximum node in the tree rooted by node + */ +treeNode* TreeNodeMaximum(treeNode* node) +{ + treeNode* temp = node; + if(temp == NULL) return NULL; + while(temp->right != NULL) { + temp = temp->right; + } + return temp; +} + +/*return the first node (in sorted order) which is to the right of this node + */ +treeNode* TreeNodeSuccessor(treeNode* node) +{ + if(node == NULL) return NULL; + if(node->right != NULL) + return TreeNodeMinimum(node->right); + else{ /*node->right is NULL*/ + + /*find the first right-ancestor*/ + treeNode *y = node->parent; + treeNode* x = node; + while(y != NULL && x == y->right) /*if y is a left parent of x*/ + { + + x = y; + y = y->parent; + } + return y; + } +} + +/*return the first node (in sorted order) which is to the left of this node + */ +treeNode* TreeNodePredecessor(treeNode* node) +{ + if(node == NULL) return NULL; + if(node->left != NULL) + return TreeNodeMaximum(node->left); + else{ /*node->left is NULL*/ + /*find the first left-ancestor*/ + treeNode *y = node->parent; + treeNode *x = node; + while(y != NULL && x == y->left) /*if y is a right parent of x*/ + { + x = y; + y = y->parent; + } + return y; + } +} diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/searchTree.h b/mesalib/src/glu/sgi/libnurbs/nurbtess/searchTree.h new file mode 100644 index 000000000..d5e33314b --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/searchTree.h @@ -0,0 +1,61 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ +/* +*/ + +#ifndef _SEARCHTREE_H +#define _SEARCHTREE_H + +typedef struct treeNode{ + void *key; + struct treeNode* parent; + struct treeNode* left; /*children*/ + struct treeNode* right; +} treeNode; + +treeNode* TreeNodeMake(void *key); +void TreeNodeDeleteSingleNode(treeNode* node); +void TreeNodeDeleteWholeTree(treeNode* node); +void TreeNodePrint(treeNode* node, + void (*keyPrint) (void*)); +int TreeNodeDepth(treeNode* root); +treeNode* TreeNodeMinimum(treeNode* node); +treeNode* TreeNodeMaximum(treeNode* node); +treeNode* TreeNodePredecessor(treeNode* node); +treeNode* TreeNodeSuccessor(treeNode* node); +treeNode* TreeNodeFind(treeNode* tree, void* key, + int (*compkey) (void*, void*)); + +treeNode* TreeNodeInsert(treeNode* root, treeNode* newnode, + int (*comp) (void *, void *)); +treeNode* TreeNodeDeleteSingleNode(treeNode* tree, treeNode* node); + + +#endif diff --git a/mesalib/src/glu/sgi/libnurbs/nurbtess/zlassert.h b/mesalib/src/glu/sgi/libnurbs/nurbtess/zlassert.h new file mode 100644 index 000000000..b9c073257 --- /dev/null +++ b/mesalib/src/glu/sgi/libnurbs/nurbtess/zlassert.h @@ -0,0 +1,34 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ +/* +*/ + +/*XXXblythe this file should be deleted*/ +#include <assert.h> |