| 1 | /* $Id: quilt.cpp,v 1.1 2000-02-09 08:50:27 jeroen Exp $ */
|
|---|
| 2 | /*
|
|---|
| 3 | ** License Applicability. Except to the extent portions of this file are
|
|---|
| 4 | ** made subject to an alternative license as permitted in the SGI Free
|
|---|
| 5 | ** Software License B, Version 1.0 (the "License"), the contents of this
|
|---|
| 6 | ** file are subject only to the provisions of the License. You may not use
|
|---|
| 7 | ** this file except in compliance with the License. You may obtain a copy
|
|---|
| 8 | ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
|
|---|
| 9 | ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
|
|---|
| 10 | **
|
|---|
| 11 | ** http://oss.sgi.com/projects/FreeB
|
|---|
| 12 | **
|
|---|
| 13 | ** Note that, as provided in the License, the Software is distributed on an
|
|---|
| 14 | ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
|
|---|
| 15 | ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
|
|---|
| 16 | ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
|
|---|
| 17 | ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
|---|
| 18 | **
|
|---|
| 19 | ** Original Code. The Original Code is: OpenGL Sample Implementation,
|
|---|
| 20 | ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
|
|---|
| 21 | ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
|
|---|
| 22 | ** Copyright in any portions created by third parties is as indicated
|
|---|
| 23 | ** elsewhere herein. All Rights Reserved.
|
|---|
| 24 | **
|
|---|
| 25 | ** Additional Notice Provisions: The application programming interfaces
|
|---|
| 26 | ** established by SGI in conjunction with the Original Code are The
|
|---|
| 27 | ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
|
|---|
| 28 | ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
|
|---|
| 29 | ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
|
|---|
| 30 | ** Window System(R) (Version 1.3), released October 19, 1998. This software
|
|---|
| 31 | ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
|
|---|
| 32 | ** published by SGI, but has not been independently verified as being
|
|---|
| 33 | ** compliant with the OpenGL(R) version 1.2.1 Specification.
|
|---|
| 34 | */
|
|---|
| 35 |
|
|---|
| 36 | /*
|
|---|
| 37 | * quilt.c++
|
|---|
| 38 | *
|
|---|
| 39 | * $Date: 2000-02-09 08:50:27 $ $Revision: 1.1 $
|
|---|
| 40 | * $Header: /home/ktk/tmp/odin/2007/netlabs.cvs/odin32/src/opengl/glu/nurbs/internals/quilt.cpp,v 1.1 2000-02-09 08:50:27 jeroen Exp $
|
|---|
| 41 | */
|
|---|
| 42 |
|
|---|
| 43 | #include <stdlib.h>
|
|---|
| 44 | #include "glimports.h"
|
|---|
| 45 | #include "mystdio.h"
|
|---|
| 46 | #include "myassert.h"
|
|---|
| 47 | #include "quilt.h"
|
|---|
| 48 | #include "backend.h"
|
|---|
| 49 | #include "mapdesc.h"
|
|---|
| 50 | #include "flist.h"
|
|---|
| 51 | #include "knotvector.h"
|
|---|
| 52 | #include "patchlist.h"
|
|---|
| 53 | #include "math.h" //fabs()
|
|---|
| 54 | #include "simplemath.h" //min()
|
|---|
| 55 |
|
|---|
| 56 | /* local preprocessor definitions */
|
|---|
| 57 | #define DEF_PATCH_STEPSIZE .4
|
|---|
| 58 | #define fsizeof(x) (sizeof(x)/sizeof(REAL))
|
|---|
| 59 |
|
|---|
| 60 |
|
|---|
| 61 | Quilt::Quilt( Mapdesc *_mapdesc )
|
|---|
| 62 | {
|
|---|
| 63 | mapdesc = _mapdesc;
|
|---|
| 64 | }
|
|---|
| 65 |
|
|---|
| 66 | void
|
|---|
| 67 | Quilt::deleteMe( Pool& p )
|
|---|
| 68 | {
|
|---|
| 69 | for( Quiltspec *q=qspec; q != eqspec; q++ ) {
|
|---|
| 70 | #if 1
|
|---|
| 71 | if( q->breakpoints) delete[] q->breakpoints; q->breakpoints = 0;
|
|---|
| 72 | #else
|
|---|
| 73 | if( q->breakpoints) {
|
|---|
| 74 | delete[] q->breakpoints;
|
|---|
| 75 | q->breakpoints = 0;
|
|---|
| 76 | printf("in here\n");
|
|---|
| 77 | }
|
|---|
| 78 | #endif
|
|---|
| 79 | }
|
|---|
| 80 | if( cpts ) delete[] cpts;
|
|---|
| 81 | cpts = 0;
|
|---|
| 82 | PooledObj::deleteMe( p );
|
|---|
| 83 | }
|
|---|
| 84 |
|
|---|
| 85 | void
|
|---|
| 86 | Quilt::show( void )
|
|---|
| 87 | {
|
|---|
| 88 | #ifndef NDEBUG
|
|---|
| 89 | int nc = mapdesc->getNcoords();
|
|---|
| 90 | REAL *ps = cpts;
|
|---|
| 91 | ps += qspec[0].offset;
|
|---|
| 92 | ps += qspec[1].offset;
|
|---|
| 93 | for( int i=0; i!= qspec[0].order * qspec[0].width; i++ ) {
|
|---|
| 94 | for( int j = 0; j!= qspec[1].order * qspec[1].width; j++ ) {
|
|---|
| 95 | for( int k=0; k < nc; k++ )
|
|---|
| 96 | dprintf( "%g ", ps[i*qspec[0].stride + j*qspec[1].stride + k] );
|
|---|
| 97 | dprintf( "\n" );
|
|---|
| 98 | }
|
|---|
| 99 | dprintf( "\n" );
|
|---|
| 100 | }
|
|---|
| 101 | dprintf( "\n" );
|
|---|
| 102 | #endif
|
|---|
| 103 | }
|
|---|
| 104 |
|
|---|
| 105 | /*--------------------------------------------------------------------------
|
|---|
| 106 | * Quilt::select - find which map in each quilt contains the points
|
|---|
| 107 | * pta and ptb with pta[i] < ptb[i]
|
|---|
| 108 | *--------------------------------------------------------------------------
|
|---|
| 109 | */
|
|---|
| 110 |
|
|---|
| 111 | void
|
|---|
| 112 | Quilt::select( REAL *pta, REAL *ptb )
|
|---|
| 113 | {
|
|---|
| 114 | int dim = eqspec - qspec;
|
|---|
| 115 | int i, j;
|
|---|
| 116 | for( i=0; i<dim; i++) {
|
|---|
| 117 | for( j=qspec[i].width-1; j>=0; j-- )
|
|---|
| 118 | if( (qspec[i].breakpoints[j] <= pta[i] ) &&
|
|---|
| 119 | (ptb[i] <= qspec[i].breakpoints[j+1] ) )
|
|---|
| 120 | break;
|
|---|
| 121 | assert( j != -1 );
|
|---|
| 122 | qspec[i].index = j;
|
|---|
| 123 | }
|
|---|
| 124 | }
|
|---|
| 125 |
|
|---|
| 126 | void
|
|---|
| 127 | Quilt::download( Backend &backend )
|
|---|
| 128 | {
|
|---|
| 129 | if( getDimension() == 2 ) {
|
|---|
| 130 | REAL *ps = cpts;
|
|---|
| 131 | ps += qspec[0].offset;
|
|---|
| 132 | ps += qspec[1].offset;
|
|---|
| 133 | ps += qspec[0].index * qspec[0].order * qspec[0].stride;
|
|---|
| 134 | ps += qspec[1].index * qspec[1].order * qspec[1].stride;
|
|---|
| 135 | backend.surfpts( mapdesc->getType(), ps,
|
|---|
| 136 | qspec[0].stride,
|
|---|
| 137 | qspec[1].stride,
|
|---|
| 138 | qspec[0].order,
|
|---|
| 139 | qspec[1].order,
|
|---|
| 140 | qspec[0].breakpoints[qspec[0].index],
|
|---|
| 141 | qspec[0].breakpoints[qspec[0].index+1],
|
|---|
| 142 | qspec[1].breakpoints[qspec[1].index],
|
|---|
| 143 | qspec[1].breakpoints[qspec[1].index+1] );
|
|---|
| 144 | } else {
|
|---|
| 145 | REAL *ps = cpts;
|
|---|
| 146 | ps += qspec[0].offset;
|
|---|
| 147 | ps += qspec[0].index * qspec[0].order * qspec[0].stride;
|
|---|
| 148 | backend.curvpts( mapdesc->getType(), ps,
|
|---|
| 149 | qspec[0].stride,
|
|---|
| 150 | qspec[0].order,
|
|---|
| 151 | qspec[0].breakpoints[qspec[0].index],
|
|---|
| 152 | qspec[0].breakpoints[qspec[0].index+1] );
|
|---|
| 153 | }
|
|---|
| 154 | }
|
|---|
| 155 |
|
|---|
| 156 | /*--------------------------------------------------------------------------
|
|---|
| 157 | * Quilt::downloadAll - download each map that contains the current patch
|
|---|
| 158 | *--------------------------------------------------------------------------
|
|---|
| 159 | */
|
|---|
| 160 |
|
|---|
| 161 | void
|
|---|
| 162 | Quilt::downloadAll( REAL *pta, REAL *ptb, Backend &backend )
|
|---|
| 163 | {
|
|---|
| 164 | for( Quilt *m = this; m; m=m->next ) {
|
|---|
| 165 | m->select( pta, ptb );
|
|---|
| 166 | m->download( backend );
|
|---|
| 167 | }
|
|---|
| 168 | }
|
|---|
| 169 |
|
|---|
| 170 | /*--------------------------------------------------------------------------
|
|---|
| 171 | * Quilt::isCulled - determine if an entire quilt is trivially rejected.
|
|---|
| 172 | *--------------------------------------------------------------------------
|
|---|
| 173 | */
|
|---|
| 174 |
|
|---|
| 175 | int
|
|---|
| 176 | Quilt::isCulled( void )
|
|---|
| 177 | {
|
|---|
| 178 | if( mapdesc->isCulling() )
|
|---|
| 179 | return mapdesc->xformAndCullCheck( cpts + qspec[0].offset + qspec[1].offset,
|
|---|
| 180 | qspec[0].order * qspec[0].width, qspec[0].stride,
|
|---|
| 181 | qspec[1].order * qspec[1].width, qspec[1].stride );
|
|---|
| 182 | else
|
|---|
| 183 | return CULL_ACCEPT;
|
|---|
| 184 | }
|
|---|
| 185 |
|
|---|
| 186 | /*---------------------------------------------------------------------------
|
|---|
| 187 | * Quilt::getRange - retrieve the valid paramater range of a set of quilts
|
|---|
| 188 | *---------------------------------------------------------------------------
|
|---|
| 189 | */
|
|---|
| 190 | void
|
|---|
| 191 | Quilt::getRange( REAL *from, REAL *to, Flist& slist, Flist &tlist )
|
|---|
| 192 | {
|
|---|
| 193 | getRange( from, to, 0, slist );
|
|---|
| 194 | getRange( from, to, 1, tlist );
|
|---|
| 195 | }
|
|---|
| 196 |
|
|---|
| 197 | /*---------------------------------------------------------------------------
|
|---|
| 198 | * Quilt::getRange - retrieve the valid paramater range of a set of quilts
|
|---|
| 199 | *---------------------------------------------------------------------------
|
|---|
| 200 | */
|
|---|
| 201 | void
|
|---|
| 202 | Quilt::getRange( REAL *from, REAL *to, int i, Flist &list )
|
|---|
| 203 | {
|
|---|
| 204 | Quilt *maps = this;
|
|---|
| 205 | from[i] = maps->qspec[i].breakpoints[0];
|
|---|
| 206 | to[i] = maps->qspec[i].breakpoints[maps->qspec[i].width];
|
|---|
| 207 | int maxpts = 0;
|
|---|
| 208 | Quilt_ptr m;
|
|---|
| 209 | for( m=maps; m; m=m->next ) {
|
|---|
| 210 | if( m->qspec[i].breakpoints[0] > from[i] )
|
|---|
| 211 | from[i] = m->qspec[i].breakpoints[0];
|
|---|
| 212 | if( m->qspec[i].breakpoints[m->qspec[i].width] < to[i] )
|
|---|
| 213 | to[i] = m->qspec[i].breakpoints[m->qspec[i].width];
|
|---|
| 214 | maxpts += m->qspec[i].width + 1;
|
|---|
| 215 | }
|
|---|
| 216 |
|
|---|
| 217 | list.grow( maxpts );
|
|---|
| 218 |
|
|---|
| 219 | for( m=maps; m; m=m->next )
|
|---|
| 220 | for( int j=0; j<=m->qspec[i].width; j++ ) {
|
|---|
| 221 | list.add( m->qspec[i].breakpoints[j] );
|
|---|
| 222 | }
|
|---|
| 223 |
|
|---|
| 224 | list.filter( );
|
|---|
| 225 | list.taper( from[i], to[i] );
|
|---|
| 226 | }
|
|---|
| 227 |
|
|---|
| 228 | void
|
|---|
| 229 | Quilt::getRange( REAL *from, REAL *to, Flist& slist )
|
|---|
| 230 | {
|
|---|
| 231 | getRange( from, to, 0, slist );
|
|---|
| 232 | }
|
|---|
| 233 |
|
|---|
| 234 | void
|
|---|
| 235 | Quilt::findRates( Flist& slist, Flist& tlist, REAL rate[2] )
|
|---|
| 236 | {
|
|---|
| 237 | findSampleRates( slist, tlist );
|
|---|
| 238 | rate[0] = qspec[0].step_size;
|
|---|
| 239 | rate[1] = qspec[1].step_size;
|
|---|
| 240 |
|
|---|
| 241 | for( Quilt *q = next; q; q = q->next ) {
|
|---|
| 242 | q->findSampleRates( slist, tlist );
|
|---|
| 243 | if( q->qspec[0].step_size < rate[0] )
|
|---|
| 244 | rate[0] = q->qspec[0].step_size;
|
|---|
| 245 | if( q->qspec[1].step_size < rate[1] )
|
|---|
| 246 | rate[1] = q->qspec[1].step_size;
|
|---|
| 247 | }
|
|---|
| 248 | }
|
|---|
| 249 |
|
|---|
| 250 | void
|
|---|
| 251 | Quilt::findSampleRates( Flist& slist, Flist& tlist )
|
|---|
| 252 | {
|
|---|
| 253 | qspec[0].step_size = DEF_PATCH_STEPSIZE *
|
|---|
| 254 | (qspec[0].breakpoints[qspec[0].width] - qspec[0].breakpoints[0]);
|
|---|
| 255 | qspec[1].step_size = DEF_PATCH_STEPSIZE *
|
|---|
| 256 | (qspec[1].breakpoints[qspec[1].width] - qspec[1].breakpoints[0]);
|
|---|
| 257 |
|
|---|
| 258 | for( int i = slist.start; i < slist.end-1; i++ ) {
|
|---|
| 259 | for( int j = tlist.start; j < tlist.end-1; j++ ) {
|
|---|
| 260 |
|
|---|
| 261 | REAL pta[2], ptb[2];
|
|---|
| 262 | pta[0] = slist.pts[i];
|
|---|
| 263 | ptb[0] = slist.pts[i+1];
|
|---|
| 264 | pta[1] = tlist.pts[j];
|
|---|
| 265 | ptb[1] = tlist.pts[j+1];
|
|---|
| 266 | Patchlist patchlist( this, pta, ptb );
|
|---|
| 267 | patchlist.getstepsize();
|
|---|
| 268 |
|
|---|
| 269 | {
|
|---|
| 270 | float edge_len_s = min(fabs(ptb[0]-pta[0]),1.0);
|
|---|
| 271 | float edge_len_t = min(fabs(ptb[1]-pta[1]),1.0);
|
|---|
| 272 |
|
|---|
| 273 | if( patchlist.getStepsize(0)/edge_len_s < qspec[0].step_size )
|
|---|
| 274 | qspec[0].step_size = patchlist.getStepsize(0)/edge_len_s;
|
|---|
| 275 | if( patchlist.getStepsize(1)/edge_len_t < qspec[1].step_size )
|
|---|
| 276 | qspec[1].step_size = patchlist.getStepsize(1)/edge_len_t;
|
|---|
| 277 | }
|
|---|
| 278 | }
|
|---|
| 279 | }
|
|---|
| 280 | }
|
|---|