Windows2003-3790/multimedia/opengl/glu/nurbs/core/mapdesc.cxx
2020-09-30 16:53:55 +02:00

832 lines
23 KiB
C++

/**************************************************************************
* *
* Copyright (C) 1992, Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
**************************************************************************/
/*
* mapdesc.c++ - $Revision: 1.2 $
* Derrick Burns - 1991
*/
#include "glimport.h"
#include "mystdio.h"
#include "myassert.h"
#include "mystring.h"
#include "mymath.h"
#include "backend.h"
#include "nurbscon.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;
}
#ifdef NT
return 0;
#else
abort();
#endif
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;
}
#ifdef NT
return 0;
#else
abort();
#endif
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 == mask ) && ( inbits != mask ) ) return CULL_ACCEPT;
}
}
if( outbits != mask ) {
return CULL_TRIVIAL_REJECT;
} else if( inbits == 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 == mask ) && ( inbits != mask ) ) return CULL_ACCEPT;
}
}
if( outbits != mask ) {
return CULL_TRIVIAL_REJECT;
} else if( inbits == 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 == mask ) && ( inbits != mask ) ) return CULL_ACCEPT;
}
if( outbits != mask ) {
return CULL_TRIVIAL_REJECT;
} else if( inbits == 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 )
{
for( int 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:
#ifdef NT
return( (REAL) 0.0 );
#else
abort();
return -1; //not necessary, needed to shut up compiler
#endif
}
}
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:
#ifndef NT
abort();
#endif
break;
}
}