From f22bdaf0859130455e9c72beff9375e206f1e044 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni cignoni Date: Wed, 22 Oct 2014 05:28:12 +0000 Subject: [PATCH] Poisson 6.12 Merging: - One of my this-> has been changed into a base class reference (to be checked...) --- .../Src/BSplineData.inl | 1020 ++++++++--------- 1 file changed, 510 insertions(+), 510 deletions(-) diff --git a/src/plugins_experimental/filter_screened_poisson/Src/BSplineData.inl b/src/plugins_experimental/filter_screened_poisson/Src/BSplineData.inl index a8b5af46f..ef9cb7b53 100755 --- a/src/plugins_experimental/filter_screened_poisson/Src/BSplineData.inl +++ b/src/plugins_experimental/filter_screened_poisson/Src/BSplineData.inl @@ -8,14 +8,14 @@ are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the distribution. +in the documentation and/or other materials provided with the distribution. Neither the name of the Johns Hopkins University nor the names of its contributors may be used to endorse or promote products derived from this software without specific -prior written permission. +prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO THE IMPLIED WARRANTIES +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED @@ -50,327 +50,327 @@ DAMAGE. // <=> i < r + 0.5 * Degree template< int Degree > inline bool LeftOverlap( unsigned int depth , int offset ) { - offset <<= 1; - if( Degree & 1 ) return (offset < 1+Degree) && (offset > -1-Degree ); - else return (offset < Degree) && (offset > -2-Degree ); + offset <<= 1; + if( Degree & 1 ) return (offset < 1+Degree) && (offset > -1-Degree ); + else return (offset < Degree) && (offset > -2-Degree ); } template< int Degree > inline bool RightOverlap( unsigned int depth , int offset ) { - offset <<= 1; - int r = 1<<(depth+1); - if( Degree & 1 ) return (offset > 2-1-Degree) && (offset < 2+1+Degree ); - else return (offset > 2-2-Degree) && (offset < 2+ Degree ); + offset <<= 1; + int r = 1<<(depth+1); + if( Degree & 1 ) return (offset > 2-1-Degree) && (offset < 2+1+Degree ); + else return (offset > 2-2-Degree) && (offset < 2+ Degree ); } template< int Degree > inline int ReflectLeft( unsigned int depth , int offset ) { - if( Degree&1 ) return -offset; - else return -1-offset; + if( Degree&1 ) return -offset; + else return -1-offset; } template< int Degree > inline int ReflectRight( unsigned int depth , int offset ) { - int r = 1<<(depth+1); - if( Degree&1 ) return r -offset; - else return r-1-offset; + int r = 1<<(depth+1); + if( Degree&1 ) return r -offset; + else return r-1-offset; } template< int Degree > BSplineData< Degree >::BSplineData( void ) { - functionCount = sampleCount = 0; - SetBSplineElementIntegrals< Degree , Degree >( _vvIntegrals ); - SetBSplineElementIntegrals< Degree , Degree-1 >( _vdIntegrals ); - SetBSplineElementIntegrals< Degree-1 , Degree >( _dvIntegrals ); - SetBSplineElementIntegrals< Degree-1 , Degree-1 >( _ddIntegrals ); + functionCount = sampleCount = 0; + SetBSplineElementIntegrals< Degree , Degree >( _vvIntegrals ); + SetBSplineElementIntegrals< Degree , Degree-1 >( _vdIntegrals ); + SetBSplineElementIntegrals< Degree-1 , Degree >( _dvIntegrals ); + SetBSplineElementIntegrals< Degree-1 , Degree-1 >( _ddIntegrals ); } template< int Degree > double BSplineData< Degree >::Integrator::dot( int depth , int off1 , int off2 , bool d1 , bool d2 , bool childParent ) const { - if( depth<0 || depth>=int( iTables.size() ) ) return 0.; - const typename Integrator::IntegralTables& iTable = iTables[depth]; - if( childParent ) - { - int c = off1&1; - off1 >>= 1 , depth--; - int ii , d = off2-off1 , res = (1<=res || off2>=res || d<-Degree || d>Degree ) return 0; - if ( off1< Degree ) ii = off1; - else if( off1>=res-Degree ) ii = 2*Degree + off1 - (res-1); - else ii = Degree; - if ( d1 && d2 ) return iTable.dd_cpIntegrals[2*ii+c][d+Degree]; - else if( d1 ) return iTable.dv_cpIntegrals[2*ii+c][d+Degree]; - else if( d2 ) return iTable.vd_cpIntegrals[2*ii+c][d+Degree]; - else return iTable.vv_cpIntegrals[2*ii+c][d+Degree]; - } - else - { - int ii , d = off2-off1 , res = (1<=res || off2>=res || d<-Degree || d>Degree ) return 0; - if ( off1< Degree ) ii = off1; - else if( off1>=res-Degree ) ii = 2*Degree + off1 - (res-1); - else ii = Degree; - if ( d1 && d2 ) return iTable.dd_ccIntegrals[ii][d+Degree]; - else if( d1 ) return iTable.dv_ccIntegrals[ii][d+Degree]; - else if( d2 ) return iTable.vd_ccIntegrals[ii][d+Degree]; - else return iTable.vv_ccIntegrals[ii][d+Degree]; - } + if( depth<0 || depth>=int( iTables.size() ) ) return 0.; + const typename Integrator::IntegralTables& iTable = iTables[depth]; + if( childParent ) + { + int c = off1&1; + off1 >>= 1 , depth--; + int ii , d = off2-off1 , res = (1<=res || off2>=res || d<-Degree || d>Degree ) return 0; + if ( off1< Degree ) ii = off1; + else if( off1>=res-Degree ) ii = 2*Degree + off1 - (res-1); + else ii = Degree; + if ( d1 && d2 ) return iTable.dd_cpIntegrals[2*ii+c][d+Degree]; + else if( d1 ) return iTable.dv_cpIntegrals[2*ii+c][d+Degree]; + else if( d2 ) return iTable.vd_cpIntegrals[2*ii+c][d+Degree]; + else return iTable.vv_cpIntegrals[2*ii+c][d+Degree]; + } + else + { + int ii , d = off2-off1 , res = (1<=res || off2>=res || d<-Degree || d>Degree ) return 0; + if ( off1< Degree ) ii = off1; + else if( off1>=res-Degree ) ii = 2*Degree + off1 - (res-1); + else ii = Degree; + if ( d1 && d2 ) return iTable.dd_ccIntegrals[ii][d+Degree]; + else if( d1 ) return iTable.dv_ccIntegrals[ii][d+Degree]; + else if( d2 ) return iTable.vd_ccIntegrals[ii][d+Degree]; + else return iTable.vv_ccIntegrals[ii][d+Degree]; + } } template< int Degree > template< int Radius > double BSplineData< Degree >::CenterEvaluator< Radius >::value( int depth , int off1 , int off2 , bool d , bool childParent ) const { - if( depth<0 || depth>=int( vTables.size() ) ) return 0.; - if( childParent ) - { - int c = off1&1; - off1 >>= 1 , depth--; - const typename CenterEvaluator::ValueTables& vTable = vTables[depth]; - int ii , dd = off1-off2 , res = (1<=res || off2>=res || dd<-Radius || dd>Radius ) return 0; - if ( off2< Degree ) ii = off2; - else if( off2>=res-Degree ) ii = 2*Degree + off2 - (res-1); - else ii = Degree; - if( d ) return vTable.dValues[ii][(dd+Radius)*3+2*c]; - else return vTable.vValues[ii][(dd+Radius)*3+2*c]; - } - else - { - const typename CenterEvaluator::ValueTables& vTable = vTables[depth]; - int ii , dd = off1-off2 , res = (1<=res || off2>=res || dd<-Radius || dd>Radius ) return 0; - if ( off2< Degree ) ii = off2; - else if( off2>=res-Degree ) ii = 2*Degree + off2 - (res-1); - else ii = Degree; - if( d ) return vTable.dValues[ii][(dd+Radius)*3+1]; - else return vTable.vValues[ii][(dd+Radius)*3+1]; - } + if( depth<0 || depth>=int( vTables.size() ) ) return 0.; + if( childParent ) + { + int c = off1&1; + off1 >>= 1 , depth--; + const typename CenterEvaluator::ValueTables& vTable = vTables[depth]; + int ii , dd = off1-off2 , res = (1<=res || off2>=res || dd<-Radius || dd>Radius ) return 0; + if ( off2< Degree ) ii = off2; + else if( off2>=res-Degree ) ii = 2*Degree + off2 - (res-1); + else ii = Degree; + if( d ) return vTable.dValues[ii][(dd+Radius)*3+2*c]; + else return vTable.vValues[ii][(dd+Radius)*3+2*c]; + } + else + { + const typename CenterEvaluator::ValueTables& vTable = vTables[depth]; + int ii , dd = off1-off2 , res = (1<=res || off2>=res || dd<-Radius || dd>Radius ) return 0; + if ( off2< Degree ) ii = off2; + else if( off2>=res-Degree ) ii = 2*Degree + off2 - (res-1); + else ii = Degree; + if( d ) return vTable.dValues[ii][(dd+Radius)*3+1]; + else return vTable.vValues[ii][(dd+Radius)*3+1]; + } } template< int Degree > template< int Radius > double BSplineData< Degree >::CornerEvaluator< Radius >::value( int depth , int off1 , int c1 , int off2 , bool d , bool childParent ) const { - if( c1<0 || c1>=2 ) - { - fprintf( stderr , "[WARNING] Clamping corner to {0,1}\n" ); - c1 = std::max< int >( 0 , std::min< int >( c1 , 1 ) ); - } - if( depth<0 || depth>=int( vTables.size() ) ) return 0.; - if( childParent ) - { - int c = off1&1; - off1 >>= 1 , depth--; - const typename CornerEvaluator::ValueTables& vTable = vTables[depth]; - int ii , dd = off1-off2 , res = (1<=res || off2>=res || dd<-Radius || dd>Radius ) return 0; - if ( off2< Degree ) ii = off2; - else if( off2>=res-Degree ) ii = 2*Degree + off2 - (res-1); - else ii = Degree; - if( d ) return vTable.dValues[ii][(dd+Radius)*2+c+c1]; - else return vTable.vValues[ii][(dd+Radius)*2+c+c1]; - } - else - { - const typename CornerEvaluator::ValueTables& vTable = vTables[depth]; - int ii , dd = off1-off2 , res = (1<=res || off2>=res || dd<-Radius || dd>Radius ) return 0; - if ( off2< Degree ) ii = off2; - else if( off2>=res-Degree ) ii = 2*Degree + off2 - (res-1); - else ii = Degree; - if( d ) return vTable.dValues[ii][(dd+Radius)*2+2*c1]; - else return vTable.vValues[ii][(dd+Radius)*2+2*c1]; - } + if( c1<0 || c1>=2 ) + { + fprintf( stderr , "[WARNING] Clamping corner to {0,1}\n" ); + c1 = std::max< int >( 0 , std::min< int >( c1 , 1 ) ); + } + if( depth<0 || depth>=int( vTables.size() ) ) return 0.; + if( childParent ) + { + int c = off1&1; + off1 >>= 1 , depth--; + const typename CornerEvaluator::ValueTables& vTable = vTables[depth]; + int ii , dd = off1-off2 , res = (1<=res || off2>=res || dd<-Radius || dd>Radius ) return 0; + if ( off2< Degree ) ii = off2; + else if( off2>=res-Degree ) ii = 2*Degree + off2 - (res-1); + else ii = Degree; + if( d ) return vTable.dValues[ii][(dd+Radius)*2+c+c1]; + else return vTable.vValues[ii][(dd+Radius)*2+c+c1]; + } + else + { + const typename CornerEvaluator::ValueTables& vTable = vTables[depth]; + int ii , dd = off1-off2 , res = (1<=res || off2>=res || dd<-Radius || dd>Radius ) return 0; + if ( off2< Degree ) ii = off2; + else if( off2>=res-Degree ) ii = 2*Degree + off2 - (res-1); + else ii = Degree; + if( d ) return vTable.dValues[ii][(dd+Radius)*2+2*c1]; + else return vTable.vValues[ii][(dd+Radius)*2+2*c1]; + } } template< int Degree > void BSplineData< Degree >::set( int maxDepth , int boundaryType ) { - _boundaryType = boundaryType; + _boundaryType = boundaryType; - depth = maxDepth; - // [Warning] This assumes that the functions spacing is dual - functionCount = BinaryNode::CumulativeCenterCount( depth ); - sampleCount = BinaryNode::CenterCount( depth ) + BinaryNode::CornerCount( depth ); - baseFunctions = NewPointer< PPolynomial< Degree > >( functionCount ); - baseBSplines = NewPointer< BSplineComponents >( functionCount ); + depth = maxDepth; + // [Warning] This assumes that the functions spacing is dual + functionCount = BinaryNode::CumulativeCenterCount( depth ); + sampleCount = BinaryNode::CenterCount( depth ) + BinaryNode::CornerCount( depth ); + baseFunctions = NewPointer< PPolynomial< Degree > >( functionCount ); + baseBSplines = NewPointer< BSplineComponents >( functionCount ); - baseFunction = PPolynomial< Degree >::BSpline(); - for( int i=0 ; i<=Degree ; i++ ) baseBSpline[i] = Polynomial< Degree >::BSplineComponent( i ).shift( double(-(Degree+1)/2) + i - 0.5 ); - dBaseFunction = baseFunction.derivative(); - StartingPolynomial< Degree > sPolys[Degree+4]; + baseFunction = PPolynomial< Degree >::BSpline(); + for( int i=0 ; i<=Degree ; i++ ) baseBSpline[i] = Polynomial< Degree >::BSplineComponent( i ).shift( double(-(Degree+1)/2) + i - 0.5 ); + dBaseFunction = baseFunction.derivative(); + StartingPolynomial< Degree > sPolys[Degree+4]; - for( int i=0 ; i=1 && i<=Degree+1 ) sPolys[i].p += baseBSpline[i-1]; - for( int j=0 ; j=1 && i<=Degree+1 ) sPolys[i].p += baseBSpline[i-1].shift( 1 ) * _boundaryType; - for( int j=0 ; j=1 && i<=Degree+1 ) sPolys[i].p += baseBSpline[i-1]; // The centered B-Spline - if( i>=2 && i<=Degree+2 ) sPolys[i].p += baseBSpline[i-2].shift( 1 ) * _boundaryType; // The right-shifted B-spline - for( int j=0 ; j=1 && i<=Degree+1 ) sPolys[i].p += baseBSpline[i-1]; + for( int j=0 ; j=1 && i<=Degree+1 ) sPolys[i].p += baseBSpline[i-1].shift( 1 ) * _boundaryType; + for( int j=0 ; j=1 && i<=Degree+1 ) sPolys[i].p += baseBSpline[i-1]; // The centered B-Spline + if( i>=2 && i<=Degree+2 ) sPolys[i].p += baseBSpline[i-2].shift( 1 ) * _boundaryType; // The right-shifted B-spline + for( int j=0 ; j double BSplineData< Degree >::dot( int depth1 , int off1 , int depth2 , int off2 , bool d1 , bool d2 , bool inset ) const { - const int _Degree1 = (d1 ? (Degree-1) : Degree) , _Degree2 = (d2 ? (Degree-1) : Degree); - int sums[ Degree+1 ][ Degree+1 ]; + const int _Degree1 = (d1 ? (Degree-1) : Degree) , _Degree2 = (d2 ? (Degree-1) : Degree); + int sums[ Degree+1 ][ Degree+1 ]; - int depth = std::max< int >( depth1 , depth2 ); + int depth = std::max< int >( depth1 , depth2 ); - BSplineElements< Degree > b1( 1< b1( 1< b; - while( depth1 b; + while( depth1 db1 , db2; - b1.differentiate( db1 ) , b2.differentiate( db2 ); + BSplineElements< Degree-1 > db1 , db2; + b1.differentiate( db1 ) , b2.differentiate( db2 ); - int start1=-1 , end1=-1 , start2=-1 , end2=-1; - for( int i=0 ; i=end2 || start2>=end1 ) return 0.; - int start = std::max< int >( start1 , start2 ) , end = std::min< int >( end1 , end2 ); - memset( sums , 0 , sizeof( sums ) ); - for( int i=start ; i=end2 || start2>=end1 ) return 0.; + int start = std::max< int >( start1 , start2 ) , end = std::min< int >( end1 , end2 ); + memset( sums , 0 , sizeof( sums ) ); + for( int i=start ; i double BSplineData< Degree >::value( int depth , int off , double smoothingRadius , double s , bool d , bool inset ) const { - PPolynomial< Degree+1 > function; - PPolynomial< Degree > dFunction; + PPolynomial< Degree+1 > function; + PPolynomial< Degree > dFunction; - if( off<0 || off>=(1<=(1<0 ) function = baseFunctions[idx].MovingAverage( smoothingRadius ); - else function = baseFunctions[idx]; - dFunction = function.derivative(); + if( smoothingRadius>0 ) function = baseFunctions[idx].MovingAverage( smoothingRadius ); + else function = baseFunctions[idx]; + dFunction = function.derivative(); - if( d ) return dFunction(s); - else return function(s); + if( d ) return dFunction(s); + else return function(s); } template< int Degree > void BSplineData< Degree >::setIntegrator( Integrator& integrator , bool inset , bool useDotRatios ) const { - integrator.iTables.resize( depth+1 ); - for( int d=0 ; d<=depth ; d++ ) for( int i=0 ; i<=2*Degree ; i++ ) for( int j=-Degree ; j<=Degree ; j++ ) - { - int res = 1< template< int Radius > void BSplineData< Degree >::setCenterEvaluator( CenterEvaluator< Radius >& evaluator , double smoothingRadius , double dSmoothingRadius , bool inset ) const { - evaluator.vTables.resize( depth+1 ); - for( int d=0 ; d<=depth ; d++ ) for( int i=0 ; i<=2*Degree ; i++ ) for( int j=-Radius ; j<=Radius ; j++ ) for( int k=-1 ; k<=1 ; k++ ) - { - int res = 1< template< int Radius > void BSplineData< Degree >::setCornerEvaluator( CornerEvaluator< Radius >& evaluator , double smoothingRadius , double dSmoothingRadius , bool inset ) const { - evaluator.vTables.resize( depth+1 ); - for( int d=0 ; d<=depth ; d++ ) for( int i=0 ; i<=2*Degree ; i++ ) for( int j=-Radius ; j<=Radius ; j++ ) for( int k=0 ; k<=2 ; k++ ) - { - int res = 1< template< class Real > BSplineData< Degree >::DotTables< Real >::DotTables( void ) { - vvDotTable = NullPointer< Real >(); - dvDotTable = NullPointer< Real >(); - ddDotTable = NullPointer< Real >(); + vvDotTable = NullPointer< Real >(); + dvDotTable = NullPointer< Real >(); + ddDotTable = NullPointer< Real >(); } template< int Degree > template< class Real > BSplineData< Degree >::DotTables< Real >::~DotTables( void ) { - DeletePointer( vvDotTable ); - DeletePointer( dvDotTable ); - DeletePointer( ddDotTable ); + DeletePointer( vvDotTable ); + DeletePointer( dvDotTable ); + DeletePointer( ddDotTable ); } template< int Degree > template< class Real > @@ -397,151 +397,151 @@ template< int Degree > template< class Real > inline size_t BSplineData< Degree >::DotTables< Real >::SymmetricIndex( int i1 , int i2 ) { - size_t _i1 = i1 , _i2 = i2; - if( i1>i2 ) return ((_i1*_i1+i1)>>1)+_i2; - else return ((_i2*_i2+i2)>>1)+_i1; + size_t _i1 = i1 , _i2 = i2; + if( i1>i2 ) return ((_i1*_i1+i1)>>1)+_i2; + else return ((_i2*_i2+i2)>>1)+_i1; } template< int Degree > template< class Real > inline int BSplineData< Degree >::DotTables< Real >::SymmetricIndex( int i1 , int i2 , size_t& index ) { - size_t _i1 = i1 , _i2 = i2; - if( i1>1)+_i1; - return 1; - } - else - { - index = ((_i1*_i1+_i1)>>1)+_i2; - return 0; - } + size_t _i1 = i1 , _i2 = i2; + if( i1>1)+_i1; + return 1; + } + else + { + index = ((_i1*_i1+_i1)>>1)+_i2; + return 0; + } } template< int Degree > template< class Real > typename BSplineData< Degree >::template DotTables< Real > BSplineData< Degree >::getDotTables( int flags , bool useDotRatios , bool inset ) const { - typename BSplineData< Degree >::template DotTables< Real > dTables; - dTables.functionCount = functionCount; + typename BSplineData< Degree >::template DotTables< Real > dTables; + dTables.functionCount = functionCount; - size_t size = ( functionCount*functionCount + functionCount )>>1; - size_t fullSize = functionCount*functionCount; - if( flags & VV_DOT_FLAG ) - { - dTables.vvDotTable = NewPointer< Real >( size ); - memset( dTables.vvDotTable , 0 , sizeof(Real)*size ); - } - if( flags & DV_DOT_FLAG ) - { - dTables.dvDotTable = NewPointer< Real >( fullSize ); - memset( dTables.dvDotTable , 0 , sizeof(Real)*fullSize ); - } - if( flags & DD_DOT_FLAG ) - { - dTables.ddDotTable = NewPointer< Real >( size ); - memset( dTables.ddDotTable , 0 , sizeof(Real)*size ); - } - int vvSums[Degree+1][Degree+1]; - int vdSums[Degree+1][Degree ]; - int dvSums[Degree ][Degree+1]; - int ddSums[Degree ][Degree ]; - double vvIntegrals[Degree+1][Degree+1]; - double vdIntegrals[Degree+1][Degree ]; - double dvIntegrals[Degree ][Degree+1]; - double ddIntegrals[Degree ][Degree ]; - SetBSplineElementIntegrals< Degree , Degree >( vvIntegrals ); - SetBSplineElementIntegrals< Degree , Degree-1 >( vdIntegrals ); - SetBSplineElementIntegrals< Degree-1 , Degree >( dvIntegrals ); - SetBSplineElementIntegrals< Degree-1 , Degree-1 >( ddIntegrals ); + size_t size = ( functionCount*functionCount + functionCount )>>1; + size_t fullSize = functionCount*functionCount; + if( flags & VV_DOT_FLAG ) + { + dTables.vvDotTable = NewPointer< Real >( size ); + memset( dTables.vvDotTable , 0 , sizeof(Real)*size ); + } + if( flags & DV_DOT_FLAG ) + { + dTables.dvDotTable = NewPointer< Real >( fullSize ); + memset( dTables.dvDotTable , 0 , sizeof(Real)*fullSize ); + } + if( flags & DD_DOT_FLAG ) + { + dTables.ddDotTable = NewPointer< Real >( size ); + memset( dTables.ddDotTable , 0 , sizeof(Real)*size ); + } + int vvSums[Degree+1][Degree+1]; + int vdSums[Degree+1][Degree ]; + int dvSums[Degree ][Degree+1]; + int ddSums[Degree ][Degree ]; + double vvIntegrals[Degree+1][Degree+1]; + double vdIntegrals[Degree+1][Degree ]; + double dvIntegrals[Degree ][Degree+1]; + double ddIntegrals[Degree ][Degree ]; + SetBSplineElementIntegrals< Degree , Degree >( vvIntegrals ); + SetBSplineElementIntegrals< Degree , Degree-1 >( vdIntegrals ); + SetBSplineElementIntegrals< Degree-1 , Degree >( dvIntegrals ); + SetBSplineElementIntegrals< Degree-1 , Degree-1 >( ddIntegrals ); - for( int d1=0 ; d1<=depth ; d1++ ) for( int off1=0 ; off1<(1< b1( 1< db1; - b1.differentiate( db1 ); - int start1 , end1; + for( int d1=0 ; d1<=depth ; d1++ ) for( int off1=0 ; off1<(1< b1( 1< db1; + b1.differentiate( db1 ); + int start1 , end1; - start1 = -1 , end1 = -1; - for( int i=0 ; i=end1 || start1>=end2 ) continue; - start2 = std::max< int >( start1 , start2 ); - end2 = std::min< int >( end1 , end2 ); - if( d1==d2 && off2 b2( 1< db2; - b2.differentiate( db2 ); + start1 = -1 , end1 = -1; + for( int i=0 ; i=end1 || start1>=end2 ) continue; + start2 = std::max< int >( start1 , start2 ); + end2 = std::min< int >( end1 , end2 ); + if( d1==d2 && off2 b2( 1< db2; + b2.differentiate( db2 ); - size_t idx = DotTables< Real >::SymmetricIndex( ii , jj ); - size_t idx1 = DotTables< Real >::Index( ii , jj ) , idx2 = DotTables< Real >::Index( jj , ii ); + size_t idx = DotTables< Real >::SymmetricIndex( ii , jj ); + size_t idx1 = DotTables< Real >::Index( ii , jj ) , idx2 = DotTables< Real >::Index( jj , ii ); - memset( vvSums , 0 , sizeof( int ) * ( Degree+1 ) * ( Degree+1 ) ); - memset( vdSums , 0 , sizeof( int ) * ( Degree+1 ) * ( Degree ) ); - memset( dvSums , 0 , sizeof( int ) * ( Degree ) * ( Degree+1 ) ); - memset( ddSums , 0 , sizeof( int ) * ( Degree ) * ( Degree ) ); - for( int i=start2 ; i b; - b = b1; - b.upSample( b1 ); - b1.differentiate( db1 ); - start1 = -1; - for( int i=0 ; i b; + b = b1; + b.upSample( b1 ); + b1.differentiate( db1 ); + start1 = -1; + for( int i=0 ; i template< class Real > BSplineData< Degree >::ValueTables< Real >::ValueTables( void ) { - valueTable = NullPointer< Real >(); - dValueTable = NullPointer< Real >(); + valueTable = NullPointer< Real >(); + dValueTable = NullPointer< Real >(); } template< int Degree > template< class Real > BSplineData< Degree >::ValueTables< Real >::~ValueTables( void ) { - DeletePointer( valueTable ); - DeletePointer( dValueTable ); + DeletePointer( valueTable ); + DeletePointer( dValueTable ); } template< int Degree > template< class Real > @@ -550,49 +550,49 @@ template< int Degree > template< class Real > typename BSplineData< Degree >::template ValueTables< Real > BSplineData< Degree >::getValueTables( int flags , double valueSmooth , double derivativeSmooth ) const { - typename BSplineData< Degree >::template ValueTables< Real > vTables; - vTables.functionCount = functionCount; - vTables.sampleCount = sampleCount; + typename BSplineData< Degree >::template ValueTables< Real > vTables; + vTables.functionCount = functionCount; + vTables.sampleCount = sampleCount; - if( flags & VALUE_FLAG ) vTables.valueTable = NewPointer< Real >( functionCount*sampleCount ); - if( flags & D_VALUE_FLAG ) vTables.dValueTable = NewPointer< Real >( functionCount*sampleCount ); - PPolynomial< Degree+1 > function; - PPolynomial< Degree > dFunction; - for( size_t i=0 ; i0 ) function=baseFunctions[i].MovingAverage( valueSmooth ); - else function=baseFunctions[i]; - if( derivativeSmooth>0 ) dFunction=baseFunctions[i].derivative().MovingAverage( derivativeSmooth ); - else dFunction=baseFunctions[i].derivative(); + if( flags & VALUE_FLAG ) vTables.valueTable = NewPointer< Real >( functionCount*sampleCount ); + if( flags & D_VALUE_FLAG ) vTables.dValueTable = NewPointer< Real >( functionCount*sampleCount ); + PPolynomial< Degree+1 > function; + PPolynomial< Degree > dFunction; + for( size_t i=0 ; i0 ) function=baseFunctions[i].MovingAverage( valueSmooth ); + else function=baseFunctions[i]; + if( derivativeSmooth>0 ) dFunction=baseFunctions[i].derivative().MovingAverage( derivativeSmooth ); + else dFunction=baseFunctions[i].derivative(); - for( size_t j=0 ; j template< class Real > void BSplineData< Degree >::ValueTables< Real >::setSampleSpan( int idx , int& start , int& end , double smooth ) const { - int d , off , res; - BinaryNode::DepthAndOffset( idx , d , off ); - res = 1<_start && (start-1)/(sampleCount-1)<=_start - // => start > _start * (sampleCount-1 ) && start <= _start*(sampleCount-1) + 1 - // => _start * (sampleCount-1) + 1 >= start > _start * (sampleCount-1) - start = int( floor( _start * (sampleCount-1) + 1 ) ); - if( start<0 ) start = 0; - // (end)/(sampleCount-1)<_end && (end+1)/(sampleCount-1)>=_end - // => end < _end * (sampleCount-1 ) && end >= _end*(sampleCount-1) - 1 - // => _end * (sampleCount-1) > end >= _end * (sampleCount-1) - 1 - end = int( ceil( _end * (sampleCount-1) - 1 ) ); - if( end>=int(sampleCount) ) end = int(sampleCount)-1; + int d , off , res; + BinaryNode::DepthAndOffset( idx , d , off ); + res = 1<_start && (start-1)/(sampleCount-1)<=_start + // => start > _start * (sampleCount-1 ) && start <= _start*(sampleCount-1) + 1 + // => _start * (sampleCount-1) + 1 >= start > _start * (sampleCount-1) + start = int( floor( _start * (sampleCount-1) + 1 ) ); + if( start<0 ) start = 0; + // (end)/(sampleCount-1)<_end && (end+1)/(sampleCount-1)>=_end + // => end < _end * (sampleCount-1 ) && end >= _end*(sampleCount-1) - 1 + // => _end * (sampleCount-1) > end >= _end * (sampleCount-1) - 1 + end = int( ceil( _end * (sampleCount-1) - 1 ) ); + if( end>=int(sampleCount) ) end = int(sampleCount)-1; } @@ -602,132 +602,132 @@ void BSplineData< Degree >::ValueTables< Real >::setSampleSpan( int idx , int& s template< int Degree > BSplineElements< Degree >::BSplineElements( int res , int offset , int boundary , int inset ) { - denominator = 1; - this->resize( res , BSplineElementCoefficients< Degree >() ); + denominator = 1; + std::vector< BSplineElementCoefficients< Degree > >::resize( res , BSplineElementCoefficients< Degree >() ); - for( int i=0 ; i<=Degree ; i++ ) - { - int idx = -_off + offset + i; - if( idx>=0 && idx=0 && idx void BSplineElements< Degree >::_addLeft( int offset , int boundary ) { - int res = int( std::vector< BSplineElementCoefficients< Degree > >::size() ); - bool set = false; - for( int i=0 ; i<=Degree ; i++ ) - { - int idx = -_off + offset + i; - if( idx>=0 && idx >::size() ); + bool set = false; + for( int i=0 ; i<=Degree ; i++ ) + { + int idx = -_off + offset + i; + if( idx>=0 && idx void BSplineElements< Degree >::_addRight( int offset , int boundary ) { - int res = int( std::vector< BSplineElementCoefficients< Degree > >::size() ); - bool set = false; - for( int i=0 ; i<=Degree ; i++ ) - { - int idx = -_off + offset + i; - if( idx>=0 && idx >::size() ); + bool set = false; + for( int i=0 ; i<=Degree ; i++ ) + { + int idx = -_off + offset + i; + if( idx>=0 && idx void BSplineElements< Degree >::upSample( BSplineElements< Degree >& high ) const { - fprintf( stderr , "[ERROR] B-spline up-sampling not supported for degree %d\n" , Degree ); - exit( 0 ); + fprintf( stderr , "[ERROR] B-spline up-sampling not supported for degree %d\n" , Degree ); + exit( 0 ); } template<> void BSplineElements< 1 >::upSample( BSplineElements< 1 >& high ) const { - high.resize( size()*2 ); - high.assign( high.size() , BSplineElementCoefficients<1>() ); - for( int i=0 ; i() ); + for( int i=0 ; i void BSplineElements< 2 >::upSample( BSplineElements< 2 >& high ) const { - // /----\ - // / \ - // / \ = 1 /--\ +3 /--\ +3 /--\ +1 /--\ - // / \ / \ / \ / \ / \ - // |----------| |----------| |----------| |----------| |----------| + // /----\ + // / \ + // / \ = 1 /--\ +3 /--\ +3 /--\ +1 /--\ + // / \ / \ / \ / \ / \ + // |----------| |----------| |----------| |----------| |----------| - high.resize( size()*2 ); - high.assign( high.size() , BSplineElementCoefficients<2>() ); - for( int i=0 ; i() ); + for( int i=0 ; i void BSplineElements< Degree >::differentiate( BSplineElements< Degree-1 >& d ) const { - d.resize( std::vector< BSplineElementCoefficients< Degree > >::size() ); - d.assign( d.size() , BSplineElementCoefficients< Degree-1 >() ); - for( int i=0 ; i >::size()) ; i++ ) for( int j=0 ; j<=Degree ; j++ ) - { - if( j-1>=0 ) d[i][j-1] -= (*this)[i][j]; - if( j >::size() ); + d.assign( d.size() , BSplineElementCoefficients< Degree-1 >() ); + for( int i=0 ; i >::size()) ; i++ ) for( int j=0 ; j<=Degree ; j++ ) + { + if( j-1>=0 ) d[i][j-1] -= (*this)[i][j]; + if( j void SetBSplineElementIntegrals( double integrals[Degree1+1][Degree2+1] ) { - for( int i=0 ; i<=Degree1 ; i++ ) - { - Polynomial< Degree1 > p1 = Polynomial< Degree1 >::BSplineComponent( i ); - for( int j=0 ; j<=Degree2 ; j++ ) - { - Polynomial< Degree2 > p2 = Polynomial< Degree2 >::BSplineComponent( j ); - integrals[i][j] = ( p1 * p2 ).integral( 0 , 1 ); - } - } + for( int i=0 ; i<=Degree1 ; i++ ) + { + Polynomial< Degree1 > p1 = Polynomial< Degree1 >::BSplineComponent( i ); + for( int j=0 ; j<=Degree2 ; j++ ) + { + Polynomial< Degree2 > p2 = Polynomial< Degree2 >::BSplineComponent( j ); + integrals[i][j] = ( p1 * p2 ).integral( 0 , 1 ); + } + } }