From 9fce3d2f8594030058f5e9f2aa14fdd9bb39baa7 Mon Sep 17 00:00:00 2001 From: Bradley J Chambers Date: Wed, 26 Jul 2017 13:17:03 -0400 Subject: [PATCH 1/2] Changes the expectations slightly for this sparse dataset --- test/unit/OldPCLBlockTest.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/unit/OldPCLBlockTest.cpp b/test/unit/OldPCLBlockTest.cpp index 47231ba45c..d5d382b913 100644 --- a/test/unit/OldPCLBlockTest.cpp +++ b/test/unit/OldPCLBlockTest.cpp @@ -213,8 +213,8 @@ TEST(OldPCLBlockTests, PMF) assign->setInput(*r); Options fo; - fo.add("max_window_size", 33); - fo.add("cell_size", 1.0); + fo.add("max_window_size", 33.0); + fo.add("cell_size", 10.0); fo.add("slope", 1.0); fo.add("initial_distance", 0.15); fo.add("max_distance", 2.5); @@ -239,5 +239,5 @@ TEST(OldPCLBlockTests, PMF) EXPECT_EQ(1u, viewSet.size()); PointViewPtr view = *viewSet.begin(); - EXPECT_EQ(106u, view->size()); + EXPECT_EQ(79u, view->size()); } From 78f0d83dcb73ffce3e88793c57b4ef7595fb95d7 Mon Sep 17 00:00:00 2001 From: Andrew Bell Date: Thu, 27 Jul 2017 13:00:17 -0400 Subject: [PATCH 2/2] Remove accidentally added files. --- vendor/poisson_surface/allocator.h | 168 - vendor/poisson_surface/binary_node.h | 88 - vendor/poisson_surface/bspline_data.h | 148 - vendor/poisson_surface/bspline_data.hpp | 528 --- vendor/poisson_surface/factor.h | 60 - vendor/poisson_surface/function_data.h | 123 - vendor/poisson_surface/function_data.hpp | 423 -- vendor/poisson_surface/geometry.h | 333 -- vendor/poisson_surface/geometry.hpp | 433 -- vendor/poisson_surface/hash.h | 32 - .../poisson_surface/marching_cubes_poisson.h | 144 - vendor/poisson_surface/mat.h | 59 - vendor/poisson_surface/mat.hpp | 223 - .../poisson_surface/multi_grid_octree_data.h | 371 -- .../multi_grid_octree_data.hpp | 3918 ----------------- vendor/poisson_surface/octree_poisson.h | 287 -- vendor/poisson_surface/octree_poisson.hpp | 1911 -------- vendor/poisson_surface/polynomial.h | 102 - vendor/poisson_surface/polynomial.hpp | 325 -- vendor/poisson_surface/ppolynomial.h | 128 - vendor/poisson_surface/ppolynomial.hpp | 441 -- vendor/poisson_surface/sparse_matrix.h | 188 - vendor/poisson_surface/sparse_matrix.hpp | 970 ---- vendor/poisson_surface/vector.h | 155 - vendor/poisson_surface/vector.hpp | 492 --- 25 files changed, 12050 deletions(-) delete mode 100644 vendor/poisson_surface/allocator.h delete mode 100644 vendor/poisson_surface/binary_node.h delete mode 100644 vendor/poisson_surface/bspline_data.h delete mode 100644 vendor/poisson_surface/bspline_data.hpp delete mode 100644 vendor/poisson_surface/factor.h delete mode 100644 vendor/poisson_surface/function_data.h delete mode 100644 vendor/poisson_surface/function_data.hpp delete mode 100644 vendor/poisson_surface/geometry.h delete mode 100644 vendor/poisson_surface/geometry.hpp delete mode 100644 vendor/poisson_surface/hash.h delete mode 100644 vendor/poisson_surface/marching_cubes_poisson.h delete mode 100644 vendor/poisson_surface/mat.h delete mode 100644 vendor/poisson_surface/mat.hpp delete mode 100644 vendor/poisson_surface/multi_grid_octree_data.h delete mode 100644 vendor/poisson_surface/multi_grid_octree_data.hpp delete mode 100644 vendor/poisson_surface/octree_poisson.h delete mode 100644 vendor/poisson_surface/octree_poisson.hpp delete mode 100644 vendor/poisson_surface/polynomial.h delete mode 100644 vendor/poisson_surface/polynomial.hpp delete mode 100644 vendor/poisson_surface/ppolynomial.h delete mode 100644 vendor/poisson_surface/ppolynomial.hpp delete mode 100644 vendor/poisson_surface/sparse_matrix.h delete mode 100644 vendor/poisson_surface/sparse_matrix.hpp delete mode 100644 vendor/poisson_surface/vector.h delete mode 100644 vendor/poisson_surface/vector.hpp diff --git a/vendor/poisson_surface/allocator.h b/vendor/poisson_surface/allocator.h deleted file mode 100644 index 1b5cb0aafd..0000000000 --- a/vendor/poisson_surface/allocator.h +++ /dev/null @@ -1,168 +0,0 @@ -/* -Copyright (c) 2006, Michael Kazhdan and Matthew Bolitho -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -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. - -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. - -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 -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 -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. -*/ - -#ifndef ALLOCATOR_INCLUDED -#define ALLOCATOR_INCLUDED -#include - -namespace pcl -{ - namespace poisson - { - class AllocatorState{ - public: - int index,remains; - }; - /** This templated class assists in memory allocation and is well suited for instances - * when it is known that the sequence of memory allocations is performed in a stack-based - * manner, so that memory allocated last is released first. It also preallocates memory - * in chunks so that multiple requests for small chunks of memory do not require separate - * system calls to the memory manager. - * The allocator is templated off of the class of objects that we would like it to allocate, - * ensuring that appropriate constructors and destructors are called as necessary. - */ - template - class Allocator{ - int blockSize; - int index,remains; - std::vector memory; - public: - Allocator(void){ - blockSize=index=remains=0; - } - ~Allocator(void){ - reset(); - } - - /** This method is the allocators destructor. It frees up any of the memory that - * it has allocated. */ - void reset(void){ - for(size_t i=0;iblockSize=blockSize; - index=-1; - remains=0; - } - - /** This method returns a pointer to an array of elements objects. If there is left over pre-allocated - * memory, this method simply returns a pointer to the next free piece of memory, otherwise it pre-allocates - * more memory. Note that if the number of objects requested is larger than the value blockSize with which - * the allocator was initialized, the request for memory will fail. - */ - T* newElements( int elements=1){ - T* mem; - if(!elements){return NULL;} - if(elements>blockSize){ - fprintf(stderr,"Allocator Error, elements bigger than block-size: %d>%d\n",elements,blockSize); - return NULL; - } - if(remains - class BinaryNode - { - public: - static inline int CenterCount( int depth ) { return 1<>= 1; - depth++; - } -#if MSVC_2010_FIX - depth--; -#endif // MSVC_2010_FIX - offset = ( idx+1 ) - (1< - class BSplineData - { - bool useDotRatios; - bool reflectBoundary; - public: - struct BSplineComponents - { - Polynomial< Degree > polys[Degree+1]; - Polynomial< Degree >& operator[] ( int idx ) { return polys[idx]; } - const Polynomial< Degree >& operator[] ( int idx ) const { return polys[idx]; } - void printnl( void ) const { for( int d=0 ; d<=Degree ; d++ ) polys[d].printnl(); } - BSplineComponents scale( double s ) const { BSplineComponents b ; for( int d=0 ; d<=Degree ; d++ ) b[d] = polys[d].scale(s) ; return b; } - BSplineComponents shift( double s ) const { BSplineComponents b ; for( int d=0 ; d<=Degree ; d++ ) b[d] = polys[d].shift(s) ; return b; } - }; - const static int VV_DOT_FLAG = 1; - const static int DV_DOT_FLAG = 2; - const static int DD_DOT_FLAG = 4; - const static int VALUE_FLAG = 1; - const static int D_VALUE_FLAG = 2; - - int depth , functionCount , sampleCount; - Real *vvDotTable , *dvDotTable , *ddDotTable; - Real *valueTables , *dValueTables; - PPolynomial< Degree > baseFunction , leftBaseFunction , rightBaseFunction; - PPolynomial< Degree-1 > dBaseFunction , dLeftBaseFunction , dRightBaseFunction; - BSplineComponents baseBSpline, leftBSpline , rightBSpline; - PPolynomial* baseFunctions; - BSplineComponents* baseBSplines; - - BSplineData(void); - ~BSplineData(void); - - virtual void setDotTables( int flags ); - virtual void clearDotTables( int flags ); - - virtual void setValueTables( int flags,double smooth=0); - virtual void setValueTables( int flags,double valueSmooth,double normalSmooth); - virtual void clearValueTables(void); - - void setSampleSpan( int idx , int& start , int& end , double smooth=0 ) const; - - /******************************************************** - * Sets the translates and scales of the basis function - * up to the prescribed depth - * the maximum depth - * specifies if dot-products of derivatives - * should be pre-divided by function integrals - * spcifies if function space should be - * forced to be reflectively symmetric across the boundary - ********************************************************/ - void set( int maxDepth , bool useDotRatios=true , bool reflectBoundary=false ); - - inline int Index( int i1 , int i2 ) const; - static inline int SymmetricIndex( int i1 , int i2 ); - static inline int SymmetricIndex( int i1 , int i2 , int& index ); - }; - - template< int Degree > - struct BSplineElementCoefficients - { - int coeffs[Degree+1]; - BSplineElementCoefficients( void ) { memset( coeffs , 0 , sizeof( int ) * ( Degree+1 ) ); } - int& operator[]( int idx ){ return coeffs[idx]; } - const int& operator[]( int idx ) const { return coeffs[idx]; } - }; - template< int Degree > - struct BSplineElements : public std::vector< BSplineElementCoefficients< Degree > > - { - static const int _off = (Degree+1)/2; - void _addLeft ( int offset , int boundary ); - void _addRight( int offset , int boundary ); - public: - enum - { - NONE = 0, - DIRICHLET = -1, - NEUMANN = 1 - }; - // Coefficients are ordered as "/" "-" "\" - int denominator; - - BSplineElements( void ) { denominator = 1; } - BSplineElements( int res , int offset , int boundary=NONE ); - - void upSample( BSplineElements& high ) const; - void differentiate( BSplineElements< Degree-1 >& d ) const; - - void print( FILE* fp=stdout ) const - { - for( int i=0 ; isize() ; i++ ) - { - printf( "%d]" , i ); - for( int j=0 ; j<=Degree ; j++ ) printf( " %d" , (*this)[i][j] ); - printf( " (%d)\n" , denominator ); - } - } - }; - template< int Degree1 , int Degree2 > void SetBSplineElementIntegrals( double integrals[Degree1+1][Degree2+1] ); - - - } -} - - -#include "bspline_data.hpp" - -#endif // BSPLINE_DATA_INCLUDED diff --git a/vendor/poisson_surface/bspline_data.hpp b/vendor/poisson_surface/bspline_data.hpp deleted file mode 100644 index 6e688c549a..0000000000 --- a/vendor/poisson_surface/bspline_data.hpp +++ /dev/null @@ -1,528 +0,0 @@ -/* -Copyright (c) 2006, Michael Kazhdan and Matthew Bolitho -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -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. - -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. - -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 -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 -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. -*/ - - -namespace pcl -{ - namespace poisson - { - - ///////////////// - // BSplineData // - ///////////////// - // Support[i]: - // Odd: i +/- 0.5 * ( 1 + Degree ) - // i - 0.5 * ( 1 + Degree ) < 0 - // <=> i < 0.5 * ( 1 + Degree ) - // i + 0.5 * ( 1 + Degree ) > 0 - // <=> i > - 0.5 * ( 1 + Degree ) - // i + 0.5 * ( 1 + Degree ) > r - // <=> i > r - 0.5 * ( 1 + Degree ) - // i - 0.5 * ( 1 + Degree ) < r - // <=> i < r + 0.5 * ( 1 + Degree ) - // Even: i + 0.5 +/- 0.5 * ( 1 + Degree ) - // i - 0.5 * Degree < 0 - // <=> i < 0.5 * Degree - // i + 1 + 0.5 * Degree > 0 - // <=> i > -1 - 0.5 * Degree - // i + 1 + 0.5 * Degree > r - // <=> i > r - 1 - 0.5 * Degree - // i - 0.5 * Degree < r - // <=> 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 ); - } - 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 ); - } - template< int Degree > inline int ReflectLeft( unsigned int depth , int 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; - } - - template< int Degree , class Real > - BSplineData::BSplineData( void ) - { - vvDotTable = dvDotTable = ddDotTable = NULL; - valueTables = dValueTables = NULL; - functionCount = sampleCount = 0; - } - - template< int Degree , class Real > - BSplineData< Degree , Real >::~BSplineData(void) - { - if( functionCount ) - { - if( vvDotTable ) delete[] vvDotTable; - if( dvDotTable ) delete[] dvDotTable; - if( ddDotTable ) delete[] ddDotTable; - - if( valueTables ) delete[] valueTables; - if( dValueTables ) delete[] dValueTables; - } - vvDotTable = dvDotTable = ddDotTable = NULL; - valueTables = dValueTables=NULL; - functionCount = 0; - } - - template - void BSplineData::set( int maxDepth , bool useDotRatios , bool reflectBoundary ) - { - this->useDotRatios = useDotRatios; - this->reflectBoundary = reflectBoundary; - - depth = maxDepth; - // [Warning] This assumes that the functions spacing is dual - functionCount = BinaryNode< double >::CumulativeCenterCount( depth ); - sampleCount = BinaryNode< double >::CenterCount( depth ) + BinaryNode< double >::CornerCount( depth ); - baseFunctions = new PPolynomial[functionCount]; - baseBSplines = new 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+3]; - - 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 ); - for( int j=0 ; j::CenterAndWidth( i , c , w ); - baseFunctions[i] = baseFunction.scale(w).shift(c); - baseBSplines[i] = baseBSpline.scale(w).shift(c); - if( reflectBoundary ) - { - int d , off , r; - BinaryNode< double >::DepthAndOffset( i , d , off ); - r = 1< - void BSplineData::setDotTables( int flags ) - { - clearDotTables( flags ); - int size = ( functionCount*functionCount + functionCount )>>1; - int fullSize = functionCount*functionCount; - if( flags & VV_DOT_FLAG ) - { - vvDotTable = new Real[size]; - memset( vvDotTable , 0 , sizeof(Real)*size ); - } - if( flags & DV_DOT_FLAG ) - { - dvDotTable = new Real[fullSize]; - memset( dvDotTable , 0 , sizeof(Real)*fullSize ); - } - if( flags & DD_DOT_FLAG ) - { - ddDotTable = new Real[size]; - memset( ddDotTable , 0 , sizeof(Real)*size ); - } - double vvIntegrals[Degree+1][Degree+1]; - double vdIntegrals[Degree+1][Degree ]; - double dvIntegrals[Degree ][Degree+1]; - double ddIntegrals[Degree ][Degree ]; - int vvSums[Degree+1][Degree+1]; - int vdSums[Degree+1][Degree ]; - int dvSums[Degree ][Degree+1]; - int ddSums[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<::CenterIndex( d1 , off1 ); - BSplineElements< Degree > b1( 1<::NEUMANN : BSplineElements< Degree>::NONE ); - BSplineElements< Degree-1 > db1; - b1.differentiate( db1 ); - - int start1 , end1; - - start1 = -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::CenterIndex( d2 , off2 ); - BSplineElements< Degree > b2( 1<::NEUMANN : BSplineElements< Degree>::NONE ); - BSplineElements< Degree-1 > db2; - b2.differentiate( db2 ); - - int idx = SymmetricIndex( ii , jj ); - int idx1 = Index( ii , jj ) , idx2 = 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 - void BSplineData::clearDotTables( int flags ) - { - if( (flags & VV_DOT_FLAG) && vvDotTable ) delete[] vvDotTable , vvDotTable = NULL; - if( (flags & DV_DOT_FLAG) && dvDotTable ) delete[] dvDotTable , dvDotTable = NULL; - if( (flags & DD_DOT_FLAG) && ddDotTable ) delete[] ddDotTable , ddDotTable = NULL; - } - template< int Degree , class Real > - void BSplineData< Degree , Real >::setSampleSpan( int idx , int& start , int& end , double smooth ) const - { - int d , off , res; - BinaryNode< double >::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>=sampleCount ) end = sampleCount-1; - } - template - void BSplineData::setValueTables( int flags , double smooth ) - { - clearValueTables(); - if( flags & VALUE_FLAG ) valueTables = new Real[functionCount*sampleCount]; - if( flags & D_VALUE_FLAG ) dValueTables = new Real[functionCount*sampleCount]; - PPolynomial function; - PPolynomial dFunction; - for( int i=0 ; i0) - { - function = baseFunctions[i].MovingAverage(smooth); - dFunction = baseFunctions[i].derivative().MovingAverage(smooth); - } - else - { - function = baseFunctions[i]; - dFunction = baseFunctions[i].derivative(); - } - for( int j=0 ; j - void BSplineData::setValueTables(int flags,double valueSmooth,double normalSmooth){ - clearValueTables(); - if(flags & VALUE_FLAG){ valueTables=new Real[functionCount*sampleCount];} - if(flags & D_VALUE_FLAG){dValueTables=new Real[functionCount*sampleCount];} - PPolynomial function; - PPolynomial dFunction; - for(int i=0;i0) { function=baseFunctions[i].MovingAverage(valueSmooth);} - else { function=baseFunctions[i];} - if(normalSmooth>0) {dFunction=baseFunctions[i].derivative().MovingAverage(normalSmooth);} - else {dFunction=baseFunctions[i].derivative();} - - for(int j=0;j - void BSplineData::clearValueTables(void){ - if( valueTables){delete[] valueTables;} - if(dValueTables){delete[] dValueTables;} - valueTables=dValueTables=NULL; - } - - template - inline int BSplineData::Index( int i1 , int i2 ) const { return i1*functionCount+i2; } - template - inline int BSplineData::SymmetricIndex( int i1 , int i2 ) - { - if( i1>i2 ) return ((i1*i1+i1)>>1)+i2; - else return ((i2*i2+i2)>>1)+i1; - } - template - inline int BSplineData::SymmetricIndex( int i1 , int i2 , int& index ) - { - if( i1>1)+i1; - return 1; - } - else - { - index = ((i1*i1+i1)>>1)+i2; - return 0; - } - } - - - //////////////////////// - // BSplineElementData // - //////////////////////// - template< int Degree > - BSplineElements< Degree >::BSplineElements( int res , int offset , int boundary ) - { - denominator = 1; - this->resize( res , BSplineElementCoefficients() ); - - for( int i=0 ; i<=Degree ; i++ ) - { - int idx = -_off + offset + i; - if( idx>=0 && idx - void BSplineElements< Degree >::_addLeft( int offset , int boundary ) - { - int res = int( this->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( this->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 ); - } - template<> - void BSplineElements< 1 >::upSample( BSplineElements< 1 >& high ) const - { - high.resize( size()*2 ); - high.assign( high.size() , BSplineElementCoefficients<1>() ); - for( int i=0 ; i - void BSplineElements< 2 >::upSample( BSplineElements< 2 >& high ) const - { - // /----\ - // / \ - // / \ = 1 /--\ +3 /--\ +3 /--\ +1 /--\ - // / \ / \ / \ / \ / \ - // |----------| |----------| |----------| |----------| |----------| - - high.resize( size()*2 ); - high.assign( high.size() , BSplineElementCoefficients<2>() ); - for( int i=0 ; i - void BSplineElements< Degree >::differentiate( BSplineElements< Degree-1 >& d ) const - { - d.resize( this->size() ); - d.assign( d.size() , BSplineElementCoefficients< Degree-1 >() ); - for( int i=0 ; isize()) ; 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 ); - } - } - } - - - } -} diff --git a/vendor/poisson_surface/factor.h b/vendor/poisson_surface/factor.h deleted file mode 100644 index 747c8f0b1f..0000000000 --- a/vendor/poisson_surface/factor.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -Copyright (c) 2006, Michael Kazhdan and Matthew Bolitho -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -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. - -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. - -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 -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 -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. -*/ - -#ifndef FACTOR_INCLUDED -#define FACTOR_INCLUDED - -#include - -#define PI 3.1415926535897932384 -#define SQRT_3 1.7320508075688772935 - -namespace pcl -{ - namespace poisson - { - PCL_EXPORTS double ArcTan2(double y,double x); - PCL_EXPORTS double Angle(const double in[2]); - PCL_EXPORTS void Sqrt(const double in[2],double out[2]); - PCL_EXPORTS void Add(const double in1[2],const double in2[2],double out[2]); - PCL_EXPORTS void Subtract(const double in1[2],const double in2[2],double out[2]); - PCL_EXPORTS void Multiply(const double in1[2],const double in2[2],double out[2]); - PCL_EXPORTS void Divide(const double in1[2],const double in2[2],double out[2]); - - PCL_EXPORTS int Factor(double a1,double a0,double roots[1][2],double EPS); - PCL_EXPORTS int Factor(double a2,double a1,double a0,double roots[2][2],double EPS); - PCL_EXPORTS int Factor(double a3,double a2,double a1,double a0,double roots[3][2],double EPS); - PCL_EXPORTS int Factor(double a4,double a3,double a2,double a1,double a0,double roots[4][2],double EPS); - - PCL_EXPORTS int Solve(const double* eqns,const double* values,double* solutions, int dim); - - } -} - - -#endif // FACTOR_INCLUDED diff --git a/vendor/poisson_surface/function_data.h b/vendor/poisson_surface/function_data.h deleted file mode 100644 index fc1634ed3e..0000000000 --- a/vendor/poisson_surface/function_data.h +++ /dev/null @@ -1,123 +0,0 @@ -/* -Copyright (c) 2006, Michael Kazhdan and Matthew Bolitho -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -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. - -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. - -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 -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 -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. -*/ - -#ifndef FUNCTION_DATA_INCLUDED -#define FUNCTION_DATA_INCLUDED - -#define BOUNDARY_CONDITIONS 1 - -#if defined __GNUC__ -# pragma GCC system_header -#endif - - -#include "ppolynomial.h" - -namespace pcl -{ - namespace poisson - { - - template - class FunctionData{ - bool useDotRatios; - int normalize; -#if BOUNDARY_CONDITIONS - bool reflectBoundary; -#endif // BOUNDARY_CONDITIONS - public: - const static int DOT_FLAG = 1; - const static int D_DOT_FLAG = 2; - const static int D2_DOT_FLAG = 4; - const static int VALUE_FLAG = 1; - const static int D_VALUE_FLAG = 2; - - int depth , res , res2; - Real *dotTable , *dDotTable , *d2DotTable; - Real *valueTables , *dValueTables; -#if BOUNDARY_CONDITIONS - PPolynomial baseFunction , leftBaseFunction , rightBaseFunction; - PPolynomial dBaseFunction , dLeftBaseFunction , dRightBaseFunction; -#else // !BOUNDARY_CONDITIONS - PPolynomial baseFunction; - PPolynomial dBaseFunction; -#endif // BOUNDARY_CONDITIONS - PPolynomial* baseFunctions; - - FunctionData(void); - ~FunctionData(void); - - virtual void setDotTables(const int& flags); - virtual void clearDotTables(const int& flags); - - virtual void setValueTables(const int& flags,const double& smooth=0); - virtual void setValueTables(const int& flags,const double& valueSmooth,const double& normalSmooth); - virtual void clearValueTables(void); - - /******************************************************** - * Sets the translates and scales of the basis function - * up to the prescribed depth - * the maximum depth - * the basis function - * how the functions should be scaled - * 0] Value at zero equals 1 - * 1] Integral equals 1 - * 2] L2-norm equals 1 - * specifies if dot-products of derivatives - * should be pre-divided by function integrals - * spcifies if function space should be - * forced to be reflectively symmetric across the boundary - ********************************************************/ -#if BOUNDARY_CONDITIONS - void set( const int& maxDepth , const PPolynomial& F , const int& normalize , bool useDotRatios=true , bool reflectBoundary=false ); -#else // !BOUNDARY_CONDITIONS - void set(const int& maxDepth,const PPolynomial& F,const int& normalize , bool useDotRatios=true ); -#endif // BOUNDARY_CONDITIONS - -#if BOUNDARY_CONDITIONS - Real dotProduct( const double& center1 , const double& width1 , const double& center2 , const double& width2 , int boundary1 , int boundary2 ) const; - Real dDotProduct( const double& center1 , const double& width1 , const double& center2 , const double& width2 , int boundary1 , int boundary2 ) const; - Real d2DotProduct( const double& center1 , const double& width1 , const double& center2 , const double& width2 , int boundary1 , int boundary2 ) const; -#else // !BOUNDARY_CONDITIONS - Real dotProduct( const double& center1 , const double& width1 , const double& center2 , const double& width2 ) const; - Real dDotProduct( const double& center1 , const double& width1 , const double& center2 , const double& width2 ) const; - Real d2DotProduct( const double& center1 , const double& width1 , const double& center2 , const double& width2 ) const; -#endif // BOUNDARY_CONDITIONS - - static inline int SymmetricIndex( const int& i1 , const int& i2 ); - static inline int SymmetricIndex( const int& i1 , const int& i2 , int& index ); - }; - - - } -} - - -#include "function_data.hpp" - -#endif // FUNCTION_DATA_INCLUDED diff --git a/vendor/poisson_surface/function_data.hpp b/vendor/poisson_surface/function_data.hpp deleted file mode 100644 index 8fa4cdc37e..0000000000 --- a/vendor/poisson_surface/function_data.hpp +++ /dev/null @@ -1,423 +0,0 @@ -/* -Copyright (c) 2006, Michael Kazhdan and Matthew Bolitho -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -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. - -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. - -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 -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 -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. -*/ - -////////////////// -// FunctionData // -////////////////// - -namespace pcl -{ - namespace poisson - { - - template - FunctionData::FunctionData(void) - { - dotTable=dDotTable=d2DotTable=NULL; - valueTables=dValueTables=NULL; - res=0; - } - - template - FunctionData::~FunctionData(void) - { - if(res) - { - if( dotTable) delete[] dotTable; - if( dDotTable) delete[] dDotTable; - if(d2DotTable) delete[] d2DotTable; - if( valueTables) delete[] valueTables; - if(dValueTables) delete[] dValueTables; - } - dotTable=dDotTable=d2DotTable=NULL; - valueTables=dValueTables=NULL; - res=0; - } - - template -#if BOUNDARY_CONDITIONS - void FunctionData::set( const int& maxDepth , const PPolynomial& F , const int& normalize , bool useDotRatios , bool reflectBoundary ) -#else // !BOUNDARY_CONDITIONS - void FunctionData::set(const int& maxDepth,const PPolynomial& F,const int& normalize , bool useDotRatios ) -#endif // BOUNDARY_CONDITIONS - { - this->normalize = normalize; - this->useDotRatios = useDotRatios; -#if BOUNDARY_CONDITIONS - this->reflectBoundary = reflectBoundary; -#endif // BOUNDARY_CONDITIONS - - depth = maxDepth; - res = BinaryNode::CumulativeCenterCount( depth ); - res2 = (1<<(depth+1))+1; - baseFunctions = new PPolynomial[res]; - // Scale the function so that it has: - // 0] Value 1 at 0 - // 1] Integral equal to 1 - // 2] Square integral equal to 1 - switch( normalize ) - { - case 2: - baseFunction=F/sqrt((F*F).integral(F.polys[0].start,F.polys[F.polyCount-1].start)); - break; - case 1: - baseFunction=F/F.integral(F.polys[0].start,F.polys[F.polyCount-1].start); - break; - default: - baseFunction=F/F(0); - } - dBaseFunction = baseFunction.derivative(); -#if BOUNDARY_CONDITIONS - leftBaseFunction = baseFunction + baseFunction.shift( -1 ); - rightBaseFunction = baseFunction + baseFunction.shift( 1 ); - dLeftBaseFunction = leftBaseFunction.derivative(); - dRightBaseFunction = rightBaseFunction.derivative(); -#endif // BOUNDARY_CONDITIONS - double c1,w1; - for( int i=0 ; i::CenterAndWidth( i , c1 , w1 ); -#if BOUNDARY_CONDITIONS - if( reflectBoundary ) - { - int d , off; - BinaryNode< double >::DepthAndOffset( i , d , off ); - if ( off==0 ) baseFunctions[i] = leftBaseFunction.scale( w1 ).shift( c1 ); - else if( off==((1< - void FunctionData::setDotTables( const int& flags ) - { - clearDotTables( flags ); - int size; - size = ( res*res + res )>>1; - if( flags & DOT_FLAG ) - { - dotTable = new Real[size]; - memset( dotTable , 0 , sizeof(Real)*size ); - } - if( flags & D_DOT_FLAG ) - { - dDotTable = new Real[size]; - memset( dDotTable , 0 , sizeof(Real)*size ); - } - if( flags & D2_DOT_FLAG ) - { - d2DotTable = new Real[size]; - memset( d2DotTable , 0 , sizeof(Real)*size ); - } - double t1 , t2; - t1 = baseFunction.polys[0].start; - t2 = baseFunction.polys[baseFunction.polyCount-1].start; - for( int i=0 ; i::CenterAndWidth( i , c1 , w1 ); -#if BOUNDARY_CONDITIONS - int d1 , d2 , off1 , off2; - BinaryNode< double >::DepthAndOffset( i , d1 , off1 ); - int boundary1 = 0; - if ( reflectBoundary && off1==0 ) boundary1 = -1; - else if( reflectBoundary && off1==( (1<::CenterAndWidth( j , c2 , w2 ); -#if BOUNDARY_CONDITIONS - BinaryNode< double >::DepthAndOffset( j , d2 , off2 ); - int boundary2 = 0; - if ( reflectBoundary && off2==0 ) boundary2 = -1; - else if( reflectBoundary && off2==( (1<1 ) start = 1; - if( end <0 ) end = 0; - if( end >1 ) end = 1; - } -#endif // BOUNDARY_CONDITIONS - - if( start< start1 ) start = start1; - if( end > end1 ) end = end1; - if( start>= end ) continue; - -#if BOUNDARY_CONDITIONS - Real dot = dotProduct( c1 , w1 , c2 , w2 , boundary1 , boundary2 ); -#else // !BOUNDARY_CONDITIONS - Real dot = dotProduct( c1 , w1 , c2 , w2 ); -#endif // BOUNDARY_CONDITIONS - if( fabs(dot)<1e-15 ) continue; - if( flags & DOT_FLAG ) dotTable[idx]=dot; - if( useDotRatios ) - { -#if BOUNDARY_CONDITIONS - if( flags & D_DOT_FLAG ) dDotTable[idx] = -dDotProduct( c1 , w1 , c2 , w2 , boundary1 , boundary2 ) / dot; - if( flags & D2_DOT_FLAG ) d2DotTable[idx] = d2DotProduct( c1 , w1 , c2 , w2 , boundary1 , boundary2 ) / dot; -#else // !BOUNDARY_CONDITIONS - if( flags & D_DOT_FLAG ) dDotTable[idx] = -dDotProduct(c1,w1,c2,w2)/dot; - if( flags & D2_DOT_FLAG ) d2DotTable[idx] = d2DotProduct(c1,w1,c2,w2)/dot; -#endif // BOUNDARY_CONDITIONS - } - else - { -#if BOUNDARY_CONDITIONS - if( flags & D_DOT_FLAG ) dDotTable[idx] = dDotProduct( c1 , w1 , c2 , w2 , boundary1 , boundary2 ); - if( flags & D2_DOT_FLAG ) d2DotTable[idx] = d2DotProduct( c1 , w1 , c2 , w2 , boundary1 , boundary2 ); -#else // !BOUNDARY_CONDTIONS - if( flags & D_DOT_FLAG ) dDotTable[idx] = dDotProduct(c1,w1,c2,w2); - if( flags & D2_DOT_FLAG ) d2DotTable[idx] = d2DotProduct(c1,w1,c2,w2); -#endif // BOUNDARY_CONDITIONS - } - } - } - } - template - void FunctionData::clearDotTables( const int& flags ) - { - if((flags & DOT_FLAG) && dotTable) - { - delete[] dotTable; - dotTable=NULL; - } - if((flags & D_DOT_FLAG) && dDotTable) - { - delete[] dDotTable; - dDotTable=NULL; - } - if((flags & D2_DOT_FLAG) && d2DotTable) - { - delete[] d2DotTable; - d2DotTable=NULL; - } - } - template - void FunctionData::setValueTables( const int& flags , const double& smooth ) - { - clearValueTables(); - if( flags & VALUE_FLAG ) valueTables = new Real[res*res2]; - if( flags & D_VALUE_FLAG ) dValueTables = new Real[res*res2]; - PPolynomial function; - PPolynomial dFunction; - for( int i=0 ; i0) - { - function=baseFunctions[i].MovingAverage(smooth); - dFunction=baseFunctions[i].derivative().MovingAverage(smooth); - } - else - { - function=baseFunctions[i]; - dFunction=baseFunctions[i].derivative(); - } - for( int j=0 ; j - void FunctionData::setValueTables(const int& flags,const double& valueSmooth,const double& normalSmooth){ - clearValueTables(); - if(flags & VALUE_FLAG){ valueTables=new Real[res*res2];} - if(flags & D_VALUE_FLAG){dValueTables=new Real[res*res2];} - PPolynomial function; - PPolynomial dFunction; - for(int i=0;i0) { function=baseFunctions[i].MovingAverage(valueSmooth);} - else { function=baseFunctions[i];} - if(normalSmooth>0) {dFunction=baseFunctions[i].derivative().MovingAverage(normalSmooth);} - else {dFunction=baseFunctions[i].derivative();} - - for(int j=0;j - void FunctionData::clearValueTables(void){ - if( valueTables){delete[] valueTables;} - if(dValueTables){delete[] dValueTables;} - valueTables=dValueTables=NULL; - } - -#if BOUNDARY_CONDITIONS - template - Real FunctionData::dotProduct( const double& center1 , const double& width1 , const double& center2 , const double& width2 , int boundary1 , int boundary2 ) const - { - const PPolynomial< Degree > *b1 , *b2; - if ( boundary1==-1 ) b1 = & leftBaseFunction; - else if( boundary1== 0 ) b1 = & baseFunction; - else if( boundary1== 1 ) b1 = &rightBaseFunction; - if ( boundary2==-1 ) b2 = & leftBaseFunction; - else if( boundary2== 0 ) b2 = & baseFunction; - else if( boundary2== 1 ) b2 = &rightBaseFunction; - double r=fabs( baseFunction.polys[0].start ); - switch( normalize ) - { - case 2: - return Real(((*b1)*b2->scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)*width1/sqrt(width1*width2)); - case 1: - return Real(((*b1)*b2->scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)*width1/(width1*width2)); - default: - return Real(((*b1)*b2->scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)*width1); - } - } - template - Real FunctionData::dDotProduct( const double& center1 , const double& width1 , const double& center2 , const double& width2 , int boundary1 , int boundary2 ) const - { - const PPolynomial< Degree-1 > *b1; - const PPolynomial< Degree > *b2; - if ( boundary1==-1 ) b1 = & dLeftBaseFunction; - else if( boundary1== 0 ) b1 = & dBaseFunction; - else if( boundary1== 1 ) b1 = &dRightBaseFunction; - if ( boundary2==-1 ) b2 = & leftBaseFunction; - else if( boundary2== 0 ) b2 = & baseFunction; - else if( boundary2== 1 ) b2 = & rightBaseFunction; - double r=fabs(baseFunction.polys[0].start); - switch(normalize){ - case 2: - return Real(((*b1)*b2->scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)/sqrt(width1*width2)); - case 1: - return Real(((*b1)*b2->scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)/(width1*width2)); - default: - return Real(((*b1)*b2->scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)); - } - } - template - Real FunctionData::d2DotProduct( const double& center1 , const double& width1 , const double& center2 , const double& width2 , int boundary1 , int boundary2 ) const - { - const PPolynomial< Degree-1 > *b1 , *b2; - if ( boundary1==-1 ) b1 = & dLeftBaseFunction; - else if( boundary1== 0 ) b1 = & dBaseFunction; - else if( boundary1== 1 ) b1 = &dRightBaseFunction; - if ( boundary2==-1 ) b2 = & dLeftBaseFunction; - else if( boundary2== 0 ) b2 = & dBaseFunction; - else if( boundary2== 1 ) b2 = &dRightBaseFunction; - double r=fabs(baseFunction.polys[0].start); - switch( normalize ) - { - case 2: - return Real(((*b1)*b2->scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)/width2/sqrt(width1*width2)); - case 1: - return Real(((*b1)*b2->scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)/width2/(width1*width2)); - default: - return Real(((*b1)*b2->scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)/width2); - } - } -#else // !BOUNDARY_CONDITIONS - template - Real FunctionData::dotProduct(const double& center1,const double& width1,const double& center2,const double& width2) const{ - double r=fabs(baseFunction.polys[0].start); - switch( normalize ) - { - case 2: - return Real((baseFunction*baseFunction.scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)*width1/sqrt(width1*width2)); - case 1: - return Real((baseFunction*baseFunction.scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)*width1/(width1*width2)); - default: - return Real((baseFunction*baseFunction.scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)*width1); - } - } - template - Real FunctionData::dDotProduct(const double& center1,const double& width1,const double& center2,const double& width2) const{ - double r=fabs(baseFunction.polys[0].start); - switch(normalize){ - case 2: - return Real((dBaseFunction*baseFunction.scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)/sqrt(width1*width2)); - case 1: - return Real((dBaseFunction*baseFunction.scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)/(width1*width2)); - default: - return Real((dBaseFunction*baseFunction.scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)); - } - } - template - Real FunctionData::d2DotProduct(const double& center1,const double& width1,const double& center2,const double& width2) const{ - double r=fabs(baseFunction.polys[0].start); - switch(normalize){ - case 2: - return Real((dBaseFunction*dBaseFunction.scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)/width2/sqrt(width1*width2)); - case 1: - return Real((dBaseFunction*dBaseFunction.scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)/width2/(width1*width2)); - default: - return Real((dBaseFunction*dBaseFunction.scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)/width2); - } - } -#endif // BOUNDARY_CONDITIONS - template - inline int FunctionData::SymmetricIndex( const int& i1 , const int& i2 ) - { - if( i1>i2 ) return ((i1*i1+i1)>>1)+i2; - else return ((i2*i2+i2)>>1)+i1; - } - template - inline int FunctionData::SymmetricIndex( const int& i1 , const int& i2 , int& index ) - { - if( i1>1)+i1; - return 1; - } - else{ - index = ((i1*i1+i1)>>1)+i2; - return 0; - } - } - } -} diff --git a/vendor/poisson_surface/geometry.h b/vendor/poisson_surface/geometry.h deleted file mode 100644 index a2978e30b4..0000000000 --- a/vendor/poisson_surface/geometry.h +++ /dev/null @@ -1,333 +0,0 @@ -/* -Copyright (c) 2006, Michael Kazhdan and Matthew Bolitho -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -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. - -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. - -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 -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 -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. -*/ - -#ifndef GEOMETRY_INCLUDED -#define GEOMETRY_INCLUDED - -#if defined __GNUC__ -# pragma GCC system_header -#endif - -#include -#include -#include -#include "hash.h" - -namespace pcl -{ - namespace poisson - { - - template - Real Random(void); - - template< class Real > - struct Point3D - { - Real coords[3]; - Point3D( void ) { coords[0] = coords[1] = coords[2] = Real(0); } - inline Real& operator[] ( int i ) { return coords[i]; } - inline const Real& operator[] ( int i ) const { return coords[i]; } - inline Point3D& operator += ( Point3D p ){ coords[0] += p.coords[0] , coords[1] += p.coords[1] , coords[2] += p.coords[2] ; return *this; } - inline Point3D& operator -= ( Point3D p ){ coords[0] -= p.coords[0] , coords[1] -= p.coords[1] , coords[2] -= p.coords[2] ; return *this; } - inline Point3D& operator *= ( Real r ){ coords[0] *= r , coords[1] *= r , coords[2] *= r ; return *this; } - inline Point3D& operator /= ( Real r ){ coords[0] /= r , coords[1] /= r , coords[2] /= r ; return *this; } - inline Point3D operator + ( Point3D p ) const { Point3D q ; q.coords[0] = coords[0] + p.coords[0] , q.coords[1] = coords[1] + p.coords[1] , q.coords[2] = coords[2] + p.coords[2] ; return q; } - inline Point3D operator - ( Point3D p ) const { Point3D q ; q.coords[0] = coords[0] - p.coords[0] , q.coords[1] = coords[1] - p.coords[1] , q.coords[2] = coords[2] - p.coords[2] ; return q; } - inline Point3D operator * ( Real r ) const { Point3D q ; q.coords[0] = coords[0] * r , q.coords[1] = coords[1] * r , q.coords[2] = coords[2] * r ; return q; } - inline Point3D operator / ( Real r ) const { return (*this) * ( Real(1.)/r ); } - }; - - template - Point3D RandomBallPoint(void); - - template - Point3D RandomSpherePoint(void); - - template - double Length(const Point3D& p); - - template - double SquareLength(const Point3D& p); - - template - double Distance(const Point3D& p1,const Point3D& p2); - - template - double SquareDistance(const Point3D& p1,const Point3D& p2); - - template - void CrossProduct(const Point3D& p1,const Point3D& p2,Point3D& p); - - class Edge - { - public: - double p[2][2]; - double Length(void) const - { - double d[2]; - d[0]=p[0][0]-p[1][0]; - d[1]=p[0][1]-p[1][1]; - - return sqrt(d[0]*d[0]+d[1]*d[1]); - } - }; - class Triangle - { - public: - double p[3][3]; - double Area(void) const - { - double v1[3] , v2[3] , v[3]; - for( int d=0 ; d<3 ; d++ ) - { - v1[d] = p[1][d] - p[0][d]; - v2[d] = p[2][d] - p[0][d]; - } - v[0] = v1[1]*v2[2] - v1[2]*v2[1]; - v[1] = -v1[0]*v2[2] + v1[2]*v2[0]; - v[2] = v1[0]*v2[1] - v1[1]*v2[0]; - return sqrt( v[0]*v[0] + v[1]*v[1] + v[2]*v[2] ) / 2; - } - double AspectRatio(void) const - { - double d=0; - int i,j; - for(i=0;i<3;i++){ - for(i=0;i<3;i++) - for(j=0;j<3;j++){d+=(p[(i+1)%3][j]-p[i][j])*(p[(i+1)%3][j]-p[i][j]);} - } - return Area()/d; - } - - }; - class PCL_EXPORTS CoredPointIndex - { - public: - int index; - char inCore; - - int operator == (const CoredPointIndex& cpi) const {return (index==cpi.index) && (inCore==cpi.inCore);}; - int operator != (const CoredPointIndex& cpi) const {return (index!=cpi.index) || (inCore!=cpi.inCore);}; - }; - class EdgeIndex{ - public: - int idx[2]; - }; - class CoredEdgeIndex{ - public: - CoredPointIndex idx[2]; - }; - class TriangleIndex{ - public: - int idx[3]; - }; - - class TriangulationEdge - { - public: - TriangulationEdge(void); - int pIndex[2]; - int tIndex[2]; - }; - - class TriangulationTriangle - { - public: - TriangulationTriangle(void); - int eIndex[3]; - }; - - template - class Triangulation - { - public: - - std::vector > points; - std::vector edges; - std::vector triangles; - - int factor( int tIndex,int& p1,int& p2,int& p3); - double area(void); - double area( int tIndex ); - double area( int p1 , int p2 , int p3 ); - int flipMinimize( int eIndex); - int addTriangle( int p1 , int p2 , int p3 ); - - protected: - hash_map edgeMap; - static long long EdgeIndex( int p1 , int p2 ); - double area(const Triangle& t); - }; - - - template - void EdgeCollapse(const Real& edgeRatio,std::vector& triangles,std::vector< Point3D >& positions,std::vector >* normals); - template - void TriangleCollapse(const Real& edgeRatio,std::vector& triangles,std::vector >& positions,std::vector >* normals); - - struct CoredVertexIndex - { - int idx; - bool inCore; - }; - class PCL_EXPORTS CoredMeshData - { - public: - std::vector > inCorePoints; - virtual void resetIterator( void ) = 0; - - virtual int addOutOfCorePoint( const Point3D& p ) = 0; - virtual int addPolygon( const std::vector< CoredVertexIndex >& vertices ) = 0; - - virtual int nextOutOfCorePoint( Point3D& p )=0; - virtual int nextPolygon( std::vector< CoredVertexIndex >& vertices ) = 0; - - virtual int outOfCorePointCount(void)=0; - virtual int polygonCount( void ) = 0; - }; - // Stores the iso-span of each vertex, rather than it's position - class PCL_EXPORTS CoredMeshData2 - { - public: - struct Vertex - { - Point3D< float > start , end; - float value; - Vertex( void ) { ; } - Vertex( Point3D< float > s , Point3D< float > e , float v ) { start = s , end = e , value = v; } - Vertex( Point3D< float > s , Point3D< float > e , Point3D< float > p ) - { - start = s , end = e; - // < p , e-s > = < s + v*(e-s) , e-s > - // < p , e-s > - < s , e-s > = v || e-s || ^2 - // v = < p-s , e-s > / || e-s ||^2 - Point3D< float > p1 = p-s , p2 = e-s; - value = ( p1[0] * p2[0] + p1[1] * p2[1] + p1[2] * p2[2] ) / ( p2[0] * p2[0] + p2[1] * p2[1] + p2[2] * p2[2] ); - } - }; - std::vector< Vertex > inCorePoints; - virtual void resetIterator( void ) = 0; - - virtual int addOutOfCorePoint( const Vertex& v ) = 0; - virtual int addPolygon( const std::vector< CoredVertexIndex >& vertices ) = 0; - - virtual int nextOutOfCorePoint( Vertex& v ) = 0; - virtual int nextPolygon( std::vector< CoredVertexIndex >& vertices ) = 0; - - virtual int outOfCorePointCount( void )=0; - virtual int polygonCount( void ) = 0; - }; - - class PCL_EXPORTS CoredVectorMeshData : public CoredMeshData - { - std::vector > oocPoints; - std::vector< std::vector< int > > polygons; - int polygonIndex; - int oocPointIndex; - public: - CoredVectorMeshData(void); - - void resetIterator(void); - - int addOutOfCorePoint( const Point3D& p ); - int addPolygon( const std::vector< CoredVertexIndex >& vertices ); - - int nextOutOfCorePoint( Point3D& p ); - int nextPolygon( std::vector< CoredVertexIndex >& vertices ); - - int outOfCorePointCount(void); - int polygonCount( void ); - }; - class PCL_EXPORTS CoredVectorMeshData2 : public CoredMeshData2 - { - std::vector< CoredMeshData2::Vertex > oocPoints; - std::vector< std::vector< int > > polygons; - int polygonIndex; - int oocPointIndex; - public: - CoredVectorMeshData2( void ); - - void resetIterator(void); - - int addOutOfCorePoint( const CoredMeshData2::Vertex& v ); - int addPolygon( const std::vector< CoredVertexIndex >& vertices ); - - int nextOutOfCorePoint( CoredMeshData2::Vertex& v ); - int nextPolygon( std::vector< CoredVertexIndex >& vertices ); - - int outOfCorePointCount( void ); - int polygonCount( void ); - }; - class CoredFileMeshData : public CoredMeshData - { - FILE *oocPointFile , *polygonFile; - int oocPoints , polygons; - public: - CoredFileMeshData(void); - ~CoredFileMeshData(void); - - void resetIterator(void); - - int addOutOfCorePoint(const Point3D& p); - int addPolygon( const std::vector< CoredVertexIndex >& vertices ); - - int nextOutOfCorePoint(Point3D& p); - int nextPolygon( std::vector< CoredVertexIndex >& vertices ); - - int outOfCorePointCount(void); - int polygonCount( void ); - }; - class CoredFileMeshData2 : public CoredMeshData2 - { - FILE *oocPointFile , *polygonFile; - int oocPoints , polygons; - public: - CoredFileMeshData2( void ); - ~CoredFileMeshData2( void ); - - void resetIterator( void ); - - int addOutOfCorePoint( const CoredMeshData2::Vertex& v ); - int addPolygon( const std::vector< CoredVertexIndex >& vertices ); - - int nextOutOfCorePoint( CoredMeshData2::Vertex& v ); - int nextPolygon( std::vector< CoredVertexIndex >& vertices ); - - int outOfCorePointCount( void ); - int polygonCount( void ); - }; - } -} - -#include "geometry.hpp" - - - - -#endif // GEOMETRY_INCLUDED diff --git a/vendor/poisson_surface/geometry.hpp b/vendor/poisson_surface/geometry.hpp deleted file mode 100644 index dcc9c9c052..0000000000 --- a/vendor/poisson_surface/geometry.hpp +++ /dev/null @@ -1,433 +0,0 @@ -/* -Copyright (c) 2006, Michael Kazhdan and Matthew Bolitho -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -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. - -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. - -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 -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 -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. -*/ - -#include - -namespace pcl -{ - namespace poisson - { - - - template - Real Random(void){return Real(rand())/RAND_MAX;} - - template - Point3D RandomBallPoint(void){ - Point3D p; - while(1){ - p.coords[0]=Real(1.0-2.0*Random()); - p.coords[1]=Real(1.0-2.0*Random()); - p.coords[2]=Real(1.0-2.0*Random()); - double l=SquareLength(p); - if(l<=1){return p;} - } - } - template - Point3D RandomSpherePoint(void){ - Point3D p=RandomBallPoint(); - Real l=Real(Length(p)); - p.coords[0]/=l; - p.coords[1]/=l; - p.coords[2]/=l; - return p; - } - - template - double SquareLength(const Point3D& p){return p.coords[0]*p.coords[0]+p.coords[1]*p.coords[1]+p.coords[2]*p.coords[2];} - - template - double Length(const Point3D& p){return sqrt(SquareLength(p));} - - template - double SquareDistance(const Point3D& p1,const Point3D& p2){ - return (p1.coords[0]-p2.coords[0])*(p1.coords[0]-p2.coords[0])+(p1.coords[1]-p2.coords[1])*(p1.coords[1]-p2.coords[1])+(p1.coords[2]-p2.coords[2])*(p1.coords[2]-p2.coords[2]); - } - - template - double Distance(const Point3D& p1,const Point3D& p2){return sqrt(SquareDistance(p1,p2));} - - template - void CrossProduct(const Point3D& p1,const Point3D& p2,Point3D& p){ - p.coords[0]= p1.coords[1]*p2.coords[2]-p1.coords[2]*p2.coords[1]; - p.coords[1]=-p1.coords[0]*p2.coords[2]+p1.coords[2]*p2.coords[0]; - p.coords[2]= p1.coords[0]*p2.coords[1]-p1.coords[1]*p2.coords[0]; - } - template - void EdgeCollapse(const Real& edgeRatio,std::vector& triangles,std::vector< Point3D >& positions,std::vector< Point3D >* normals){ - int i,j,*remapTable,*pointCount,idx[3]; - Point3D p[3],q[2],c; - double d[3],a; - double Ratio=12.0/sqrt(3.0); // (Sum of Squares Length / Area) for and equilateral triangle - - remapTable=new int[positions.size()]; - pointCount=new int[positions.size()]; - for(i=0;i=0;i--){ - for(j=0;j<3;j++){ - idx[j]=triangles[i].idx[j]; - while(remapTable[idx[j]] a*Ratio){ - // Find the smallest edge - j=0; - if(d[1]=0;i--){ - for(j=0;j<3;j++){ - idx[j]=triangles[i].idx[j]; - while(remapTable[idx[j]] - void TriangleCollapse(const Real& edgeRatio,std::vector& triangles,std::vector< Point3D >& positions,std::vector< Point3D >* normals){ - int i,j,*remapTable,*pointCount,idx[3]; - Point3D p[3],q[2],c; - double d[3],a; - double Ratio=12.0/sqrt(3.0); // (Sum of Squares Length / Area) for and equilateral triangle - - remapTable=new int[positions.size()]; - pointCount=new int[positions.size()]; - for(i=0;i=0;i--){ - for(j=0;j<3;j++){ - idx[j]=triangles[i].idx[j]; - while(remapTable[idx[j]] a*Ratio){ - // Find the smallest edge - j=0; - if(d[1]=0;i--){ - for(j=0;j<3;j++){ - idx[j]=triangles[i].idx[j]; - while(remapTable[idx[j]] - long long Triangulation::EdgeIndex( int p1 , int p2 ) - { - if(p1>p2) {return ((long long)(p1)<<32) | ((long long)(p2));} - else {return ((long long)(p2)<<32) | ((long long)(p1));} - } - - template - int Triangulation::factor(int tIndex,int& p1,int& p2,int & p3){ - if(triangles[tIndex].eIndex[0]<0 || triangles[tIndex].eIndex[1]<0 || triangles[tIndex].eIndex[2]<0){return 0;} - if(edges[triangles[tIndex].eIndex[0]].tIndex[0]==tIndex){p1=edges[triangles[tIndex].eIndex[0]].pIndex[0];} - else {p1=edges[triangles[tIndex].eIndex[0]].pIndex[1];} - if(edges[triangles[tIndex].eIndex[1]].tIndex[0]==tIndex){p2=edges[triangles[tIndex].eIndex[1]].pIndex[0];} - else {p2=edges[triangles[tIndex].eIndex[1]].pIndex[1];} - if(edges[triangles[tIndex].eIndex[2]].tIndex[0]==tIndex){p3=edges[triangles[tIndex].eIndex[2]].pIndex[0];} - else {p3=edges[triangles[tIndex].eIndex[2]].pIndex[1];} - return 1; - } - template - double Triangulation::area(int p1,int p2,int p3){ - Point3D q1,q2,q; - for(int i=0;i<3;i++){ - q1.coords[i]=points[p2].coords[i]-points[p1].coords[i]; - q2.coords[i]=points[p3].coords[i]-points[p1].coords[i]; - } - CrossProduct(q1,q2,q); - return Length(q); - } - template - double Triangulation::area(int tIndex){ - int p1,p2,p3; - factor(tIndex,p1,p2,p3); - return area(p1,p2,p3); - } - template - double Triangulation::area(void){ - double a=0; - for(int i=0;i - int Triangulation::addTriangle(int p1,int p2,int p3){ - hash_map::iterator iter; - int tIdx,eIdx,p[3]; - p[0]=p1; - p[1]=p2; - p[2]=p3; - triangles.push_back(TriangulationTriangle()); - tIdx=int(triangles.size())-1; - - for(int i=0;i<3;i++) - { - long long e = EdgeIndex(p[i],p[(i+1)%3]); - iter=edgeMap.find(e); - if(iter==edgeMap.end()) - { - TriangulationEdge edge; - edge.pIndex[0]=p[i]; - edge.pIndex[1]=p[(i+1)%3]; - edges.push_back(edge); - eIdx=int(edges.size())-1; - edgeMap[e]=eIdx; - edges[eIdx].tIndex[0]=tIdx; - } - else{ - eIdx=edgeMap[e]; - if(edges[eIdx].pIndex[0]==p[i]){ - if(edges[eIdx].tIndex[0]<0){edges[eIdx].tIndex[0]=tIdx;} - else{PCL_DEBUG("Edge Triangle in use 1\n");return 0;} - } - else{ - if(edges[eIdx].tIndex[1]<0){edges[eIdx].tIndex[1]=tIdx;} - else{PCL_DEBUG("Edge Triangle in use 2\n");return 0;} - } - - } - triangles[tIdx].eIndex[i]=eIdx; - } - return tIdx; - } - template - int Triangulation::flipMinimize(int eIndex){ - double oldArea,newArea; - int oldP[3],oldQ[3],newP[3],newQ[3]; - TriangulationEdge newEdge; - - if(edges[eIndex].tIndex[0]<0 || edges[eIndex].tIndex[1]<0){return 0;} - - if(!factor(edges[eIndex].tIndex[0],oldP[0],oldP[1],oldP[2])){return 0;} - if(!factor(edges[eIndex].tIndex[1],oldQ[0],oldQ[1],oldQ[2])){return 0;} - - oldArea=area(oldP[0],oldP[1],oldP[2])+area(oldQ[0],oldQ[1],oldQ[2]); - int idxP,idxQ; - for(idxP=0;idxP<3;idxP++){ - int i; - for(i=0;i<3;i++){if(oldP[idxP]==oldQ[i]){break;}} - if(i==3){break;} - } - for(idxQ=0;idxQ<3;idxQ++){ - int i; - for(i=0;i<3;i++){if(oldP[i]==oldQ[idxQ]){break;}} - if(i==3){break;} - } - if(idxP==3 || idxQ==3){return 0;} - newP[0]=oldP[idxP]; - newP[1]=oldP[(idxP+1)%3]; - newP[2]=oldQ[idxQ]; - newQ[0]=oldQ[idxQ]; - newQ[1]=oldP[(idxP+2)%3]; - newQ[2]=oldP[idxP]; - - newArea=area(newP[0],newP[1],newP[2])+area(newQ[0],newQ[1],newQ[2]); - if(oldArea<=newArea){return 0;} - - // Remove the entry in the hash_table for the old edge - edgeMap.erase(EdgeIndex(edges[eIndex].pIndex[0],edges[eIndex].pIndex[1])); - // Set the new edge so that the zero-side is newQ - edges[eIndex].pIndex[0]=newP[0]; - edges[eIndex].pIndex[1]=newQ[0]; - // Insert the entry into the hash_table for the new edge - edgeMap[EdgeIndex(newP[0],newQ[0])]=eIndex; - // Update the triangle information - for(int i=0;i<3;i++){ - int idx; - idx=edgeMap[EdgeIndex(newQ[i],newQ[(i+1)%3])]; - triangles[edges[eIndex].tIndex[0]].eIndex[i]=idx; - if(idx!=eIndex){ - if(edges[idx].tIndex[0]==edges[eIndex].tIndex[1]){edges[idx].tIndex[0]=edges[eIndex].tIndex[0];} - if(edges[idx].tIndex[1]==edges[eIndex].tIndex[1]){edges[idx].tIndex[1]=edges[eIndex].tIndex[0];} - } - - idx=edgeMap[EdgeIndex(newP[i],newP[(i+1)%3])]; - triangles[edges[eIndex].tIndex[1]].eIndex[i]=idx; - if(idx!=eIndex){ - if(edges[idx].tIndex[0]==edges[eIndex].tIndex[0]){edges[idx].tIndex[0]=edges[eIndex].tIndex[1];} - if(edges[idx].tIndex[1]==edges[eIndex].tIndex[0]){edges[idx].tIndex[1]=edges[eIndex].tIndex[1];} - } - } - return 1; - } - - } -} diff --git a/vendor/poisson_surface/hash.h b/vendor/poisson_surface/hash.h deleted file mode 100644 index a189dceacc..0000000000 --- a/vendor/poisson_surface/hash.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef HASH_INCLUDED -#define HASH_INCLUDED -#if defined _WIN32 && !defined __MINGW32__ -#define _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS -#include -using namespace stdext; -#else // !_WIN32 || __MINGW32__ -#define _GLIBCXX_PERMIT_BACKWARD_HASH -#include -using namespace __gnu_cxx; - - -namespace __gnu_cxx -{ - template<> struct hash { - size_t operator()(long long __x) const { return __x; } - }; - template<> struct hash { - size_t operator()(const long long __x) const { return __x; } - }; - - - template<> struct hash { - size_t operator()(unsigned long long __x) const { return __x; } - }; - template<> struct hash { - size_t operator()(const unsigned long long __x) const { return __x; } - }; -} -#endif // _WIN32 && !__MINGW32__ -#endif // HASH_INCLUDED - diff --git a/vendor/poisson_surface/marching_cubes_poisson.h b/vendor/poisson_surface/marching_cubes_poisson.h deleted file mode 100644 index 26fedac89d..0000000000 --- a/vendor/poisson_surface/marching_cubes_poisson.h +++ /dev/null @@ -1,144 +0,0 @@ -/* -Copyright (c) 2006, Michael Kazhdan and Matthew Bolitho -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -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. - -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. - -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 -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 -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. -*/ - -#ifndef MARCHING_CUBES_INCLUDED -#define MARCHING_CUBES_INCLUDED -#include -#include -#include "geometry.h" - - -namespace pcl -{ - namespace poisson - { - - class PCL_EXPORTS Square - { - public: - enum { CORNERS=4,EDGES=4,NEIGHBORS=4 }; - static int CornerIndex (int x,int y); - static int AntipodalCornerIndex(int idx); - static void FactorCornerIndex (int idx,int& x,int& y); - static int EdgeIndex (int orientation,int i); - static void FactorEdgeIndex (int idx,int& orientation,int& i); - - static int ReflectCornerIndex (int idx,int edgeIndex); - static int ReflectEdgeIndex (int idx,int edgeIndex); - - static void EdgeCorners(int idx,int& c1,int &c2); - }; - - class PCL_EXPORTS Cube - { - public: - enum { CORNERS=8,EDGES=12,NEIGHBORS=6 }; - - static int CornerIndex (int x,int y,int z); - static void FactorCornerIndex (int idx,int& x,int& y,int& z); - static int EdgeIndex (int orientation,int i,int j); - static void FactorEdgeIndex (int idx,int& orientation,int& i,int &j); - static int FaceIndex (int dir,int offSet); - static int FaceIndex (int x,int y,int z); - static void FactorFaceIndex (int idx,int& x,int &y,int& z); - static void FactorFaceIndex (int idx,int& dir,int& offSet); - - static int AntipodalCornerIndex (int idx); - static int FaceReflectCornerIndex (int idx,int faceIndex); - static int FaceReflectEdgeIndex (int idx,int faceIndex); - static int FaceReflectFaceIndex (int idx,int faceIndex); - static int EdgeReflectCornerIndex (int idx,int edgeIndex); - static int EdgeReflectEdgeIndex (int edgeIndex); - - static int FaceAdjacentToEdges (int eIndex1,int eIndex2); - static void FacesAdjacentToEdge (int eIndex,int& f1Index,int& f2Index); - - static void EdgeCorners(int idx,int& c1,int &c2); - static void FaceCorners(int idx,int& c1,int &c2,int& c3,int& c4); - }; - - class PCL_EXPORTS MarchingSquares - { - static double Interpolate(double v1,double v2); - static void SetVertex(int e,const double values[Square::CORNERS],double iso); - public: - enum { MAX_EDGES=2 }; - static const int* edgeMask(); - static int edges(int i, int j); - static double& vertexList(int i, int j); - - static int GetIndex(const double values[Square::CORNERS],double iso); - static int IsAmbiguous(const double v[Square::CORNERS],double isoValue); - static int AddEdges(const double v[Square::CORNERS],double isoValue,Edge* edges); - static int AddEdgeIndices(const double v[Square::CORNERS],double isoValue,int* edges); - }; - - class PCL_EXPORTS MarchingCubes - { - static void SetVertex(int e,const double values[Cube::CORNERS],double iso); - static int GetFaceIndex(const double values[Cube::CORNERS],double iso,int faceIndex); - - static void SetVertex(int e,const float values[Cube::CORNERS],float iso); - static int GetFaceIndex(const float values[Cube::CORNERS],float iso,int faceIndex); - - static int GetFaceIndex(int mcIndex,int faceIndex); - public: - static double Interpolate(double v1,double v2); - static float Interpolate(float v1,float v2); - enum { MAX_TRIANGLES=5 }; - static const int* edgeMask(); - static int triangles(int i, int j); - static const int* cornerMap(); - static double& vertexList(int i, int j); - - static int AddTriangleIndices(int mcIndex,int* triangles); - - static int GetIndex(const double values[Cube::CORNERS],double iso); - static int IsAmbiguous(const double v[Cube::CORNERS],double isoValue,int faceIndex); - static int HasRoots(const double v[Cube::CORNERS],double isoValue); - static int HasRoots(const double v[Cube::CORNERS],double isoValue,int faceIndex); - static int AddTriangles(const double v[Cube::CORNERS],double isoValue,Triangle* triangles); - static int AddTriangleIndices(const double v[Cube::CORNERS],double isoValue,int* triangles); - - static int GetIndex(const float values[Cube::CORNERS],float iso); - static int IsAmbiguous(const float v[Cube::CORNERS],float isoValue,int faceIndex); - static int HasRoots(const float v[Cube::CORNERS],float isoValue); - static int HasRoots(const float v[Cube::CORNERS],float isoValue,int faceIndex); - static int AddTriangles(const float v[Cube::CORNERS],float isoValue,Triangle* triangles); - static int AddTriangleIndices(const float v[Cube::CORNERS],float isoValue,int* triangles); - - static int IsAmbiguous(int mcIndex,int faceIndex); - static int HasRoots(int mcIndex); - static int HasFaceRoots(int mcIndex,int faceIndex); - static int HasEdgeRoots(int mcIndex,int edgeIndex); - }; - } -} - - -#endif //MARCHING_CUBES_INCLUDED diff --git a/vendor/poisson_surface/mat.h b/vendor/poisson_surface/mat.h deleted file mode 100644 index 102482cfe5..0000000000 --- a/vendor/poisson_surface/mat.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -Copyright (c) 2007, Michael Kazhdan -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -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. - -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. - -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 -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 -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. -*/ -#ifndef MAT_INCLUDED -#define MAT_INCLUDED -#include "geometry.h" - - -namespace pcl -{ - namespace poisson - { - - template - class MinimalAreaTriangulation - { - Real* bestTriangulation; - int* midPoint; - Real GetArea(const size_t& i,const size_t& j,const std::vector >& vertices); - void GetTriangulation(const size_t& i,const size_t& j,const std::vector >& vertices,std::vector& triangles); - public: - MinimalAreaTriangulation(void); - ~MinimalAreaTriangulation(void); - Real GetArea(const std::vector >& vertices); - void GetTriangulation(const std::vector >& vertices,std::vector& triangles); - }; - - } -} - -#include "mat.hpp" - - - -#endif // MAT_INCLUDED diff --git a/vendor/poisson_surface/mat.hpp b/vendor/poisson_surface/mat.hpp deleted file mode 100644 index 400d387d9a..0000000000 --- a/vendor/poisson_surface/mat.hpp +++ /dev/null @@ -1,223 +0,0 @@ -/* -Copyright (c) 2007, Michael Kazhdan -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -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. - -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. - -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 -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 -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. -*/ -////////////////////////////// -// MinimalAreaTriangulation // -////////////////////////////// - -namespace pcl -{ - namespace poisson - { - - template - MinimalAreaTriangulation::MinimalAreaTriangulation(void) - { - bestTriangulation=NULL; - midPoint=NULL; - } - template - MinimalAreaTriangulation::~MinimalAreaTriangulation(void) - { - if(bestTriangulation) - delete[] bestTriangulation; - bestTriangulation=NULL; - if(midPoint) - delete[] midPoint; - midPoint=NULL; - } - template - void MinimalAreaTriangulation::GetTriangulation(const std::vector >& vertices,std::vector& triangles) - { - if(vertices.size()==3) - { - triangles.resize(1); - triangles[0].idx[0]=0; - triangles[0].idx[1]=1; - triangles[0].idx[2]=2; - return; - } - else if(vertices.size()==4) - { - TriangleIndex tIndex[2][2]; - Real area[2]; - - area[0]=area[1]=0; - triangles.resize(2); - - tIndex[0][0].idx[0]=0; - tIndex[0][0].idx[1]=1; - tIndex[0][0].idx[2]=2; - tIndex[0][1].idx[0]=2; - tIndex[0][1].idx[1]=3; - tIndex[0][1].idx[2]=0; - - tIndex[1][0].idx[0]=0; - tIndex[1][0].idx[1]=1; - tIndex[1][0].idx[2]=3; - tIndex[1][1].idx[0]=3; - tIndex[1][1].idx[1]=1; - tIndex[1][1].idx[2]=2; - - Point3D n,p1,p2; - for(int i=0;i<2;i++) - for(int j=0;j<2;j++) - { - p1=vertices[tIndex[i][j].idx[1]]-vertices[tIndex[i][j].idx[0]]; - p2=vertices[tIndex[i][j].idx[2]]-vertices[tIndex[i][j].idx[0]]; - CrossProduct(p1,p2,n); - area[i] += Real( Length(n) ); - } - if(area[0]>area[1]) - { - triangles[0]=tIndex[1][0]; - triangles[1]=tIndex[1][1]; - } - else - { - triangles[0]=tIndex[0][0]; - triangles[1]=tIndex[0][1]; - } - return; - } - if(bestTriangulation) - delete[] bestTriangulation; - if(midPoint) - delete[] midPoint; - bestTriangulation=NULL; - midPoint=NULL; - size_t eCount=vertices.size(); - bestTriangulation=new Real[eCount*eCount]; - midPoint=new int[eCount*eCount]; - for(size_t i=0;i - Real MinimalAreaTriangulation::GetArea(const std::vector >& vertices) - { - if(bestTriangulation) - delete[] bestTriangulation; - if(midPoint) - delete[] midPoint; - bestTriangulation=NULL; - midPoint=NULL; - int eCount=vertices.size(); - bestTriangulation=new double[eCount*eCount]; - midPoint=new int[eCount*eCount]; - for(int i=0;i - void MinimalAreaTriangulation::GetTriangulation(const size_t& i,const size_t& j,const std::vector >& vertices,std::vector& triangles) - { - TriangleIndex tIndex; - size_t eCount=vertices.size(); - size_t ii=i; - if(i=ii) - return; - ii=midPoint[i*eCount+j]; - if(ii>=0) - { - tIndex.idx[0] = int( i ); - tIndex.idx[1] = int( j ); - tIndex.idx[2] = int( ii ); - triangles.push_back(tIndex); - GetTriangulation(i,ii,vertices,triangles); - GetTriangulation(ii,j,vertices,triangles); - } - } - - template - Real MinimalAreaTriangulation::GetArea(const size_t& i,const size_t& j,const std::vector >& vertices) - { - Real a=FLT_MAX,temp; - size_t eCount=vertices.size(); - size_t idx=i*eCount+j; - size_t ii=i; - if(i=ii) - { - bestTriangulation[idx]=0; - return 0; - } - if(midPoint[idx]!=-1) - return bestTriangulation[idx]; - int mid=-1; - for(size_t r=j+1;r p,p1,p2; - p1=vertices[i]-vertices[rr]; - p2=vertices[j]-vertices[rr]; - CrossProduct(p1,p2,p); - temp = Real( Length(p) ); - if(bestTriangulation[idx1]>=0) - { - temp+=bestTriangulation[idx1]; - if(temp>a) - continue; - if(bestTriangulation[idx2]>0) - temp+=bestTriangulation[idx2]; - else - temp+=GetArea(rr,j,vertices); - } - else - { - if(bestTriangulation[idx2]>=0) - temp+=bestTriangulation[idx2]; - else - temp+=GetArea(rr,j,vertices); - if(temp>a) - continue; - temp+=GetArea(i,rr,vertices); - } - - if(temp -// b_1[i] = < \nabla B_i(p) , V(p) > -// 2] Formulate this as a Poisson equation: -// \sum_i x_i \Delta B_i(p) = \nabla \cdot V(p) -// which is solved by the system A_2x = b_2 where: -// A_2[i,j] = - < \Delta B_i(p) , B_j(p) > -// b_2[i] = - < B_i(p) , \nabla \cdot V(p) > -// Although the two system matrices should be the same (assuming that the B_i satisfy dirichlet/neumann boundary conditions) -// the constraint vectors can differ when V does not satisfy the Neumann boundary conditions: -// A_1[i,j] = \int_R < \nabla B_i(p) , \nabla B_j(p) > -// = \int_R [ \nabla \cdot ( B_i(p) \nabla B_j(p) ) - B_i(p) \Delta B_j(p) ] -// = \int_dR < N(p) , B_i(p) \nabla B_j(p) > + A_2[i,j] -// and the first integral is zero if either f_i is zero on the boundary dR or the derivative of B_i across the boundary is zero. -// However, for the constraints we have: -// b_1(i) = \int_R < \nabla B_i(p) , V(p) > -// = \int_R [ \nabla \cdot ( B_i(p) V(p) ) - B_i(p) \nabla \cdot V(p) ] -// = \int_dR < N(p) , B_i(p) V(p) > + b_2[i] -// In particular, this implies that if the B_i satisfy the Neumann boundary conditions (rather than Dirichlet), -// and V is not zero across the boundary, then the two constraints are different. -// Forcing the < V(p) , N(p) > = 0 on the boundary, by killing off the component of the vector-field in the normal direction -// (FORCE_NEUMANN_FIELD), makes the two systems equal, and the value of this flag should be immaterial. -// Note that under interpretation 1, we have: -// \sum_i b_1(i) = < \nabla \sum_ i B_i(p) , V(p) > = 0 -// because the B_i's sum to one. However, in general, we could have -// \sum_i b_2(i) \neq 0. -// This could cause trouble because the constant functions are in the kernel of the matrix A, so CG will misbehave if the constraint -// has a non-zero DC term. (Again, forcing < V(p) , N(p) > = 0 along the boundary resolves this problem.) - -#define FORCE_NEUMANN_FIELD 1 // This flag forces the normal component across the boundary of the integration domain to be zero. -// This should be enabled if GRADIENT_DOMAIN_SOLUTION is not, so that CG doesn't run into trouble. - - -#include "hash.h" -#include "bspline_data.h" - - - -namespace pcl -{ - namespace poisson - { - - typedef float Real; - typedef float BSplineDataReal; - typedef pcl::poisson::OctNode< class TreeNodeData , Real > TreeOctNode; - - - - class RootInfo - { - public: - const TreeOctNode* node; - int edgeIndex; - long long key; - }; - - class VertexData - { - public: - static long long EdgeIndex( const TreeOctNode* node , int eIndex , int maxDepth , int index[DIMENSION] ); - static long long EdgeIndex( const TreeOctNode* node , int eIndex , int maxDepth ); - static long long FaceIndex( const TreeOctNode* node , int fIndex , int maxDepth,int index[DIMENSION] ); - static long long FaceIndex( const TreeOctNode* node , int fIndex , int maxDepth ); - static long long CornerIndex( int depth , const int offSet[DIMENSION] , int cIndex , int maxDepth , int index[DIMENSION] ); - static long long CornerIndex( const TreeOctNode* node , int cIndex , int maxDepth , int index[DIMENSION] ); - static long long CornerIndex( const TreeOctNode* node , int cIndex , int maxDepth ); - static long long CenterIndex( int depth , const int offSet[DIMENSION] , int maxDepth , int index[DIMENSION] ); - static long long CenterIndex( const TreeOctNode* node , int maxDepth , int index[DIMENSION] ); - static long long CenterIndex( const TreeOctNode* node , int maxDepth ); - static long long CornerIndexKey( const int index[DIMENSION] ); - }; - class SortedTreeNodes - { - public: - TreeOctNode** treeNodes; - int *nodeCount; - int maxDepth; - SortedTreeNodes( void ); - ~SortedTreeNodes( void ); - void set( TreeOctNode& root ); - struct CornerIndices - { - int idx[pcl::poisson::Cube::CORNERS]; - CornerIndices( void ) { memset( idx , -1 , sizeof( int ) * pcl::poisson::Cube::CORNERS ); } - int& operator[] ( int i ) { return idx[i]; } - const int& operator[] ( int i ) const { return idx[i]; } - }; - struct CornerTableData - { - CornerTableData( void ) { cCount=0; } - ~CornerTableData( void ) { clear(); } - void clear( void ) { cTable.clear() ; cCount = 0; } - CornerIndices& operator[] ( const TreeOctNode* node ); - const CornerIndices& operator[] ( const TreeOctNode* node ) const; - CornerIndices& cornerIndices( const TreeOctNode* node ); - const CornerIndices& cornerIndices( const TreeOctNode* node ) const; - int cCount; - std::vector< CornerIndices > cTable; - std::vector< int > offsets; - }; - void setCornerTable( CornerTableData& cData , const TreeOctNode* rootNode , int depth , int threads ) const; - void setCornerTable( CornerTableData& cData , const TreeOctNode* rootNode , int threads ) const { setCornerTable( cData , rootNode , maxDepth-1 , threads ); } - void setCornerTable( CornerTableData& cData , int threads ) const { setCornerTable( cData , treeNodes[0] , maxDepth-1 , threads ); } - int getMaxCornerCount( const TreeOctNode* rootNode , int depth , int maxDepth , int threads ) const ; - struct EdgeIndices - { - int idx[pcl::poisson::Cube::EDGES]; - EdgeIndices( void ) { memset( idx , -1 , sizeof( int ) * pcl::poisson::Cube::EDGES ); } - int& operator[] ( int i ) { return idx[i]; } - const int& operator[] ( int i ) const { return idx[i]; } - }; - struct EdgeTableData - { - EdgeTableData( void ) { eCount=0; } - ~EdgeTableData( void ) { clear(); } - void clear( void ) { eTable.clear() , eCount=0; } - EdgeIndices& operator[] ( const TreeOctNode* node ); - const EdgeIndices& operator[] ( const TreeOctNode* node ) const; - EdgeIndices& edgeIndices( const TreeOctNode* node ); - const EdgeIndices& edgeIndices( const TreeOctNode* node ) const; - int eCount; - std::vector< EdgeIndices > eTable; - std::vector< int > offsets; - }; - void setEdgeTable( EdgeTableData& eData , const TreeOctNode* rootNode , int depth , int threads ); - void setEdgeTable( EdgeTableData& eData , const TreeOctNode* rootNode , int threads ) { setEdgeTable( eData , rootNode , maxDepth-1 , threads ); } - void setEdgeTable( EdgeTableData& eData , int threads ) { setEdgeTable( eData , treeNodes[0] , maxDepth-1 , threads ); } - int getMaxEdgeCount( const TreeOctNode* rootNode , int depth , int threads ) const ; - }; - - class TreeNodeData - { - public: - static int UseIndex; - int nodeIndex; - union - { - int mcIndex; - struct - { - Real centerWeightContribution; - int normalIndex; - }; - }; - Real constraint , solution; - int pointIndex; - - TreeNodeData(void); - ~TreeNodeData(void); - }; - - template< int Degree > - class Octree - { - SortedTreeNodes _sNodes; - int _minDepth; - bool _constrainValues; - std::vector< int > _pointCount; - struct PointData - { - pcl::poisson::Point3D< Real > position; - Real weight; - Real value; - PointData( pcl::poisson::Point3D< Real > p , Real w , Real v=0 ) { position = p , weight = w , value = v; } - }; - std::vector< PointData > _points; - TreeOctNode::NeighborKey3 neighborKey; - TreeOctNode::ConstNeighborKey3 neighborKey2; - - Real radius; - int width; - Real GetLaplacian( const int index[DIMENSION] ) const; - // Note that this is a slight misnomer. We're only taking the diveregence/Laplacian in the weak sense, so there is a change of sign. - Real GetLaplacian( const TreeOctNode* node1 , const TreeOctNode* node2 ) const; - Real GetDivergence( const TreeOctNode* node1 , const TreeOctNode* node2 , const pcl::poisson::Point3D& normal1 ) const; - Real GetDivergenceMinusLaplacian( const TreeOctNode* node1 , const TreeOctNode* node2 , Real value1 , const pcl::poisson::Point3D& normal1 ) const; - struct PointInfo - { - float splineValues[3][3]; - float weightedValue; - }; - Real GetValue( const PointInfo points[3][3][3] , const bool hasPoints[3][3] , const int d[3] ) const; - - class AdjacencyCountFunction - { - public: - int adjacencyCount; - void Function(const TreeOctNode* node1,const TreeOctNode* node2); - }; - class AdjacencySetFunction{ - public: - int *adjacencies,adjacencyCount; - void Function(const TreeOctNode* node1,const TreeOctNode* node2); - }; - - class RefineFunction{ - public: - int depth; - void Function(TreeOctNode* node1,const TreeOctNode* node2); - }; - class FaceEdgesFunction - { - public: - int fIndex , maxDepth; - std::vector< std::pair< RootInfo , RootInfo > >* edges; - hash_map< long long , std::pair< RootInfo , int > >* vertexCount; - void Function( const TreeOctNode* node1 , const TreeOctNode* node2 ); - }; - - int SolveFixedDepthMatrix( int depth , const SortedTreeNodes& sNodes , Real* subConstraints , bool showResidual , int minIters , double accuracy ); - int SolveFixedDepthMatrix( int depth , const SortedTreeNodes& sNodes , Real* subConstraints , int startingDepth , bool showResidual , int minIters , double accuracy ); - - void SetMatrixRowBounds( const TreeOctNode* node , int rDepth , const int rOff[3] , int& xStart , int& xEnd , int& yStart , int& yEnd , int& zStart , int& zEnd ) const; - int GetMatrixRowSize( const TreeOctNode::Neighbors5& neighbors5 ) const; - int GetMatrixRowSize( const TreeOctNode::Neighbors5& neighbors5 , int xStart , int xEnd , int yStart , int yEnd , int zStart , int zEnd ) const; - int SetMatrixRow( const TreeOctNode::Neighbors5& neighbors5 , pcl::poisson::MatrixEntry< float >* row , int offset , const double stencil[5][5][5] ) const; - int SetMatrixRow( const TreeOctNode::Neighbors5& neighbors5 , pcl::poisson::MatrixEntry< float >* row , int offset , const double stencil[5][5][5] , int xStart , int xEnd , int yStart , int yEnd , int zStart , int zEnd ) const; - void SetDivergenceStencil( int depth , pcl::poisson::Point3D< double > *stencil , bool scatter ) const; - void SetLaplacianStencil( int depth , double stencil[5][5][5] ) const; - template< class C , int N > struct Stencil{ C values[N][N][N]; }; - void SetLaplacianStencils( int depth , Stencil< double , 5 > stencil[2][2][2] ) const; - void SetDivergenceStencils( int depth , Stencil< pcl::poisson::Point3D< double > , 5 > stencil[2][2][2] , bool scatter ) const; - void SetEvaluationStencils( int depth , Stencil< double , 3 > stencil1[8] , Stencil< double , 3 > stencil2[8][8] ) const; - - static void UpdateCoarserSupportBounds( const TreeOctNode* node , int& startX , int& endX , int& startY , int& endY , int& startZ , int& endZ ); - void UpdateConstraintsFromCoarser( const TreeOctNode::NeighborKey5& neighborKey5 , TreeOctNode* node , Real* metSolution , const Stencil< double , 5 >& stencil ) const; - void SetCoarserPointValues( int depth , const SortedTreeNodes& sNodes , Real* metSolution ); - Real WeightedCoarserFunctionValue( const TreeOctNode::NeighborKey3& neighborKey3 , const TreeOctNode* node , Real* metSolution ) const; - void UpSampleCoarserSolution( int depth , const SortedTreeNodes& sNodes , pcl::poisson::Vector< Real >& solution ) const; - void DownSampleFinerConstraints( int depth , SortedTreeNodes& sNodes ) const; - template< class C > void DownSample( int depth , const SortedTreeNodes& sNodes , C* constraints ) const; - template< class C > void UpSample( int depth , const SortedTreeNodes& sNodes , C* coefficients ) const; - int GetFixedDepthLaplacian( pcl::poisson::SparseSymmetricMatrix& matrix , int depth , const SortedTreeNodes& sNodes , Real* subConstraints ); - int GetRestrictedFixedDepthLaplacian( pcl::poisson::SparseSymmetricMatrix& matrix , int depth , const int* entries , int entryCount , const TreeOctNode* rNode, Real radius , const SortedTreeNodes& sNodes , Real* subConstraints ); - - void SetIsoCorners( Real isoValue , TreeOctNode* leaf , SortedTreeNodes::CornerTableData& cData , char* valuesSet , Real* values , TreeOctNode::ConstNeighborKey3& nKey , const Real* metSolution , const Stencil< double , 3 > stencil1[8] , const Stencil< double , 3 > stencil2[8][8] ); - static int IsBoundaryFace( const TreeOctNode* node , int faceIndex , int subdivideDepth ); - static int IsBoundaryEdge( const TreeOctNode* node , int edgeIndex , int subdivideDepth ); - static int IsBoundaryEdge( const TreeOctNode* node , int dir , int x , int y , int subidivideDepth ); - - // For computing the iso-surface there is a lot of re-computation of information across shared geometry. - // For function values we don't care so much. - // For edges we need to be careful so that the mesh remains water-tight - struct RootData : public SortedTreeNodes::CornerTableData , public SortedTreeNodes::EdgeTableData - { - // Edge to iso-vertex map - hash_map< long long , int > boundaryRoots; - // Vertex to ( value , normal ) map - hash_map< long long , std::pair< Real , pcl::poisson::Point3D< Real > > > *boundaryValues; - int* interiorRoots; - Real *cornerValues; - pcl::poisson::Point3D< Real >* cornerNormals; - char *cornerValuesSet , *cornerNormalsSet , *edgesSet; - }; - - int SetBoundaryMCRootPositions( int sDepth , Real isoValue , RootData& rootData , pcl::poisson::CoredMeshData* mesh , int nonLinearFit ); - int SetMCRootPositions( TreeOctNode* node , int sDepth , Real isoValue , TreeOctNode::ConstNeighborKey5& neighborKey5 , RootData& rootData , - std::vector< pcl::poisson::Point3D< float > >* interiorPositions , pcl::poisson::CoredMeshData* mesh , const Real* metSolution , int nonLinearFit ); -#if MISHA_DEBUG - int GetMCIsoTriangles( TreeOctNode* node , pcl::poisson::CoredMeshData* mesh , RootData& rootData , - std::vector< pcl::poisson::Point3D< float > >* interiorPositions , int offSet , int sDepth , bool polygonMesh , std::vector< pcl::poisson::Point3D< float > >* barycenters ); - static int AddTriangles( pcl::poisson::CoredMeshData* mesh , std::vector& edges , std::vector >* interiorPositions , int offSet , bool polygonMesh , std::vector< pcl::poisson::Point3D< float > >* barycenters ); -#else // !MISHA_DEBUG - int GetMCIsoTriangles( TreeOctNode* node , pcl::poisson::CoredMeshData* mesh , RootData& rootData , - std::vector< pcl::poisson::Point3D< float > >* interiorPositions , int offSet , int sDepth , bool addBarycenter , bool polygonMesh ); - static int AddTriangles( pcl::poisson::CoredMeshData* mesh , std::vector& edges , std::vector >* interiorPositions , int offSet , bool addBarycenter , bool polygonMesh ); -#endif // MISHA_DEBUG - - - void GetMCIsoEdges( TreeOctNode* node , int sDepth , std::vector< std::pair< RootInfo , RootInfo > >& edges ); - static int GetEdgeLoops( std::vector< std::pair< RootInfo , RootInfo > >& edges , std::vector< std::vector< std::pair< RootInfo , RootInfo > > >& loops); - static int InteriorFaceRootCount( const TreeOctNode* node , const int &faceIndex , int maxDepth ); - static int EdgeRootCount( const TreeOctNode* node , int edgeIndex , int maxDepth ); - static void GetRootSpan( const RootInfo& ri , pcl::poisson::Point3D< float >& start , pcl::poisson::Point3D< float >& end ); - int GetRoot( const RootInfo& ri , Real isoValue , TreeOctNode::ConstNeighborKey5& neighborKey5 , pcl::poisson::Point3D & position , RootData& rootData , int sDepth , const Real* metSolution , int nonLinearFit ); - static int GetRootIndex( const TreeOctNode* node , int edgeIndex , int maxDepth , RootInfo& ri ); - static int GetRootIndex( const TreeOctNode* node , int edgeIndex , int maxDepth , int sDepth , RootInfo& ri ); - static int GetRootIndex( const RootInfo& ri , RootData& rootData , pcl::poisson::CoredPointIndex& index ); - static int GetRootPair( const RootInfo& root , int maxDepth , RootInfo& pair ); - - int NonLinearUpdateWeightContribution(TreeOctNode* node,const pcl::poisson::Point3D& position,Real weight=Real(1.0)); - Real NonLinearGetSampleWeight(TreeOctNode* node,const pcl::poisson::Point3D& position); - void NonLinearGetSampleDepthAndWeight(TreeOctNode* node,const pcl::poisson::Point3D& position,Real samplesPerNode,Real& depth,Real& weight); - int NonLinearSplatOrientedPoint(TreeOctNode* node,const pcl::poisson::Point3D& point,const pcl::poisson::Point3D& normal); - Real NonLinearSplatOrientedPoint(const pcl::poisson::Point3D& point,const pcl::poisson::Point3D& normal , int kernelDepth , Real samplesPerNode , int minDepth , int maxDepth); - - int HasNormals(TreeOctNode* node,Real epsilon); - Real getCornerValue( const TreeOctNode::ConstNeighborKey3& neighborKey3 , const TreeOctNode* node , int corner , const Real* metSolution ); - pcl::poisson::Point3D< Real > getCornerNormal( const TreeOctNode::ConstNeighborKey5& neighborKey5 , const TreeOctNode* node , int corner , const Real* metSolution ); - Real getCornerValue( const TreeOctNode::ConstNeighborKey3& neighborKey3 , const TreeOctNode* node , int corner , const Real* metSolution , const double stencil1[3][3][3] , const double stencil2[3][3][3] ); - Real getCenterValue( const TreeOctNode::ConstNeighborKey3& neighborKey3 , const TreeOctNode* node ); - public: - int threads; - static double maxMemoryUsage; - static double MemoryUsage( void ); - std::vector< pcl::poisson::Point3D >* normals; - Real postNormalSmooth; - TreeOctNode tree; - pcl::poisson::BSplineData fData; - Octree( void ); - - void setBSplineData( int maxDepth , Real normalSmooth=-1 , bool reflectBoundary=false ); - void finalize( void ); - void RefineBoundary( int subdivisionDepth ); - Real* GetWeightGrid( int& res , int depth=-1 ); - Real* GetSolutionGrid( int& res , float isoValue=0.f , int depth=-1 ); - - template int - setTree( boost::shared_ptr > input_ , int maxDepth , int minDepth , - int kernelDepth , Real samplesPerNode , Real scaleFactor , Point3D& center , Real& scale , - int useConfidence , Real constraintWeight , bool adaptiveWeights ); - - void SetLaplacianConstraints(void); - void ClipTree(void); - int LaplacianMatrixIteration( int subdivideDepth , bool showResidual , int minIters , double accuracy ); - - Real GetIsoValue(void); - void GetMCIsoTriangles( Real isoValue , int subdivideDepth , pcl::poisson::CoredMeshData* mesh , int fullDepthIso=0 , int nonLinearFit=1 , bool addBarycenter=false , bool polygonMesh=false ); - }; - - - } -} - - - - -#include "multi_grid_octree_data.hpp" -#endif // MULTI_GRID_OCTREE_DATA_INCLUDED diff --git a/vendor/poisson_surface/multi_grid_octree_data.hpp b/vendor/poisson_surface/multi_grid_octree_data.hpp deleted file mode 100644 index 7cfe20c1de..0000000000 --- a/vendor/poisson_surface/multi_grid_octree_data.hpp +++ /dev/null @@ -1,3918 +0,0 @@ -/* -Copyright (c) 2006, Michael Kazhdan and Matthew Bolitho -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -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. - -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. - -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 -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 -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. -*/ - -#include "octree_poisson.h" -#include "mat.h" - -#if defined WIN32 || defined _WIN32 - #if !defined __MINGW32__ - #include - #include - #endif -#endif - - -#define ITERATION_POWER 1.0/3 -#define MEMORY_ALLOCATOR_BLOCK_SIZE 1<<12 -#define SPLAT_ORDER 2 - -#ifndef _MSC_VER -namespace std -{ - using namespace __gnu_cxx; -} -#endif - -namespace pcl -{ - namespace poisson - { - - const Real MATRIX_ENTRY_EPSILON = Real(0); - const Real EPSILON=Real(1e-6); - const Real ROUND_EPS=Real(1e-5); - -#if defined _WIN32 && !defined __MINGW32__ - using stdext::hash_map; -#else - using std::hash_map; -#endif - - - void atomicOr(volatile int& dest, int value) - { -#if defined _WIN32 && !defined __MINGW32__ - #if defined (_M_IX86) - _InterlockedOr( (long volatile*)&dest, value ); - #else - InterlockedOr( (long volatile*)&dest , value ); - #endif -#else // !_WIN32 || __MINGW32__ - #pragma omp atomic - dest |= value; -#endif // _WIN32 && !__MINGW32__ - } - - - ///////////////////// - // SortedTreeNodes // - ///////////////////// - SortedTreeNodes::SortedTreeNodes(void) - { - nodeCount=NULL; - treeNodes=NULL; - maxDepth=0; - } - SortedTreeNodes::~SortedTreeNodes(void){ - if( nodeCount ) delete[] nodeCount; - if( treeNodes ) delete[] treeNodes; - nodeCount = NULL; - treeNodes = NULL; - } - - void SortedTreeNodes::set( TreeOctNode& root ) - { - if( nodeCount ) delete[] nodeCount; - if( treeNodes ) delete[] treeNodes; - maxDepth = root.maxDepth()+1; - nodeCount = new int[ maxDepth+1 ]; - treeNodes = new TreeOctNode*[ root.nodes() ]; - - nodeCount[0] = 0 , nodeCount[1] = 1; - treeNodes[0] = &root; - for( int d=1 ; dchildren ) for( int c=0 ; c<8 ; c++ ) treeNodes[ nodeCount[d+1]++ ] = temp->children + c; - } - } - for( int i=0 ; inodeData.nodeIndex = i; - } - SortedTreeNodes::CornerIndices& SortedTreeNodes::CornerTableData::operator[] ( const TreeOctNode* node ) { return cTable[ node->nodeData.nodeIndex + offsets[node->d] ]; } - const SortedTreeNodes::CornerIndices& SortedTreeNodes::CornerTableData::operator[] ( const TreeOctNode* node ) const { return cTable[ node->nodeData.nodeIndex + offsets[node->d] ]; } - SortedTreeNodes::CornerIndices& SortedTreeNodes::CornerTableData::cornerIndices( const TreeOctNode* node ) { return cTable[ node->nodeData.nodeIndex + offsets[node->d] ]; } - const SortedTreeNodes::CornerIndices& SortedTreeNodes::CornerTableData::cornerIndices( const TreeOctNode* node ) const { return cTable[ node->nodeData.nodeIndex + offsets[node->d] ]; } - void SortedTreeNodes::setCornerTable( CornerTableData& cData , const TreeOctNode* rootNode , int maxDepth , int threads ) const - { - if( threads<=0 ) threads = 1; - // The vector of per-depth node spans - std::vector< std::pair< int , int > > spans( this->maxDepth , std::pair< int , int >( -1 , -1 ) ); - int minDepth , off[3]; - rootNode->depthAndOffset( minDepth , off ); - cData.offsets.resize( this->maxDepth , -1 ); - int nodeCount = 0; - { - int start=rootNode->nodeData.nodeIndex , end=start; - for( int d=minDepth ; d<=maxDepth ; d++ ) - { - spans[d] = std::pair< int , int >( start , end+1 ); - cData.offsets[d] = nodeCount - spans[d].first; - nodeCount += spans[d].second - spans[d].first; - if( dchildren ) start++; - while( end> start && !treeNodes[end ]->children ) end--; - if( start==end && !treeNodes[start]->children ) break; - start = treeNodes[start]->children[0].nodeData.nodeIndex; - end = treeNodes[end ]->children[7].nodeData.nodeIndex; - } - } - } - cData.cTable.resize( nodeCount ); - std::vector< int > count( threads ); -#pragma omp parallel for num_threads( threads ) - for( int t=0 ; tchildren ) continue; - const TreeOctNode::ConstNeighbors3& neighbors = neighborKey.getNeighbors( node , minDepth ); - for( int c=0 ; cchildren ) ) - { - int _d , _off[3]; - neighbors.neighbors[xx][yy][zz]->depthAndOffset( _d , _off ); - _off[0] >>= (d-minDepth) , _off[1] >>= (d-minDepth) , _off[2] >>= (d-minDepth); - if( _off[0]==off[0] && _off[1]==off[1] && _off[2]==off[2] ) - { - cornerOwner = false; - break; - } - else fprintf( stderr , "[WARNING] How did we leave the subtree?\n" ); - } - } - if( cornerOwner ) - { - const TreeOctNode* n = node; - int d = n->depth(); - do - { - const TreeOctNode::ConstNeighbors3& neighbors = neighborKey.neighbors[d]; - // Set all the corner indices at the current depth - for( int cc=0 ; ccparent->children+c) ) break; - n = n->parent; - d--; - } - while( 1 ); - count[t]++; - } - } - } - } - } - cData.cCount = 0; - std::vector< int > offsets( threads+1 ); - offsets[0] = 0; - for( int t=0 ; tnodeData.nodeIndex , c , idx , minDepth , maxDepth ); - int _d , _off[3]; - treeNodes[i]->depthAndOffset( _d , _off ); - printf( "(%d [%d %d %d) <-> (%d [%d %d %d])\n" , minDepth , off[0] , off[1] , off[2] , _d , _off[0] , _off[1] , _off[2] ); - printf( "[%d %d]\n" , spans[d].first , spans[d].second ); - exit( 0 ); - } - else - { - int div = idx / ( nodeCount*Cube::CORNERS ); - int rem = idx % ( nodeCount*Cube::CORNERS ); - idx = rem + offsets[div]; - } - } - } - } - int SortedTreeNodes::getMaxCornerCount( const TreeOctNode* rootNode , int depth , int maxDepth , int threads ) const - { - if( threads<=0 ) threads = 1; - int res = 1< > cornerCount( threads ); - for( int t=0 ; t& _cornerCount = cornerCount[t]; - TreeOctNode::ConstNeighborKey3 neighborKey; - neighborKey.set( maxDepth ); - int start = nodeCount[depth] , end = nodeCount[maxDepth+1] , range = end-start; - for( int i=(range*t)/threads ; i<(range*(t+1))/threads ; i++ ) - { - TreeOctNode* node = treeNodes[start+i]; - int d , off[3]; - node->depthAndOffset( d , off ); - if( dchildren ) continue; - - const TreeOctNode::ConstNeighbors3& neighbors = neighborKey.getNeighbors( node , depth ); - for( int c=0 ; cchildren ) ) - { - cornerOwner = false; - break; - } - } - if( cornerOwner ) _cornerCount[ ( ( off[0]>>(d-depth) ) * res * res) + ( ( off[1]>>(d-depth) ) * res) + ( off[2]>>(d-depth) ) ]++; - } - } - } - int maxCount = 0; - for( int i=0 ; i( maxCount , c ); - } - return maxCount; - } - SortedTreeNodes::EdgeIndices& SortedTreeNodes::EdgeTableData::operator[] ( const TreeOctNode* node ) { return eTable[ node->nodeData.nodeIndex + offsets[node->d] ]; } - const SortedTreeNodes::EdgeIndices& SortedTreeNodes::EdgeTableData::operator[] ( const TreeOctNode* node ) const { return eTable[ node->nodeData.nodeIndex + offsets[node->d] ]; } - SortedTreeNodes::EdgeIndices& SortedTreeNodes::EdgeTableData::edgeIndices( const TreeOctNode* node ) { return eTable[ node->nodeData.nodeIndex + offsets[node->d] ]; } - const SortedTreeNodes::EdgeIndices& SortedTreeNodes::EdgeTableData::edgeIndices( const TreeOctNode* node ) const { return eTable[ node->nodeData.nodeIndex + offsets[node->d] ]; } - void SortedTreeNodes::setEdgeTable( EdgeTableData& eData , const TreeOctNode* rootNode , int maxDepth , int threads ) - { - if( threads<=0 ) threads = 1; - std::vector< std::pair< int , int > > spans( this->maxDepth , std::pair< int , int >( -1 , -1 ) ); - - int minDepth , off[3]; - rootNode->depthAndOffset( minDepth , off ); - eData.offsets.resize( this->maxDepth , -1 ); - int nodeCount = 0; - { - int start=rootNode->nodeData.nodeIndex , end=start; - for( int d=minDepth ; d<=maxDepth ; d++ ) - { - spans[d] = std::pair< int , int >( start , end+1 ); - eData.offsets[d] = nodeCount - spans[d].first; - nodeCount += spans[d].second - spans[d].first; - if( dchildren ) start++; - while( end> start && !treeNodes[end ]->children ) end--; - if( start==end && !treeNodes[start]->children ) break; - start = treeNodes[start]->children[0].nodeData.nodeIndex; - end = treeNodes[end ]->children[7].nodeData.nodeIndex; - } - } - } - eData.eTable.resize( nodeCount ); - std::vector< int > count( threads ); -#pragma omp parallel for num_threads( threads ) - for( int t=0 ; t offsets( threads+1 ); - offsets[0] = 0; - for( int t=0 ; t > edgeCount( threads ); - for( int t=0 ; t& _edgeCount = edgeCount[t]; - TreeOctNode::ConstNeighborKey3 neighborKey; - neighborKey.set( maxDepth-1 ); - int start = nodeCount[depth] , end = nodeCount[maxDepth] , range = end-start; - for( int i=(range*t)/threads ; i<(range*(t+1))/threads ; i++ ) - { - TreeOctNode* node = treeNodes[start+i]; - const TreeOctNode::ConstNeighbors3& neighbors = neighborKey.getNeighbors( node , depth ); - int d , off[3]; - node->depthAndOffset( d , off ); - - for( int e=0 ; e>(d-depth) ) * res * res) + ( ( off[1]>>(d-depth) ) * res) + ( off[2]>>(d-depth) ) ]++; - } - } - } - int maxCount = 0; - for( int i=0 ; i( maxCount , c ); - } - return maxCount; - } - - - - ////////////////// - // TreeNodeData // - ////////////////// - int TreeNodeData::UseIndex=1; - TreeNodeData::TreeNodeData( void ) - { - if( UseIndex ) - { - nodeIndex = -1; - centerWeightContribution=0; - } - else mcIndex=0; - normalIndex = -1; - constraint = solution = 0; - pointIndex = -1; - } - TreeNodeData::~TreeNodeData( void ) { } - - - //////////// - // Octree // - //////////// - template - double Octree::maxMemoryUsage=0; - - - - template - double Octree::MemoryUsage(void){ - double mem = 0;//double( MemoryInfo::Usage() ) / (1<<20); - if(mem>maxMemoryUsage){maxMemoryUsage=mem;} - return mem; - } - - template - Octree::Octree(void) - { - threads = 1; - radius = 0; - width = 0; - postNormalSmooth = 0; - _constrainValues = false; - } - - template - int Octree::NonLinearSplatOrientedPoint( TreeOctNode* node , const Point3D& position , const Point3D& normal ) - { - double x , dxdy , dxdydz , dx[DIMENSION][SPLAT_ORDER+1]; - int off[3]; - TreeOctNode::Neighbors3& neighbors = neighborKey.setNeighbors( node ); - double width; - Point3D center; - Real w; - node->centerAndWidth( center , w ); - width=w; - for( int i=0 ; i<3 ; i++ ) - { -#if SPLAT_ORDER==2 - off[i] = 0; - x = ( center[i] - position[i] - width ) / width; - dx[i][0] = 1.125+1.500*x+0.500*x*x; - x = ( center[i] - position[i] ) / width; - dx[i][1] = 0.750 - x*x; - - dx[i][2] = 1. - dx[i][1] - dx[i][0]; -#elif SPLAT_ORDER==1 - x = ( position[i] - center[i] ) / width; - if( x<0 ) - { - off[i] = 0; - dx[i][0] = -x; - } - else - { - off[i] = 1; - dx[i][0] = 1. - x; - } - dx[i][1] = 1. - dx[i][0]; -#elif SPLAT_ORDER==0 - off[i] = 1; - dx[i][0] = 1.; -#else -# error Splat order not supported -#endif // SPLAT_ORDER - } - for( int i=off[0] ; i<=off[0]+SPLAT_ORDER ; i++ ) for( int j=off[1] ; j<=off[1]+SPLAT_ORDER ; j++ ) - { - dxdy = dx[0][i] * dx[1][j]; - for( int k=off[2] ; k<=off[2]+SPLAT_ORDER ; k++ ) - if( neighbors.neighbors[i][j][k] ) - { - dxdydz = dxdy * dx[2][k]; - TreeOctNode* _node = neighbors.neighbors[i][j][k]; - int idx =_node->nodeData.normalIndex; - if( idx<0 ) - { - Point3D n; - n[0] = n[1] = n[2] = 0; - _node->nodeData.nodeIndex = 0; - idx = _node->nodeData.normalIndex = int(normals->size()); - normals->push_back(n); - } - (*normals)[idx] += normal * Real( dxdydz ); - } - } - return 0; - } - template - Real Octree::NonLinearSplatOrientedPoint( const Point3D& position , const Point3D& normal , int splatDepth , Real samplesPerNode , - int minDepth , int maxDepth ) - { - double dx; - Point3D n; - TreeOctNode* temp; - int cnt=0; - double width; - Point3D< Real > myCenter; - Real myWidth; - myCenter[0] = myCenter[1] = myCenter[2] = Real(0.5); - myWidth = Real(1.0); - - temp = &tree; - while( temp->depth()children ) - { - fprintf( stderr , "Octree::NonLinearSplatOrientedPoint error\n" ); - return -1; - } - int cIndex=TreeOctNode::CornerIndex(myCenter,position); - temp=&temp->children[cIndex]; - myWidth/=2; - if(cIndex&1) myCenter[0] += myWidth/2; - else myCenter[0] -= myWidth/2; - if(cIndex&2) myCenter[1] += myWidth/2; - else myCenter[1] -= myWidth/2; - if(cIndex&4) myCenter[2] += myWidth/2; - else myCenter[2] -= myWidth/2; - } - Real alpha,newDepth; - NonLinearGetSampleDepthAndWeight( temp , position , samplesPerNode , newDepth , alpha ); - - if( newDepthmaxDepth ) newDepth=Real(maxDepth); - int topDepth=int(ceil(newDepth)); - - dx = 1.0-(topDepth-newDepth); - if( topDepth<=minDepth ) - { - topDepth=minDepth; - dx=1; - } - else if( topDepth>maxDepth ) - { - topDepth=maxDepth; - dx=1; - } - while( temp->depth()>topDepth ) temp=temp->parent; - while( temp->depth()children) temp->initChildren(); - int cIndex=TreeOctNode::CornerIndex(myCenter,position); - temp=&temp->children[cIndex]; - myWidth/=2; - if(cIndex&1) myCenter[0] += myWidth/2; - else myCenter[0] -= myWidth/2; - if(cIndex&2) myCenter[1] += myWidth/2; - else myCenter[1] -= myWidth/2; - if(cIndex&4) myCenter[2] += myWidth/2; - else myCenter[2] -= myWidth/2; - } - width = 1.0 / ( 1<depth() ); - n = normal * alpha / Real( pow( width , 3 ) ) * Real( dx ); - NonLinearSplatOrientedPoint( temp , position , n ); - if( fabs(1.0-dx) > EPSILON ) - { - dx = Real(1.0-dx); - temp = temp->parent; - width = 1.0 / ( 1<depth() ); - - n = normal * alpha / Real( pow( width , 3 ) ) * Real( dx ); - NonLinearSplatOrientedPoint( temp , position , n ); - } - return alpha; - } - template - void Octree::NonLinearGetSampleDepthAndWeight(TreeOctNode* node,const Point3D& position,Real samplesPerNode,Real& depth,Real& weight){ - TreeOctNode* temp=node; - weight = Real(1.0)/NonLinearGetSampleWeight(temp,position); - if( weight>=samplesPerNode ) depth=Real( temp->depth() + log( weight / samplesPerNode ) / log(double(1<<(DIMENSION-1))) ); - else - { - Real oldAlpha,newAlpha; - oldAlpha=newAlpha=weight; - while( newAlphaparent ) - { - temp=temp->parent; - oldAlpha=newAlpha; - newAlpha=Real(1.0)/NonLinearGetSampleWeight(temp,position); - } - depth = Real( temp->depth() + log( newAlpha / samplesPerNode ) / log( newAlpha / oldAlpha ) ); - } - weight=Real(pow(double(1<<(DIMENSION-1)),-double(depth))); - } - - template - Real Octree::NonLinearGetSampleWeight( TreeOctNode* node , const Point3D& position ) - { - Real weight=0; - double x,dxdy,dx[DIMENSION][3]; - TreeOctNode::Neighbors3& neighbors=neighborKey.setNeighbors( node ); - double width; - Point3D center; - Real w; - node->centerAndWidth(center,w); - width=w; - - for( int i=0 ; inodeData.centerWeightContribution ); - } - return Real( 1.0 / weight ); - } - - template - int Octree::NonLinearUpdateWeightContribution( TreeOctNode* node , const Point3D& position , Real weight ) - { - TreeOctNode::Neighbors3& neighbors = neighborKey.setNeighbors( node ); - double x,dxdy,dx[DIMENSION][3]; - double width; - Point3D center; - Real w; - node->centerAndWidth( center , w ); - width=w; - const double SAMPLE_SCALE = 1. / ( 0.125 * 0.125 + 0.75 * 0.75 + 0.125 * 0.125 ); - - for( int i=0 ; inodeData.centerWeightContribution += Real( dxdy * dx[2][k] ); - } - return 0; - } - - template< int Degree > template int - Octree::setTree( boost::shared_ptr > input_, int maxDepth , int minDepth , - int kernelDepth , Real samplesPerNode , Real scaleFactor , Point3D& center , Real& scale , - int useConfidence , Real constraintWeight , bool adaptiveWeights ) - { - _minDepth = std::min< int >( std::max< int >( 0 , minDepth ) , maxDepth ); - _constrainValues = (constraintWeight>0); - double pointWeightSum = 0; - Point3D min , max , position , normal , myCenter; - Real myWidth; - int i , cnt=0; - TreeOctNode* temp; - int splatDepth=0; - - TreeNodeData::UseIndex = 1; - neighborKey.set( maxDepth ); - splatDepth = kernelDepth; - if( splatDepth<0 ) splatDepth = 0; - - - tree.setFullDepth( _minDepth ); - // Read through once to get the center and scale - while (cnt != input_->size ()) - { - Point3D< Real > p; - p[0] = input_->points[cnt].x; - p[1] = input_->points[cnt].y; - p[2] = input_->points[cnt].z; - - for (i = 0; i < DIMENSION; i++) - { - if( !cnt || p[i]max[i] ) max[i] = p[i]; - } - cnt++; - } - - scale = std::max< Real >( max[0]-min[0] , std::max< Real >( max[1]-min[1] , max[2]-min[2] ) ); - center = ( max+min ) /2; - - scale *= scaleFactor; - for( i=0 ; i0 ) - { - cnt = 0; - while (cnt != input_->size ()) - { - position[0] = input_->points[cnt].x; - position[1] = input_->points[cnt].y; - position[2] = input_->points[cnt].z; - normal[0] = input_->points[cnt].normal_x; - normal[1] = input_->points[cnt].normal_y; - normal[2] = input_->points[cnt].normal_z; - - for( i=0 ; imyCenter[i]+myWidth/2 ) break; - if( i!=DIMENSION ) continue; - Real weight=Real( 1. ); - if( useConfidence ) weight = Real( Length(normal) ); - temp = &tree; - int d=0; - while( dchildren ) temp->initChildren(); - int cIndex=TreeOctNode::CornerIndex(myCenter,position); - temp=&temp->children[cIndex]; - myWidth/=2; - if(cIndex&1) myCenter[0] += myWidth/2; - else myCenter[0] -= myWidth/2; - if(cIndex&2) myCenter[1] += myWidth/2; - else myCenter[1] -= myWidth/2; - if(cIndex&4) myCenter[2] += myWidth/2; - else myCenter[2] -= myWidth/2; - d++; - } - NonLinearUpdateWeightContribution( temp , position , weight ); - cnt++; - } - } - - normals = new std::vector< Point3D >(); - cnt=0; - while (cnt != input_->size ()) - { - position[0] = input_->points[cnt].x; - position[1] = input_->points[cnt].y; - position[2] = input_->points[cnt].z; - normal[0] = input_->points[cnt].normal_x; - normal[1] = input_->points[cnt].normal_y; - normal[2] = input_->points[cnt].normal_z; - cnt ++; - for( i=0 ; imyCenter[i]+myWidth/2) break; - if( i!=DIMENSION ) continue; - Real l = Real( Length( normal ) ); - if( l!=l || l<=EPSILON ) continue; - if( !useConfidence ) normal /= l; - - l = Real(1.); - Real pointWeight = Real(1.f); - if( samplesPerNode>0 && splatDepth ) - { - pointWeight = NonLinearSplatOrientedPoint( position , normal , splatDepth , samplesPerNode , _minDepth , maxDepth ); - } - else - { - Real alpha=1; - temp = &tree; - int d=0; - if( splatDepth ) - { - while( dchildren[cIndex]; - myWidth/=2; - if(cIndex&1) myCenter[0]+=myWidth/2; - else myCenter[0]-=myWidth/2; - if(cIndex&2) myCenter[1]+=myWidth/2; - else myCenter[1]-=myWidth/2; - if(cIndex&4) myCenter[2]+=myWidth/2; - else myCenter[2]-=myWidth/2; - d++; - } - alpha = NonLinearGetSampleWeight( temp , position ); - } - for( i=0 ; ichildren){temp->initChildren();} - int cIndex=TreeOctNode::CornerIndex(myCenter,position); - temp=&temp->children[cIndex]; - myWidth/=2; - if(cIndex&1) myCenter[0]+=myWidth/2; - else myCenter[0]-=myWidth/2; - if(cIndex&2) myCenter[1]+=myWidth/2; - else myCenter[1]-=myWidth/2; - if(cIndex&4) myCenter[2]+=myWidth/2; - else myCenter[2]-=myWidth/2; - d++; - } - NonLinearSplatOrientedPoint( temp , position , normal ); - pointWeight = alpha; - } - pointWeight = 1; - pointWeightSum += pointWeight; - if( _constrainValues ) - { - int d = 0; - TreeOctNode* temp = &tree; - myCenter[0] = myCenter[1] = myCenter[2] = Real(0.5); - myWidth = Real(1.0); - while( 1 ) - { - int idx = temp->nodeData.pointIndex; - if( idx==-1 ) - { - Point3D< Real > p; - p[0] = p[1] = p[2] = 0; - idx = int( _points.size() ); - _points.push_back( PointData( position*pointWeight , pointWeight ) ); - temp->nodeData.pointIndex = idx; - } - else - { - _points[idx].weight += pointWeight; - _points[idx].position += position * pointWeight; - } - - int cIndex = TreeOctNode::CornerIndex( myCenter , position ); - if( !temp->children ) break; - temp = &temp->children[cIndex]; - myWidth /= 2; - if( cIndex&1 ) myCenter[0] += myWidth/2; - else myCenter[0] -= myWidth/2; - if( cIndex&2 ) myCenter[1] += myWidth/2; - else myCenter[1] -= myWidth/2; - if( cIndex&4 ) myCenter[2] += myWidth/2; - else myCenter[2] -= myWidth/2; - d++; - } - } - } - - - if( _constrainValues ) - for( TreeOctNode* n=tree.nextNode() ; n ; n=tree.nextNode(n) ) - if( n->nodeData.pointIndex!=-1 ) - { - int idx = n->nodeData.pointIndex; - _points[idx].position /= _points[idx].weight; - if( adaptiveWeights ) _points[idx].weight *= (1<d); - else _points[idx].weight *= (1<depthAndOffset( d , off ); - res = 1<nodeData.normalIndex<0 ) continue; - Point3D< Real >& normal = (*normals)[node->nodeData.normalIndex]; - for( int d=0 ; d<3 ; d++ ) if( off[d]==0 || off[d]==res-1 ) normal[d] = 0; - } -#endif // FORCE_NEUMANN_FIELD - _sNodes.set( tree ); - - - return cnt; - } - - - template - void Octree::setBSplineData( int maxDepth , Real normalSmooth , bool reflectBoundary ) - { - radius = 0.5 + 0.5 * Degree; - width=int(double(radius+0.5-EPSILON)*2); - if( normalSmooth>0 ) postNormalSmooth = normalSmooth; - fData.set( maxDepth , true , reflectBoundary ); - } - - template - void Octree::finalize( void ) - { - int maxDepth = tree.maxDepth( ); - TreeOctNode::NeighborKey5 nKey; - nKey.set( maxDepth ); - for( int d=maxDepth ; d>0 ; d-- ) - for( TreeOctNode* node=tree.nextNode() ; node ; node=tree.nextNode( node ) ) - if( node->d==d ) - { - int xStart=0 , xEnd=5 , yStart=0 , yEnd=5 , zStart=0 , zEnd=5; - int c = int( node - node->parent->children ); - int x , y , z; - Cube::FactorCornerIndex( c , x , y , z ); - if( x ) xStart = 1; - else xEnd = 4; - if( y ) yStart = 1; - else yEnd = 4; - if( z ) zStart = 1; - else zEnd = 4; - nKey.setNeighbors( node->parent , xStart , xEnd , yStart , yEnd , zStart , zEnd ); - } - _sNodes.set( tree ); - MemoryUsage(); - } - template< int Degree > - Real Octree< Degree >::GetValue( const PointInfo points[3][3][3] , const bool hasPoints[3][3] , const int d[3] ) const - { - double v = 0.; - const int min[] = { std::max( 0 , d[0]+0 ) , std::max( 0 , d[1]+0 ) , std::max( 0 , d[2]+0 ) }; - const int max[] = { std::min( 2 , d[0]+2 ) , std::min( 2 , d[1]+2 ) , std::min( 2 , d[2]+2 ) }; - for( int i=min[0] ; i<=max[0] ; i++ ) for( int j=min[1] ; j<=max[1] ; j++ ) - { - if( !hasPoints[i][j] ) continue; - const PointInfo* pInfo = points[i][j]; - int ii = -d[0]+i; - int jj = -d[1]+j; - for( int k=min[2] ; k<=max[2] ; k++ ) - if( pInfo[k].weightedValue ) - v += pInfo[k].splineValues[0][ii] * pInfo[k].splineValues[1][jj] * pInfo[k].splineValues[2][-d[2]+k]; - } - return Real( v ); - } - template - Real Octree::GetLaplacian( const int idx[DIMENSION] ) const - { - return Real( fData.vvDotTable[idx[0]] * fData.vvDotTable[idx[1]] * fData.vvDotTable[idx[2]] * (fData.ddDotTable[idx[0]]+fData.ddDotTable[idx[1]]+fData.ddDotTable[idx[2]] ) ); - } - template< int Degree > - Real Octree< Degree >::GetLaplacian( const TreeOctNode* node1 , const TreeOctNode* node2 ) const - { - int symIndex[] = - { - BSplineData< Degree , Real >::SymmetricIndex( node1->off[0] , node2->off[0] ) , - BSplineData< Degree , Real >::SymmetricIndex( node1->off[1] , node2->off[1] ) , - BSplineData< Degree , Real >::SymmetricIndex( node1->off[2] , node2->off[2] ) - }; - return GetLaplacian( symIndex ); - } - template< int Degree > - Real Octree< Degree >::GetDivergence( const TreeOctNode* node1 , const TreeOctNode* node2 , const Point3D< Real >& normal1 ) const - { - int symIndex[] = - { - BSplineData< Degree , Real >::SymmetricIndex( node1->off[0] , node2->off[0] ) , - BSplineData< Degree , Real >::SymmetricIndex( node1->off[1] , node2->off[1] ) , - BSplineData< Degree , Real >::SymmetricIndex( node1->off[2] , node2->off[2] ) , - }; - int aSymIndex[] = - { - #if GRADIENT_DOMAIN_SOLUTION - // Take the dot-product of the vector-field with the gradient of the basis function - fData.Index( node2->off[0] , node1->off[0] ) , - fData.Index( node2->off[1] , node1->off[1] ) , - fData.Index( node2->off[2] , node1->off[2] ) - #else // !GRADIENT_DOMAIN_SOLUTION - // Take the dot-product of the divergence of the vector-field with the basis function - fData.Index( node1->off[0] , node2->off[0] ) , - fData.Index( node1->off[1] , node2->off[1] ) , - fData.Index( node1->off[2] , node2->off[2] ) - #endif // GRADIENT_DOMAIN_SOLUTION - }; - double dot = fData.vvDotTable[symIndex[0]] * fData.vvDotTable[symIndex[1]] * fData.vvDotTable[symIndex[2]]; -#if GRADIENT_DOMAIN_SOLUTION - return Real( dot * ( fData.dvDotTable[aSymIndex[0]]*normal1[0] + fData.dvDotTable[aSymIndex[1]]*normal1[1] + fData.dvDotTable[aSymIndex[2]]*normal1[2] ) ); -#else // !GRADIENT_DOMAIN_SOLUTION - return -Real( dot * ( fData.dvDotTable[aSymIndex[0]]*normal1[0] + fData.dvDotTable[aSymIndex[1]]*normal1[1] + fData.dvDotTable[aSymIndex[2]]*normal1[2] ) ); -#endif // GRADIENT_DOMAIN_SOLUTION - } - template< int Degree > - Real Octree< Degree >::GetDivergenceMinusLaplacian( const TreeOctNode* node1 , const TreeOctNode* node2 , Real value1 , const Point3D& normal1 ) const - { - int symIndex[] = - { - BSplineData< Degree , Real >::SymmetricIndex( node1->off[0] , node2->off[0] ) , - BSplineData< Degree , Real >::SymmetricIndex( node1->off[1] , node2->off[1] ) , - BSplineData< Degree , Real >::SymmetricIndex( node1->off[2] , node2->off[2] ) - }; - int aSymIndex[] = - { - #if GRADIENT_DOMAIN_SOLUTION - // Take the dot-product of the vector-field with the gradient of the basis function - fData.Index( node2->off[0] , node1->off[0] ) , - fData.Index( node2->off[1] , node1->off[1] ) , - fData.Index( node2->off[2] , node1->off[2] ) - #else // !GRADIENT_DOMAIN_SOLUTION - // Take the dot-product of the divergence of the vector-field with the basis function - fData.Index( node1->off[0] , node2->off[0] ) , - fData.Index( node1->off[1] , node2->off[1] ) , - fData.Index( node1->off[2] , node2->off[2] ) - #endif // GRADIENT_DOMAIN_SOLUTION - }; - double dot = fData.vvDotTable[symIndex[0]] * fData.vvDotTable[symIndex[1]] * fData.vvDotTable[symIndex[2]]; - return Real( dot * - ( - #if GRADIENT_DOMAIN_SOLUTION - - ( fData.ddDotTable[ symIndex[0]] + fData.ddDotTable[ symIndex[1]] + fData.ddDotTable[ symIndex[2]] ) * value1 - + ( fData.dvDotTable[aSymIndex[0]]*normal1[0] + fData.dvDotTable[aSymIndex[1]]*normal1[1] + fData.dvDotTable[aSymIndex[2]]*normal1[2] ) - #else // !GRADIENT_DOMAIN_SOLUTION - - ( fData.ddDotTable[ symIndex[0]] + fData.ddDotTable[ symIndex[1]] + fData.ddDotTable[ symIndex[2]] ) * value1 - - ( fData.dvDotTable[aSymIndex[0]]*normal1[0] + fData.dvDotTable[aSymIndex[1]]*normal1[1] + fData.dvDotTable[aSymIndex[2]]*normal1[2] ) - #endif // GRADIENT_DOMAIN_SOLUTION - ) - ); - } - template< int Degree > - void Octree< Degree >::SetMatrixRowBounds( const TreeOctNode* node , int rDepth , const int rOff[3] , int& xStart , int& xEnd , int& yStart , int& yEnd , int& zStart , int& zEnd ) const - { - xStart = 0 , yStart = 0 , zStart = 0 , xEnd = 5 , yEnd = 5 , zEnd = 5; - int depth , off[3]; - node->depthAndOffset( depth , off ); - int width = 1 << ( depth-rDepth ); - off[0] -= rOff[0] << ( depth-rDepth ) , off[1] -= rOff[1] << ( depth-rDepth ) , off[2] -= rOff[2] << ( depth-rDepth ); - if( off[0]<0 ) xStart = -off[0]; - if( off[1]<0 ) yStart = -off[1]; - if( off[2]<0 ) zStart = -off[2]; - if( off[0]>=width ) xEnd = 4 - ( off[0]-width ); - if( off[1]>=width ) yEnd = 4 - ( off[1]-width ); - if( off[2]>=width ) zEnd = 4 - ( off[2]-width ); - } - template< int Degree > - int Octree< Degree >::GetMatrixRowSize( const OctNode< TreeNodeData , Real >::Neighbors5& neighbors5 ) const { return GetMatrixRowSize( neighbors5 , 0 , 5 , 0 , 5 , 0 , 5 ); } - template< int Degree > - int Octree< Degree >::GetMatrixRowSize( const OctNode< TreeNodeData , Real >::Neighbors5& neighbors5 , int xStart , int xEnd , int yStart , int yEnd , int zStart , int zEnd ) const - { - int count = 0; - for( int x=xStart ; x<=2 ; x++ ) - for( int y=yStart ; y2 ) continue; - else for( int z=zStart ; z2 ) continue; - else if( neighbors5.neighbors[x][y][z] && neighbors5.neighbors[x][y][z]->nodeData.nodeIndex>=0 ) - count++; - return count; - } - template< int Degree > - int Octree< Degree >::SetMatrixRow( const OctNode< TreeNodeData , Real >::Neighbors5& neighbors5 , MatrixEntry< float >* row , int offset , const double stencil[5][5][5] ) const - { - return SetMatrixRow( neighbors5 , row , offset , stencil , 0 , 5 , 0 , 5 , 0 , 5 ); - } - template< int Degree > - int Octree< Degree >::SetMatrixRow( const OctNode< TreeNodeData , Real >::Neighbors5& neighbors5 , MatrixEntry< float >* row , int offset , const double stencil[5][5][5] , int xStart , int xEnd , int yStart , int yEnd , int zStart , int zEnd ) const - { - bool hasPoints[3][3]; - Real diagonal = 0; - PointInfo samples[3][3][3]; - - int count = 0; - const TreeOctNode* node = neighbors5.neighbors[2][2][2]; - int index[] = { int( node->off[0] ) , int( node->off[1] ), int( node->off[2] ) }; - - if( _constrainValues ) - { - int d , idx[3]; - node->depthAndOffset( d , idx ); - idx[0] = BinaryNode< double >::CenterIndex( d , idx[0] ); - idx[1] = BinaryNode< double >::CenterIndex( d , idx[1] ); - idx[2] = BinaryNode< double >::CenterIndex( d , idx[2] ); - for( int j=0 ; j<3 ; j++ ) for( int k=0 ; k<3 ; k++ ) - { - hasPoints[j][k] = false; - for( int l=0 ; l<3 ; l++ ) - { - const TreeOctNode* _node = neighbors5.neighbors[j+1][k+1][l+1]; - if( _node && _node->nodeData.pointIndex!=-1 ) - { - const PointData& pData = _points[ _node->nodeData.pointIndex ]; - PointInfo& pointInfo = samples[j][k][l]; - Real weight = pData.weight; - Point3D< Real > p = pData.position; - for( int s=0 ; s<3 ; s++ ) - { - pointInfo.splineValues[0][s] = float( fData.baseBSplines[ idx[0]+j-s][s]( p[0] ) ); - pointInfo.splineValues[1][s] = float( fData.baseBSplines[ idx[1]+k-s][s]( p[1] ) ); - pointInfo.splineValues[2][s] = float( fData.baseBSplines[ idx[2]+l-s][s]( p[2] ) ); - } - float value = pointInfo.splineValues[0][j] * pointInfo.splineValues[1][k] * pointInfo.splineValues[2][l]; - diagonal += value * value * weight; - pointInfo.weightedValue = value * weight; - for( int s=0 ; s<3 ; s++ ) pointInfo.splineValues[0][s] *= pointInfo.weightedValue; - hasPoints[j][k] = true; - } - else samples[j][k][l].weightedValue = 0; - } - } - } - - bool isInterior; - int d , off[3]; - neighbors5.neighbors[2][2][2]->depthAndOffset( d , off ); - int mn = 2 , mx = (1<=mn && off[0]=mn && off[1]=mn && off[2]2 ) continue; - else for( int z=zStart ; z2 ) continue; - else if( neighbors5.neighbors[x][y][z] && neighbors5.neighbors[x][y][z]->nodeData.nodeIndex>=0 ) - { - const TreeOctNode* _node = neighbors5.neighbors[x][y][z]; - int _index[] = { int( _node->off[0] ) , int( _node->off[1] ), int( _node->off[2] ) }; - Real temp; - if( isInterior ) temp = Real( stencil[x][y][z] ); - else temp = GetLaplacian( node , _node ); - if( _constrainValues ) - { - int _d[] = { _index[0]-index[0] , _index[1]-index[1] , _index[2]-index[2] }; - if( x==2 && y==2 && z==2 ) temp += diagonal; - else temp += GetValue( samples , hasPoints , _d ); - } - if( x==2 && y==2 && z==2 ) temp /= 2; - if( fabs(temp)>MATRIX_ENTRY_EPSILON ) - { - row[count].N = _node->nodeData.nodeIndex-offset; - row[count].Value = temp; - count++; - } - } - return count; - } - template< int Degree > - void Octree< Degree >::SetDivergenceStencil( int depth , Point3D< double > *stencil , bool scatter ) const - { - int offset[] = { 2 , 2 , 2 }; - short d , off[3]; - TreeOctNode::Index( depth , offset , d , off ); - int index1[3] , index2[3]; - if( scatter ) index2[0] = int( off[0] ) , index2[1] = int( off[1] ) , index2[2] = int( off[2] ); - else index1[0] = int( off[0] ) , index1[1] = int( off[1] ) , index1[2] = int( off[2] ); - for( int x=0 ; x<5 ; x++ ) for( int y=0 ; y<5 ; y++ ) for( int z=0 ; z<5 ; z++ ) - { - int _offset[] = { x , y , z }; - TreeOctNode::Index( depth , _offset , d , off ); - if( scatter ) index1[0] = int( off[0] ) , index1[1] = int( off[1] ) , index1[2] = int( off[2] ); - else index2[0] = int( off[0] ) , index2[1] = int( off[1] ) , index2[2] = int( off[2] ); - int symIndex[] = - { - BSplineData< Degree , Real >::SymmetricIndex( index1[0] , index2[0] ) , - BSplineData< Degree , Real >::SymmetricIndex( index1[1] , index2[1] ) , - BSplineData< Degree , Real >::SymmetricIndex( index1[2] , index2[2] ) , - }; - int aSymIndex[] = - { - #if GRADIENT_DOMAIN_SOLUTION - // Take the dot-product of the vector-field with the gradient of the basis function - fData.Index( index1[0] , index2[0] ) , - fData.Index( index1[1] , index2[1] ) , - fData.Index( index1[2] , index2[2] ) - #else // !GRADIENT_DOMAIN_SOLUTION - // Take the dot-product of the divergence of the vector-field with the basis function - fData.Index( index2[0] , index1[0] ) , - fData.Index( index2[1] , index1[1] ) , - fData.Index( index2[2] , index1[2] ) - #endif // GRADIENT_DOMAIN_SOLUTION - }; - - double dot = fData.vvDotTable[symIndex[0]] * fData.vvDotTable[symIndex[1]] * fData.vvDotTable[symIndex[2]]; -#if GRADIENT_DOMAIN_SOLUTION - Point3D temp; - temp[0] = fData.dvDotTable[aSymIndex[0]] * dot; - temp[1] = fData.dvDotTable[aSymIndex[1]] * dot; - temp[2] = fData.dvDotTable[aSymIndex[2]] * dot; - stencil[25*x + 5*y + z] = temp; - // stencil[x][y][z][0] = fData.dvDotTable[aSymIndex[0]] * dot; - // stencil[x][y][z][1] = fData.dvDotTable[aSymIndex[1]] * dot; - // stencil[x][y][z][2] = fData.dvDotTable[aSymIndex[2]] * dot; -#else // !GRADIENT_DOMAIN_SOLUTION - Point3D temp; - temp[0] = -fData.dvDotTable[aSymIndex[0]] * dot; - temp[1] = -fData.dvDotTable[aSymIndex[1]] * dot; - temp[2] = -fData.dvDotTable[aSymIndex[2]] * dot; - stencil[25*x + 5*y + z] = temp; - // stencil[x][y][z][0] = -fData.dvDotTable[aSymIndex[0]] * dot; - // stencil[x][y][z][1] = -fData.dvDotTable[aSymIndex[1]] * dot; - // stencil[x][y][z][2] = -fData.dvDotTable[aSymIndex[2]] * dot; -#endif // GRADIENT_DOMAIN_SOLUTION - } - } - template< int Degree > - void Octree< Degree >::SetLaplacianStencil( int depth , double stencil[5][5][5] ) const - { - int offset[] = { 2 , 2 , 2 }; - short d , off[3]; - TreeOctNode::Index( depth , offset , d , off ); - int index[] = { int( off[0] ) , int( off[1] ) , int( off[2] ) }; - for( int x=0 ; x<5 ; x++ ) for( int y=0 ; y<5 ; y++ ) for( int z=0 ; z<5 ; z++ ) - { - int _offset[] = { x , y , z }; - short _d , _off[3]; - TreeOctNode::Index( depth , _offset , _d , _off ); - int _index[] = { int( _off[0] ) , int( _off[1] ) , int( _off[2] ) }; - int symIndex[3]; - symIndex[0] = BSplineData< Degree , Real >::SymmetricIndex( index[0] , _index[0] ); - symIndex[1] = BSplineData< Degree , Real >::SymmetricIndex( index[1] , _index[1] ); - symIndex[2] = BSplineData< Degree , Real >::SymmetricIndex( index[2] , _index[2] ); - stencil[x][y][z] = GetLaplacian( symIndex ); - } - } - template< int Degree > - void Octree< Degree >::SetLaplacianStencils( int depth , Stencil< double , 5 > stencils[2][2][2] ) const - { - if( depth<=1 ) return; - for( int i=0 ; i<2 ; i++ ) for( int j=0 ; j<2 ; j++ ) for( int k=0 ; k<2 ; k++ ) - { - short d , off[3]; - int offset[] = { 4+i , 4+j , 4+k }; - TreeOctNode::Index( depth , offset , d , off ); - int index[] = { int( off[0] ) , int( off[1] ) , int( off[2] ) }; - for( int x=0 ; x<5 ; x++ ) for( int y=0 ; y<5 ; y++ ) for( int z=0 ; z<5 ; z++ ) - { - int _offset[] = { x , y , z }; - short _d , _off[3]; - TreeOctNode::Index( depth-1 , _offset , _d , _off ); - int _index[] = { int( _off[0] ) , int( _off[1] ) , int( _off[2] ) }; - int symIndex[3]; - symIndex[0] = BSplineData< Degree , Real >::SymmetricIndex( index[0] , _index[0] ); - symIndex[1] = BSplineData< Degree , Real >::SymmetricIndex( index[1] , _index[1] ); - symIndex[2] = BSplineData< Degree , Real >::SymmetricIndex( index[2] , _index[2] ); - stencils[i][j][k].values[x][y][z] = GetLaplacian( symIndex ); - } - } - } - template< int Degree > - void Octree< Degree >::SetDivergenceStencils( int depth , Stencil< Point3D< double > , 5 > stencils[2][2][2] , bool scatter ) const - { - if( depth<=1 ) return; - int index1[3] , index2[3]; - for( int i=0 ; i<2 ; i++ ) for( int j=0 ; j<2 ; j++ ) for( int k=0 ; k<2 ; k++ ) - { - short d , off[3]; - int offset[] = { 4+i , 4+j , 4+k }; - TreeOctNode::Index( depth , offset , d , off ); - if( scatter ) index2[0] = int( off[0] ) , index2[1] = int( off[1] ) , index2[2] = int( off[2] ); - else index1[0] = int( off[0] ) , index1[1] = int( off[1] ) , index1[2] = int( off[2] ); - for( int x=0 ; x<5 ; x++ ) for( int y=0 ; y<5 ; y++ ) for( int z=0 ; z<5 ; z++ ) - { - int _offset[] = { x , y , z }; - TreeOctNode::Index( depth-1 , _offset , d , off ); - if( scatter ) index1[0] = int( off[0] ) , index1[1] = int( off[1] ) , index1[2] = int( off[2] ); - else index2[0] = int( off[0] ) , index2[1] = int( off[1] ) , index2[2] = int( off[2] ); - - int symIndex[] = - { - BSplineData< Degree , Real >::SymmetricIndex( index1[0] , index2[0] ) , - BSplineData< Degree , Real >::SymmetricIndex( index1[1] , index2[1] ) , - BSplineData< Degree , Real >::SymmetricIndex( index1[2] , index2[2] ) , - }; - int aSymIndex[] = - { - #if GRADIENT_DOMAIN_SOLUTION - // Take the dot-product of the vector-field with the gradient of the basis function - fData.Index( index1[0] , index2[0] ) , - fData.Index( index1[1] , index2[1] ) , - fData.Index( index1[2] , index2[2] ) - #else // !GRADIENT_DOMAIN_SOLUTION - // Take the dot-product of the divergence of the vector-field with the basis function - fData.Index( index2[0] , index1[0] ) , - fData.Index( index2[1] , index1[1] ) , - fData.Index( index2[2] , index1[2] ) - #endif // GRADIENT_DOMAIN_SOLUTION - }; - double dot = fData.vvDotTable[symIndex[0]] * fData.vvDotTable[symIndex[1]] * fData.vvDotTable[symIndex[2]]; -#if GRADIENT_DOMAIN_SOLUTION - stencils[i][j][k].values[x][y][z][0] = fData.dvDotTable[aSymIndex[0]] * dot; - stencils[i][j][k].values[x][y][z][1] = fData.dvDotTable[aSymIndex[1]] * dot; - stencils[i][j][k].values[x][y][z][2] = fData.dvDotTable[aSymIndex[2]] * dot; -#else // !GRADIENT_DOMAIN_SOLUTION - stencils[i][j][k].values[x][y][z][0] = -fData.dvDotTable[aSymIndex[0]] * dot; - stencils[i][j][k].values[x][y][z][1] = -fData.dvDotTable[aSymIndex[1]] * dot; - stencils[i][j][k].values[x][y][z][2] = -fData.dvDotTable[aSymIndex[2]] * dot; -#endif // GRADIENT_DOMAIN_SOLUTION - } - } - } - template< int Degree > - void Octree< Degree >::SetEvaluationStencils( int depth , Stencil< double , 3 > stencil1[8] , Stencil< double , 3 > stencil2[8][8] ) const - { - if( depth>2 ) - { - int idx[3]; - int off[] = { 2 , 2 , 2 }; - for( int c=0 ; c<8 ; c++ ) - { - VertexData::CornerIndex( depth , off , c , fData.depth , idx ); - idx[0] *= fData.functionCount , idx[1] *= fData.functionCount , idx[2] *= fData.functionCount; - for( int x=0 ; x<3 ; x++ ) for( int y=0 ; y<3 ; y++ ) for( int z=0 ; z<3 ; z++ ) - { - short _d , _off[3]; - int _offset[] = { x+1 , y+1 , z+1 }; - TreeOctNode::Index( depth , _offset , _d , _off ); - stencil1[c].values[x][y][z] = fData.valueTables[ idx[0]+int(_off[0]) ] * fData.valueTables[ idx[1]+int(_off[1]) ] * fData.valueTables[ idx[2]+int(_off[2]) ]; - } - } - } - if( depth>3 ) - for( int _c=0 ; _c<8 ; _c++ ) - { - int idx[3]; - int _cx , _cy , _cz; - Cube::FactorCornerIndex( _c , _cx , _cy , _cz ); - int off[] = { 4+_cx , 4+_cy , 4+_cz }; - for( int c=0 ; c<8 ; c++ ) - { - VertexData::CornerIndex( depth , off , c , fData.depth , idx ); - idx[0] *= fData.functionCount , idx[1] *= fData.functionCount , idx[2] *= fData.functionCount; - for( int x=0 ; x<3 ; x++ ) for( int y=0 ; y<3 ; y++ ) for( int z=0 ; z<3 ; z++ ) - { - short _d , _off[3]; - int _offset[] = { x+1 , y+1 , z+1 }; - TreeOctNode::Index( depth-1 , _offset , _d , _off ); - stencil2[_c][c].values[x][y][z] = fData.valueTables[ idx[0]+int(_off[0]) ] * fData.valueTables[ idx[1]+int(_off[1]) ] * fData.valueTables[ idx[2]+int(_off[2]) ]; - } - } - } - } - template< int Degree > - void Octree< Degree >::UpdateCoarserSupportBounds( const TreeOctNode* node , int& startX , int& endX , int& startY , int& endY , int& startZ , int& endZ ) - { - if( node->parent ) - { - int x , y , z , c = int( node - node->parent->children ); - Cube::FactorCornerIndex( c , x , y , z ); - if( x==0 ) endX = 4; - else startX = 1; - if( y==0 ) endY = 4; - else startY = 1; - if( z==0 ) endZ = 4; - else startZ = 1; - } - } - - template< int Degree > - void Octree< Degree >::UpdateConstraintsFromCoarser( const OctNode< TreeNodeData , Real >::NeighborKey5& neighborKey5 , TreeOctNode* node , Real* metSolution , const Stencil< double , 5 >& lapStencil ) const - { - bool isInterior; - { - int d , off[3]; - node->depthAndOffset( d , off ); - int mn = 4 , mx = (1<=mn && off[0]=mn && off[1]=mn && off[2]depth(); - if( depth<=_minDepth ) return; - int i = node->nodeData.nodeIndex; - // Offset the constraints using the solution from lower resolutions. - int startX = 0 , endX = 5 , startY = 0 , endY = 5 , startZ = 0 , endZ = 5; - UpdateCoarserSupportBounds( node , startX , endX , startY , endY , startZ , endZ ); - - const TreeOctNode::Neighbors5& neighbors5 = neighborKey5.neighbors[depth-1]; - for( int x=startX ; xnodeData.nodeIndex>=0 ) - { - const TreeOctNode* _node = neighbors5.neighbors[x][y][z]; - Real _solution = metSolution[ _node->nodeData.nodeIndex ]; - { - if( isInterior ) node->nodeData.constraint -= Real( lapStencil.values[x][y][z] * _solution ); - else node->nodeData.constraint -= GetLaplacian( _node , node ) * _solution; - } - } - if( _constrainValues ) - { - int d , idx[3]; - node->depthAndOffset( d, idx ); - idx[0] = BinaryNode< double >::CenterIndex( d , idx[0] ); - idx[1] = BinaryNode< double >::CenterIndex( d , idx[1] ); - idx[2] = BinaryNode< double >::CenterIndex( d , idx[2] ); - const TreeOctNode::Neighbors5& neighbors5 = neighborKey5.neighbors[depth]; - for( int x=1 ; x<4 ; x++ ) for( int y=1 ; y<4 ; y++ ) for( int z=1 ; z<4 ; z++ ) - if( neighbors5.neighbors[x][y][z] && neighbors5.neighbors[x][y][z]->nodeData.pointIndex!=-1 ) - { - const PointData& pData = _points[ neighbors5.neighbors[x][y][z]->nodeData.pointIndex ]; - Real pointValue = pData.value; - Point3D< Real > p = pData.position; - node->nodeData.constraint -= - Real( - fData.baseBSplines[idx[0]][x-1]( p[0] ) * - fData.baseBSplines[idx[1]][y-1]( p[1] ) * - fData.baseBSplines[idx[2]][z-1]( p[2] ) * - pointValue - ); - } - } - } - struct UpSampleData - { - int start; - double v[2]; - UpSampleData( void ) { start = 0 , v[0] = v[1] = 0.; } - UpSampleData( int s , double v1 , double v2 ) { start = s , v[0] = v1 , v[1] = v2; } - }; - template< int Degree > - void Octree< Degree >::UpSampleCoarserSolution( int depth , const SortedTreeNodes& sNodes , Vector< Real >& Solution ) const - { - int start = sNodes.nodeCount[depth] , end = sNodes.nodeCount[depth+1] , range = end-start; - Solution.Resize( range ); - if( !depth ) return; - else if( depth==1 ) for( int i=start ; inodeData.solution; - else - { - // For every node at the current depth -#pragma omp parallel for num_threads( threads ) - for( int t=0 ; tdepthAndOffset( d , off ); - for( int d=0 ; d<3 ; d++ ) - { - if ( off[d] ==0 ) usData[d] = UpSampleData( 1 , 1.00 , 0.00 ); - else if( off[d]+1==(1<nodeData.solution * dxyz ); - } - } - } - } - } - } - // Clear the coarser solution - start = sNodes.nodeCount[depth-1] , end = sNodes.nodeCount[depth] , range = end-start; -#pragma omp parallel for num_threads( threads ) - for( int i=start ; inodeData.solution = Real( 0. ); - } - template< int Degree > - void Octree< Degree >::DownSampleFinerConstraints( int depth , SortedTreeNodes& sNodes ) const - { - if( !depth ) return; -#pragma omp parallel for num_threads( threads ) - for( int i=sNodes.nodeCount[depth-1] ; inodeData.constraint = Real( 0 ); - - if( depth==1 ) - { - sNodes.treeNodes[0]->nodeData.constraint = Real( 0 ); - for( int i=sNodes.nodeCount[depth] ; inodeData.constraint += sNodes.treeNodes[i]->nodeData.constraint; - return; - } - std::vector< Vector< double > > constraints( threads ); - for( int t=0 ; tdepthAndOffset( d , off ); - for( int d=0 ; d<3 ; d++ ) - { - if ( off[d] ==0 ) usData[d] = UpSampleData( 1 , 1.00 , 0.00 ); - else if( off[d]+1==(1<nodeData.nodeIndex-lStart] += sNodes.treeNodes[i]->nodeData.constraint * dxyz; - } - } - } - } - } -#pragma omp parallel for num_threads( threads ) - for( int i=lStart ; inodeData.constraint += cSum; - } - } - template< int Degree > - template< class C > - void Octree< Degree >::DownSample( int depth , const SortedTreeNodes& sNodes , C* constraints ) const - { - if( depth==0 ) return; - if( depth==1 ) - { - for( int i=sNodes.nodeCount[1] ; i > _constraints( threads ); - for( int t=0 ; tdepthAndOffset( d , off ); - for( int d=0 ; d<3 ; d++ ) - { - if ( off[d] ==0 ) usData[d] = UpSampleData( 1 , 1.00 , 0.00 ); - else if( off[d]+1==(1<parent ); - C c = constraints[i]; - for( int ii=0 ; ii<2 ; ii++ ) - { - int _ii = ii + usData[0].start; - C cx = C( c*usData[0].v[ii] ); - for( int jj=0 ; jj<2 ; jj++ ) - { - int _jj = jj + usData[1].start; - C cxy = C( cx*usData[1].v[jj] ); - for( int kk=0 ; kk<2 ; kk++ ) - { - int _kk = kk + usData[2].start; - if( neighbors.neighbors[_ii][_jj][_kk] ) - _constraints[t][neighbors.neighbors[_ii][_jj][_kk]->nodeData.nodeIndex-lStart] += C( cxy*usData[2].v[kk] ); - } - } - } - } - } -#pragma omp parallel for num_threads( threads ) - for( int i=lStart ; i - template< class C > - void Octree< Degree >::UpSample( int depth , const SortedTreeNodes& sNodes , C* coefficients ) const - { - if ( depth==0 ) return; - else if( depth==1 ) - { - for( int i=sNodes.nodeCount[1] ; idepthAndOffset( d , off ); - for( int d=0 ; d<3 ; d++ ) - { - if ( off[d] ==0 ) usData[d] = UpSampleData( 1 , 1.00 , 0.00 ); - else if( off[d]+1==(1<parent ); - for( int ii=0 ; ii<2 ; ii++ ) - { - int _ii = ii + usData[0].start; - double dx = usData[0].v[ii]; - for( int jj=0 ; jj<2 ; jj++ ) - { - int _jj = jj + usData[1].start; - double dxy = dx * usData[1].v[jj]; - for( int kk=0 ; kk<2 ; kk++ ) - { - int _kk = kk + usData[2].start; - if( neighbors.neighbors[_ii][_jj][_kk] ) - { - double dxyz = dxy * usData[2].v[kk]; - int _i = neighbors.neighbors[_ii][_jj][_kk]->nodeData.nodeIndex; - coefficients[i] += coefficients[_i] * Real( dxyz ); - } - } - } - } - } - } - } - template< int Degree > - void Octree< Degree >::SetCoarserPointValues( int depth , const SortedTreeNodes& sNodes , Real* metSolution ) - { - int start = sNodes.nodeCount[depth] , end = sNodes.nodeCount[depth+1] , range = end-start; - // For every node at the current depth -#pragma omp parallel for num_threads( threads ) - for( int t=0 ; tnodeData.pointIndex; - if( pIdx!=-1 ) - { - neighborKey.getNeighbors( sNodes.treeNodes[i] ); - _points[ pIdx ].value = WeightedCoarserFunctionValue( neighborKey , sNodes.treeNodes[i] , metSolution ); - } - } - } - } - template< int Degree > - Real Octree< Degree >::WeightedCoarserFunctionValue( const OctNode< TreeNodeData , Real >::NeighborKey3& neighborKey , const TreeOctNode* pointNode , Real* metSolution ) const - { - int depth = pointNode->depth(); - if( !depth || pointNode->nodeData.pointIndex==-1 ) return Real(0.); - double pointValue = 0; - - Real weight = _points[ pointNode->nodeData.pointIndex ].weight; - Point3D< Real > p = _points[ pointNode->nodeData.pointIndex ].position; - - // Iterate over all basis functions that overlap the point at the coarser resolutions - { - int d , _idx[3]; - const TreeOctNode::Neighbors3& neighbors = neighborKey.neighbors[depth-1]; - neighbors.neighbors[1][1][1]->depthAndOffset( d , _idx ); - _idx[0] = BinaryNode< double >::CenterIndex( d , _idx[0]-1 ); - _idx[1] = BinaryNode< double >::CenterIndex( d , _idx[1]-1 ); - _idx[2] = BinaryNode< double >::CenterIndex( d , _idx[2]-1 ); - for( int j=0 ; j<3 ; j++ ) for( int k=0 ; k<3 ; k++ ) for( int l=0 ; l<3 ; l++ ) - if( neighbors.neighbors[j][k][l] && neighbors.neighbors[j][k][l]->nodeData.nodeIndex>=0 ) - { - // Accumulate the contribution from these basis nodes - const TreeOctNode* basisNode = neighbors.neighbors[j][k][l]; - int idx[] = { _idx[0]+j , _idx[1]+k , _idx[2]+l }; - pointValue += - fData.baseBSplines[ idx[0] ][2-j]( p[0] ) * - fData.baseBSplines[ idx[1] ][2-k]( p[1] ) * - fData.baseBSplines[ idx[2] ][2-l]( p[2] ) * - metSolution[basisNode->nodeData.nodeIndex]; - } - } - return Real( pointValue * weight ); - } - template - int Octree::GetFixedDepthLaplacian( SparseSymmetricMatrix< Real >& matrix , int depth , const SortedTreeNodes& sNodes , Real* metSolution ) - { - int start = sNodes.nodeCount[depth] , end = sNodes.nodeCount[depth+1] , range = end-start; - double stencil[5][5][5]; - SetLaplacianStencil( depth , stencil ); - Stencil< double , 5 > stencils[2][2][2]; - SetLaplacianStencils( depth , stencils ); - matrix.Resize( range ); -#pragma omp parallel for num_threads( threads ) - for( int t=0 ; tparent ) - { - c = int( node - node->parent->children ); - Cube::FactorCornerIndex( c , x , y , z ); - } - else x = y = z = 0; - UpdateConstraintsFromCoarser( neighborKey5 , node , metSolution , stencils[x][y][z] ); - } - } - return 1; - } - template - int Octree::GetRestrictedFixedDepthLaplacian( SparseSymmetricMatrix< Real >& matrix,int depth,const int* entries,int entryCount, - const TreeOctNode* rNode , Real radius , - const SortedTreeNodes& sNodes , Real* metSolution ) - { - for( int i=0 ; inodeData.nodeIndex = i; - double stencil[5][5][5]; - int rDepth , rOff[3]; - rNode->depthAndOffset( rDepth , rOff ); - matrix.Resize( entryCount ); - SetLaplacianStencil( depth , stencil ); - Stencil< double , 5 > stencils[2][2][2]; - SetLaplacianStencils( depth , stencils ); -#pragma omp parallel for num_threads( threads ) - for( int t=0 ; tdepthAndOffset( d , off ); - off[0] >>= (depth-rDepth) , off[1] >>= (depth-rDepth) , off[2] >>= (depth-rDepth); - bool isInterior = ( off[0]==rOff[0] && off[1]==rOff[1] && off[2]==rOff[2] ); - - neighborKey5.getNeighbors( node ); - - int xStart=0 , xEnd=5 , yStart=0 , yEnd=5 , zStart=0 , zEnd=5; - if( !isInterior ) SetMatrixRowBounds( neighborKey5.neighbors[depth].neighbors[2][2][2] , rDepth , rOff , xStart , xEnd , yStart , yEnd , zStart , zEnd ); - - // Get the matrix row size - int count = GetMatrixRowSize( neighborKey5.neighbors[depth] , xStart , xEnd , yStart , yEnd , zStart , zEnd ); - - // Allocate memory for the row -#pragma omp critical (matrix_set_row_size) - { - matrix.SetRowSize( i , count ); - } - - // Set the matrix row entries - matrix.rowSizes[i] = SetMatrixRow( neighborKey5.neighbors[depth] , matrix[i] , 0 , stencil , xStart , xEnd , yStart , yEnd , zStart , zEnd ); - // Adjust the system constraints - int x , y , z , c; - if( node->parent ) - { - c = int( node - node->parent->children ); - Cube::FactorCornerIndex( c , x , y , z ); - } - else x = y = z = 0; - UpdateConstraintsFromCoarser( neighborKey5 , node , metSolution , stencils[x][y][z] ); - } - } - for( int i=0 ; inodeData.nodeIndex = entries[i]; - return 1; - } - - template - int Octree::LaplacianMatrixIteration( int subdivideDepth , bool showResidual , int minIters , double accuracy ) - { - int i,iter=0; - double t = 0; - fData.setDotTables( fData.DD_DOT_FLAG | fData.DV_DOT_FLAG ); - - SparseMatrix< float >::SetAllocator( MEMORY_ALLOCATOR_BLOCK_SIZE ); - _sNodes.treeNodes[0]->nodeData.solution = 0; - - std::vector< Real > metSolution( _sNodes.nodeCount[ _sNodes.maxDepth ] , 0 ); - - for( i=1 ; i<_sNodes.maxDepth ; i++ ) - { - if( subdivideDepth>0 ) iter += SolveFixedDepthMatrix( i , _sNodes , &metSolution[0] , subdivideDepth , showResidual , minIters , accuracy ); - else iter += SolveFixedDepthMatrix( i , _sNodes , &metSolution[0] , showResidual , minIters , accuracy ); - } - SparseMatrix< float >::internalAllocator.reset(); - fData.clearDotTables( fData.VV_DOT_FLAG | fData.DV_DOT_FLAG | fData.DD_DOT_FLAG ); - - return iter; - } - - template - int Octree::SolveFixedDepthMatrix( int depth , const SortedTreeNodes& sNodes , Real* metSolution , bool showResidual , int minIters , double accuracy ) - { - int iter = 0; - Vector< Real > X , B; - SparseSymmetricMatrix< Real > M; - double systemTime=0. , solveTime=0. , updateTime=0. , evaluateTime = 0.; - - X.Resize( sNodes.nodeCount[depth+1]-sNodes.nodeCount[depth] ); - if( depth<=_minDepth ) UpSampleCoarserSolution( depth , sNodes , X ); - else - { - // Up-sample the cumulative solution into the previous depth - UpSample( depth-1 , sNodes , metSolution ); - // Add in the solution from that depth - if( depth ) -#pragma omp parallel for num_threads( threads ) - for( int i=_sNodes.nodeCount[depth-1] ; i<_sNodes.nodeCount[depth] ; i++ ) metSolution[i] += _sNodes.treeNodes[i]->nodeData.solution; - } - if( _constrainValues ) - { - SetCoarserPointValues( depth , sNodes , metSolution ); - } - - SparseSymmetricMatrix< Real >::internalAllocator.rollBack(); - { - int maxECount = ( (2*Degree+1)*(2*Degree+1)*(2*Degree+1) + 1 ) / 2; - maxECount = ( ( maxECount + 15 ) / 16 ) * 16; - M.Resize( sNodes.nodeCount[depth+1]-sNodes.nodeCount[depth] ); - for( int i=0 ; i::internalAllocator.rollBack(); - GetFixedDepthLaplacian( M , depth , sNodes , metSolution ); - // Set the constraint vector - B.Resize( sNodes.nodeCount[depth+1]-sNodes.nodeCount[depth] ); - for( int i=sNodes.nodeCount[depth] ; inodeData.constraint; - } - - // Solve the linear system - iter += SparseSymmetricMatrix< Real >::Solve( M , B , std::max< int >( int( pow( M.rows , ITERATION_POWER ) ) , minIters ) , X , Real(accuracy) , 0 , threads , (depth<=_minDepth) && !_constrainValues ); - - if( showResidual ) - { - double mNorm = 0; - for( int i=0 ; i %g (%f) [%d]\n" , M.Entries() , sqrt(mNorm) , bNorm , rNorm , rNorm/bNorm , iter ); - } - - // Copy the solution back into the tree (over-writing the constraints) - for( int i=sNodes.nodeCount[depth] ; inodeData.solution = Real( X[i-sNodes.nodeCount[depth]] ); - - return iter; - } - template - int Octree::SolveFixedDepthMatrix( int depth , const SortedTreeNodes& sNodes , Real* metSolution , int startingDepth , bool showResidual , int minIters , double accuracy ) - { - if( startingDepth>=depth ) return SolveFixedDepthMatrix( depth , sNodes , metSolution , showResidual , minIters , accuracy ); - - int i , j , d , tIter=0; - SparseSymmetricMatrix< Real > _M; - Vector< Real > B , B_ , X_; - AdjacencySetFunction asf; - AdjacencyCountFunction acf; - double systemTime = 0 , solveTime = 0 , memUsage = 0 , evaluateTime = 0 , gTime = 0, sTime = 0; - Real myRadius , myRadius2; - - if( depth>_minDepth ) - { - // Up-sample the cumulative solution into the previous depth - UpSample( depth-1 , sNodes , metSolution ); - // Add in the solution from that depth - if( depth ) -#pragma omp parallel for num_threads( threads ) - for( int i=_sNodes.nodeCount[depth-1] ; i<_sNodes.nodeCount[depth] ; i++ ) metSolution[i] += _sNodes.treeNodes[i]->nodeData.solution; - } - - if( _constrainValues ) - { - SetCoarserPointValues( depth , sNodes , metSolution ); - } - B.Resize( sNodes.nodeCount[depth+1] - sNodes.nodeCount[depth] ); - - // Back-up the constraints - for( i=sNodes.nodeCount[depth] ; inodeData.constraint; - sNodes.treeNodes[i]->nodeData.constraint = 0; - } - - myRadius = 2*radius-Real(0.5); - myRadius = int(myRadius-ROUND_EPS)+ROUND_EPS; - myRadius2 = Real(radius+ROUND_EPS-0.5); - d = depth-startingDepth; - std::vector< int > subDimension( sNodes.nodeCount[d+1]-sNodes.nodeCount[d] ); - int maxDimension = 0; - for( i=sNodes.nodeCount[d] ; inextNode() ; temp ; ) - { - if( temp->depth()==depth ) acf.adjacencyCount++ , temp = sNodes.treeNodes[i]->nextBranch( temp ); - else temp = sNodes.treeNodes[i]->nextNode ( temp ); - } - for( j=sNodes.nodeCount[d] ; j( maxDimension , subDimension[i-sNodes.nodeCount[d]] ); - } - asf.adjacencies = new int[maxDimension]; - MapReduceVector< Real > mrVector; - mrVector.resize( threads , maxDimension ); - // Iterate through the coarse-level nodes - for( i=sNodes.nodeCount[d] ; inextNode() ; temp ; ) - { - if( temp->depth()==depth ) asf.adjacencies[ asf.adjacencyCount++ ] = temp->nodeData.nodeIndex , temp = sNodes.treeNodes[i]->nextBranch( temp ); - else temp = sNodes.treeNodes[i]->nextNode ( temp ); - } - for( j=sNodes.nodeCount[d] ; jnodeData.solution; - } - // Get the associated matrix - SparseSymmetricMatrix< Real >::internalAllocator.rollBack(); - GetRestrictedFixedDepthLaplacian( _M , depth , asf.adjacencies , asf.adjacencyCount , sNodes.treeNodes[i] , myRadius , sNodes , metSolution ); -#pragma omp parallel for num_threads( threads ) schedule( static ) - for( j=0 ; jnodeData.constraint; - sNodes.treeNodes[ asf.adjacencies[j] ]->nodeData.constraint = 0; - } - - // Solve the matrix - // Since we don't have the full matrix, the system shouldn't be singular, so we shouldn't have to correct it - iter += SparseSymmetricMatrix< Real >::Solve( _M , B_ , std::max< int >( int( pow( _M.rows , ITERATION_POWER ) ) , minIters ) , X_ , mrVector , Real(accuracy) , 0 ); - - if( showResidual ) - { - double mNorm = 0; - for( int i=0 ; i<_M.rows ; i++ ) for( int j=0 ; j<_M.rowSizes[i] ; j++ ) mNorm += _M[i][j].Value * _M[i][j].Value; - double bNorm = B_.Norm( 2 ) , rNorm = ( B_ - _M * X_ ).Norm( 2 ); - printf( "\t\tResidual: (%d %g) %g -> %g (%f) [%d]\n" , _M.Entries() , sqrt(mNorm) , bNorm , rNorm , rNorm/bNorm , iter ); - } - - // Update the solution for all nodes in the sub-tree - for( j=0 ; jdepth()>sNodes.treeNodes[i]->depth() ) temp=temp->parent; - if( temp->nodeData.nodeIndex>=sNodes.treeNodes[i]->nodeData.nodeIndex ) sNodes.treeNodes[ asf.adjacencies[j] ]->nodeData.solution = Real( X_[j] ); - } - systemTime += gTime; - solveTime += sTime; - memUsage = std::max< double >( MemoryUsage() , memUsage ); - tIter += iter; - } - delete[] asf.adjacencies; - return tIter; - } - template - int Octree::HasNormals(TreeOctNode* node,Real epsilon) - { - int hasNormals=0; - if( node->nodeData.normalIndex>=0 && ( (*normals)[node->nodeData.normalIndex][0]!=0 || (*normals)[node->nodeData.normalIndex][1]!=0 || (*normals)[node->nodeData.normalIndex][2]!=0 ) ) hasNormals=1; - if( node->children ) for(int i=0;ichildren[i],epsilon); - - return hasNormals; - } - template - void Octree::ClipTree( void ) - { - int maxDepth = tree.maxDepth(); - for( TreeOctNode* temp=tree.nextNode() ; temp ; temp=tree.nextNode(temp) ) - if( temp->children && temp->d>=_minDepth ) - { - int hasNormals=0; - for( int i=0 ; ichildren[i] , EPSILON/(1<children=NULL; - } - MemoryUsage(); - } - template - void Octree::SetLaplacianConstraints( void ) - { - // To set the Laplacian constraints, we iterate over the - // splatted normals and compute the dot-product of the - // divergence of the normal field with all the basis functions. - // Within the same depth: set directly as a gather - // Coarser depths - fData.setDotTables( fData.VV_DOT_FLAG | fData.DV_DOT_FLAG ); - - int maxDepth = _sNodes.maxDepth-1; - Point3D< Real > zeroPoint; - zeroPoint[0] = zeroPoint[1] = zeroPoint[2] = 0; - std::vector< Real > constraints( _sNodes.nodeCount[maxDepth] , Real(0) ); - std::vector< Point3D< Real > > coefficients( _sNodes.nodeCount[maxDepth] , zeroPoint ); - - // Clear the constraints -#pragma omp parallel for num_threads( threads ) - for( int i=0 ; i<_sNodes.nodeCount[maxDepth+1] ; i++ ) _sNodes.treeNodes[i]->nodeData.constraint = Real( 0. ); - - // For the scattering part of the operation, we parallelize by duplicating the constraints and then summing at the end. - std::vector< std::vector< Real > > _constraints( threads ); - for( int t=0 ; t=0 ; d-- ) - { - Point3D< double > stencil[5][5][5]; - SetDivergenceStencil( d , &stencil[0][0][0] , false ); - Stencil< Point3D< double > , 5 > stencils[2][2][2]; - SetDivergenceStencils( d , stencils , true ); -#pragma omp parallel for num_threads( threads ) - for( int t=0 ; tdepth(); - neighborKey5.getNeighbors( node ); - - bool isInterior , isInterior2; - { - int d , off[3]; - node->depthAndOffset( d , off ); - int mn = 2 , mx = (1<=mn && off[0]=mn && off[1]=mn && off[2]=mn && off[0]=mn && off[1]=mn && off[2]parent->children ); - Cube::FactorCornerIndex( c , cx , cy , cz ); - } - else cx = cy = cz = 0; - Stencil< Point3D< double > , 5 >& _stencil = stencils[cx][cy][cz]; - - // Set constraints from current depth - { - const TreeOctNode::Neighbors5& neighbors5 = neighborKey5.neighbors[depth]; - - if( isInterior ) - for( int x=startX ; xnodeData.normalIndex>=0 ) - { - const Point3D< Real >& _normal = (*normals)[_node->nodeData.normalIndex]; - node->nodeData.constraint += Real( stencil[x][y][z][0] * _normal[0] + stencil[x][y][z][1] * _normal[1] + stencil[x][y][z][2] * _normal[2] ); - } - } - else - for( int x=startX ; xnodeData.normalIndex>=0 ) - { - const Point3D< Real >& _normal = (*normals)[_node->nodeData.normalIndex]; - node->nodeData.constraint += GetDivergence( _node , node , _normal ); - } - } - UpdateCoarserSupportBounds( neighbors5.neighbors[2][2][2] , startX , endX , startY , endY , startZ , endZ ); - } - if( node->nodeData.nodeIndex<0 || node->nodeData.normalIndex<0 ) continue; - const Point3D< Real >& normal = (*normals)[node->nodeData.normalIndex]; - if( normal[0]==0 && normal[1]==0 && normal[2]==0 ) continue; - if( depth& div = _stencil.values[x][y][z]; - _constraints[t][ _node->nodeData.nodeIndex ] += Real( div[0] * normal[0] + div[1] * normal[1] + div[2] * normal[2] ); - } - else _constraints[t][ _node->nodeData.nodeIndex ] += GetDivergence( node , _node , normal ); - } - } - } - } - } -#pragma omp parallel for num_threads( threads ) schedule( static ) - for( int i=0 ; i<_sNodes.nodeCount[maxDepth] ; i++ ) - { - Real cSum = Real(0.); - for( int t=0 ; t=0 ; d-- ) DownSample( d , _sNodes , &constraints[0] ); - - // Coarse-to-fine up-sampling of coefficients - for( int d=0 ; dnodeData.constraint += constraints[i]; - - // Compute the contribution from all coarser depths - for( int d=0 ; d<=maxDepth ; d++ ) - { - int start = _sNodes.nodeCount[d] , end = _sNodes.nodeCount[d+1] , range = end - start; - Stencil< Point3D< double > , 5 > stencils[2][2][2]; - SetDivergenceStencils( d , stencils , false ); -#pragma omp parallel for num_threads( threads ) - for( int t=0 ; tdepth(); - if( !depth ) continue; - int startX=0 , endX=5 , startY=0 , endY=5 , startZ=0 , endZ=5; - UpdateCoarserSupportBounds( node , startX , endX , startY , endY , startZ , endZ ); - const TreeOctNode::Neighbors5& neighbors5 = neighborKey5.getNeighbors( node->parent ); - - bool isInterior; - { - int d , off[3]; - node->depthAndOffset( d , off ); - int mn = 4 , mx = (1<=mn && off[0]=mn && off[1]=mn && off[2]parent->children ); - Cube::FactorCornerIndex( c , cx , cy , cz ); - } - else cx = cy = cz = 0; - Stencil< Point3D< double > , 5 >& _stencil = stencils[cx][cy][cz]; - - Real constraint = Real(0); - for( int x=startX ; xnodeData.nodeIndex; - if( isInterior ) - { - Point3D< double >& div = _stencil.values[x][y][z]; - Point3D< Real >& normal = coefficients[_i]; - constraint += Real( div[0] * normal[0] + div[1] * normal[1] + div[2] * normal[2] ); - } - else constraint += GetDivergence( _node , node , coefficients[_i] ); - } - node->nodeData.constraint += constraint; - } - } - } - - fData.clearDotTables( fData.DV_DOT_FLAG ); - - // Set the point weights for evaluating the iso-value -#pragma omp parallel for num_threads( threads ) - for( int t=0 ; tnodeData.nodeIndex<0 || temp->nodeData.normalIndex<0 ) temp->nodeData.centerWeightContribution = 0; - else temp->nodeData.centerWeightContribution = Real( Length((*normals)[temp->nodeData.normalIndex]) ); - } - MemoryUsage(); - delete normals; - normals = NULL; - } - template - void Octree::AdjacencyCountFunction::Function(const TreeOctNode* node1,const TreeOctNode* node2){adjacencyCount++;} - template - void Octree::AdjacencySetFunction::Function(const TreeOctNode* node1,const TreeOctNode* node2){adjacencies[adjacencyCount++]=node1->nodeData.nodeIndex;} - template - void Octree::RefineFunction::Function( TreeOctNode* node1 , const TreeOctNode* node2 ) - { - if( !node1->children && node1->depth()initChildren(); - } - template< int Degree > - void Octree< Degree >::FaceEdgesFunction::Function( const TreeOctNode* node1 , const TreeOctNode* node2 ) - { - if( !node1->children && MarchingCubes::HasRoots( node1->nodeData.mcIndex ) ) - { - RootInfo ri1 , ri2; - hash_map< long long , std::pair< RootInfo , int > >::iterator iter; - int isoTri[DIMENSION*MarchingCubes::MAX_TRIANGLES]; - int count=MarchingCubes::AddTriangleIndices( node1->nodeData.mcIndex , isoTri ); - - for( int j=0 ; jpush_back( std::pair< RootInfo , RootInfo >( ri2 , ri1 ) ); - iter = vertexCount->find( key1 ); - if( iter==vertexCount->end() ) - { - (*vertexCount)[key1].first = ri1; - (*vertexCount)[key1].second=0; - } - iter=vertexCount->find(key2); - if( iter==vertexCount->end() ) - { - (*vertexCount)[key2].first = ri2; - (*vertexCount)[key2].second=0; - } - (*vertexCount)[key1].second--; - (*vertexCount)[key2].second++; - } - else fprintf( stderr , "Bad Edge 1: %d %d\n" , ri1.key , ri2.key ); - } - } - - template< int Degree > - void Octree< Degree >::RefineBoundary( int subdivideDepth ) - { - // This implementation is somewhat tricky. - // We would like to ensure that leaf-nodes across a subdivision boundary have the same depth. - // We do this by calling the setNeighbors function. - // The key is to implement this in a single pass through the leaves, ensuring that refinements don't propogate. - // To this end, we do the minimal refinement that ensures that a cross boundary neighbor, and any of its cross-boundary - // neighbors are all refined simultaneously. - // For this reason, the implementation can only support nodes deeper than sDepth. - bool flags[3][3][3]; - int maxDepth = tree.maxDepth(); - - int sDepth; - if( subdivideDepth<=0 ) sDepth = 0; - else sDepth = maxDepth-subdivideDepth; - if( sDepth<=0 ) return; - - // Ensure that face adjacent neighbors across the subdivision boundary exist to allow for - // a consistent definition of the iso-surface - TreeOctNode::NeighborKey3 nKey; - nKey.set( maxDepth ); - for( TreeOctNode* leaf=tree.nextLeaf() ; leaf ; leaf=tree.nextLeaf( leaf ) ) - if( leaf->depth()>sDepth ) - { - int d , off[3] , _off[3]; - leaf->depthAndOffset( d , off ); - int res = (1< - void Octree::GetMCIsoTriangles( Real isoValue , int subdivideDepth , CoredMeshData* mesh , int fullDepthIso , int nonLinearFit , bool addBarycenter , bool polygonMesh ) - { - fData.setValueTables( fData.VALUE_FLAG | fData.D_VALUE_FLAG , 0 , postNormalSmooth ); - - // Ensure that the subtrees are self-contained - RefineBoundary( subdivideDepth ); - - RootData rootData , coarseRootData; - std::vector< Point3D< float > >* interiorPoints; - int maxDepth = tree.maxDepth(); - - int sDepth = subdivideDepth<=0 ? 0 : std::max< int >( 0 , maxDepth-subdivideDepth ); - - std::vector< Real > metSolution( _sNodes.nodeCount[maxDepth] , 0 ); -#pragma omp parallel for num_threads( threads ) - for( int i=_sNodes.nodeCount[_minDepth] ; i<_sNodes.nodeCount[maxDepth] ; i++ ) metSolution[i] = _sNodes.treeNodes[i]->nodeData.solution; - for( int d=0 ; dnodeData.mcIndex = 0; - - rootData.boundaryValues = new hash_map< long long , std::pair< Real , Point3D< Real > > >(); - int offSet = 0; - - int maxCCount = _sNodes.getMaxCornerCount( &tree , sDepth , maxDepth , threads ); - int maxECount = _sNodes.getMaxEdgeCount ( &tree , sDepth , threads ); - rootData.cornerValues = new Real [ maxCCount ]; - rootData.cornerNormals = new Point3D< Real >[ maxCCount ]; - rootData.interiorRoots = new int [ maxECount ]; - rootData.cornerValuesSet = new char[ maxCCount ]; - rootData.cornerNormalsSet = new char[ maxCCount ]; - rootData.edgesSet = new char[ maxECount ]; - _sNodes.setCornerTable( coarseRootData , &tree , sDepth , threads ); - coarseRootData.cornerValues = new Real[ coarseRootData.cCount ]; - coarseRootData.cornerNormals = new Point3D< Real >[ coarseRootData.cCount ]; - coarseRootData.cornerValuesSet = new char[ coarseRootData.cCount ]; - coarseRootData.cornerNormalsSet = new char[ coarseRootData.cCount ]; - memset( coarseRootData.cornerValuesSet , 0 , sizeof( char ) * coarseRootData.cCount ); - memset( coarseRootData.cornerNormalsSet , 0 , sizeof( char ) * coarseRootData.cCount ); - MemoryUsage(); - - std::vector< TreeOctNode::ConstNeighborKey3 > nKeys( threads ); - for( int t=0 ; t nKeys5( threads ); - for( int t=0 ; tchildren ) continue; - - _sNodes.setCornerTable( rootData , _sNodes.treeNodes[i] , threads ); - _sNodes.setEdgeTable ( rootData , _sNodes.treeNodes[i] , threads ); - memset( rootData.cornerValuesSet , 0 , sizeof( char ) * rootData.cCount ); - memset( rootData.cornerNormalsSet , 0 , sizeof( char ) * rootData.cCount ); - memset( rootData.edgesSet , 0 , sizeof( char ) * rootData.eCount ); - interiorPoints = new std::vector< Point3D< float > >(); - for( int d=maxDepth ; d>sDepth ; d-- ) - { - int leafNodeCount = 0; - std::vector< TreeOctNode* > leafNodes; - for( TreeOctNode* node=_sNodes.treeNodes[i]->nextLeaf() ; node ; node=_sNodes.treeNodes[i]->nextLeaf( node ) ) if( node->d==d ) leafNodeCount++; - leafNodes.reserve( leafNodeCount ); - for( TreeOctNode* node=_sNodes.treeNodes[i]->nextLeaf() ; node ; node=_sNodes.treeNodes[i]->nextLeaf( node ) ) if( node->d==d ) leafNodes.push_back( node ); - Stencil< double , 3 > stencil1[8] , stencil2[8][8]; - SetEvaluationStencils( d , stencil1 , stencil2 ); - - // First set the corner values and associated marching-cube indices -#pragma omp parallel for num_threads( threads ) - for( int t=0 ; tdepthAndOffset( d , off ); - int res = 1<<(d-sDepth); - off[0] %= res , off[1] %=res , off[2] %= res; - res--; - if( !(off[0]%res) && !(off[1]%res) && !(off[2]%res) ) - { - const TreeOctNode* temp = leaf; - while( temp->d!=sDepth ) temp = temp->parent; - int x = off[0]==0 ? 0 : 1 , y = off[1]==0 ? 0 : 1 , z = off[2]==0 ? 0 : 1; - int c = Cube::CornerIndex( x , y , z ); - int idx = coarseRootData.cornerIndices( temp )[ c ]; - coarseRootData.cornerValues[ idx ] = rootData.cornerValues[ rootData.cornerIndices( leaf )[c] ]; - coarseRootData.cornerValuesSet[ idx ] = true; - } - - // Compute the iso-vertices - if( MarchingCubes::HasRoots( leaf->nodeData.mcIndex ) ) - SetMCRootPositions( leaf , sDepth , isoValue , nKeys5[t] , rootData , interiorPoints , mesh , &metSolution[0] , nonLinearFit ); - } - // Note that this should be broken off for multi-threading as - // the SetMCRootPositions writes to interiorPoints (with lockupdateing) - // while GetMCIsoTriangles reads from interiorPoints (without locking) -#if MISHA_DEBUG - std::vector< Point3D< float > > barycenters; - std::vector< Point3D< float > >* barycenterPtr = addBarycenter ? & barycenters : NULL; -#endif // MISHA_DEBUG -#pragma omp parallel for num_threads( threads ) - for( int t=0 ; tnodeData.mcIndex ) ) -#if MISHA_DEBUG - GetMCIsoTriangles( leaf , mesh , rootData , interiorPoints , offSet , sDepth , polygonMesh , barycenterPtr ); -#else // !MISHA_DEBUG - GetMCIsoTriangles( leaf , mesh , rootData , interiorPoints , offSet , sDepth , addBarycenter , polygonMesh ); -#endif // MISHA_DEBUG - } -#if MISHA_DEBUG - for( int i=0 ; ipush_back( barycenters[i] ); -#endif // MISHA_DEBUG - } - offSet = mesh->outOfCorePointCount(); -#if 1 - delete interiorPoints; -#endif - } - MemoryUsage(); - delete[] rootData.cornerValues , delete[] rootData.cornerNormals , rootData.cornerValues = NULL , rootData.cornerNormals = NULL; - delete[] rootData.cornerValuesSet , delete[] rootData.cornerNormalsSet , rootData.cornerValuesSet = NULL , rootData.cornerNormalsSet = NULL; - delete[] rootData.interiorRoots ; rootData.interiorRoots = NULL; - delete[] rootData.edgesSet ; rootData.edgesSet = NULL; - coarseRootData.interiorRoots = NULL; - coarseRootData.boundaryValues = rootData.boundaryValues; - for( poisson::hash_map< long long , int >::iterator iter=rootData.boundaryRoots.begin() ; iter!=rootData.boundaryRoots.end() ; iter++ ) - coarseRootData.boundaryRoots[iter->first] = iter->second; - - for( int d=sDepth ; d>=0 ; d-- ) - { - Stencil< double , 3 > stencil1[8] , stencil2[8][8]; - SetEvaluationStencils( d , stencil1 , stencil2 ); -#if MISHA_DEBUG - std::vector< Point3D< float > > barycenters; - std::vector< Point3D< float > >* barycenterPtr = addBarycenter ? &barycenters : NULL; -#endif // MISHA_DEBUG - for( int i=_sNodes.nodeCount[d] ; i<_sNodes.nodeCount[d+1] ; i++ ) - { - TreeOctNode* leaf = _sNodes.treeNodes[i]; - if( leaf->children ) continue; - - // First set the corner values and associated marching-cube indices - SetIsoCorners( isoValue , leaf , coarseRootData , coarseRootData.cornerValuesSet , coarseRootData.cornerValues , nKey , &metSolution[0] , stencil1 , stencil2 ); - - // Now compute the iso-vertices - if( MarchingCubes::HasRoots( leaf->nodeData.mcIndex ) ) - { - SetMCRootPositions( leaf , 0 , isoValue , nKey5 , coarseRootData , NULL , mesh , &metSolution[0] , nonLinearFit ); -#if MISHA_DEBUG - GetMCIsoTriangles( leaf , mesh , coarseRootData , NULL , 0 , 0 , polygonMesh , barycenterPtr ); -#else // !MISHA_DEBUG - GetMCIsoTriangles( leaf , mesh , coarseRootData , NULL , 0 , 0 , addBarycenter , polygonMesh ); -#endif // MISHA_DEBUG - } - } - } - MemoryUsage(); - - delete[] coarseRootData.cornerValues , delete[] coarseRootData.cornerNormals; - delete[] coarseRootData.cornerValuesSet , delete[] coarseRootData.cornerNormalsSet; - delete rootData.boundaryValues; - } - template - Real Octree::getCenterValue( const OctNode< TreeNodeData , Real >::ConstNeighborKey3& neighborKey , const TreeOctNode* node){ - int idx[3]; - Real value=0; - - VertexData::CenterIndex(node,fData.depth,idx); - idx[0]*=fData.functionCount; - idx[1]*=fData.functionCount; - idx[2]*=fData.functionCount; - int minDepth = std::max< int >( 0 , std::min< int >( _minDepth , node->depth()-1 ) ); - for( int i=minDepth ; i<=node->depth() ; i++ ) - for(int j=0;j<3;j++) - for(int k=0;k<3;k++) - for(int l=0;l<3;l++) - { - const TreeOctNode* n=neighborKey.neighbors[i].neighbors[j][k][l]; - if( n ) - { - Real temp=n->nodeData.solution; - value+=temp*Real( - fData.valueTables[idx[0]+int(n->off[0])]* - fData.valueTables[idx[1]+int(n->off[1])]* - fData.valueTables[idx[2]+int(n->off[2])]); - } - } - if(node->children) - { - for(int i=0;ichildren[i]; - while(1){ - value+=n->nodeData.solution*Real( - fData.valueTables[idx[0]+int(n->off[0])]* - fData.valueTables[idx[1]+int(n->off[1])]* - fData.valueTables[idx[2]+int(n->off[2])]); - if( n->children ) n=&n->children[ii]; - else break; - } - } - } - return value; - } - template< int Degree > - Real Octree< Degree >::getCornerValue( const OctNode< TreeNodeData , Real >::ConstNeighborKey3& neighborKey3 , const TreeOctNode* node , int corner , const Real* metSolution ) - { - int idx[3]; - double value = 0; - - VertexData::CornerIndex( node , corner , fData.depth , idx ); - idx[0] *= fData.functionCount; - idx[1] *= fData.functionCount; - idx[2] *= fData.functionCount; - - int d = node->depth(); - int cx , cy , cz; - int startX = 0 , endX = 3 , startY = 0 , endY = 3 , startZ = 0 , endZ = 3; - Cube::FactorCornerIndex( corner , cx , cy , cz ); - { - TreeOctNode::ConstNeighbors3& neighbors = neighborKey3.neighbors[d]; - if( cx==0 ) endX = 2; - else startX = 1; - if( cy==0 ) endY = 2; - else startY = 1; - if( cz==0 ) endZ = 2; - else startZ = 1; - for( int x=startX ; xoff[0]) ]* - fData.valueTables[ idx[1]+int(n->off[1]) ]* - fData.valueTables[ idx[2]+int(n->off[2]) ]; - value += n->nodeData.solution * v; - } - } - } - if( d>0 && d>_minDepth ) - { - int _corner = int( node - node->parent->children ); - int _cx , _cy , _cz; - Cube::FactorCornerIndex( _corner , _cx , _cy , _cz ); - if( cx!=_cx ) startX = 0 , endX = 3; - if( cy!=_cy ) startY = 0 , endY = 3; - if( cz!=_cz ) startZ = 0 , endZ = 3; - TreeOctNode::ConstNeighbors3& neighbors = neighborKey3.neighbors[d-1]; - for( int x=startX ; xoff[0]) ]* - fData.valueTables[ idx[1]+int(n->off[1]) ]* - fData.valueTables[ idx[2]+int(n->off[2]) ]; - value += metSolution[ n->nodeData.nodeIndex ] * v; - } - } - } - return Real( value ); - } - template< int Degree > - Real Octree< Degree >::getCornerValue( const OctNode< TreeNodeData , Real >::ConstNeighborKey3& neighborKey3 , const TreeOctNode* node , int corner , const Real* metSolution , const double stencil1[3][3][3] , const double stencil2[3][3][3] ) - { - double value = 0; - int d = node->depth(); - int cx , cy , cz; - int startX = 0 , endX = 3 , startY = 0 , endY = 3 , startZ = 0 , endZ = 3; - Cube::FactorCornerIndex( corner , cx , cy , cz ); - { - TreeOctNode::ConstNeighbors3& neighbors = neighborKey3.neighbors[d]; - if( cx==0 ) endX = 2; - else startX = 1; - if( cy==0 ) endY = 2; - else startY = 1; - if( cz==0 ) endZ = 2; - else startZ = 1; - for( int x=startX ; xnodeData.solution * stencil1[x][y][z]; - } - } - if( d>0 && d>_minDepth ) - { - int _corner = int( node - node->parent->children ); - int _cx , _cy , _cz; - Cube::FactorCornerIndex( _corner , _cx , _cy , _cz ); - if( cx!=_cx ) startX = 0 , endX = 3; - if( cy!=_cy ) startY = 0 , endY = 3; - if( cz!=_cz ) startZ = 0 , endZ = 3; - TreeOctNode::ConstNeighbors3& neighbors = neighborKey3.neighbors[d-1]; - for( int x=startX ; xnodeData.nodeIndex ] * stencil2[x][y][z]; - } - } - return Real( value ); - } - template< int Degree > - Point3D< Real > Octree< Degree >::getCornerNormal( const OctNode< TreeNodeData , Real >::ConstNeighborKey5& neighborKey5 , const TreeOctNode* node , int corner , const Real* metSolution ) - { - int idx[3]; - Point3D< Real > normal; - normal[0] = normal[1] = normal[2] = 0.; - - VertexData::CornerIndex( node , corner , fData.depth , idx ); - idx[0] *= fData.functionCount; - idx[1] *= fData.functionCount; - idx[2] *= fData.functionCount; - - int d = node->depth(); - // Iterate over all ancestors that can overlap the corner - { - TreeOctNode::ConstNeighbors5& neighbors = neighborKey5.neighbors[d]; - for( int j=0 ; j<5 ; j++ ) for( int k=0 ; k<5 ; k++ ) for( int l=0 ; l<5 ; l++ ) - { - const TreeOctNode* n=neighbors.neighbors[j][k][l]; - if( n ) - { - int _idx[] = { idx[0] + n->off[0] , idx[1] + n->off[1] , idx[2] + n->off[2] }; - double values[] = { fData.valueTables[_idx[0]] , fData.valueTables[_idx[1]] , fData.valueTables[_idx[2]] }; - double dValues[] = { fData.dValueTables[_idx[0]] , fData.dValueTables[_idx[1]] , fData.dValueTables[_idx[2]] }; - Real solution = n->nodeData.solution; - normal[0] += Real( dValues[0] * values[1] * values[2] * solution ); - normal[1] += Real( values[0] * dValues[1] * values[2] * solution ); - normal[2] += Real( values[0] * values[1] * dValues[2] * solution ); - } - } - } - if( d>0 && d>_minDepth ) - { - TreeOctNode::ConstNeighbors5& neighbors = neighborKey5.neighbors[d-1]; - for( int j=0 ; j<5 ; j++ ) for( int k=0 ; k<5 ; k++ ) for( int l=0 ; l<5 ; l++ ) - { - const TreeOctNode* n=neighbors.neighbors[j][k][l]; - if( n ) - { - int _idx[] = { idx[0] + n->off[0] , idx[1] + n->off[1] , idx[2] + n->off[2] }; - double values[] = { fData.valueTables[_idx[0]] , fData.valueTables[_idx[1]] , fData.valueTables[_idx[2]] }; - double dValues[] = { fData.dValueTables[_idx[0]] , fData.dValueTables[_idx[1]] , fData.dValueTables[_idx[2]] }; - Real solution = metSolution[ n->nodeData.nodeIndex ]; - normal[0] += Real( dValues[0] * values[1] * values[2] * solution ); - normal[1] += Real( values[0] * dValues[1] * values[2] * solution ); - normal[2] += Real( values[0] * values[1] * dValues[2] * solution ); - } - } - } - return normal; - } - template< int Degree > - Real Octree::GetIsoValue( void ) - { - Real isoValue , weightSum; - - neighborKey2.set( fData.depth ); - fData.setValueTables( fData.VALUE_FLAG , 0 ); - - isoValue = weightSum = 0; -#pragma omp parallel for num_threads( threads ) reduction( + : isoValue , weightSum ) - for( int t=0 ; tnodeData.centerWeightContribution; - if( w!=0 ) - { - isoValue += getCenterValue( nKey , temp ) * w; - weightSum += w; - } - } - } - return isoValue/weightSum; - } - - template< int Degree > - void Octree< Degree >::SetIsoCorners( Real isoValue , TreeOctNode* leaf , SortedTreeNodes::CornerTableData& cData , char* valuesSet , Real* values , TreeOctNode::ConstNeighborKey3& nKey , const Real* metSolution , const Stencil< double , 3 > stencil1[8] , const Stencil< double , 3 > stencil2[8][8] ) - { - Real cornerValues[ Cube::CORNERS ]; - const SortedTreeNodes::CornerIndices& cIndices = cData[ leaf ]; - - bool isInterior; - int d , off[3]; - leaf->depthAndOffset( d , off ); - int mn = 2 , mx = (1<=mn && off[0]=mn && off[1]=mn && off[2]parent->children)][c].values ); - else cornerValues[c] = getCornerValue( nKey , leaf , c , metSolution ); - values[vIndex] = cornerValues[c]; - valuesSet[vIndex] = 1; - } - } - - leaf->nodeData.mcIndex = MarchingCubes::GetIndex( cornerValues , isoValue ); - - // Set the marching cube indices for all interior nodes. - if( leaf->parent ) - { - TreeOctNode* parent = leaf->parent; - int c = int( leaf - leaf->parent->children ); - int mcid = leaf->nodeData.mcIndex & (1<nodeData.mcIndex, mcid); - - while( 1 ) - { - if( parent->parent && parent->parent->d>=_minDepth && (parent-parent->parent->children)==c ) - { - poisson::atomicOr(parent->parent->nodeData.mcIndex, mcid); - parent = parent->parent; - } - else break; - } - } - } - } - - - template - int Octree::InteriorFaceRootCount(const TreeOctNode* node,const int &faceIndex,int maxDepth){ - int c1,c2,e1,e2,dir,off,cnt=0; - int corners[Cube::CORNERS/2]; - if(node->children){ - Cube::FaceCorners(faceIndex,corners[0],corners[1],corners[2],corners[3]); - Cube::FactorFaceIndex(faceIndex,dir,off); - c1=corners[0]; - c2=corners[3]; - switch(dir){ - case 0: - e1=Cube::EdgeIndex(1,off,1); - e2=Cube::EdgeIndex(2,off,1); - break; - case 1: - e1=Cube::EdgeIndex(0,off,1); - e2=Cube::EdgeIndex(2,1,off); - break; - case 2: - e1=Cube::EdgeIndex(0,1,off); - e2=Cube::EdgeIndex(1,1,off); - break; - }; - cnt+=EdgeRootCount(&node->children[c1],e1,maxDepth)+EdgeRootCount(&node->children[c1],e2,maxDepth); - switch(dir){ - case 0: - e1=Cube::EdgeIndex(1,off,0); - e2=Cube::EdgeIndex(2,off,0); - break; - case 1: - e1=Cube::EdgeIndex(0,off,0); - e2=Cube::EdgeIndex(2,0,off); - break; - case 2: - e1=Cube::EdgeIndex(0,0,off); - e2=Cube::EdgeIndex(1,0,off); - break; - }; - cnt+=EdgeRootCount(&node->children[c2],e1,maxDepth)+EdgeRootCount(&node->children[c2],e2,maxDepth); - for(int i=0;ichildren[corners[i]].children){cnt+=InteriorFaceRootCount(&node->children[corners[i]],faceIndex,maxDepth);}} - } - return cnt; - } - - template - int Octree::EdgeRootCount(const TreeOctNode* node,int edgeIndex,int maxDepth){ - int f1,f2,c1,c2; - const TreeOctNode* temp; - Cube::FacesAdjacentToEdge(edgeIndex,f1,f2); - - int eIndex; - const TreeOctNode* finest=node; - eIndex=edgeIndex; - if(node->depth()faceNeighbor(f1); - if(temp && temp->children){ - finest=temp; - eIndex=Cube::FaceReflectEdgeIndex(edgeIndex,f1); - } - else{ - temp=node->faceNeighbor(f2); - if(temp && temp->children){ - finest=temp; - eIndex=Cube::FaceReflectEdgeIndex(edgeIndex,f2); - } - else{ - temp=node->edgeNeighbor(edgeIndex); - if(temp && temp->children){ - finest=temp; - eIndex=Cube::EdgeReflectEdgeIndex(edgeIndex); - } - } - } - } - - Cube::EdgeCorners(eIndex,c1,c2); - if(finest->children) return EdgeRootCount(&finest->children[c1],eIndex,maxDepth)+EdgeRootCount(&finest->children[c2],eIndex,maxDepth); - else return MarchingCubes::HasEdgeRoots(finest->nodeData.mcIndex,eIndex); - } - template - int Octree::IsBoundaryFace(const TreeOctNode* node,int faceIndex,int subdivideDepth){ - int dir,offset,d,o[3],idx; - - if(subdivideDepth<0){return 0;} - if(node->d<=subdivideDepth){return 1;} - Cube::FactorFaceIndex(faceIndex,dir,offset); - node->depthAndOffset(d,o); - - idx=(int(o[dir])<<1) + (offset<<1); - return !(idx%(2<<(int(node->d)-subdivideDepth))); - } - template - int Octree::IsBoundaryEdge(const TreeOctNode* node,int edgeIndex,int subdivideDepth){ - int dir,x,y; - Cube::FactorEdgeIndex(edgeIndex,dir,x,y); - return IsBoundaryEdge(node,dir,x,y,subdivideDepth); - } - template - int Octree::IsBoundaryEdge( const TreeOctNode* node , int dir , int x , int y , int subdivideDepth ) - { - int d , o[3] , idx1 , idx2 , mask; - - if( subdivideDepth<0 ) return 0; - if( node->d<=subdivideDepth ) return 1; - node->depthAndOffset( d , o ); - - switch( dir ) - { - case 0: - idx1 = o[1] + x; - idx2 = o[2] + y; - break; - case 1: - idx1 = o[0] + x; - idx2 = o[2] + y; - break; - case 2: - idx1 = o[0] + x; - idx2 = o[1] + y; - break; - } - mask = 1<<( int(node->d) - subdivideDepth ); - return !(idx1%(mask)) || !(idx2%(mask)); - } - template< int Degree > - void Octree< Degree >::GetRootSpan( const RootInfo& ri , Point3D< float >& start , Point3D< float >& end ) - { - int o , i1 , i2; - Real width; - Point3D< Real > c; - - Cube::FactorEdgeIndex( ri.edgeIndex , o , i1 , i2 ); - ri.node->centerAndWidth( c , width ); - switch(o) - { - case 0: - start[0] = c[0] - width/2; - end [0] = c[0] + width/2; - start[1] = end[1] = c[1] - width/2 + width*i1; - start[2] = end[2] = c[2] - width/2 + width*i2; - break; - case 1: - start[0] = end[0] = c[0] - width/2 + width*i1; - start[1] = c[1] - width/2; - end [1] = c[1] + width/2; - start[2] = end[2] = c[2] - width/2 + width*i2; - break; - case 2: - start[0] = end[0] = c[0] - width/2 + width*i1; - start[1] = end[1] = c[1] - width/2 + width*i2; - start[2] = c[2] - width/2; - end [2] = c[2] + width/2; - break; - } - } - ////////////////////////////////////////////////////////////////////////////////////// - // The assumption made when calling this code is that the edge has at most one root // - ////////////////////////////////////////////////////////////////////////////////////// - template< int Degree > - int Octree< Degree >::GetRoot( const RootInfo& ri , Real isoValue , TreeOctNode::ConstNeighborKey5& neighborKey5 , Point3D< Real > & position , RootData& rootData , int sDepth , const Real* metSolution , int nonLinearFit ) - { - if( !MarchingCubes::HasRoots( ri.node->nodeData.mcIndex ) ) return 0; - int c1 , c2; - Cube::EdgeCorners( ri.edgeIndex , c1 , c2 ); - if( !MarchingCubes::HasEdgeRoots( ri.node->nodeData.mcIndex , ri.edgeIndex ) ) return 0; - - long long key1 , key2; - Point3D< Real > n[2]; - - int i , o , i1 , i2 , rCount=0; - Polynomial<2> P; - std::vector< double > roots; - double x0 , x1; - Real center , width; - Real averageRoot=0; - Cube::FactorEdgeIndex( ri.edgeIndex , o , i1 , i2 ); - int idx1[3] , idx2[3]; - key1 = VertexData::CornerIndex( ri.node , c1 , fData.depth , idx1 ); - key2 = VertexData::CornerIndex( ri.node , c2 , fData.depth , idx2 ); - - bool isBoundary = ( IsBoundaryEdge( ri.node , ri.edgeIndex , sDepth )!=0 ); - bool haveKey1 , haveKey2; - std::pair< Real , Point3D< Real > > keyValue1 , keyValue2; - int iter1 , iter2; - { - iter1 = rootData.cornerIndices( ri.node )[ c1 ]; - iter2 = rootData.cornerIndices( ri.node )[ c2 ]; - keyValue1.first = rootData.cornerValues[iter1]; - keyValue2.first = rootData.cornerValues[iter2]; - if( isBoundary ) - { -#pragma omp critical (normal_hash_access) - { - haveKey1 = ( rootData.boundaryValues->find( key1 )!=rootData.boundaryValues->end() ); - haveKey2 = ( rootData.boundaryValues->find( key2 )!=rootData.boundaryValues->end() ); - if( haveKey1 ) keyValue1 = (*rootData.boundaryValues)[key1]; - if( haveKey2 ) keyValue2 = (*rootData.boundaryValues)[key2]; - } - } - else - { - haveKey1 = ( rootData.cornerNormalsSet[ iter1 ] != 0 ); - haveKey2 = ( rootData.cornerNormalsSet[ iter2 ] != 0 ); - keyValue1.first = rootData.cornerValues[iter1]; - keyValue2.first = rootData.cornerValues[iter2]; - if( haveKey1 ) keyValue1.second = rootData.cornerNormals[iter1]; - if( haveKey2 ) keyValue2.second = rootData.cornerNormals[iter2]; - } - } - if( !haveKey1 || !haveKey2 ) neighborKey5.getNeighbors( ri.node ); - if( !haveKey1 ) keyValue1.second = getCornerNormal( neighborKey5 , ri.node , c1 , metSolution ); - x0 = keyValue1.first; - n[0] = keyValue1.second; - - if( !haveKey2 ) keyValue2.second = getCornerNormal( neighborKey5 , ri.node , c2 , metSolution ); - x1 = keyValue2.first; - n[1] = keyValue2.second; - - if( !haveKey1 || !haveKey2 ) - { - if( isBoundary ) - { -#pragma omp critical (normal_hash_access) - { - if( !haveKey1 ) (*rootData.boundaryValues)[key1] = keyValue1; - if( !haveKey2 ) (*rootData.boundaryValues)[key2] = keyValue2; - } - } - else - { - if( !haveKey1 ) rootData.cornerNormals[iter1] = keyValue1.second , rootData.cornerNormalsSet[ iter1 ] = 1; - if( !haveKey2 ) rootData.cornerNormals[iter2] = keyValue2.second , rootData.cornerNormalsSet[ iter2 ] = 1; - } - } - - Point3D< Real > c; - ri.node->centerAndWidth(c,width); - center=c[o]; - for( i=0 ; i=0 && roots[i]<=1 ) - { - averageRoot += Real( roots[i] ); - rCount++; - } - if( rCount && nonLinearFit ) averageRoot /= rCount; - else averageRoot = Real((x0-isoValue)/(x0-x1)); - if( averageRoot<0 || averageRoot>1 ) - { - fprintf( stderr , "[WARNING] Bad average root: %f\n" , averageRoot ); - fprintf( stderr , "\t(%f %f) , (%f %f) (%f)\n" , x0 , x1 , dx0 , dx1 , isoValue ); - if( averageRoot<0 ) averageRoot = 0; - if( averageRoot>1 ) averageRoot = 1; - } - position[o] = Real(center-width/2+width*averageRoot); - return 1; - } - template< int Degree > - int Octree< Degree >::GetRootIndex( const TreeOctNode* node , int edgeIndex , int maxDepth , int sDepth,RootInfo& ri ) - { - int c1,c2,f1,f2; - const TreeOctNode *temp,*finest; - int finestIndex; - - Cube::FacesAdjacentToEdge(edgeIndex,f1,f2); - - finest=node; - finestIndex=edgeIndex; - if(node->depth()faceNeighbor(f1);} - if(temp && temp->children){ - finest=temp; - finestIndex=Cube::FaceReflectEdgeIndex(edgeIndex,f1); - } - else{ - if(IsBoundaryFace(node,f2,sDepth)){temp=NULL;} - else{temp=node->faceNeighbor(f2);} - if(temp && temp->children){ - finest=temp; - finestIndex=Cube::FaceReflectEdgeIndex(edgeIndex,f2); - } - else{ - if(IsBoundaryEdge(node,edgeIndex,sDepth)){temp=NULL;} - else{temp=node->edgeNeighbor(edgeIndex);} - if(temp && temp->children){ - finest=temp; - finestIndex=Cube::EdgeReflectEdgeIndex(edgeIndex); - } - } - } - } - - Cube::EdgeCorners(finestIndex,c1,c2); - if(finest->children){ - if (GetRootIndex(&finest->children[c1],finestIndex,maxDepth,sDepth,ri)) {return 1;} - else if (GetRootIndex(&finest->children[c2],finestIndex,maxDepth,sDepth,ri)) {return 1;} - else - { - fprintf( stderr , "[WARNING] Couldn't find root index with either child\n" ); - return 0; - } - } - else - { - if( !(MarchingCubes::edgeMask()[finest->nodeData.mcIndex] & (1<depthAndOffset(d,off); - ri.node=finest; - ri.edgeIndex=finestIndex; - int eIndex[2],offset; - offset=BinaryNode::Index( d , off[o] ); - switch(o) - { - case 0: - eIndex[0]=BinaryNode::CornerIndex(maxDepth+1,d,off[1],i1); - eIndex[1]=BinaryNode::CornerIndex(maxDepth+1,d,off[2],i2); - break; - case 1: - eIndex[0]=BinaryNode::CornerIndex(maxDepth+1,d,off[0],i1); - eIndex[1]=BinaryNode::CornerIndex(maxDepth+1,d,off[2],i2); - break; - case 2: - eIndex[0]=BinaryNode::CornerIndex(maxDepth+1,d,off[0],i1); - eIndex[1]=BinaryNode::CornerIndex(maxDepth+1,d,off[1],i2); - break; - } - ri.key = (long long)(o) | (long long)(eIndex[0])<<5 | (long long)(eIndex[1])<<25 | (long long)(offset)<<45; - return 1; - } - } - template - int Octree::GetRootIndex( const TreeOctNode* node , int edgeIndex , int maxDepth , RootInfo& ri ) - { - int c1,c2,f1,f2; - const TreeOctNode *temp,*finest; - int finestIndex; - - - // The assumption is that the super-edge has a root along it. - if(!(MarchingCubes::edgeMask()[node->nodeData.mcIndex] & (1<depth()children ) - { - temp=node->faceNeighbor( f1 ); - if( temp && temp->children ) finest = temp , finestIndex = Cube::FaceReflectEdgeIndex( edgeIndex , f1 ); - else - { - temp = node->faceNeighbor( f2 ); - if( temp && temp->children ) finest = temp , finestIndex = Cube::FaceReflectEdgeIndex( edgeIndex , f2 ); - else - { - temp = node->edgeNeighbor( edgeIndex ); - if( temp && temp->children ) finest = temp , finestIndex = Cube::EdgeReflectEdgeIndex( edgeIndex ); - } - } - } - - Cube::EdgeCorners( finestIndex , c1 , c2 ); - if( finest->children ) - { - if ( GetRootIndex( finest->children + c1 , finestIndex , maxDepth , ri ) ) return 1; - else if( GetRootIndex( finest->children + c2 , finestIndex , maxDepth , ri ) ) return 1; - else - { - int d1 , off1[3] , d2 , off2[3]; - node->depthAndOffset( d1 , off1 ); - finest->depthAndOffset( d2 , off2 ); - fprintf( stderr , "[WARNING] Couldn't find root index with either child [%d] (%d %d %d) -> [%d] (%d %d %d) (%d %d)\n" , d1 , off1[0] , off1[1] , off1[2] , d2 , off2[0] , off2[1] , off2[2] , node->children!=NULL , finest->children!=NULL ); - printf( "\t" ); - for( int i=0 ; i<8 ; i++ ) if( node->nodeData.mcIndex & (1<nodeData.mcIndex & (1<depthAndOffset(d,off); - ri.node=finest; - ri.edgeIndex=finestIndex; - int offset,eIndex[2]; - offset = BinaryNode< Real >::CenterIndex( d , off[o] ); - switch(o){ - case 0: - eIndex[0]=BinaryNode::CornerIndex(maxDepth+1,d,off[1],i1); - eIndex[1]=BinaryNode::CornerIndex(maxDepth+1,d,off[2],i2); - break; - case 1: - eIndex[0]=BinaryNode::CornerIndex(maxDepth+1,d,off[0],i1); - eIndex[1]=BinaryNode::CornerIndex(maxDepth+1,d,off[2],i2); - break; - case 2: - eIndex[0]=BinaryNode::CornerIndex(maxDepth+1,d,off[0],i1); - eIndex[1]=BinaryNode::CornerIndex(maxDepth+1,d,off[1],i2); - break; - } - ri.key= (long long)(o) | (long long)(eIndex[0])<<5 | (long long)(eIndex[1])<<25 | (long long)(offset)<<45; - return 1; - } - } - template - int Octree::GetRootPair(const RootInfo& ri,int maxDepth,RootInfo& pair){ - const TreeOctNode* node=ri.node; - int c1,c2,c; - Cube::EdgeCorners(ri.edgeIndex,c1,c2); - while(node->parent){ - c=int(node-node->parent->children); - if(c!=c1 && c!=c2){return 0;} - if(!MarchingCubes::HasEdgeRoots(node->parent->nodeData.mcIndex,ri.edgeIndex)){ - if(c==c1){return GetRootIndex(&node->parent->children[c2],ri.edgeIndex,maxDepth,pair);} - else{return GetRootIndex(&node->parent->children[c1],ri.edgeIndex,maxDepth,pair);} - } - node=node->parent; - } - return 0; - - } - template - int Octree< Degree >::GetRootIndex( const RootInfo& ri , RootData& rootData , CoredPointIndex& index ) - { - long long key = ri.key; - hash_map< long long , int >::iterator rootIter; - rootIter = rootData.boundaryRoots.find( key ); - if( rootIter!=rootData.boundaryRoots.end() ) - { - index.inCore = 1; - index.index = rootIter->second; - return 1; - } - else if( rootData.interiorRoots ) - { - int eIndex = rootData.edgeIndices( ri.node )[ ri.edgeIndex ]; - if( rootData.edgesSet[ eIndex ] ) - { - index.inCore = 0; - index.index = rootData.interiorRoots[ eIndex ]; - return 1; - } - } - return 0; - } - template< int Degree > - int Octree< Degree >::SetMCRootPositions( TreeOctNode* node , int sDepth , Real isoValue , TreeOctNode::ConstNeighborKey5& neighborKey5 , RootData& rootData , - std::vector< Point3D< float > >* interiorPositions , CoredMeshData* mesh , const Real* metSolution , int nonLinearFit ) - { - Point3D< Real > position; - int eIndex; - RootInfo ri; - int count=0; - if( !MarchingCubes::HasRoots( node->nodeData.mcIndex ) ) return 0; - for( int i=0 ; i::iterator iter , end; - // Check if the root has already been set -#pragma omp critical (boundary_roots_hash_access) - { - iter = rootData.boundaryRoots.find( key ); - end = rootData.boundaryRoots.end(); - } - if( iter==end ) - { - // Get the root information - GetRoot( ri , isoValue , neighborKey5 , position , rootData , sDepth , metSolution , nonLinearFit ); - // Add the root if it hasn't been added already -#pragma omp critical (boundary_roots_hash_access) - { - iter = rootData.boundaryRoots.find( key ); - end = rootData.boundaryRoots.end(); - if( iter==end ) - { - mesh->inCorePoints.push_back( position ); - rootData.boundaryRoots[key] = int( mesh->inCorePoints.size() ) - 1; - } - } - if( iter==end ) count++; - } - } - else - { - int nodeEdgeIndex = rootData.edgeIndices( ri.node )[ ri.edgeIndex ]; - if( !rootData.edgesSet[ nodeEdgeIndex ] ) - { - // Get the root information - GetRoot( ri , isoValue , neighborKey5 , position , rootData , sDepth , metSolution , nonLinearFit ); - // Add the root if it hasn't been added already -#pragma omp critical (add_point_access) - { - if( !rootData.edgesSet[ nodeEdgeIndex ] ) - { - rootData.interiorRoots[ nodeEdgeIndex ] = mesh->addOutOfCorePoint( position ); - interiorPositions->push_back( position ); - rootData.edgesSet[ nodeEdgeIndex ] = 1; - count++; - } - } - } - } - } - } - return count; - } - template - int Octree< Degree >::SetBoundaryMCRootPositions( int sDepth , Real isoValue , RootData& rootData , CoredMeshData* mesh , int nonLinearFit ) - { - Point3D< Real > position; - int i,j,k,eIndex,hits=0; - RootInfo ri; - int count=0; - TreeOctNode* node; - - node = tree.nextLeaf(); - while( node ) - { - if( MarchingCubes::HasRoots( node->nodeData.mcIndex ) ) - { - hits=0; - for( i=0 ; iinCorePoints.push_back( position ); - rootData.boundaryRoots[key] = int( mesh->inCorePoints.size() )-1; - count++; - } - } - } - } - if( hits ) node=tree.nextLeaf(node); - else node=tree.nextBranch(node); - } - return count; - } - template - void Octree< Degree >::GetMCIsoEdges( TreeOctNode* node , int sDepth , std::vector< std::pair< RootInfo , RootInfo > >& edges ) - { - TreeOctNode* temp; - int count=0 , tris=0; - int isoTri[ DIMENSION * MarchingCubes::MAX_TRIANGLES ]; - FaceEdgesFunction fef; - int ref , fIndex; - hash_map< long long , std::pair< RootInfo , int > >::iterator iter; - hash_map< long long , std::pair< RootInfo , int > > vertexCount; - - fef.edges = &edges; - fef.maxDepth = fData.depth; - fef.vertexCount = &vertexCount; - count = MarchingCubes::AddTriangleIndices( node->nodeData.mcIndex , isoTri ); - for( fIndex=0 ; fIndexfaceNeighbor( fIndex ); - // If the face neighbor exists and has higher resolution than the current node, - // get the iso-curve from the neighbor - if( temp && temp->children && !IsBoundaryFace( node , fIndex , sDepth ) ) temp->processNodeFaces( temp , &fef , ref ); - // Otherwise, get it from the node - else - { - RootInfo ri1 , ri2; - for( int j=0 ; j( ri1 , ri2 ) ); - iter=vertexCount.find( key1 ); - if( iter==vertexCount.end() ) - { - vertexCount[key1].first = ri1; - vertexCount[key1].second = 0; - } - iter=vertexCount.find( key2 ); - if( iter==vertexCount.end() ) - { - vertexCount[key2].first = ri2; - vertexCount[key2].second = 0; - } - vertexCount[key1].second++; - vertexCount[key2].second--; - } - else - { - int r1 = MarchingCubes::HasEdgeRoots( node->nodeData.mcIndex , isoTri[j*3+k] ); - int r2 = MarchingCubes::HasEdgeRoots( node->nodeData.mcIndex , isoTri[j*3+((k+1)%3)] ); - fprintf( stderr , "Bad Edge 2: %d %d\t%d %d\n" , ri1.key , ri2.key , r1 , r2 ); - } - } - } - for( int i=0 ; idepthAndOffset( d , off ); - printf( "Vertex pair not in list 1 (%lld) %d\t[%d] (%d %d %d)\n" , key , IsBoundaryEdge( ri.node , ri.edgeIndex , sDepth ) , d , off[0] , off[1] , off[2] ); - } - else - { - edges.push_back( std::pair< RootInfo , RootInfo >( ri , edges[i].first ) ); - vertexCount[ key ].second++; - vertexCount[ edges[i].first.key ].second--; - } - } - - iter = vertexCount.find( edges[i].second.key ); - if( iter==vertexCount.end() ) printf( "Could not find vertex: %lld\n" , edges[i].second ); - else if( vertexCount[edges[i].second.key].second ) - { - RootInfo ri; - GetRootPair( vertexCount[edges[i].second.key].first , fData.depth , ri ); - long long key = ri.key; - iter=vertexCount.find( key ); - if( iter==vertexCount.end() ) - { - int d , off[3]; - node->depthAndOffset( d , off ); - printf( "Vertex pair not in list 2\t[%d] (%d %d %d)\n" , d , off[0] , off[1] , off[2] ); - } - else - { - edges.push_back( std::pair< RootInfo , RootInfo >( edges[i].second , ri ) ); - vertexCount[key].second--; - vertexCount[ edges[i].second.key ].second++; - } - } - } - } - template -#if MISHA_DEBUG - int Octree< Degree >::GetMCIsoTriangles( TreeOctNode* node , CoredMeshData* mesh , RootData& rootData , std::vector< Point3D< float > >* interiorPositions , int offSet , int sDepth , bool polygonMesh , std::vector< Point3D< float > >* barycenters ) -#else // !MISHA_DEBUG - int Octree< Degree >::GetMCIsoTriangles( TreeOctNode* node , CoredMeshData* mesh , RootData& rootData , std::vector< Point3D< float > >* interiorPositions , int offSet , int sDepth , bool addBarycenter , bool polygonMesh ) -#endif // MISHA_DEBUG - { - int tris=0; - std::vector< std::pair< RootInfo , RootInfo > > edges; - std::vector< std::vector< std::pair< RootInfo , RootInfo > > > edgeLoops; - GetMCIsoEdges( node , sDepth , edges ); - - GetEdgeLoops( edges , edgeLoops ); - for( int i=0 ; i edgeIndices; - for( int j=0 ; j - int Octree< Degree >::GetEdgeLoops( std::vector< std::pair< RootInfo , RootInfo > >& edges , std::vector< std::vector< std::pair< RootInfo , RootInfo > > >& loops ) - { - int loopSize=0; - long long frontIdx , backIdx; - std::pair< RootInfo , RootInfo > e , temp; - loops.clear(); - - while( edges.size() ) - { - std::vector< std::pair< RootInfo , RootInfo > > front , back; - e = edges[0]; - loops.resize( loopSize+1 ); - edges[0] = edges.back(); - edges.pop_back(); - frontIdx = e.second.key; - backIdx = e.first.key; - for( int j=int(edges.size())-1 ; j>=0 ; j-- ) - { - if( edges[j].first.key==frontIdx || edges[j].second.key==frontIdx ) - { - if( edges[j].first.key==frontIdx ) temp = edges[j]; - else temp.first = edges[j].second , temp.second = edges[j].first; - frontIdx = temp.second.key; - front.push_back(temp); - edges[j] = edges.back(); - edges.pop_back(); - j = int(edges.size()); - } - else if( edges[j].first.key==backIdx || edges[j].second.key==backIdx ) - { - if( edges[j].second.key==backIdx ) temp = edges[j]; - else temp.first = edges[j].second , temp.second = edges[j].first; - backIdx = temp.first.key; - back.push_back(temp); - edges[j] = edges.back(); - edges.pop_back(); - j = int(edges.size()); - } - } - for( int j=int(back.size())-1 ; j>=0 ; j-- ) loops[loopSize].push_back( back[j] ); - loops[loopSize].push_back(e); - for( int j=0 ; j -#if MISHA_DEBUG - int Octree::AddTriangles( CoredMeshData* mesh , std::vector& edges , std::vector >* interiorPositions , int offSet , bool polygonMesh , std::vector< Point3D< float > >* barycenters ) -#else // !MISHA_DEBUG - int Octree::AddTriangles( CoredMeshData* mesh , std::vector& edges , std::vector >* interiorPositions , int offSet , bool addBarycenter , bool polygonMesh ) -#endif // MISHA_DEBUG - { - MinimalAreaTriangulation< float > MAT; - std::vector< Point3D< float > > vertices; - std::vector< TriangleIndex > triangles; - if( polygonMesh ) - { - std::vector< CoredVertexIndex > vertices( edges.size() ); - for( int i=0 ; iaddPolygon( vertices ); - } - return 1; - } - if( edges.size()>3 ) - { - bool isCoplanar = false; - -#if MISHA_DEBUG - if( barycenters ) -#else // !MISHA_DEBUG - if( addBarycenter ) -#endif // MISHA_DEBUG - for( int i=0 ; i v1 , v2; - if( edges[i].inCore ) v1 = mesh->inCorePoints[ edges[i].index ]; - else v1 = (*interiorPositions)[ edges[i].index-offSet ]; - if( edges[j].inCore ) v2 = mesh->inCorePoints[ edges[j].index ]; - else v2 = (*interiorPositions)[ edges[j].index-offSet ]; - for( int k=0 ; k<3 ; k++ ) if( v1[k]==v2[k] ) isCoplanar = true; - } - if( isCoplanar ) - { - Point3D< Real > c; - c[0] = c[1] = c[2] = 0; - for( int i=0 ; i p; - if(edges[i].inCore) p = mesh->inCorePoints[edges[i].index ]; - else p = (*interiorPositions)[edges[i].index-offSet]; - c += p; - } - c /= Real( edges.size() ); - int cIdx; -#pragma omp critical (add_point_access) - { - cIdx = mesh->addOutOfCorePoint( c ); -#if MISHA_DEBUG - barycenters->push_back( c ); -#else // !MISHA_DEBUG - interiorPositions->push_back( c ); -#endif // MISHA_DEBUG - } - for( int i=0 ; i vertices( 3 ); - vertices[0].idx = edges[i ].index; - vertices[1].idx = edges[(i+1)%edges.size()].index; - vertices[2].idx = cIdx; - vertices[0].inCore = (edges[i ].inCore!=0); - vertices[1].inCore = (edges[(i+1)%edges.size()].inCore!=0); - vertices[2].inCore = 0; -#pragma omp critical (add_polygon_access) - { - mesh->addPolygon( vertices ); - } - } - return int( edges.size() ); - } - else - { - vertices.resize( edges.size() ); - // Add the points - for( int i=0 ; i p; - if( edges[i].inCore ) p = mesh->inCorePoints[edges[i].index ]; - else p = (*interiorPositions)[edges[i].index-offSet]; - vertices[i] = p; - } - MAT.GetTriangulation( vertices , triangles ); - for( int i=0 ; i _vertices( 3 ); - for( int j=0 ; j<3 ; j++ ) - { - _vertices[j].idx = edges[ triangles[i].idx[j] ].index; - _vertices[j].inCore = (edges[ triangles[i].idx[j] ].inCore!=0); - } -#pragma omp critical (add_polygon_access) - { - mesh->addPolygon( _vertices ); - } - } - } - } - else if( edges.size()==3 ) - { - std::vector< CoredVertexIndex > vertices( 3 ); - for( int i=0 ; i<3 ; i++ ) - { - vertices[i].idx = edges[i].index; - vertices[i].inCore = (edges[i].inCore!=0); - } -#pragma omp critical (add_polygon_access) - mesh->addPolygon( vertices ); - } - return int(edges.size())-2; - } - template< int Degree > - Real* Octree< Degree >::GetSolutionGrid( int& res , float isoValue , int depth ) - { - if( depth<=0 || depth>tree.maxDepth() ) depth = tree.maxDepth(); - BSplineData< Degree , Real > fData; - fData.set( depth ); - fData.setValueTables( fData.VALUE_FLAG ); - res = 1<d>depth ) continue; - if( n->d<_minDepth ) continue; - int d , idx[3] , start[3] , end[3]; - n->depthAndOffset( d , idx ); - for( int i=0 ; i<3 ; i++ ) - { - // Get the index of the functions - idx[i] = BinaryNode< double >::CenterIndex( d , idx[i] ); - // Figure out which samples fall into the range - fData.setSampleSpan( idx[i] , start[i] , end[i] ); - // We only care about the odd indices - if( !(start[i]&1) ) start[i]++; - if( !( end[i]&1) ) end[i]--; - } - Real coefficient = n->nodeData.solution; - for( int x=start[0] ; x<=end[0] ; x+=2 ) - for( int y=start[1] ; y<=end[1] ; y+=2 ) - for( int z=start[2] ; z<=end[2] ; z+=2 ) - { - int xx = (x-1)>>1 , yy = (y-1)>>1 , zz = (z-1)>>1; - values[ zz*res*res + yy*res + xx ] += - coefficient * - fData.valueTables[ idx[0]+x*fData.functionCount ] * - fData.valueTables[ idx[1]+y*fData.functionCount ] * - fData.valueTables[ idx[2]+z*fData.functionCount ]; - } - } - for( int i=0 ; i - Real* Octree< Degree >::GetWeightGrid( int& res , int depth ) - { - if( depth<=0 || depth>tree.maxDepth() ) depth = tree.maxDepth(); - res = 1<d>depth ) continue; - int d , idx[3] , start[3] , end[3]; - n->depthAndOffset( d , idx ); - for( int i=0 ; i<3 ; i++ ) - { - // Get the index of the functions - idx[i] = BinaryNode< double >::CenterIndex( d , idx[i] ); - // Figure out which samples fall into the range - fData.setSampleSpan( idx[i] , start[i] , end[i] ); - // We only care about the odd indices - if( !(start[i]&1) ) start[i]++; - if( !( end[i]&1) ) end[i]--; - } - for( int x=start[0] ; x<=end[0] ; x+=2 ) - for( int y=start[1] ; y<=end[1] ; y+=2 ) - for( int z=start[2] ; z<=end[2] ; z+=2 ) - { - int xx = (x-1)>>1 , yy = (y-1)>>1 , zz = (z-1)>>1; - values[ zz*res*res + yy*res + xx ] += - n->nodeData.centerWeightContribution * - fData.valueTables[ idx[0]+x*fData.functionCount ] * - fData.valueTables[ idx[1]+y*fData.functionCount ] * - fData.valueTables[ idx[2]+z*fData.functionCount ]; - } - } - return values; - } - - //////////////// - // VertexData // - //////////////// - long long VertexData::CenterIndex(const TreeOctNode* node,int maxDepth){ - int idx[DIMENSION]; - return CenterIndex(node,maxDepth,idx); - } - long long VertexData::CenterIndex(const TreeOctNode* node,int maxDepth,int idx[DIMENSION]){ - int d,o[3]; - node->depthAndOffset(d,o); - for(int i=0;i::CornerIndex(maxDepth+1,d+1,o[i]<<1,1);} - return (long long)(idx[0]) | (long long)(idx[1])<<15 | (long long)(idx[2])<<30; - } - long long VertexData::CenterIndex(int depth,const int offSet[DIMENSION],int maxDepth,int idx[DIMENSION]){ - for(int i=0;i::CornerIndex(maxDepth+1,depth+1,offSet[i]<<1,1);} - return (long long)(idx[0]) | (long long)(idx[1])<<15 | (long long)(idx[2])<<30; - } - long long VertexData::CornerIndex(const TreeOctNode* node,int cIndex,int maxDepth){ - int idx[DIMENSION]; - return CornerIndex(node,cIndex,maxDepth,idx); - } - long long VertexData::CornerIndex( const TreeOctNode* node , int cIndex , int maxDepth , int idx[DIMENSION] ) - { - int x[DIMENSION]; - Cube::FactorCornerIndex( cIndex , x[0] , x[1] , x[2] ); - int d , o[3]; - node->depthAndOffset( d , o ); - for( int i=0 ; i::CornerIndex( maxDepth+1 , d , o[i] , x[i] ); - return CornerIndexKey( idx ); - } - long long VertexData::CornerIndex( int depth , const int offSet[DIMENSION] , int cIndex , int maxDepth , int idx[DIMENSION] ) - { - int x[DIMENSION]; - Cube::FactorCornerIndex( cIndex , x[0] , x[1] , x[2] ); - for( int i=0 ; i::CornerIndex( maxDepth+1 , depth , offSet[i] , x[i] ); - return CornerIndexKey( idx ); - } - long long VertexData::CornerIndexKey( const int idx[DIMENSION] ) - { - return (long long)(idx[0]) | (long long)(idx[1])<<15 | (long long)(idx[2])<<30; - } - long long VertexData::FaceIndex(const TreeOctNode* node,int fIndex,int maxDepth){ - int idx[DIMENSION]; - return FaceIndex(node,fIndex,maxDepth,idx); - } - long long VertexData::FaceIndex(const TreeOctNode* node,int fIndex,int maxDepth,int idx[DIMENSION]){ - int dir,offset; - Cube::FactorFaceIndex(fIndex,dir,offset); - int d,o[3]; - node->depthAndOffset(d,o); - for(int i=0;i::CornerIndex(maxDepth+1,d+1,o[i]<<1,1);} - idx[dir]=BinaryNode::CornerIndex(maxDepth+1,d,o[dir],offset); - return (long long)(idx[0]) | (long long)(idx[1])<<15 | (long long)(idx[2])<<30; - } - long long VertexData::EdgeIndex(const TreeOctNode* node,int eIndex,int maxDepth){ - int idx[DIMENSION]; - return EdgeIndex(node,eIndex,maxDepth,idx); - } - long long VertexData::EdgeIndex(const TreeOctNode* node,int eIndex,int maxDepth,int idx[DIMENSION]){ - int o,i1,i2; - int d,off[3]; - node->depthAndOffset(d,off); - for(int i=0;i::CornerIndex(maxDepth+1,d+1,off[i]<<1,1);} - Cube::FactorEdgeIndex(eIndex,o,i1,i2); - switch(o){ - case 0: - idx[1]=BinaryNode::CornerIndex(maxDepth+1,d,off[1],i1); - idx[2]=BinaryNode::CornerIndex(maxDepth+1,d,off[2],i2); - break; - case 1: - idx[0]=BinaryNode::CornerIndex(maxDepth+1,d,off[0],i1); - idx[2]=BinaryNode::CornerIndex(maxDepth+1,d,off[2],i2); - break; - case 2: - idx[0]=BinaryNode::CornerIndex(maxDepth+1,d,off[0],i1); - idx[1]=BinaryNode::CornerIndex(maxDepth+1,d,off[1],i2); - break; - }; - return (long long)(idx[0]) | (long long)(idx[1])<<15 | (long long)(idx[2])<<30; - } - - - } -} - - diff --git a/vendor/poisson_surface/octree_poisson.h b/vendor/poisson_surface/octree_poisson.h deleted file mode 100644 index 68e082a9c2..0000000000 --- a/vendor/poisson_surface/octree_poisson.h +++ /dev/null @@ -1,287 +0,0 @@ -/* -Copyright (c) 2006, Michael Kazhdan and Matthew Bolitho -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -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. - -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. - -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 -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 -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. -*/ - -#ifndef OCT_NODE_INCLUDED -#define OCT_NODE_INCLUDED - -#if defined __GNUC__ -# pragma GCC system_header -#endif - -#include "allocator.h" -#include "binary_node.h" -#include "marching_cubes_poisson.h" - -#define DIMENSION 3 - -namespace pcl -{ - namespace poisson - { - - template< class NodeData , class Real=float > - class OctNode - { - private: - static int UseAlloc; - - class AdjacencyCountFunction - { - public: - int count; - void Function( const OctNode* node1 , const OctNode* node2 ); - }; - template - void __processNodeFaces(OctNode* node,NodeAdjacencyFunction* F,int cIndex1,int cIndex2,int cIndex3,int cIndex4); - template - void __processNodeEdges(OctNode* node,NodeAdjacencyFunction* F,int cIndex1,int cIndex2); - template - void __processNodeNodes(OctNode* node,NodeAdjacencyFunction* F); - template - static void __ProcessNodeAdjacentNodes(int dx,int dy,int dz,OctNode* node1,int radius1,OctNode* node2,int radius2,int cWidth2,NodeAdjacencyFunction* F); - template - static void __ProcessTerminatingNodeAdjacentNodes(int dx,int dy,int dz,OctNode* node1,int radius1,OctNode* node2,int radius2,int cWidth2,TerminatingNodeAdjacencyFunction* F); - template - static void __ProcessPointAdjacentNodes(int dx,int dy,int dz,OctNode* node2,int radius2,int cWidth2,PointAdjacencyFunction* F); - template - static void __ProcessFixedDepthNodeAdjacentNodes(int dx,int dy,int dz,OctNode* node1,int radius1,OctNode* node2,int radius2,int cWidth2,int depth,NodeAdjacencyFunction* F); - template - static void __ProcessMaxDepthNodeAdjacentNodes(int dx,int dy,int dz,OctNode* node1,int radius1,OctNode* node2,int radius2,int cWidth2,int depth,NodeAdjacencyFunction* F); - - // This is made private because the division by two has been pulled out. - static inline int Overlap(int c1,int c2,int c3,int dWidth); - inline static int ChildOverlap(int dx,int dy,int dz,int d,int cRadius2); - - const OctNode* __faceNeighbor(int dir,int off) const; - const OctNode* __edgeNeighbor(int o,const int i[2],const int idx[2]) const; - OctNode* __faceNeighbor(int dir,int off,int forceChildren); - OctNode* __edgeNeighbor(int o,const int i[2],const int idx[2],int forceChildren); - public: - static const int DepthShift,OffsetShift,OffsetShift1,OffsetShift2,OffsetShift3; - static const int DepthMask,OffsetMask; - - static Allocator internalAllocator; - static int UseAllocator(void); - static void SetAllocator(int blockSize); - - OctNode* parent; - OctNode* children; - short d , off[DIMENSION]; - NodeData nodeData; - - OctNode(void); - ~OctNode(void); - int initChildren(void); - - void depthAndOffset(int& depth,int offset[DIMENSION]) const; - int depth(void) const; - static inline void DepthAndOffset(const long long& index,int& depth,int offset[DIMENSION]); - static inline void CenterAndWidth(const long long& index,Point3D& center,Real& width); - static inline int Depth(const long long& index); - static inline void Index(int depth,const int offset[3],short& d,short off[DIMENSION]); - void centerAndWidth( Point3D& center , Real& width ) const; - bool isInside( Point3D< Real > p ) const; - - int leaves(void) const; - int maxDepthLeaves(int maxDepth) const; - int nodes(void) const; - int maxDepth(void) const; - - const OctNode* root(void) const; - - const OctNode* nextLeaf(const OctNode* currentLeaf=NULL) const; - OctNode* nextLeaf(OctNode* currentLeaf=NULL); - const OctNode* nextNode(const OctNode* currentNode=NULL) const; - OctNode* nextNode(OctNode* currentNode=NULL); - const OctNode* nextBranch(const OctNode* current) const; - OctNode* nextBranch(OctNode* current); - const OctNode* prevBranch(const OctNode* current) const; - OctNode* prevBranch(OctNode* current); - - void setFullDepth(int maxDepth); - - void printLeaves(void) const; - void printRange(void) const; - - template - void processNodeFaces(OctNode* node,NodeAdjacencyFunction* F,int fIndex,int processCurrent=1); - template - void processNodeEdges(OctNode* node,NodeAdjacencyFunction* F,int eIndex,int processCurrent=1); - template - void processNodeCorners(OctNode* node,NodeAdjacencyFunction* F,int cIndex,int processCurrent=1); - template - void processNodeNodes(OctNode* node,NodeAdjacencyFunction* F,int processCurrent=1); - - template - static void ProcessNodeAdjacentNodes(int maxDepth,OctNode* node1,int width1,OctNode* node2,int width2,NodeAdjacencyFunction* F,int processCurrent=1); - template - static void ProcessNodeAdjacentNodes(int dx,int dy,int dz,OctNode* node1,int radius1,OctNode* node2,int radius2,int width2,NodeAdjacencyFunction* F,int processCurrent=1); - template - static void ProcessTerminatingNodeAdjacentNodes(int maxDepth,OctNode* node1,int width1,OctNode* node2,int width2,TerminatingNodeAdjacencyFunction* F,int processCurrent=1); - template - static void ProcessTerminatingNodeAdjacentNodes(int dx,int dy,int dz,OctNode* node1,int radius1,OctNode* node2,int radius2,int width2,TerminatingNodeAdjacencyFunction* F,int processCurrent=1); - template - static void ProcessPointAdjacentNodes(int maxDepth,const int center1[3],OctNode* node2,int width2,PointAdjacencyFunction* F,int processCurrent=1); - template - static void ProcessPointAdjacentNodes(int dx,int dy,int dz,OctNode* node2,int radius2,int width2,PointAdjacencyFunction* F,int processCurrent=1); - template - static void ProcessFixedDepthNodeAdjacentNodes(int maxDepth,OctNode* node1,int width1,OctNode* node2,int width2,int depth,NodeAdjacencyFunction* F,int processCurrent=1); - template - static void ProcessFixedDepthNodeAdjacentNodes(int dx,int dy,int dz,OctNode* node1,int radius1,OctNode* node2,int radius2,int width2,int depth,NodeAdjacencyFunction* F,int processCurrent=1); - template - static void ProcessMaxDepthNodeAdjacentNodes(int maxDepth,OctNode* node1,int width1,OctNode* node2,int width2,int depth,NodeAdjacencyFunction* F,int processCurrent=1); - template - static void ProcessMaxDepthNodeAdjacentNodes(int dx,int dy,int dz,OctNode* node1,int radius1,OctNode* node2,int radius2,int width2,int depth,NodeAdjacencyFunction* F,int processCurrent=1); - - static int CornerIndex(const Point3D& center,const Point3D &p); - - OctNode* faceNeighbor(int faceIndex,int forceChildren=0); - const OctNode* faceNeighbor(int faceIndex) const; - OctNode* edgeNeighbor(int edgeIndex,int forceChildren=0); - const OctNode* edgeNeighbor(int edgeIndex) const; - OctNode* cornerNeighbor(int cornerIndex,int forceChildren=0); - const OctNode* cornerNeighbor(int cornerIndex) const; - - OctNode* getNearestLeaf(const Point3D& p); - const OctNode* getNearestLeaf(const Point3D& p) const; - - static int CommonEdge(const OctNode* node1,int eIndex1,const OctNode* node2,int eIndex2); - static int CompareForwardDepths(const void* v1,const void* v2); - static int CompareByDepthAndXYZ( const void* v1 , const void* v2 ); - static int CompareByDepthAndZIndex( const void* v1 , const void* v2 ); - static int CompareForwardPointerDepths(const void* v1,const void* v2); - static int CompareBackwardDepths(const void* v1,const void* v2); - static int CompareBackwardPointerDepths(const void* v1,const void* v2); - - - template - OctNode& operator = (const OctNode& node); - - static inline int Overlap2(const int &depth1,const int offSet1[DIMENSION],const Real& multiplier1,const int &depth2,const int offSet2[DIMENSION],const Real& multiplier2); - - - int write(const char* fileName) const; - int write(FILE* fp) const; - int read(const char* fileName); - int read(FILE* fp); - - class Neighbors3 - { - public: - OctNode* neighbors[3][3][3]; - Neighbors3( void ); - void clear( void ); - }; - class NeighborKey3 - { - public: - Neighbors3* neighbors; - - NeighborKey3( void ); - ~NeighborKey3( void ); - - void set( int depth ); - Neighbors3& setNeighbors( OctNode* root , Point3D< Real > p , int d ); - Neighbors3& getNeighbors( OctNode* root , Point3D< Real > p , int d ); - Neighbors3& setNeighbors( OctNode* node , bool flags[3][3][3] ); - Neighbors3& setNeighbors( OctNode* node ); - Neighbors3& getNeighbors( OctNode* node ); - }; - class ConstNeighbors3 - { - public: - const OctNode* neighbors[3][3][3]; - ConstNeighbors3( void ); - void clear( void ); - }; - class ConstNeighborKey3 - { - public: - ConstNeighbors3* neighbors; - - ConstNeighborKey3(void); - ~ConstNeighborKey3(void); - - void set(int depth); - ConstNeighbors3& getNeighbors( const OctNode* node ); - ConstNeighbors3& getNeighbors( const OctNode* node , int minDepth ); - }; - class Neighbors5 - { - public: - OctNode* neighbors[5][5][5]; - Neighbors5( void ); - void clear( void ); - }; - class ConstNeighbors5 - { - public: - const OctNode* neighbors[5][5][5]; - ConstNeighbors5( void ); - void clear( void ); - }; - - class NeighborKey5 - { - int _depth; - public: - Neighbors5* neighbors; - - NeighborKey5( void ); - ~NeighborKey5( void ); - - void set( int depth ); - Neighbors5& getNeighbors( OctNode* node ); - Neighbors5& setNeighbors( OctNode* node , int xStart=0 , int xEnd=5 , int yStart=0 , int yEnd=5 , int zStart=0 , int zEnd=5 ); - }; - class ConstNeighborKey5 - { - int _depth; - public: - ConstNeighbors5* neighbors; - - ConstNeighborKey5( void ); - ~ConstNeighborKey5( void ); - - void set( int depth ); - ConstNeighbors5& getNeighbors( const OctNode* node ); - }; - - void centerIndex(int maxDepth,int index[DIMENSION]) const; - int width(int maxDepth) const; - }; - - - } -} - -#include "octree_poisson.hpp" - - - -#endif // OCT_NODE diff --git a/vendor/poisson_surface/octree_poisson.hpp b/vendor/poisson_surface/octree_poisson.hpp deleted file mode 100644 index d9115ceb2a..0000000000 --- a/vendor/poisson_surface/octree_poisson.hpp +++ /dev/null @@ -1,1911 +0,0 @@ -/* -Copyright (c) 2006, Michael Kazhdan and Matthew Bolitho -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -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. - -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. - -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 -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 -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. -*/ - -#include -#include -#include - -///////////// -// OctNode // -///////////// - -namespace pcl -{ - namespace poisson - { - - template const int OctNode::DepthShift=5; - template const int OctNode::OffsetShift=19; - template const int OctNode::DepthMask=(1< const int OctNode::OffsetMask=(1< const int OctNode::OffsetShift1=DepthShift; - template const int OctNode::OffsetShift2=OffsetShift1+OffsetShift; - template const int OctNode::OffsetShift3=OffsetShift2+OffsetShift; - - template int OctNode::UseAlloc=0; - template Allocator > OctNode::internalAllocator; - - template - void OctNode::SetAllocator(int blockSize) - { - if(blockSize>0) - { - UseAlloc=1; - internalAllocator.set(blockSize); - } - else{UseAlloc=0;} - } - template - int OctNode::UseAllocator(void){return UseAlloc;} - - template - OctNode::OctNode(void){ - parent=children=NULL; - d=off[0]=off[1]=off[2]=0; - } - - template - OctNode::~OctNode(void){ - if(!UseAlloc){if(children){delete[] children;}} - parent=children=NULL; - } - template - void OctNode::setFullDepth(int maxDepth){ - if( maxDepth ) - { - if( !children ) initChildren(); - for( int i=0 ; i<8 ; i++ ) children[i].setFullDepth( maxDepth-1 ); - } - } - - template - int OctNode::initChildren(void){ - int i,j,k; - - if(UseAlloc){children=internalAllocator.newElements(8);} - else{ - if(children){delete[] children;} - children=NULL; - children=new OctNode[Cube::CORNERS]; - } - if(!children){ - fprintf(stderr,"Failed to initialize children in OctNode::initChildren\n"); - exit(0); - return 0; - } - int d,off[3]; - depthAndOffset(d,off); - for(i=0;i<2;i++){ - for(j=0;j<2;j++){ - for(k=0;k<2;k++){ - int idx=Cube::CornerIndex(i,j,k); - children[idx].parent=this; - children[idx].children=NULL; - int off2[3]; - off2[0]=(off[0]<<1)+i; - off2[1]=(off[1]<<1)+j; - off2[2]=(off[2]<<1)+k; - Index(d+1,off2,children[idx].d,children[idx].off); - } - } - } - return 1; - } - template - inline void OctNode::Index(int depth,const int offset[3],short& d,short off[3]){ - d=short(depth); - off[0]=short((1< - inline void OctNode::depthAndOffset(int& depth,int offset[3]) const { - depth=int(d); - offset[0]=(int(off[0])+1)&(~(1< - inline int OctNode::depth(void) const {return int(d);} - template - inline void OctNode::DepthAndOffset(const long long& index,int& depth,int offset[3]){ - depth=int(index&DepthMask); - offset[0]=(int((index>>OffsetShift1)&OffsetMask)+1)&(~(1<>OffsetShift2)&OffsetMask)+1)&(~(1<>OffsetShift3)&OffsetMask)+1)&(~(1< - inline int OctNode::Depth(const long long& index){return int(index&DepthMask);} - template - void OctNode::centerAndWidth(Point3D& center,Real& width) const{ - int depth,offset[3]; - depth=int(d); - offset[0]=(int(off[0])+1)&(~(1< - bool OctNode< NodeData , Real >::isInside( Point3D< Real > p ) const - { - Point3D< Real > c; - Real w; - centerAndWidth( c , w ); - w /= 2; - return (c[0]-w) - inline void OctNode::CenterAndWidth(const long long& index,Point3D& center,Real& width){ - int depth,offset[3]; - depth=index&DepthMask; - offset[0]=(int((index>>OffsetShift1)&OffsetMask)+1)&(~(1<>OffsetShift2)&OffsetMask)+1)&(~(1<>OffsetShift3)&OffsetMask)+1)&(~(1< - int OctNode::maxDepth(void) const{ - if(!children){return 0;} - else{ - int c,d; - for(int i=0;ic){c=d;} - } - return c+1; - } - } - template - int OctNode::nodes(void) const{ - if(!children){return 1;} - else{ - int c=0; - for(int i=0;i - int OctNode::leaves(void) const{ - if(!children){return 1;} - else{ - int c=0; - for(int i=0;i - int OctNode::maxDepthLeaves(int maxDepth) const{ - if(depth()>maxDepth){return 0;} - if(!children){return 1;} - else{ - int c=0; - for(int i=0;i - const OctNode* OctNode::root(void) const{ - const OctNode* temp=this; - while(temp->parent){temp=temp->parent;} - return temp; - } - - - template - const OctNode* OctNode::nextBranch( const OctNode* current ) const - { - if( !current->parent || current==this ) return NULL; - if(current-current->parent->children==Cube::CORNERS-1) return nextBranch( current->parent ); - else return current+1; - } - template - OctNode* OctNode::nextBranch(OctNode* current){ - if(!current->parent || current==this){return NULL;} - if(current-current->parent->children==Cube::CORNERS-1){return nextBranch(current->parent);} - else{return current+1;} - } - template< class NodeData , class Real > - const OctNode< NodeData , Real >* OctNode< NodeData , Real >::prevBranch( const OctNode* current ) const - { - if( !current->parent || current==this ) return NULL; - if( current-current->parent->children==0 ) return prevBranch( current->parent ); - else return current-1; - } - template< class NodeData , class Real > - OctNode< NodeData , Real >* OctNode< NodeData , Real >::prevBranch( OctNode* current ) - { - if( !current->parent || current==this ) return NULL; - if( current-current->parent->children==0 ) return prevBranch( current->parent ); - else return current-1; - } - template - const OctNode* OctNode::nextLeaf(const OctNode* current) const{ - if(!current){ - const OctNode* temp=this; - while(temp->children){temp=&temp->children[0];} - return temp; - } - if(current->children){return current->nextLeaf();} - const OctNode* temp=nextBranch(current); - if(!temp){return NULL;} - else{return temp->nextLeaf();} - } - template - OctNode* OctNode::nextLeaf(OctNode* current){ - if(!current){ - OctNode* temp=this; - while(temp->children){temp=&temp->children[0];} - return temp; - } - if(current->children){return current->nextLeaf();} - OctNode* temp=nextBranch(current); - if(!temp){return NULL;} - else{return temp->nextLeaf();} - } - - template - const OctNode* OctNode::nextNode( const OctNode* current ) const - { - if( !current ) return this; - else if( current->children ) return ¤t->children[0]; - else return nextBranch(current); - } - template - OctNode* OctNode::nextNode( OctNode* current ) - { - if( !current ) return this; - else if( current->children ) return ¤t->children[0]; - else return nextBranch( current ); - } - - template - void OctNode::printRange(void) const{ - Point3D center; - Real width; - centerAndWidth(center,width); - for(int dim=0;dim - void OctNode::AdjacencyCountFunction::Function(const OctNode* node1,const OctNode* node2){count++;} - - template - template - void OctNode::processNodeNodes(OctNode* node,NodeAdjacencyFunction* F,int processCurrent){ - if(processCurrent){F->Function(this,node);} - if(children){__processNodeNodes(node,F);} - } - template - template - void OctNode::processNodeFaces(OctNode* node,NodeAdjacencyFunction* F,int fIndex,int processCurrent){ - if(processCurrent){F->Function(this,node);} - if(children){ - int c1,c2,c3,c4; - Cube::FaceCorners(fIndex,c1,c2,c3,c4); - __processNodeFaces(node,F,c1,c2,c3,c4); - } - } - template - template - void OctNode::processNodeEdges(OctNode* node,NodeAdjacencyFunction* F,int eIndex,int processCurrent){ - if(processCurrent){F->Function(this,node);} - if(children){ - int c1,c2; - Cube::EdgeCorners(eIndex,c1,c2); - __processNodeEdges(node,F,c1,c2); - } - } - template - template - void OctNode::processNodeCorners(OctNode* node,NodeAdjacencyFunction* F,int cIndex,int processCurrent){ - if(processCurrent){F->Function(this,node);} - OctNode* temp=this; - while(temp->children){ - temp=&temp->children[cIndex]; - F->Function(temp,node); - } - } - template - template - void OctNode::__processNodeNodes(OctNode* node,NodeAdjacencyFunction* F){ - F->Function(&children[0],node); - F->Function(&children[1],node); - F->Function(&children[2],node); - F->Function(&children[3],node); - F->Function(&children[4],node); - F->Function(&children[5],node); - F->Function(&children[6],node); - F->Function(&children[7],node); - if(children[0].children){children[0].__processNodeNodes(node,F);} - if(children[1].children){children[1].__processNodeNodes(node,F);} - if(children[2].children){children[2].__processNodeNodes(node,F);} - if(children[3].children){children[3].__processNodeNodes(node,F);} - if(children[4].children){children[4].__processNodeNodes(node,F);} - if(children[5].children){children[5].__processNodeNodes(node,F);} - if(children[6].children){children[6].__processNodeNodes(node,F);} - if(children[7].children){children[7].__processNodeNodes(node,F);} - } - template - template - void OctNode::__processNodeEdges(OctNode* node,NodeAdjacencyFunction* F,int cIndex1,int cIndex2){ - F->Function(&children[cIndex1],node); - F->Function(&children[cIndex2],node); - if(children[cIndex1].children){children[cIndex1].__processNodeEdges(node,F,cIndex1,cIndex2);} - if(children[cIndex2].children){children[cIndex2].__processNodeEdges(node,F,cIndex1,cIndex2);} - } - template - template - void OctNode::__processNodeFaces(OctNode* node,NodeAdjacencyFunction* F,int cIndex1,int cIndex2,int cIndex3,int cIndex4){ - F->Function(&children[cIndex1],node); - F->Function(&children[cIndex2],node); - F->Function(&children[cIndex3],node); - F->Function(&children[cIndex4],node); - if(children[cIndex1].children){children[cIndex1].__processNodeFaces(node,F,cIndex1,cIndex2,cIndex3,cIndex4);} - if(children[cIndex2].children){children[cIndex2].__processNodeFaces(node,F,cIndex1,cIndex2,cIndex3,cIndex4);} - if(children[cIndex3].children){children[cIndex3].__processNodeFaces(node,F,cIndex1,cIndex2,cIndex3,cIndex4);} - if(children[cIndex4].children){children[cIndex4].__processNodeFaces(node,F,cIndex1,cIndex2,cIndex3,cIndex4);} - } - template - template - void OctNode::ProcessNodeAdjacentNodes(int maxDepth,OctNode* node1,int width1,OctNode* node2,int width2,NodeAdjacencyFunction* F,int processCurrent){ - int c1[3],c2[3],w1,w2; - node1->centerIndex(maxDepth+1,c1); - node2->centerIndex(maxDepth+1,c2); - w1=node1->width(maxDepth+1); - w2=node2->width(maxDepth+1); - - ProcessNodeAdjacentNodes(c1[0]-c2[0],c1[1]-c2[1],c1[2]-c2[2],node1,(width1*w1)>>1,node2,(width2*w2)>>1,w2,F,processCurrent); - } - template - template - void OctNode::ProcessNodeAdjacentNodes(int dx,int dy,int dz, - OctNode* node1,int radius1, - OctNode* node2,int radius2,int width2, - NodeAdjacencyFunction* F,int processCurrent){ - if(!Overlap(dx,dy,dz,radius1+radius2)){return;} - if(processCurrent){F->Function(node2,node1);} - if(!node2->children){return;} - __ProcessNodeAdjacentNodes(-dx,-dy,-dz,node1,radius1,node2,radius2,width2/2,F); - } - template - template - void OctNode::ProcessTerminatingNodeAdjacentNodes(int maxDepth,OctNode* node1,int width1,OctNode* node2,int width2,TerminatingNodeAdjacencyFunction* F,int processCurrent){ - int c1[3],c2[3],w1,w2; - node1->centerIndex(maxDepth+1,c1); - node2->centerIndex(maxDepth+1,c2); - w1=node1->width(maxDepth+1); - w2=node2->width(maxDepth+1); - - ProcessTerminatingNodeAdjacentNodes(c1[0]-c2[0],c1[1]-c2[1],c1[2]-c2[2],node1,(width1*w1)>>1,node2,(width2*w2)>>1,w2,F,processCurrent); - } - template - template - void OctNode::ProcessTerminatingNodeAdjacentNodes(int dx,int dy,int dz, - OctNode* node1,int radius1, - OctNode* node2,int radius2,int width2, - TerminatingNodeAdjacencyFunction* F,int processCurrent) - { - if(!Overlap(dx,dy,dz,radius1+radius2)){return;} - if(processCurrent){F->Function(node2,node1);} - if(!node2->children){return;} - __ProcessTerminatingNodeAdjacentNodes(-dx,-dy,-dz,node1,radius1,node2,radius2,width2/2,F); - } - template - template - void OctNode::ProcessPointAdjacentNodes( int maxDepth , const int c1[3] , OctNode* node2 , int width2 , PointAdjacencyFunction* F , int processCurrent ) - { - int c2[3] , w2; - node2->centerIndex( maxDepth+1 , c2 ); - w2 = node2->width( maxDepth+1 ); - ProcessPointAdjacentNodes( c1[0]-c2[0] , c1[1]-c2[1] , c1[2]-c2[2] , node2 , (width2*w2)>>1 , w2 , F , processCurrent ); - } - template - template - void OctNode::ProcessPointAdjacentNodes(int dx,int dy,int dz, - OctNode* node2,int radius2,int width2, - PointAdjacencyFunction* F,int processCurrent) - { - if( !Overlap(dx,dy,dz,radius2) ) return; - if( processCurrent ) F->Function(node2); - if( !node2->children ) return; - __ProcessPointAdjacentNodes( -dx , -dy , -dz , node2 , radius2 , width2>>1 , F ); - } - template - template - void OctNode::ProcessFixedDepthNodeAdjacentNodes(int maxDepth, - OctNode* node1,int width1, - OctNode* node2,int width2, - int depth,NodeAdjacencyFunction* F,int processCurrent) - { - int c1[3],c2[3],w1,w2; - node1->centerIndex(maxDepth+1,c1); - node2->centerIndex(maxDepth+1,c2); - w1=node1->width(maxDepth+1); - w2=node2->width(maxDepth+1); - - ProcessFixedDepthNodeAdjacentNodes(c1[0]-c2[0],c1[1]-c2[1],c1[2]-c2[2],node1,(width1*w1)>>1,node2,(width2*w2)>>1,w2,depth,F,processCurrent); - } - template - template - void OctNode::ProcessFixedDepthNodeAdjacentNodes(int dx,int dy,int dz, - OctNode* node1,int radius1, - OctNode* node2,int radius2,int width2, - int depth,NodeAdjacencyFunction* F,int processCurrent) - { - int d=node2->depth(); - if(d>depth){return;} - if(!Overlap(dx,dy,dz,radius1+radius2)){return;} - if(d==depth){if(processCurrent){F->Function(node2,node1);}} - else{ - if(!node2->children){return;} - __ProcessFixedDepthNodeAdjacentNodes(-dx,-dy,-dz,node1,radius1,node2,radius2,width2/2,depth-1,F); - } - } - template - template - void OctNode::ProcessMaxDepthNodeAdjacentNodes(int maxDepth, - OctNode* node1,int width1, - OctNode* node2,int width2, - int depth,NodeAdjacencyFunction* F,int processCurrent) - { - int c1[3],c2[3],w1,w2; - node1->centerIndex(maxDepth+1,c1); - node2->centerIndex(maxDepth+1,c2); - w1=node1->width(maxDepth+1); - w2=node2->width(maxDepth+1); - ProcessMaxDepthNodeAdjacentNodes(c1[0]-c2[0],c1[1]-c2[1],c1[2]-c2[2],node1,(width1*w1)>>1,node2,(width2*w2)>>1,w2,depth,F,processCurrent); - } - template - template - void OctNode::ProcessMaxDepthNodeAdjacentNodes(int dx,int dy,int dz, - OctNode* node1,int radius1, - OctNode* node2,int radius2,int width2, - int depth,NodeAdjacencyFunction* F,int processCurrent) - { - int d=node2->depth(); - if(d>depth){return;} - if(!Overlap(dx,dy,dz,radius1+radius2)){return;} - if(processCurrent){F->Function(node2,node1);} - if(dchildren){__ProcessMaxDepthNodeAdjacentNodes(-dx,-dy,-dz,node1,radius1,node2,radius2,width2>>1,depth-1,F);} - } - template - template - void OctNode::__ProcessNodeAdjacentNodes(int dx,int dy,int dz, - OctNode* node1,int radius1, - OctNode* node2,int radius2,int cWidth2, - NodeAdjacencyFunction* F) - { - int cWidth=cWidth2>>1; - int radius=radius2>>1; - int o=ChildOverlap(dx,dy,dz,radius1+radius,cWidth); - if(o){ - int dx1=dx-cWidth; - int dx2=dx+cWidth; - int dy1=dy-cWidth; - int dy2=dy+cWidth; - int dz1=dz-cWidth; - int dz2=dz+cWidth; - if(o& 1){F->Function(&node2->children[0],node1);if(node2->children[0].children){__ProcessNodeAdjacentNodes(dx1,dy1,dz1,node1,radius1,&node2->children[0],radius,cWidth,F);}} - if(o& 2){F->Function(&node2->children[1],node1);if(node2->children[1].children){__ProcessNodeAdjacentNodes(dx2,dy1,dz1,node1,radius1,&node2->children[1],radius,cWidth,F);}} - if(o& 4){F->Function(&node2->children[2],node1);if(node2->children[2].children){__ProcessNodeAdjacentNodes(dx1,dy2,dz1,node1,radius1,&node2->children[2],radius,cWidth,F);}} - if(o& 8){F->Function(&node2->children[3],node1);if(node2->children[3].children){__ProcessNodeAdjacentNodes(dx2,dy2,dz1,node1,radius1,&node2->children[3],radius,cWidth,F);}} - if(o& 16){F->Function(&node2->children[4],node1);if(node2->children[4].children){__ProcessNodeAdjacentNodes(dx1,dy1,dz2,node1,radius1,&node2->children[4],radius,cWidth,F);}} - if(o& 32){F->Function(&node2->children[5],node1);if(node2->children[5].children){__ProcessNodeAdjacentNodes(dx2,dy1,dz2,node1,radius1,&node2->children[5],radius,cWidth,F);}} - if(o& 64){F->Function(&node2->children[6],node1);if(node2->children[6].children){__ProcessNodeAdjacentNodes(dx1,dy2,dz2,node1,radius1,&node2->children[6],radius,cWidth,F);}} - if(o&128){F->Function(&node2->children[7],node1);if(node2->children[7].children){__ProcessNodeAdjacentNodes(dx2,dy2,dz2,node1,radius1,&node2->children[7],radius,cWidth,F);}} - } - } - template - template - void OctNode::__ProcessTerminatingNodeAdjacentNodes(int dx,int dy,int dz, - OctNode* node1,int radius1, - OctNode* node2,int radius2,int cWidth2, - TerminatingNodeAdjacencyFunction* F) - { - int cWidth=cWidth2>>1; - int radius=radius2>>1; - int o=ChildOverlap(dx,dy,dz,radius1+radius,cWidth); - if(o){ - int dx1=dx-cWidth; - int dx2=dx+cWidth; - int dy1=dy-cWidth; - int dy2=dy+cWidth; - int dz1=dz-cWidth; - int dz2=dz+cWidth; - if(o& 1){if(F->Function(&node2->children[0],node1) && node2->children[0].children){__ProcessTerminatingNodeAdjacentNodes(dx1,dy1,dz1,node1,radius1,&node2->children[0],radius,cWidth,F);}} - if(o& 2){if(F->Function(&node2->children[1],node1) && node2->children[1].children){__ProcessTerminatingNodeAdjacentNodes(dx2,dy1,dz1,node1,radius1,&node2->children[1],radius,cWidth,F);}} - if(o& 4){if(F->Function(&node2->children[2],node1) && node2->children[2].children){__ProcessTerminatingNodeAdjacentNodes(dx1,dy2,dz1,node1,radius1,&node2->children[2],radius,cWidth,F);}} - if(o& 8){if(F->Function(&node2->children[3],node1) && node2->children[3].children){__ProcessTerminatingNodeAdjacentNodes(dx2,dy2,dz1,node1,radius1,&node2->children[3],radius,cWidth,F);}} - if(o& 16){if(F->Function(&node2->children[4],node1) && node2->children[4].children){__ProcessTerminatingNodeAdjacentNodes(dx1,dy1,dz2,node1,radius1,&node2->children[4],radius,cWidth,F);}} - if(o& 32){if(F->Function(&node2->children[5],node1) && node2->children[5].children){__ProcessTerminatingNodeAdjacentNodes(dx2,dy1,dz2,node1,radius1,&node2->children[5],radius,cWidth,F);}} - if(o& 64){if(F->Function(&node2->children[6],node1) && node2->children[6].children){__ProcessTerminatingNodeAdjacentNodes(dx1,dy2,dz2,node1,radius1,&node2->children[6],radius,cWidth,F);}} - if(o&128){if(F->Function(&node2->children[7],node1) && node2->children[7].children){__ProcessTerminatingNodeAdjacentNodes(dx2,dy2,dz2,node1,radius1,&node2->children[7],radius,cWidth,F);}} - } - } - template - template - void OctNode::__ProcessPointAdjacentNodes(int dx,int dy,int dz, - OctNode* node2,int radius2,int cWidth2, - PointAdjacencyFunction* F) - { - int cWidth=cWidth2>>1; - int radius=radius2>>1; - int o=ChildOverlap(dx,dy,dz,radius,cWidth); - if( o ) - { - int dx1=dx-cWidth; - int dx2=dx+cWidth; - int dy1=dy-cWidth; - int dy2=dy+cWidth; - int dz1=dz-cWidth; - int dz2=dz+cWidth; - if(o& 1){F->Function(&node2->children[0]);if(node2->children[0].children){__ProcessPointAdjacentNodes(dx1,dy1,dz1,&node2->children[0],radius,cWidth,F);}} - if(o& 2){F->Function(&node2->children[1]);if(node2->children[1].children){__ProcessPointAdjacentNodes(dx2,dy1,dz1,&node2->children[1],radius,cWidth,F);}} - if(o& 4){F->Function(&node2->children[2]);if(node2->children[2].children){__ProcessPointAdjacentNodes(dx1,dy2,dz1,&node2->children[2],radius,cWidth,F);}} - if(o& 8){F->Function(&node2->children[3]);if(node2->children[3].children){__ProcessPointAdjacentNodes(dx2,dy2,dz1,&node2->children[3],radius,cWidth,F);}} - if(o& 16){F->Function(&node2->children[4]);if(node2->children[4].children){__ProcessPointAdjacentNodes(dx1,dy1,dz2,&node2->children[4],radius,cWidth,F);}} - if(o& 32){F->Function(&node2->children[5]);if(node2->children[5].children){__ProcessPointAdjacentNodes(dx2,dy1,dz2,&node2->children[5],radius,cWidth,F);}} - if(o& 64){F->Function(&node2->children[6]);if(node2->children[6].children){__ProcessPointAdjacentNodes(dx1,dy2,dz2,&node2->children[6],radius,cWidth,F);}} - if(o&128){F->Function(&node2->children[7]);if(node2->children[7].children){__ProcessPointAdjacentNodes(dx2,dy2,dz2,&node2->children[7],radius,cWidth,F);}} - } - } - template - template - void OctNode::__ProcessFixedDepthNodeAdjacentNodes(int dx,int dy,int dz, - OctNode* node1,int radius1, - OctNode* node2,int radius2,int cWidth2, - int depth,NodeAdjacencyFunction* F) - { - int cWidth=cWidth2>>1; - int radius=radius2>>1; - int o=ChildOverlap(dx,dy,dz,radius1+radius,cWidth); - if(o){ - int dx1=dx-cWidth; - int dx2=dx+cWidth; - int dy1=dy-cWidth; - int dy2=dy+cWidth; - int dz1=dz-cWidth; - int dz2=dz+cWidth; - if(node2->depth()==depth){ - if(o& 1){F->Function(&node2->children[0],node1);} - if(o& 2){F->Function(&node2->children[1],node1);} - if(o& 4){F->Function(&node2->children[2],node1);} - if(o& 8){F->Function(&node2->children[3],node1);} - if(o& 16){F->Function(&node2->children[4],node1);} - if(o& 32){F->Function(&node2->children[5],node1);} - if(o& 64){F->Function(&node2->children[6],node1);} - if(o&128){F->Function(&node2->children[7],node1);} - } - else{ - if(o& 1){if(node2->children[0].children){__ProcessFixedDepthNodeAdjacentNodes(dx1,dy1,dz1,node1,radius1,&node2->children[0],radius,cWidth,depth,F);}} - if(o& 2){if(node2->children[1].children){__ProcessFixedDepthNodeAdjacentNodes(dx2,dy1,dz1,node1,radius1,&node2->children[1],radius,cWidth,depth,F);}} - if(o& 4){if(node2->children[2].children){__ProcessFixedDepthNodeAdjacentNodes(dx1,dy2,dz1,node1,radius1,&node2->children[2],radius,cWidth,depth,F);}} - if(o& 8){if(node2->children[3].children){__ProcessFixedDepthNodeAdjacentNodes(dx2,dy2,dz1,node1,radius1,&node2->children[3],radius,cWidth,depth,F);}} - if(o& 16){if(node2->children[4].children){__ProcessFixedDepthNodeAdjacentNodes(dx1,dy1,dz2,node1,radius1,&node2->children[4],radius,cWidth,depth,F);}} - if(o& 32){if(node2->children[5].children){__ProcessFixedDepthNodeAdjacentNodes(dx2,dy1,dz2,node1,radius1,&node2->children[5],radius,cWidth,depth,F);}} - if(o& 64){if(node2->children[6].children){__ProcessFixedDepthNodeAdjacentNodes(dx1,dy2,dz2,node1,radius1,&node2->children[6],radius,cWidth,depth,F);}} - if(o&128){if(node2->children[7].children){__ProcessFixedDepthNodeAdjacentNodes(dx2,dy2,dz2,node1,radius1,&node2->children[7],radius,cWidth,depth,F);}} - } - } - } - template - template - void OctNode::__ProcessMaxDepthNodeAdjacentNodes(int dx,int dy,int dz, - OctNode* node1,int radius1, - OctNode* node2,int radius2,int cWidth2, - int depth,NodeAdjacencyFunction* F) - { - int cWidth=cWidth2>>1; - int radius=radius2>>1; - int o=ChildOverlap(dx,dy,dz,radius1+radius,cWidth); - if(o){ - int dx1=dx-cWidth; - int dx2=dx+cWidth; - int dy1=dy-cWidth; - int dy2=dy+cWidth; - int dz1=dz-cWidth; - int dz2=dz+cWidth; - if(node2->depth()<=depth){ - if(o& 1){F->Function(&node2->children[0],node1);} - if(o& 2){F->Function(&node2->children[1],node1);} - if(o& 4){F->Function(&node2->children[2],node1);} - if(o& 8){F->Function(&node2->children[3],node1);} - if(o& 16){F->Function(&node2->children[4],node1);} - if(o& 32){F->Function(&node2->children[5],node1);} - if(o& 64){F->Function(&node2->children[6],node1);} - if(o&128){F->Function(&node2->children[7],node1);} - } - if(node2->depth()children[0].children){__ProcessMaxDepthNodeAdjacentNodes(dx1,dy1,dz1,node1,radius1,&node2->children[0],radius,cWidth,depth,F);}} - if(o& 2){if(node2->children[1].children){__ProcessMaxDepthNodeAdjacentNodes(dx2,dy1,dz1,node1,radius1,&node2->children[1],radius,cWidth,depth,F);}} - if(o& 4){if(node2->children[2].children){__ProcessMaxDepthNodeAdjacentNodes(dx1,dy2,dz1,node1,radius1,&node2->children[2],radius,cWidth,depth,F);}} - if(o& 8){if(node2->children[3].children){__ProcessMaxDepthNodeAdjacentNodes(dx2,dy2,dz1,node1,radius1,&node2->children[3],radius,cWidth,depth,F);}} - if(o& 16){if(node2->children[4].children){__ProcessMaxDepthNodeAdjacentNodes(dx1,dy1,dz2,node1,radius1,&node2->children[4],radius,cWidth,depth,F);}} - if(o& 32){if(node2->children[5].children){__ProcessMaxDepthNodeAdjacentNodes(dx2,dy1,dz2,node1,radius1,&node2->children[5],radius,cWidth,depth,F);}} - if(o& 64){if(node2->children[6].children){__ProcessMaxDepthNodeAdjacentNodes(dx1,dy2,dz2,node1,radius1,&node2->children[6],radius,cWidth,depth,F);}} - if(o&128){if(node2->children[7].children){__ProcessMaxDepthNodeAdjacentNodes(dx2,dy2,dz2,node1,radius1,&node2->children[7],radius,cWidth,depth,F);}} - } - } - } - template - inline int OctNode::ChildOverlap(int dx,int dy,int dz,int d,int cRadius2) - { - int w1=d-cRadius2; - int w2=d+cRadius2; - int overlap=0; - - int test=0,test1=0; - if(dx-w1){test =1;} - if(dx-w2){test|=2;} - - if(!test){return 0;} - if(dz-w1){test1 =test;} - if(dz-w2){test1|=test<<4;} - - if(!test1){return 0;} - if(dy-w1){overlap =test1;} - if(dy-w2){overlap|=test1<<2;} - return overlap; - } - - template - OctNode* OctNode::getNearestLeaf(const Point3D& p){ - Point3D center; - Real width; - OctNode* temp; - int cIndex; - if(!children){return this;} - centerAndWidth(center,width); - temp=this; - while(temp->children){ - cIndex=CornerIndex(center,p); - temp=&temp->children[cIndex]; - width/=2; - if(cIndex&1){center.coords[0]+=width/2;} - else {center.coords[0]-=width/2;} - if(cIndex&2){center.coords[1]+=width/2;} - else {center.coords[1]-=width/2;} - if(cIndex&4){center.coords[2]+=width/2;} - else {center.coords[2]-=width/2;} - } - return temp; - } - template - const OctNode* OctNode::getNearestLeaf(const Point3D& p) const{ - int nearest; - Real temp,dist2; - if(!children){return this;} - for(int i=0;i - int OctNode::CommonEdge(const OctNode* node1,int eIndex1,const OctNode* node2,int eIndex2){ - int o1,o2,i1,i2,j1,j2; - - Cube::FactorEdgeIndex(eIndex1,o1,i1,j1); - Cube::FactorEdgeIndex(eIndex2,o2,i2,j2); - if(o1!=o2){return 0;} - - int dir[2]; - int idx1[2]; - int idx2[2]; - switch(o1){ - case 0: dir[0]=1; dir[1]=2; break; - case 1: dir[0]=0; dir[1]=2; break; - case 2: dir[0]=0; dir[1]=1; break; - }; - int d1,d2,off1[3],off2[3]; - node1->depthAndOffset(d1,off1); - node2->depthAndOffset(d2,off2); - idx1[0]=off1[dir[0]]+(1<d2){ - idx2[0]<<=(d1-d2); - idx2[1]<<=(d1-d2); - } - else{ - idx1[0]<<=(d2-d1); - idx1[1]<<=(d2-d1); - } - if(idx1[0]==idx2[0] && idx1[1]==idx2[1]){return 1;} - else {return 0;} - } - template - int OctNode::CornerIndex(const Point3D& center,const Point3D& p){ - int cIndex=0; - if(p.coords[0]>center.coords[0]){cIndex|=1;} - if(p.coords[1]>center.coords[1]){cIndex|=2;} - if(p.coords[2]>center.coords[2]){cIndex|=4;} - return cIndex; - } - template - template - OctNode& OctNode::operator = (const OctNode& node){ - int i; - if(children){delete[] children;} - children=NULL; - - d=node.depth (); - for(i=0;ioffset[i] = node.offset[i];} - if(node.children){ - initChildren(); - for(i=0;i - int OctNode::CompareForwardDepths(const void* v1,const void* v2){ - return ((const OctNode*)v1)->depth-((const OctNode*)v2)->depth; - } - template< class NodeData , class Real > - int OctNode< NodeData , Real >::CompareByDepthAndXYZ( const void* v1 , const void* v2 ) - { - const OctNode *n1 = (*(const OctNode< NodeData , Real >**)v1); - const OctNode *n2 = (*(const OctNode< NodeData , Real >**)v2); - if( n1->d!=n2->d ) return int(n1->d)-int(n2->d); - else if( n1->off[0]!=n2->off[0] ) return int(n1->off[0]) - int(n2->off[0]); - else if( n1->off[1]!=n2->off[1] ) return int(n1->off[1]) - int(n2->off[1]); - else if( n1->off[2]!=n2->off[2] ) return int(n1->off[2]) - int(n2->off[2]); - return 0; - } - - long long _InterleaveBits( int p[3] ) - { - long long key = 0; - for( int i=0 ; i<32 ; i++ ) key |= ( ( p[0] & (1< - int OctNode::CompareByDepthAndZIndex( const void* v1 , const void* v2 ) - { - const OctNode* n1 = (*(const OctNode**)v1); - const OctNode* n2 = (*(const OctNode**)v2); - int d1 , off1[3] , d2 , off2[3]; - n1->depthAndOffset( d1 , off1 ) , n2->depthAndOffset( d2 , off2 ); - if ( d1>d2 ) return 1; - else if( d1k2 ) return 1; - else if( k1 - int OctNode::CompareForwardPointerDepths( const void* v1 , const void* v2 ) - { - const OctNode* n1 = (*(const OctNode**)v1); - const OctNode* n2 = (*(const OctNode**)v2); - if(n1->d!=n2->d){return int(n1->d)-int(n2->d);} - while( n1->parent!=n2->parent ) - { - n1=n1->parent; - n2=n2->parent; - } - if(n1->off[0]!=n2->off[0]){return int(n1->off[0])-int(n2->off[0]);} - if(n1->off[1]!=n2->off[1]){return int(n1->off[1])-int(n2->off[1]);} - return int(n1->off[2])-int(n2->off[2]); - return 0; - } - template - int OctNode::CompareBackwardDepths(const void* v1,const void* v2){ - return ((const OctNode*)v2)->depth-((const OctNode*)v1)->depth; - } - template - int OctNode::CompareBackwardPointerDepths(const void* v1,const void* v2){ - return (*(const OctNode**)v2)->depth()-(*(const OctNode**)v1)->depth(); - } - template - inline int OctNode::Overlap2(const int &depth1,const int offSet1[DIMENSION],const Real& multiplier1,const int &depth2,const int offSet2[DIMENSION],const Real& multiplier2){ - int d=depth2-depth1; - Real w=multiplier2+multiplier1*(1<=w || - fabs(Real(offSet2[1]-(offSet1[1]<=w || - fabs(Real(offSet2[2]-(offSet1[2]<=w - ){return 0;} - return 1; - } - template - inline int OctNode::Overlap(int c1,int c2,int c3,int dWidth){ - if(c1>=dWidth || c1<=-dWidth || c2>=dWidth || c2<=-dWidth || c3>=dWidth || c3<=-dWidth){return 0;} - else{return 1;} - } - template - OctNode* OctNode::faceNeighbor(int faceIndex,int forceChildren){return __faceNeighbor(faceIndex>>1,faceIndex&1,forceChildren);} - template - const OctNode* OctNode::faceNeighbor(int faceIndex) const {return __faceNeighbor(faceIndex>>1,faceIndex&1);} - template - OctNode* OctNode::__faceNeighbor(int dir,int off,int forceChildren){ - if(!parent){return NULL;} - int pIndex=int(this-parent->children); - pIndex^=(1<children[pIndex];} - else{ - OctNode* temp=parent->__faceNeighbor(dir,off,forceChildren); - if(!temp){return NULL;} - if(!temp->children){ - if(forceChildren){temp->initChildren();} - else{return temp;} - } - return &temp->children[pIndex]; - } - } - template - const OctNode* OctNode::__faceNeighbor(int dir,int off) const { - if(!parent){return NULL;} - int pIndex=int(this-parent->children); - pIndex^=(1<children[pIndex];} - else{ - const OctNode* temp=parent->__faceNeighbor(dir,off); - if(!temp || !temp->children){return temp;} - else{return &temp->children[pIndex];} - } - } - - template - OctNode* OctNode::edgeNeighbor(int edgeIndex,int forceChildren){ - int idx[2],o,i[2]; - Cube::FactorEdgeIndex(edgeIndex,o,i[0],i[1]); - switch(o){ - case 0: idx[0]=1; idx[1]=2; break; - case 1: idx[0]=0; idx[1]=2; break; - case 2: idx[0]=0; idx[1]=1; break; - }; - return __edgeNeighbor(o,i,idx,forceChildren); - } - template - const OctNode* OctNode::edgeNeighbor(int edgeIndex) const { - int idx[2],o,i[2]; - Cube::FactorEdgeIndex(edgeIndex,o,i[0],i[1]); - switch(o){ - case 0: idx[0]=1; idx[1]=2; break; - case 1: idx[0]=0; idx[1]=2; break; - case 2: idx[0]=0; idx[1]=1; break; - }; - return __edgeNeighbor(o,i,idx); - } - template - const OctNode* OctNode::__edgeNeighbor(int o,const int i[2],const int idx[2]) const{ - if(!parent){return NULL;} - int pIndex=int(this-parent->children); - int aIndex,x[DIMENSION]; - - Cube::FactorCornerIndex(pIndex,x[0],x[1],x[2]); - aIndex=(~((i[0] ^ x[idx[0]]) | ((i[1] ^ x[idx[1]])<<1))) & 3; - pIndex^=(7 ^ (1<__faceNeighbor(idx[0],i[0]); - if(!temp || !temp->children){return NULL;} - else{return &temp->children[pIndex];} - } - else if(aIndex==2) { // I can get the neighbor from the parent's face adjacent neighbor - const OctNode* temp=parent->__faceNeighbor(idx[1],i[1]); - if(!temp || !temp->children){return NULL;} - else{return &temp->children[pIndex];} - } - else if(aIndex==0) { // I can get the neighbor from the parent - return &parent->children[pIndex]; - } - else if(aIndex==3) { // I can get the neighbor from the parent's edge adjacent neighbor - const OctNode* temp=parent->__edgeNeighbor(o,i,idx); - if(!temp || !temp->children){return temp;} - else{return &temp->children[pIndex];} - } - else{return NULL;} - } - template - OctNode* OctNode::__edgeNeighbor(int o,const int i[2],const int idx[2],int forceChildren){ - if(!parent){return NULL;} - int pIndex=int(this-parent->children); - int aIndex,x[DIMENSION]; - - Cube::FactorCornerIndex(pIndex,x[0],x[1],x[2]); - aIndex=(~((i[0] ^ x[idx[0]]) | ((i[1] ^ x[idx[1]])<<1))) & 3; - pIndex^=(7 ^ (1<__faceNeighbor(idx[0],i[0],0); - if(!temp || !temp->children){return NULL;} - else{return &temp->children[pIndex];} - } - else if(aIndex==2) { // I can get the neighbor from the parent's face adjacent neighbor - OctNode* temp=parent->__faceNeighbor(idx[1],i[1],0); - if(!temp || !temp->children){return NULL;} - else{return &temp->children[pIndex];} - } - else if(aIndex==0) { // I can get the neighbor from the parent - return &parent->children[pIndex]; - } - else if(aIndex==3) { // I can get the neighbor from the parent's edge adjacent neighbor - OctNode* temp=parent->__edgeNeighbor(o,i,idx,forceChildren); - if(!temp){return NULL;} - if(!temp->children){ - if(forceChildren){temp->initChildren();} - else{return temp;} - } - return &temp->children[pIndex]; - } - else{return NULL;} - } - - template - const OctNode* OctNode::cornerNeighbor(int cornerIndex) const { - int pIndex,aIndex=0; - if(!parent){return NULL;} - - pIndex=int(this-parent->children); - aIndex=(cornerIndex ^ pIndex); // The disagreement bits - pIndex=(~pIndex)&7; // The antipodal point - if(aIndex==7){ // Agree on no bits - return &parent->children[pIndex]; - } - else if(aIndex==0){ // Agree on all bits - const OctNode* temp=((const OctNode*)parent)->cornerNeighbor(cornerIndex); - if(!temp || !temp->children){return temp;} - else{return &temp->children[pIndex];} - } - else if(aIndex==6){ // Agree on face 0 - const OctNode* temp=((const OctNode*)parent)->__faceNeighbor(0,cornerIndex & 1); - if(!temp || !temp->children){return NULL;} - else{return & temp->children[pIndex];} - } - else if(aIndex==5){ // Agree on face 1 - const OctNode* temp=((const OctNode*)parent)->__faceNeighbor(1,(cornerIndex & 2)>>1); - if(!temp || !temp->children){return NULL;} - else{return & temp->children[pIndex];} - } - else if(aIndex==3){ // Agree on face 2 - const OctNode* temp=((const OctNode*)parent)->__faceNeighbor(2,(cornerIndex & 4)>>2); - if(!temp || !temp->children){return NULL;} - else{return & temp->children[pIndex];} - } - else if(aIndex==4){ // Agree on edge 2 - const OctNode* temp=((const OctNode*)parent)->edgeNeighbor(8 | (cornerIndex & 1) | (cornerIndex & 2) ); - if(!temp || !temp->children){return NULL;} - else{return & temp->children[pIndex];} - } - else if(aIndex==2){ // Agree on edge 1 - const OctNode* temp=((const OctNode*)parent)->edgeNeighbor(4 | (cornerIndex & 1) | ((cornerIndex & 4)>>1) ); - if(!temp || !temp->children){return NULL;} - else{return & temp->children[pIndex];} - } - else if(aIndex==1){ // Agree on edge 0 - const OctNode* temp=((const OctNode*)parent)->edgeNeighbor(((cornerIndex & 2) | (cornerIndex & 4))>>1 ); - if(!temp || !temp->children){return NULL;} - else{return & temp->children[pIndex];} - } - else{return NULL;} - } - template - OctNode* OctNode::cornerNeighbor(int cornerIndex,int forceChildren){ - int pIndex,aIndex=0; - if(!parent){return NULL;} - - pIndex=int(this-parent->children); - aIndex=(cornerIndex ^ pIndex); // The disagreement bits - pIndex=(~pIndex)&7; // The antipodal point - if(aIndex==7){ // Agree on no bits - return &parent->children[pIndex]; - } - else if(aIndex==0){ // Agree on all bits - OctNode* temp=((OctNode*)parent)->cornerNeighbor(cornerIndex,forceChildren); - if(!temp){return NULL;} - if(!temp->children){ - if(forceChildren){temp->initChildren();} - else{return temp;} - } - return &temp->children[pIndex]; - } - else if(aIndex==6){ // Agree on face 0 - OctNode* temp=((OctNode*)parent)->__faceNeighbor(0,cornerIndex & 1,0); - if(!temp || !temp->children){return NULL;} - else{return & temp->children[pIndex];} - } - else if(aIndex==5){ // Agree on face 1 - OctNode* temp=((OctNode*)parent)->__faceNeighbor(1,(cornerIndex & 2)>>1,0); - if(!temp || !temp->children){return NULL;} - else{return & temp->children[pIndex];} - } - else if(aIndex==3){ // Agree on face 2 - OctNode* temp=((OctNode*)parent)->__faceNeighbor(2,(cornerIndex & 4)>>2,0); - if(!temp || !temp->children){return NULL;} - else{return & temp->children[pIndex];} - } - else if(aIndex==4){ // Agree on edge 2 - OctNode* temp=((OctNode*)parent)->edgeNeighbor(8 | (cornerIndex & 1) | (cornerIndex & 2) ); - if(!temp || !temp->children){return NULL;} - else{return & temp->children[pIndex];} - } - else if(aIndex==2){ // Agree on edge 1 - OctNode* temp=((OctNode*)parent)->edgeNeighbor(4 | (cornerIndex & 1) | ((cornerIndex & 4)>>1) ); - if(!temp || !temp->children){return NULL;} - else{return & temp->children[pIndex];} - } - else if(aIndex==1){ // Agree on edge 0 - OctNode* temp=((OctNode*)parent)->edgeNeighbor(((cornerIndex & 2) | (cornerIndex & 4))>>1 ); - if(!temp || !temp->children){return NULL;} - else{return & temp->children[pIndex];} - } - else{return NULL;} - } - //////////////////////// - // OctNodeNeighborKey // - //////////////////////// - template - OctNode::Neighbors3::Neighbors3(void){clear();} - template - void OctNode::Neighbors3::clear(void){ - for(int i=0;i<3;i++){for(int j=0;j<3;j++){for(int k=0;k<3;k++){neighbors[i][j][k]=NULL;}}} - } - template - OctNode::NeighborKey3::NeighborKey3(void){ neighbors=NULL; } - template - OctNode::NeighborKey3::~NeighborKey3(void) - { - if( neighbors ) delete[] neighbors; - neighbors = NULL; - } - - template - void OctNode::NeighborKey3::set( int d ) - { - if( neighbors ) delete[] neighbors; - neighbors = NULL; - if( d<0 ) return; - neighbors = new Neighbors3[d+1]; - } - template< class NodeData , class Real > - typename OctNode::Neighbors3& OctNode::NeighborKey3::setNeighbors( OctNode* root , Point3D< Real > p , int d ) - { - if( !neighbors[d].neighbors[1][1][1] || !neighbors[d].neighbors[1][1][1]->isInside( p ) ) - { - neighbors[d].clear(); - - if( !d ) neighbors[d].neighbors[1][1][1] = root; - else - { - Neighbors3& temp = setNeighbors( root , p , d-1 ); - - int i , j , k , x1 , y1 , z1 , x2 , y2 , z2; - Point3D< Real > c; - Real w; - temp.neighbors[1][1][1]->centerAndWidth( c , w ); - int idx = CornerIndex( c , p ); - Cube::FactorCornerIndex( idx , x1 , y1 , z1 ); - Cube::FactorCornerIndex( (~idx)&7 , x2 , y2 , z2 ); - - if( !temp.neighbors[1][1][1]->children ) temp.neighbors[1][1][1]->initChildren(); - for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ ) - neighbors[d].neighbors[x2+i][y2+j][z2+k] = &temp.neighbors[1][1][1]->children[Cube::CornerIndex(i,j,k)]; - - - // Set the neighbors from across the faces - i=x1<<1; - if( temp.neighbors[i][1][1] ) - { - if( !temp.neighbors[i][1][1]->children ) temp.neighbors[i][1][1]->initChildren(); - for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ ) neighbors[d].neighbors[i][y2+j][z2+k] = &temp.neighbors[i][1][1]->children[Cube::CornerIndex(x2,j,k)]; - } - j=y1<<1; - if( temp.neighbors[1][j][1] ) - { - if( !temp.neighbors[1][j][1]->children ) temp.neighbors[1][j][1]->initChildren(); - for( i=0 ; i<2 ; i++ ) for( k=0 ; k<2 ; k++ ) neighbors[d].neighbors[x2+i][j][z2+k] = &temp.neighbors[1][j][1]->children[Cube::CornerIndex(i,y2,k)]; - } - k=z1<<1; - if( temp.neighbors[1][1][k] ) - { - if( !temp.neighbors[1][1][k]->children ) temp.neighbors[1][1][k]->initChildren(); - for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ ) neighbors[d].neighbors[x2+i][y2+j][k] = &temp.neighbors[1][1][k]->children[Cube::CornerIndex(i,j,z2)]; - } - - // Set the neighbors from across the edges - i=x1<<1 , j=y1<<1; - if( temp.neighbors[i][j][1] ) - { - if( !temp.neighbors[i][j][1]->children ) temp.neighbors[i][j][1]->initChildren(); - for( k=0 ; k<2 ; k++ ) neighbors[d].neighbors[i][j][z2+k] = &temp.neighbors[i][j][1]->children[Cube::CornerIndex(x2,y2,k)]; - } - i=x1<<1 , k=z1<<1; - if( temp.neighbors[i][1][k] ) - { - if( !temp.neighbors[i][1][k]->children ) temp.neighbors[i][1][k]->initChildren(); - for( j=0 ; j<2 ; j++ ) neighbors[d].neighbors[i][y2+j][k] = &temp.neighbors[i][1][k]->children[Cube::CornerIndex(x2,j,z2)]; - } - j=y1<<1 , k=z1<<1; - if( temp.neighbors[1][j][k] ) - { - if( !temp.neighbors[1][j][k]->children ) temp.neighbors[1][j][k]->initChildren(); - for( i=0 ; i<2 ; i++ ) neighbors[d].neighbors[x2+i][j][k] = &temp.neighbors[1][j][k]->children[Cube::CornerIndex(i,y2,z2)]; - } - - // Set the neighbor from across the corner - i=x1<<1 , j=y1<<1 , k=z1<<1; - if( temp.neighbors[i][j][k] ) - { - if( !temp.neighbors[i][j][k]->children ) temp.neighbors[i][j][k]->initChildren(); - neighbors[d].neighbors[i][j][k] = &temp.neighbors[i][j][k]->children[Cube::CornerIndex(x2,y2,z2)]; - } - } - } - return neighbors[d]; - } - template< class NodeData , class Real > - typename OctNode::Neighbors3& OctNode::NeighborKey3::getNeighbors( OctNode* root , Point3D< Real > p , int d ) - { - if( !neighbors[d].neighbors[1][1][1] || !neighbors[d].neighbors[1][1][1]->isInside( p ) ) - { - neighbors[d].clear(); - - if( !d ) neighbors[d].neighbors[1][1][1] = root; - else - { - Neighbors3& temp = getNeighbors( root , p , d-1 ); - - int i , j , k , x1 , y1 , z1 , x2 , y2 , z2; - Point3D< Real > c; - Real w; - temp.neighbors[1][1][1]->centerAndWidth( c , w ); - int idx = CornerIndex( c , p ); - Cube::FactorCornerIndex( idx , x1 , y1 , z1 ); - Cube::FactorCornerIndex( (~idx)&7 , x2 , y2 , z2 ); - - if( !temp.neighbors[1][1][1] || !temp.neighbors[1][1][1]->children ) - { - fprintf( stderr , "[ERROR] Couldn't find node at appropriate depth\n" ); - exit( 0 ); - } - for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ ) - neighbors[d].neighbors[x2+i][y2+j][z2+k] = &temp.neighbors[1][1][1]->children[Cube::CornerIndex(i,j,k)]; - - - // Set the neighbors from across the faces - i=x1<<1; - if( temp.neighbors[i][1][1] ) - for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ ) neighbors[d].neighbors[i][y2+j][z2+k] = &temp.neighbors[i][1][1]->children[Cube::CornerIndex(x2,j,k)]; - j=y1<<1; - if( temp.neighbors[1][j][1] ) - for( i=0 ; i<2 ; i++ ) for( k=0 ; k<2 ; k++ ) neighbors[d].neighbors[x2+i][j][z2+k] = &temp.neighbors[1][j][1]->children[Cube::CornerIndex(i,y2,k)]; - k=z1<<1; - if( temp.neighbors[1][1][k] ) - for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ ) neighbors[d].neighbors[x2+i][y2+j][k] = &temp.neighbors[1][1][k]->children[Cube::CornerIndex(i,j,z2)]; - - // Set the neighbors from across the edges - i=x1<<1 , j=y1<<1; - if( temp.neighbors[i][j][1] ) - for( k=0 ; k<2 ; k++ ) neighbors[d].neighbors[i][j][z2+k] = &temp.neighbors[i][j][1]->children[Cube::CornerIndex(x2,y2,k)]; - i=x1<<1 , k=z1<<1; - if( temp.neighbors[i][1][k] ) - for( j=0 ; j<2 ; j++ ) neighbors[d].neighbors[i][y2+j][k] = &temp.neighbors[i][1][k]->children[Cube::CornerIndex(x2,j,z2)]; - j=y1<<1 , k=z1<<1; - if( temp.neighbors[1][j][k] ) - for( i=0 ; i<2 ; i++ ) neighbors[d].neighbors[x2+i][j][k] = &temp.neighbors[1][j][k]->children[Cube::CornerIndex(i,y2,z2)]; - - // Set the neighbor from across the corner - i=x1<<1 , j=y1<<1 , k=z1<<1; - if( temp.neighbors[i][j][k] ) - neighbors[d].neighbors[i][j][k] = &temp.neighbors[i][j][k]->children[Cube::CornerIndex(x2,y2,z2)]; - } - } - return neighbors[d]; - } - - template< class NodeData , class Real > - typename OctNode::Neighbors3& OctNode::NeighborKey3::setNeighbors( OctNode* node ) - { - int d = node->depth(); - if( node==neighbors[d].neighbors[1][1][1] ) - { - bool reset = false; - for( int i=0 ; i<3 ; i++ ) for( int j=0 ; j<3 ; j++ ) for( int k=0 ; k<3 ; k++ ) if( !neighbors[d].neighbors[i][j][k] ) reset = true; - if( reset ) neighbors[d].neighbors[1][1][1] = NULL; - } - if( node!=neighbors[d].neighbors[1][1][1] ) - { - neighbors[d].clear(); - - if( !node->parent ) neighbors[d].neighbors[1][1][1] = node; - else - { - int i,j,k,x1,y1,z1,x2,y2,z2; - int idx=int(node-node->parent->children); - Cube::FactorCornerIndex( idx ,x1,y1,z1); - Cube::FactorCornerIndex((~idx)&7,x2,y2,z2); - for(i=0;i<2;i++){ - for(j=0;j<2;j++){ - for(k=0;k<2;k++){ - neighbors[d].neighbors[x2+i][y2+j][z2+k]=&node->parent->children[Cube::CornerIndex(i,j,k)]; - } - } - } - Neighbors3& temp=setNeighbors(node->parent); - - // Set the neighbors from across the faces - i=x1<<1; - if(temp.neighbors[i][1][1]){ - if(!temp.neighbors[i][1][1]->children){temp.neighbors[i][1][1]->initChildren();} - for(j=0;j<2;j++){for(k=0;k<2;k++){neighbors[d].neighbors[i][y2+j][z2+k]=&temp.neighbors[i][1][1]->children[Cube::CornerIndex(x2,j,k)];}} - } - j=y1<<1; - if(temp.neighbors[1][j][1]){ - if(!temp.neighbors[1][j][1]->children){temp.neighbors[1][j][1]->initChildren();} - for(i=0;i<2;i++){for(k=0;k<2;k++){neighbors[d].neighbors[x2+i][j][z2+k]=&temp.neighbors[1][j][1]->children[Cube::CornerIndex(i,y2,k)];}} - } - k=z1<<1; - if(temp.neighbors[1][1][k]){ - if(!temp.neighbors[1][1][k]->children){temp.neighbors[1][1][k]->initChildren();} - for(i=0;i<2;i++){for(j=0;j<2;j++){neighbors[d].neighbors[x2+i][y2+j][k]=&temp.neighbors[1][1][k]->children[Cube::CornerIndex(i,j,z2)];}} - } - - // Set the neighbors from across the edges - i=x1<<1; j=y1<<1; - if(temp.neighbors[i][j][1]){ - if(!temp.neighbors[i][j][1]->children){temp.neighbors[i][j][1]->initChildren();} - for(k=0;k<2;k++){neighbors[d].neighbors[i][j][z2+k]=&temp.neighbors[i][j][1]->children[Cube::CornerIndex(x2,y2,k)];} - } - i=x1<<1; k=z1<<1; - if(temp.neighbors[i][1][k]){ - if(!temp.neighbors[i][1][k]->children){temp.neighbors[i][1][k]->initChildren();} - for(j=0;j<2;j++){neighbors[d].neighbors[i][y2+j][k]=&temp.neighbors[i][1][k]->children[Cube::CornerIndex(x2,j,z2)];} - } - j=y1<<1; k=z1<<1; - if(temp.neighbors[1][j][k]){ - if(!temp.neighbors[1][j][k]->children){temp.neighbors[1][j][k]->initChildren();} - for(i=0;i<2;i++){neighbors[d].neighbors[x2+i][j][k]=&temp.neighbors[1][j][k]->children[Cube::CornerIndex(i,y2,z2)];} - } - - // Set the neighbor from across the corner - i=x1<<1; j=y1<<1; k=z1<<1; - if(temp.neighbors[i][j][k]){ - if(!temp.neighbors[i][j][k]->children){temp.neighbors[i][j][k]->initChildren();} - neighbors[d].neighbors[i][j][k]=&temp.neighbors[i][j][k]->children[Cube::CornerIndex(x2,y2,z2)]; - } - } - } - return neighbors[d]; - } - // Note the assumption is that if you enable an edge, you also enable adjacent faces. - // And, if you enable a corner, you enable adjacent edges and faces. - template< class NodeData , class Real > - typename OctNode::Neighbors3& OctNode::NeighborKey3::setNeighbors( OctNode* node , bool flags[3][3][3] ) - { - int d = node->depth(); - if( node==neighbors[d].neighbors[1][1][1] ) - { - bool reset = false; - for( int i=0 ; i<3 ; i++ ) for( int j=0 ; j<3 ; j++ ) for( int k=0 ; k<3 ; k++ ) if( flags[i][j][k] && !neighbors[d].neighbors[i][j][k] ) reset = true; - if( reset ) neighbors[d].neighbors[1][1][1] = NULL; - } - if( node!=neighbors[d].neighbors[1][1][1] ) - { - neighbors[d].clear(); - - if( !node->parent ) neighbors[d].neighbors[1][1][1] = node; - else - { - int x1,y1,z1,x2,y2,z2; - int idx=int(node-node->parent->children); - Cube::FactorCornerIndex( idx ,x1,y1,z1); - Cube::FactorCornerIndex((~idx)&7,x2,y2,z2); - for( int i=0 ; i<2 ; i++ ) - for( int j=0 ; j<2 ; j++ ) - for( int k=0 ; k<2 ; k++ ) - neighbors[d].neighbors[x2+i][y2+j][z2+k]=&node->parent->children[Cube::CornerIndex(i,j,k)]; - - Neighbors3& temp=setNeighbors( node->parent , flags ); - - // Set the neighbors from across the faces - { - int i=x1<<1; - if( temp.neighbors[i][1][1] ) - { - if( flags[i][1][1] && !temp.neighbors[i][1][1]->children ) temp.neighbors[i][1][1]->initChildren(); - if( temp.neighbors[i][1][1]->children ) for( int j=0 ; j<2 ; j++ ) for( int k=0 ; k<2 ; k++ ) neighbors[d].neighbors[i][y2+j][z2+k] = &temp.neighbors[i][1][1]->children[Cube::CornerIndex(x2,j,k)]; - } - } - { - int j = y1<<1; - if( temp.neighbors[1][j][1] ) - { - if( flags[1][j][1] && !temp.neighbors[1][j][1]->children ) temp.neighbors[1][j][1]->initChildren(); - if( temp.neighbors[1][j][1]->children ) for( int i=0 ; i<2 ; i++ ) for( int k=0 ; k<2 ; k++ ) neighbors[d].neighbors[x2+i][j][z2+k] = &temp.neighbors[1][j][1]->children[Cube::CornerIndex(i,y2,k)]; - } - } - { - int k = z1<<1; - if( temp.neighbors[1][1][k] ) - { - if( flags[1][1][k] && !temp.neighbors[1][1][k]->children ) temp.neighbors[1][1][k]->initChildren(); - if( temp.neighbors[1][1][k]->children ) for( int i=0 ; i<2 ; i++ ) for( int j=0 ; j<2 ; j++ ) neighbors[d].neighbors[x2+i][y2+j][k] = &temp.neighbors[1][1][k]->children[Cube::CornerIndex(i,j,z2)]; - } - } - - // Set the neighbors from across the edges - { - int i=x1<<1 , j=y1<<1; - if( temp.neighbors[i][j][1] ) - { - if( flags[i][j][1] && !temp.neighbors[i][j][1]->children ) temp.neighbors[i][j][1]->initChildren(); - if( temp.neighbors[i][j][1]->children ) for( int k=0 ; k<2 ; k++ ) neighbors[d].neighbors[i][j][z2+k] = &temp.neighbors[i][j][1]->children[Cube::CornerIndex(x2,y2,k)]; - } - } - { - int i=x1<<1 , k=z1<<1; - if( temp.neighbors[i][1][k] ) - { - if( flags[i][1][k] && !temp.neighbors[i][1][k]->children ) temp.neighbors[i][1][k]->initChildren(); - if( temp.neighbors[i][1][k]->children ) for( int j=0 ; j<2 ; j++ ) neighbors[d].neighbors[i][y2+j][k] = &temp.neighbors[i][1][k]->children[Cube::CornerIndex(x2,j,z2)]; - } - } - { - int j=y1<<1 , k=z1<<1; - if( temp.neighbors[1][j][k] ) - { - if( flags[1][j][k] && !temp.neighbors[1][j][k]->children ) temp.neighbors[1][j][k]->initChildren(); - if( temp.neighbors[1][j][k]->children ) for( int i=0 ; i<2 ; i++ ) neighbors[d].neighbors[x2+i][j][k] = &temp.neighbors[1][j][k]->children[Cube::CornerIndex(i,y2,z2)]; - } - } - - // Set the neighbor from across the corner - { - int i=x1<<1 , j=y1<<1 , k=z1<<1; - if( temp.neighbors[i][j][k] ) - { - if( flags[i][j][k] && !temp.neighbors[i][j][k]->children ) temp.neighbors[i][j][k]->initChildren(); - if( temp.neighbors[i][j][k]->children ) neighbors[d].neighbors[i][j][k] = &temp.neighbors[i][j][k]->children[Cube::CornerIndex(x2,y2,z2)]; - } - } - } - } - return neighbors[d]; - } - - template - typename OctNode::Neighbors3& OctNode::NeighborKey3::getNeighbors(OctNode* node){ - int d=node->depth(); - if(node!=neighbors[d].neighbors[1][1][1]){ - neighbors[d].clear(); - - if(!node->parent){neighbors[d].neighbors[1][1][1]=node;} - else{ - int i,j,k,x1,y1,z1,x2,y2,z2; - int idx=int(node-node->parent->children); - Cube::FactorCornerIndex( idx ,x1,y1,z1); - Cube::FactorCornerIndex((~idx)&7,x2,y2,z2); - for(i=0;i<2;i++){ - for(j=0;j<2;j++){ - for(k=0;k<2;k++){ - neighbors[d].neighbors[x2+i][y2+j][z2+k]=&node->parent->children[Cube::CornerIndex(i,j,k)]; - } - } - } - Neighbors3& temp=getNeighbors(node->parent); - - // Set the neighbors from across the faces - i=x1<<1; - if(temp.neighbors[i][1][1] && temp.neighbors[i][1][1]->children){ - for(j=0;j<2;j++){for(k=0;k<2;k++){neighbors[d].neighbors[i][y2+j][z2+k]=&temp.neighbors[i][1][1]->children[Cube::CornerIndex(x2,j,k)];}} - } - j=y1<<1; - if(temp.neighbors[1][j][1] && temp.neighbors[1][j][1]->children){ - for(i=0;i<2;i++){for(k=0;k<2;k++){neighbors[d].neighbors[x2+i][j][z2+k]=&temp.neighbors[1][j][1]->children[Cube::CornerIndex(i,y2,k)];}} - } - k=z1<<1; - if(temp.neighbors[1][1][k] && temp.neighbors[1][1][k]->children){ - for(i=0;i<2;i++){for(j=0;j<2;j++){neighbors[d].neighbors[x2+i][y2+j][k]=&temp.neighbors[1][1][k]->children[Cube::CornerIndex(i,j,z2)];}} - } - - // Set the neighbors from across the edges - i=x1<<1; j=y1<<1; - if(temp.neighbors[i][j][1] && temp.neighbors[i][j][1]->children){ - for(k=0;k<2;k++){neighbors[d].neighbors[i][j][z2+k]=&temp.neighbors[i][j][1]->children[Cube::CornerIndex(x2,y2,k)];} - } - i=x1<<1; k=z1<<1; - if(temp.neighbors[i][1][k] && temp.neighbors[i][1][k]->children){ - for(j=0;j<2;j++){neighbors[d].neighbors[i][y2+j][k]=&temp.neighbors[i][1][k]->children[Cube::CornerIndex(x2,j,z2)];} - } - j=y1<<1; k=z1<<1; - if(temp.neighbors[1][j][k] && temp.neighbors[1][j][k]->children){ - for(i=0;i<2;i++){neighbors[d].neighbors[x2+i][j][k]=&temp.neighbors[1][j][k]->children[Cube::CornerIndex(i,y2,z2)];} - } - - // Set the neighbor from across the corner - i=x1<<1; j=y1<<1; k=z1<<1; - if(temp.neighbors[i][j][k] && temp.neighbors[i][j][k]->children){ - neighbors[d].neighbors[i][j][k]=&temp.neighbors[i][j][k]->children[Cube::CornerIndex(x2,y2,z2)]; - } - } - } - return neighbors[node->depth()]; - } - - /////////////////////// - // ConstNeighborKey3 // - /////////////////////// - template - OctNode::ConstNeighbors3::ConstNeighbors3(void){clear();} - template - void OctNode::ConstNeighbors3::clear(void){ - for(int i=0;i<3;i++){for(int j=0;j<3;j++){for(int k=0;k<3;k++){neighbors[i][j][k]=NULL;}}} - } - template - OctNode::ConstNeighborKey3::ConstNeighborKey3(void){neighbors=NULL;} - template - OctNode::ConstNeighborKey3::~ConstNeighborKey3(void){ - if(neighbors){delete[] neighbors;} - neighbors=NULL; - } - - template - void OctNode::ConstNeighborKey3::set(int d){ - if(neighbors){delete[] neighbors;} - neighbors=NULL; - if(d<0){return;} - neighbors=new ConstNeighbors3[d+1]; - } - template - typename OctNode::ConstNeighbors3& OctNode::ConstNeighborKey3::getNeighbors(const OctNode* node){ - int d=node->depth(); - if(node!=neighbors[d].neighbors[1][1][1]){ - neighbors[d].clear(); - - if(!node->parent){neighbors[d].neighbors[1][1][1]=node;} - else{ - int i,j,k,x1,y1,z1,x2,y2,z2; - int idx=int(node-node->parent->children); - Cube::FactorCornerIndex( idx ,x1,y1,z1); - Cube::FactorCornerIndex((~idx)&7,x2,y2,z2); - for(i=0;i<2;i++){ - for(j=0;j<2;j++){ - for(k=0;k<2;k++){ - neighbors[d].neighbors[x2+i][y2+j][z2+k]=&node->parent->children[Cube::CornerIndex(i,j,k)]; - } - } - } - ConstNeighbors3& temp=getNeighbors(node->parent); - - // Set the neighbors from across the faces - i=x1<<1; - if(temp.neighbors[i][1][1] && temp.neighbors[i][1][1]->children){ - for(j=0;j<2;j++){for(k=0;k<2;k++){neighbors[d].neighbors[i][y2+j][z2+k]=&temp.neighbors[i][1][1]->children[Cube::CornerIndex(x2,j,k)];}} - } - j=y1<<1; - if(temp.neighbors[1][j][1] && temp.neighbors[1][j][1]->children){ - for(i=0;i<2;i++){for(k=0;k<2;k++){neighbors[d].neighbors[x2+i][j][z2+k]=&temp.neighbors[1][j][1]->children[Cube::CornerIndex(i,y2,k)];}} - } - k=z1<<1; - if(temp.neighbors[1][1][k] && temp.neighbors[1][1][k]->children){ - for(i=0;i<2;i++){for(j=0;j<2;j++){neighbors[d].neighbors[x2+i][y2+j][k]=&temp.neighbors[1][1][k]->children[Cube::CornerIndex(i,j,z2)];}} - } - - // Set the neighbors from across the edges - i=x1<<1; j=y1<<1; - if(temp.neighbors[i][j][1] && temp.neighbors[i][j][1]->children){ - for(k=0;k<2;k++){neighbors[d].neighbors[i][j][z2+k]=&temp.neighbors[i][j][1]->children[Cube::CornerIndex(x2,y2,k)];} - } - i=x1<<1; k=z1<<1; - if(temp.neighbors[i][1][k] && temp.neighbors[i][1][k]->children){ - for(j=0;j<2;j++){neighbors[d].neighbors[i][y2+j][k]=&temp.neighbors[i][1][k]->children[Cube::CornerIndex(x2,j,z2)];} - } - j=y1<<1; k=z1<<1; - if(temp.neighbors[1][j][k] && temp.neighbors[1][j][k]->children){ - for(i=0;i<2;i++){neighbors[d].neighbors[x2+i][j][k]=&temp.neighbors[1][j][k]->children[Cube::CornerIndex(i,y2,z2)];} - } - - // Set the neighbor from across the corner - i=x1<<1; j=y1<<1; k=z1<<1; - if(temp.neighbors[i][j][k] && temp.neighbors[i][j][k]->children){ - neighbors[d].neighbors[i][j][k]=&temp.neighbors[i][j][k]->children[Cube::CornerIndex(x2,y2,z2)]; - } - } - } - return neighbors[node->depth()]; - } - template - typename OctNode::ConstNeighbors3& OctNode::ConstNeighborKey3::getNeighbors( const OctNode* node , int minDepth ) - { - int d=node->depth(); - if( dparent->children); - Cube::FactorCornerIndex( idx ,x1,y1,z1); - Cube::FactorCornerIndex((~idx)&7,x2,y2,z2); - - ConstNeighbors3& temp=getNeighbors( node->parent , minDepth ); - - // Set the syblings - for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ ) - neighbors[d].neighbors[x2+i][y2+j][z2+k] = &node->parent->children[ Cube::CornerIndex(i,j,k) ]; - - // Set the neighbors from across the faces - i=x1<<1; - if( temp.neighbors[i][1][1] && temp.neighbors[i][1][1]->children ) - for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ ) neighbors[d].neighbors[i][y2+j][z2+k] = &temp.neighbors[i][1][1]->children[Cube::CornerIndex(x2,j,k)]; - - j=y1<<1; - if( temp.neighbors[1][j][1] && temp.neighbors[1][j][1]->children ) - for( i=0 ; i<2 ; i++ ) for( k=0 ; k<2 ; k++ ) neighbors[d].neighbors[x2+i][j][z2+k] = &temp.neighbors[1][j][1]->children[Cube::CornerIndex(i,y2,k)]; - - k=z1<<1; - if( temp.neighbors[1][1][k] && temp.neighbors[1][1][k]->children ) - for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ ) neighbors[d].neighbors[x2+i][y2+j][k] = &temp.neighbors[1][1][k]->children[Cube::CornerIndex(i,j,z2)]; - - // Set the neighbors from across the edges - i=x1<<1 , j=y1<<1; - if( temp.neighbors[i][j][1] && temp.neighbors[i][j][1]->children ) - for( k=0 ; k<2 ; k++ ) neighbors[d].neighbors[i][j][z2+k] = &temp.neighbors[i][j][1]->children[Cube::CornerIndex(x2,y2,k)]; - - i=x1<<1 , k=z1<<1; - if( temp.neighbors[i][1][k] && temp.neighbors[i][1][k]->children ) - for( j=0 ; j<2 ; j++ ) neighbors[d].neighbors[i][y2+j][k] = &temp.neighbors[i][1][k]->children[Cube::CornerIndex(x2,j,z2)]; - - j=y1<<1 , k=z1<<1; - if( temp.neighbors[1][j][k] && temp.neighbors[1][j][k]->children ) - for( i=0 ; i<2 ; i++ ) neighbors[d].neighbors[x2+i][j][k] = &temp.neighbors[1][j][k]->children[Cube::CornerIndex(i,y2,z2)]; - - // Set the neighbor from across the corner - i=x1<<1 , j=y1<<1 , k=z1<<1; - if( temp.neighbors[i][j][k] && temp.neighbors[i][j][k]->children ) - neighbors[d].neighbors[i][j][k] = &temp.neighbors[i][j][k]->children[Cube::CornerIndex(x2,y2,z2)]; - } - } - return neighbors[node->depth()]; - } - - template< class NodeData , class Real > OctNode< NodeData , Real >::Neighbors5::Neighbors5( void ){ clear(); } - template< class NodeData , class Real > OctNode< NodeData , Real >::ConstNeighbors5::ConstNeighbors5( void ){ clear(); } - template< class NodeData , class Real > - void OctNode< NodeData , Real >::Neighbors5::clear( void ) - { - for( int i=0 ; i<5 ; i++ ) for( int j=0 ; j<5 ; j++ ) for( int k=0 ; k<5 ; k++ ) neighbors[i][j][k] = NULL; - } - template< class NodeData , class Real > - void OctNode< NodeData , Real >::ConstNeighbors5::clear( void ) - { - for( int i=0 ; i<5 ; i++ ) for( int j=0 ; j<5 ; j++ ) for( int k=0 ; k<5 ; k++ ) neighbors[i][j][k] = NULL; - } - template< class NodeData , class Real > - OctNode< NodeData , Real >::NeighborKey5::NeighborKey5( void ) - { - _depth = -1; - neighbors = NULL; - } - template< class NodeData , class Real > - OctNode< NodeData , Real >::ConstNeighborKey5::ConstNeighborKey5( void ) - { - _depth = -1; - neighbors = NULL; - } - template< class NodeData , class Real > - OctNode< NodeData , Real >::NeighborKey5::~NeighborKey5( void ) - { - if( neighbors ) delete[] neighbors; - neighbors = NULL; - } - template< class NodeData , class Real > - OctNode< NodeData , Real >::ConstNeighborKey5::~ConstNeighborKey5( void ) - { - if( neighbors ) delete[] neighbors; - neighbors = NULL; - } - template< class NodeData , class Real > - void OctNode< NodeData , Real >::NeighborKey5::set( int d ) - { - if( neighbors ) delete[] neighbors; - neighbors = NULL; - if(d<0) return; - _depth = d; - neighbors=new Neighbors5[d+1]; - } - template< class NodeData , class Real > - void OctNode< NodeData , Real >::ConstNeighborKey5::set( int d ) - { - if( neighbors ) delete[] neighbors; - neighbors = NULL; - if(d<0) return; - _depth = d; - neighbors=new ConstNeighbors5[d+1]; - } - template< class NodeData , class Real > - typename OctNode< NodeData , Real >::Neighbors5& OctNode< NodeData , Real >::NeighborKey5::getNeighbors( OctNode* node ) - { - int d=node->depth(); - if( node!=neighbors[d].neighbors[2][2][2] ) - { - neighbors[d].clear(); - - if( !node->parent ) neighbors[d].neighbors[2][2][2]=node; - else - { - getNeighbors( node->parent ); - Neighbors5& temp = neighbors[d-1]; - int x1 , y1 , z1 , x2 , y2 , z2; - int idx = int( node - node->parent->children ); - Cube::FactorCornerIndex( idx , x1 , y1 , z1 ); - - Neighbors5& n = neighbors[d]; - Cube::FactorCornerIndex( (~idx)&7 , x2 , y2 , z2 ); - int i , j , k; - int fx0 = x2+1 , fy0 = y2+1 , fz0 = z2+1; // Indices of the bottom left corner of the parent within the 5x5x5 - int cx1 = x1*2+1 , cy1 = y1*2+1 , cz1 = z1*2+1; - int cx2 = x2*2+1 , cy2 = y2*2+1 , cz2 = z2*2+1; - int fx1 = x1*3 , fy1 = y1*3 , fz1 = z1*3; - int fx2 = x2*4 , fy2 = y2*4 , fz2 = z2*4; - - // Set the syblings - for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ ) - n.neighbors[fx0+i][fy0+j][fz0+k] = node->parent->children + Cube::CornerIndex( i , j , k ); - - // Set the neighbors from across the faces - if( temp.neighbors[cx1][2][2] && temp.neighbors[cx1][2][2]->children ) - for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ ) - n.neighbors[fx1+i][fy0+j][fz0+k] = temp.neighbors[cx1][2][2]->children + Cube::CornerIndex( i , j , k ); - if( temp.neighbors[2][cy1][2] && temp.neighbors[2][cy1][2]->children ) - for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ ) - n.neighbors[fx0+i][fy1+j][fz0+k] = temp.neighbors[2][cy1][2]->children + Cube::CornerIndex( i , j , k ); - if( temp.neighbors[2][2][cz1] && temp.neighbors[2][2][cz1]->children ) - for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ ) - n.neighbors[fx0+i][fy0+j][fz1+k] = temp.neighbors[2][2][cz1]->children + Cube::CornerIndex( i , j , k ); - if( temp.neighbors[cx2][2][2] && temp.neighbors[cx2][2][2]->children ) - for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ ) - n.neighbors[fx2 ][fy0+j][fz0+k] = temp.neighbors[cx2][2][2]->children + Cube::CornerIndex( x1 , j , k ); - if( temp.neighbors[2][cy2][2] && temp.neighbors[2][cy2][2]->children ) - for( i=0 ; i<2 ; i++ ) for( k=0 ; k<2 ; k++ ) - n.neighbors[fx0+i][fy2 ][fz0+k] = temp.neighbors[2][cy2][2]->children + Cube::CornerIndex( i , y1 , k ); - if( temp.neighbors[2][2][cz2] && temp.neighbors[2][2][cz2]->children ) - for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ ) - n.neighbors[fx0+i][fy0+j][fz2 ] = temp.neighbors[2][2][cz2]->children + Cube::CornerIndex( i , j , z1 ); - - // Set the neighbors from across the edges - if( temp.neighbors[cx1][cy1][2] && temp.neighbors[cx1][cy1][2]->children ) - for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ ) - n.neighbors[fx1+i][fy1+j][fz0+k] = temp.neighbors[cx1][cy1][2]->children + Cube::CornerIndex( i , j , k ); - if( temp.neighbors[cx1][2][cz1] && temp.neighbors[cx1][2][cz1]->children ) - for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ ) - n.neighbors[fx1+i][fy0+j][fz1+k] = temp.neighbors[cx1][2][cz1]->children + Cube::CornerIndex( i , j , k ); - if( temp.neighbors[2][cy1][cz1] && temp.neighbors[2][cy1][cz1]->children ) - for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ ) - n.neighbors[fx0+i][fy1+j][fz1+k] = temp.neighbors[2][cy1][cz1]->children + Cube::CornerIndex( i , j , k ); - if( temp.neighbors[cx1][cy2][2] && temp.neighbors[cx1][cy2][2]->children ) - for( i=0 ; i<2 ; i++ ) for( k=0 ; k<2 ; k++ ) - n.neighbors[fx1+i][fy2 ][fz0+k] = temp.neighbors[cx1][cy2][2]->children + Cube::CornerIndex( i , y1 , k ); - if( temp.neighbors[cx1][2][cz2] && temp.neighbors[cx1][2][cz2]->children ) - for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ ) - n.neighbors[fx1+i][fy0+j][fz2 ] = temp.neighbors[cx1][2][cz2]->children + Cube::CornerIndex( i , j , z1 ); - if( temp.neighbors[cx2][cy1][2] && temp.neighbors[cx2][cy1][2]->children ) - for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ ) - n.neighbors[fx2 ][fy1+j][fz0+k] = temp.neighbors[cx2][cy1][2]->children + Cube::CornerIndex( x1 , j , k ); - if( temp.neighbors[2][cy1][cz2] && temp.neighbors[2][cy1][cz2]->children ) - for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ ) - n.neighbors[fx0+i][fy1+j][fz2 ] = temp.neighbors[2][cy1][cz2]->children + Cube::CornerIndex( i , j , z1 ); - if( temp.neighbors[cx2][2][cz1] && temp.neighbors[cx2][2][cz1]->children ) - for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ ) - n.neighbors[fx2 ][fy0+j][fz1+k] = temp.neighbors[cx2][2][cz1]->children + Cube::CornerIndex( x1 , j , k ); - if( temp.neighbors[2][cy2][cz1] && temp.neighbors[2][cy2][cz1]->children ) - for( i=0 ; i<2 ; i++ ) for( k=0 ; k<2 ; k++ ) - n.neighbors[fx0+i][fy2 ][fz1+k] = temp.neighbors[2][cy2][cz1]->children + Cube::CornerIndex( i , y1 , k ); - if( temp.neighbors[cx2][cy2][2] && temp.neighbors[cx2][cy2][2]->children ) - for( k=0 ; k<2 ; k++ ) - n.neighbors[fx2 ][fy2 ][fz0+k] = temp.neighbors[cx2][cy2][2]->children + Cube::CornerIndex( x1 , y1 , k ); - if( temp.neighbors[cx2][2][cz2] && temp.neighbors[cx2][2][cz2]->children ) - for( j=0 ; j<2 ; j++ ) - n.neighbors[fx2 ][fy0+j][fz2 ] = temp.neighbors[cx2][2][cz2]->children + Cube::CornerIndex( x1 , j , z1 ); - if( temp.neighbors[2][cy2][cz2] && temp.neighbors[2][cy2][cz2]->children ) - for( i=0 ; i<2 ; i++ ) - n.neighbors[fx0+i][fy2 ][fz2 ] = temp.neighbors[2][cy2][cz2]->children + Cube::CornerIndex( i , y1 , z1 ); - - // Set the neighbor from across the corners - if( temp.neighbors[cx1][cy1][cz1] && temp.neighbors[cx1][cy1][cz1]->children ) - for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ ) - n.neighbors[fx1+i][fy1+j][fz1+k] = temp.neighbors[cx1][cy1][cz1]->children + Cube::CornerIndex( i , j , k ); - if( temp.neighbors[cx1][cy1][cz2] && temp.neighbors[cx1][cy1][cz2]->children ) - for( i=0 ; i<2 ; i++ ) for( j=0 ; j<2 ; j++ ) - n.neighbors[fx1+i][fy1+j][fz2 ] = temp.neighbors[cx1][cy1][cz2]->children + Cube::CornerIndex( i , j , z1 ); - if( temp.neighbors[cx1][cy2][cz1] && temp.neighbors[cx1][cy2][cz1]->children ) - for( i=0 ; i<2 ; i++ ) for( k=0 ; k<2 ; k++ ) - n.neighbors[fx1+i][fy2 ][fz1+k] = temp.neighbors[cx1][cy2][cz1]->children + Cube::CornerIndex( i , y1 , k ); - if( temp.neighbors[cx2][cy1][cz1] && temp.neighbors[cx2][cy1][cz1]->children ) - for( j=0 ; j<2 ; j++ ) for( k=0 ; k<2 ; k++ ) - n.neighbors[fx2 ][fy1+j][fz1+k] = temp.neighbors[cx2][cy1][cz1]->children + Cube::CornerIndex( x1 , j , k ); - if( temp.neighbors[cx1][cy2][cz2] && temp.neighbors[cx1][cy2][cz2]->children ) - for( i=0 ; i<2 ; i++ ) - n.neighbors[fx1+i][fy2 ][fz2 ] = temp.neighbors[cx1][cy2][cz2]->children + Cube::CornerIndex( i , y1 , z1 ); - if( temp.neighbors[cx2][cy1][cz2] && temp.neighbors[cx2][cy1][cz2]->children ) - for( j=0 ; j<2 ; j++ ) - n.neighbors[fx2 ][fy1+j][fz2 ] = temp.neighbors[cx2][cy1][cz2]->children + Cube::CornerIndex( x1 , j , z1 ); - if( temp.neighbors[cx2][cy2][cz1] && temp.neighbors[cx2][cy2][cz1]->children ) - for( k=0 ; k<2 ; k++ ) - n.neighbors[fx2 ][fy2 ][fz1+k] = temp.neighbors[cx2][cy2][cz1]->children + Cube::CornerIndex( x1 , y1 , k ); - if( temp.neighbors[cx2][cy2][cz2] && temp.neighbors[cx2][cy2][cz2]->children ) - n.neighbors[fx2 ][fy2 ][fz2 ] = temp.neighbors[cx2][cy2][cz2]->children + Cube::CornerIndex( x1 , y1 , z1 ); - } - } - return neighbors[d]; - } - template< class NodeData , class Real > - typename OctNode< NodeData , Real >::Neighbors5& OctNode< NodeData , Real >::NeighborKey5::setNeighbors( OctNode* node , int xStart , int xEnd , int yStart , int yEnd , int zStart , int zEnd ) - { - int d=node->depth(); - if( node!=neighbors[d].neighbors[2][2][2] ) - { - neighbors[d].clear(); - - if( !node->parent ) neighbors[d].neighbors[2][2][2]=node; - else - { - setNeighbors( node->parent , xStart , xEnd , yStart , yEnd , zStart , zEnd ); - Neighbors5& temp = neighbors[d-1]; - int x1 , y1 , z1 , x2 , y2 , z2 , ii , jj , kk; - int idx = int( node-node->parent->children ); - Cube::FactorCornerIndex( idx , x1 , y1 , z1 ); - - for( int i=xStart ; i>1); - for( int j=yStart ; j>1); - for( int k=zStart ; k>1); - if(temp.neighbors[x2][y2][z2] ) - { - if( !temp.neighbors[x2][y2][z2]->children ) temp.neighbors[x2][y2][z2]->initChildren(); - neighbors[d].neighbors[i][j][k] = temp.neighbors[x2][y2][z2]->children + Cube::CornerIndex(ii,jj,kk); - } - } - } - } - } - } - return neighbors[d]; - } - template< class NodeData , class Real > - typename OctNode< NodeData , Real >::ConstNeighbors5& OctNode< NodeData , Real >::ConstNeighborKey5::getNeighbors( const OctNode* node ) - { - int d=node->depth(); - if( node!=neighbors[d].neighbors[2][2][2] ) - { - neighbors[d].clear(); - - if(!node->parent) neighbors[d].neighbors[2][2][2]=node; - else - { - getNeighbors( node->parent ); - ConstNeighbors5& temp = neighbors[d-1]; - int x1,y1,z1,x2,y2,z2,ii,jj,kk; - int idx=int(node-node->parent->children); - Cube::FactorCornerIndex(idx,x1,y1,z1); - - for(int i=0;i<5;i++) - { - x2=i+x1; - ii=x2&1; - x2=1+(x2>>1); - for(int j=0;j<5;j++) - { - y2=j+y1; - jj=y2&1; - y2=1+(y2>>1); - for(int k=0;k<5;k++) - { - z2=k+z1; - kk=z2&1; - z2=1+(z2>>1); - if(temp.neighbors[x2][y2][z2] && temp.neighbors[x2][y2][z2]->children) - neighbors[d].neighbors[i][j][k] = temp.neighbors[x2][y2][z2]->children + Cube::CornerIndex(ii,jj,kk); - } - } - } - } - } - return neighbors[d]; - } - - - template - int OctNode::write(const char* fileName) const{ - FILE* fp=fopen(fileName,"wb"); - if(!fp){return 0;} - int ret=write(fp); - fclose(fp); - return ret; - } - template - int OctNode::write(FILE* fp) const{ - fwrite(this,sizeof(OctNode),1,fp); - if(children){for(int i=0;i - int OctNode::read(const char* fileName){ - FILE* fp=fopen(fileName,"rb"); - if(!fp){return 0;} - int ret=read(fp); - fclose(fp); - return ret; - } - template - int OctNode::read(FILE* fp){ - fread(this,sizeof(OctNode),1,fp); - parent=NULL; - if(children){ - children=NULL; - initChildren(); - for(int i=0;i - int OctNode::width(int maxDepth) const { - int d=depth(); - return 1<<(maxDepth-d); - } - template - void OctNode::centerIndex(int maxDepth,int index[DIMENSION]) const { - int d,o[3]; - depthAndOffset(d,o); - for(int i=0;i::CornerIndex(maxDepth,d+1,o[i]<<1,1);} - } - - } -} diff --git a/vendor/poisson_surface/polynomial.h b/vendor/poisson_surface/polynomial.h deleted file mode 100644 index f43f5dbe8e..0000000000 --- a/vendor/poisson_surface/polynomial.h +++ /dev/null @@ -1,102 +0,0 @@ -/* -Copyright (c) 2006, Michael Kazhdan and Matthew Bolitho -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -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. - -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. - -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 -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 -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. -*/ - -#ifndef POLYNOMIAL_INCLUDED -#define POLYNOMIAL_INCLUDED - -#include - -namespace pcl -{ - namespace poisson - { - - template< int Degree > - class Polynomial{ - public: - double coefficients[Degree+1]; - - Polynomial(void); - template - Polynomial(const Polynomial& P); - double operator()( double t ) const; - double integral( double tMin , double tMax ) const; - - int operator == (const Polynomial& p) const; - int operator != (const Polynomial& p) const; - int isZero(void) const; - void setZero(void); - - template - Polynomial& operator = (const Polynomial &p); - Polynomial& operator += (const Polynomial& p); - Polynomial& operator -= (const Polynomial& p); - Polynomial operator - (void) const; - Polynomial operator + (const Polynomial& p) const; - Polynomial operator - (const Polynomial& p) const; - template - Polynomial operator * (const Polynomial& p) const; - - Polynomial& operator += ( double s ); - Polynomial& operator -= ( double s ); - Polynomial& operator *= ( double s ); - Polynomial& operator /= ( double s ); - Polynomial operator + ( double s ) const; - Polynomial operator - ( double s ) const; - Polynomial operator * ( double s ) const; - Polynomial operator / ( double s ) const; - - Polynomial scale( double s ) const; - Polynomial shift( double t ) const; - - Polynomial derivative(void) const; - Polynomial integral(void) const; - - void printnl(void) const; - - Polynomial& addScaled(const Polynomial& p,double scale); - - static void Negate(const Polynomial& in,Polynomial& out); - static void Subtract(const Polynomial& p1,const Polynomial& p2,Polynomial& q); - static void Scale(const Polynomial& p,double w,Polynomial& q); - static void AddScaled(const Polynomial& p1,double w1,const Polynomial& p2,double w2,Polynomial& q); - static void AddScaled(const Polynomial& p1,const Polynomial& p2,double w2,Polynomial& q); - static void AddScaled(const Polynomial& p1,double w1,const Polynomial& p2,Polynomial& q); - - void getSolutions(double c,std::vector& roots,double EPS) const; - - static Polynomial BSplineComponent( int i ); - }; - - - } -} - - -#include "polynomial.hpp" -#endif // POLYNOMIAL_INCLUDED diff --git a/vendor/poisson_surface/polynomial.hpp b/vendor/poisson_surface/polynomial.hpp deleted file mode 100644 index 45973dbc8e..0000000000 --- a/vendor/poisson_surface/polynomial.hpp +++ /dev/null @@ -1,325 +0,0 @@ -/* -Copyright (c) 2006, Michael Kazhdan and Matthew Bolitho -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -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. - -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. - -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 -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 -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. -*/ - -#include -#include -#include -#include "factor.h" - -//////////////// -// Polynomial // -//////////////// - -namespace pcl -{ - namespace poisson - { - - - template - Polynomial::Polynomial(void){memset(coefficients,0,sizeof(double)*(Degree+1));} - template - template - Polynomial::Polynomial(const Polynomial& P){ - memset(coefficients,0,sizeof(double)*(Degree+1)); - for(int i=0;i<=Degree && i<=Degree2;i++){coefficients[i]=P.coefficients[i];} - } - - - template - template - Polynomial& Polynomial::operator = (const Polynomial &p){ - int d=Degree - Polynomial Polynomial::derivative(void) const{ - Polynomial p; - for(int i=0;i - Polynomial Polynomial::integral(void) const{ - Polynomial p; - p.coefficients[0]=0; - for(int i=0;i<=Degree;i++){p.coefficients[i+1]=coefficients[i]/(i+1);} - return p; - } - template<> double Polynomial< 0 >::operator() ( double t ) const { return coefficients[0]; } - template<> double Polynomial< 1 >::operator() ( double t ) const { return coefficients[0]+coefficients[1]*t; } - template<> double Polynomial< 2 >::operator() ( double t ) const { return coefficients[0]+(coefficients[1]+coefficients[2]*t)*t; } - template - double Polynomial::operator() ( double t ) const{ - double v=coefficients[Degree]; - for( int d=Degree-1 ; d>=0 ; d-- ) v = v*t + coefficients[d]; - return v; - } - template - double Polynomial::integral( double tMin , double tMax ) const - { - double v=0; - double t1,t2; - t1=tMin; - t2=tMax; - for(int i=0;i<=Degree;i++){ - v+=coefficients[i]*(t2-t1)/(i+1); - if(t1!=-DBL_MAX && t1!=DBL_MAX){t1*=tMin;} - if(t2!=-DBL_MAX && t2!=DBL_MAX){t2*=tMax;} - } - return v; - } - template - int Polynomial::operator == (const Polynomial& p) const{ - for(int i=0;i<=Degree;i++){if(coefficients[i]!=p.coefficients[i]){return 0;}} - return 1; - } - template - int Polynomial::operator != (const Polynomial& p) const{ - for(int i=0;i<=Degree;i++){if(coefficients[i]==p.coefficients[i]){return 0;}} - return 1; - } - template - int Polynomial::isZero(void) const{ - for(int i=0;i<=Degree;i++){if(coefficients[i]!=0){return 0;}} - return 1; - } - template - void Polynomial::setZero(void){memset(coefficients,0,sizeof(double)*(Degree+1));} - - template - Polynomial& Polynomial::addScaled(const Polynomial& p,double s){ - for(int i=0;i<=Degree;i++){coefficients[i]+=p.coefficients[i]*s;} - return *this; - } - template - Polynomial& Polynomial::operator += (const Polynomial& p){ - for(int i=0;i<=Degree;i++){coefficients[i]+=p.coefficients[i];} - return *this; - } - template - Polynomial& Polynomial::operator -= (const Polynomial& p){ - for(int i=0;i<=Degree;i++){coefficients[i]-=p.coefficients[i];} - return *this; - } - template - Polynomial Polynomial::operator + (const Polynomial& p) const{ - Polynomial q; - for(int i=0;i<=Degree;i++){q.coefficients[i]=(coefficients[i]+p.coefficients[i]);} - return q; - } - template - Polynomial Polynomial::operator - (const Polynomial& p) const{ - Polynomial q; - for(int i=0;i<=Degree;i++) {q.coefficients[i]=coefficients[i]-p.coefficients[i];} - return q; - } - template - void Polynomial::Scale(const Polynomial& p,double w,Polynomial& q){ - for(int i=0;i<=Degree;i++){q.coefficients[i]=p.coefficients[i]*w;} - } - template - void Polynomial::AddScaled(const Polynomial& p1,double w1,const Polynomial& p2,double w2,Polynomial& q){ - for(int i=0;i<=Degree;i++){q.coefficients[i]=p1.coefficients[i]*w1+p2.coefficients[i]*w2;} - } - template - void Polynomial::AddScaled(const Polynomial& p1,double w1,const Polynomial& p2,Polynomial& q){ - for(int i=0;i<=Degree;i++){q.coefficients[i]=p1.coefficients[i]*w1+p2.coefficients[i];} - } - template - void Polynomial::AddScaled(const Polynomial& p1,const Polynomial& p2,double w2,Polynomial& q){ - for(int i=0;i<=Degree;i++){q.coefficients[i]=p1.coefficients[i]+p2.coefficients[i]*w2;} - } - - template - void Polynomial::Subtract(const Polynomial &p1,const Polynomial& p2,Polynomial& q){ - for(int i=0;i<=Degree;i++){q.coefficients[i]=p1.coefficients[i]-p2.coefficients[i];} - } - template - void Polynomial::Negate(const Polynomial& in,Polynomial& out){ - out=in; - for(int i=0;i<=Degree;i++){out.coefficients[i]=-out.coefficients[i];} - } - - template - Polynomial Polynomial::operator - (void) const{ - Polynomial q=*this; - for(int i=0;i<=Degree;i++){q.coefficients[i]=-q.coefficients[i];} - return q; - } - template - template - Polynomial Polynomial::operator * (const Polynomial& p) const{ - Polynomial q; - for(int i=0;i<=Degree;i++){for(int j=0;j<=Degree2;j++){q.coefficients[i+j]+=coefficients[i]*p.coefficients[j];}} - return q; - } - - template - Polynomial& Polynomial::operator += ( double s ) - { - coefficients[0]+=s; - return *this; - } - template - Polynomial& Polynomial::operator -= ( double s ) - { - coefficients[0]-=s; - return *this; - } - template - Polynomial& Polynomial::operator *= ( double s ) - { - for(int i=0;i<=Degree;i++){coefficients[i]*=s;} - return *this; - } - template - Polynomial& Polynomial::operator /= ( double s ) - { - for(int i=0;i<=Degree;i++){coefficients[i]/=s;} - return *this; - } - template - Polynomial Polynomial::operator + ( double s ) const - { - Polynomial q=*this; - q.coefficients[0]+=s; - return q; - } - template - Polynomial Polynomial::operator - ( double s ) const - { - Polynomial q=*this; - q.coefficients[0]-=s; - return q; - } - template - Polynomial Polynomial::operator * ( double s ) const - { - Polynomial q; - for(int i=0;i<=Degree;i++){q.coefficients[i]=coefficients[i]*s;} - return q; - } - template - Polynomial Polynomial::operator / ( double s ) const - { - Polynomial q; - for( int i=0 ; i<=Degree ; i++ ) q.coefficients[i] = coefficients[i]/s; - return q; - } - template - Polynomial Polynomial::scale( double s ) const - { - Polynomial q=*this; - double s2=1.0; - for(int i=0;i<=Degree;i++){ - q.coefficients[i]*=s2; - s2/=s; - } - return q; - } - template - Polynomial Polynomial::shift( double t ) const - { - Polynomial q; - for(int i=0;i<=Degree;i++){ - double temp=1; - for(int j=i;j>=0;j--){ - q.coefficients[j]+=coefficients[i]*temp; - temp*=-t*j; - temp/=(i-j+1); - } - } - return q; - } - template - void Polynomial::printnl(void) const{ - for(int j=0;j<=Degree;j++){ - printf("%6.4f x^%d ",coefficients[j],j); - if(j=0){printf("+");} - } - printf("\n"); - } - template - void Polynomial::getSolutions(double c,std::vector& roots,double EPS) const - { - double r[4][2]; - int rCount=0; - roots.clear(); - switch(Degree){ - case 1: - rCount=Factor(coefficients[1],coefficients[0]-c,r,EPS); - break; - case 2: - rCount=Factor(coefficients[2],coefficients[1],coefficients[0]-c,r,EPS); - break; - case 3: - rCount=Factor(coefficients[3],coefficients[2],coefficients[1],coefficients[0]-c,r,EPS); - break; - // case 4: - // rCount=Factor(coefficients[4],coefficients[3],coefficients[2],coefficients[1],coefficients[0]-c,r,EPS); - // break; - default: - printf("Can't solve polynomial of degree: %d\n",Degree); - } - for(int i=0;i - Polynomial< 0 > Polynomial< 0 >::BSplineComponent( int i ) - { - Polynomial p; - p.coefficients[0] = 1.; - return p; - } - template< int Degree > - Polynomial< Degree > Polynomial< Degree >::BSplineComponent( int i ) - { - Polynomial p; - if( i>0 ) - { - Polynomial< Degree > _p = Polynomial< Degree-1 >::BSplineComponent( i-1 ).integral(); - p -= _p; - p.coefficients[0] += _p(1); - } - if( i _p = Polynomial< Degree-1 >::BSplineComponent( i ).integral(); - p += _p; - } - return p; - } - - } -} diff --git a/vendor/poisson_surface/ppolynomial.h b/vendor/poisson_surface/ppolynomial.h deleted file mode 100644 index 0f7a4436ae..0000000000 --- a/vendor/poisson_surface/ppolynomial.h +++ /dev/null @@ -1,128 +0,0 @@ -/* -Copyright (c) 2006, Michael Kazhdan and Matthew Bolitho -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -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. - -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. - -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 -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 -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. -*/ - -#ifndef P_POLYNOMIAL_INCLUDED -#define P_POLYNOMIAL_INCLUDED - -#if defined __GNUC__ -# pragma GCC system_header -#endif - -#include -#include "polynomial.h" - -namespace pcl -{ - namespace poisson - { - template - class StartingPolynomial{ - public: - Polynomial p; - double start; - - template - StartingPolynomial operator * (const StartingPolynomial& p) const; - StartingPolynomial scale(double s) const; - StartingPolynomial shift(double t) const; - int operator < (const StartingPolynomial& sp) const; - static int Compare(const void* v1,const void* v2); - }; - - template - class PPolynomial - { - public: - size_t polyCount; - StartingPolynomial* polys; - - PPolynomial(void); - PPolynomial(const PPolynomial& p); - ~PPolynomial(void); - - PPolynomial& operator = (const PPolynomial& p); - - int size(void) const; - - void set( size_t size ); - // Note: this method will sort the elements in sps - void set( StartingPolynomial* sps , int count ); - void reset( size_t newSize ); - - - double operator()( double t ) const; - double integral( double tMin , double tMax ) const; - double Integral( void ) const; - - template - PPolynomial& operator = (const PPolynomial& p); - - PPolynomial operator + (const PPolynomial& p) const; - PPolynomial operator - (const PPolynomial& p) const; - - template - PPolynomial operator * (const Polynomial& p) const; - - template - PPolynomial operator * (const PPolynomial& p) const; - - - PPolynomial& operator += ( double s ); - PPolynomial& operator -= ( double s ); - PPolynomial& operator *= ( double s ); - PPolynomial& operator /= ( double s ); - PPolynomial operator + ( double s ) const; - PPolynomial operator - ( double s ) const; - PPolynomial operator * ( double s ) const; - PPolynomial operator / ( double s ) const; - - PPolynomial& addScaled(const PPolynomial& poly,double scale); - - PPolynomial scale( double s ) const; - PPolynomial shift( double t ) const; - - PPolynomial< Degree-1 > derivative(void) const; - PPolynomial< Degree+1 > integral(void) const; - - void getSolutions(double c,std::vector& roots,double EPS,double min=-DBL_MAX,double max=DBL_MAX) const; - - void printnl( void ) const; - - PPolynomial< Degree+1 > MovingAverage( double radius ); - static PPolynomial BSpline( double radius=0.5 ); - - void write( FILE* fp , int samples , double min , double max ) const; - }; - - - } -} - - -#include "ppolynomial.hpp" -#endif // P_POLYNOMIAL_INCLUDED diff --git a/vendor/poisson_surface/ppolynomial.hpp b/vendor/poisson_surface/ppolynomial.hpp deleted file mode 100644 index dd64bce8b9..0000000000 --- a/vendor/poisson_surface/ppolynomial.hpp +++ /dev/null @@ -1,441 +0,0 @@ -/* -Copyright (c) 2006, Michael Kazhdan and Matthew Bolitho -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -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. - -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. - -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 -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 -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. -*/ - -#include "factor.h" - -//////////////////////// -// StartingPolynomial // -//////////////////////// - -namespace pcl -{ - namespace poisson - { - - - template - template - StartingPolynomial StartingPolynomial::operator * (const StartingPolynomial& p) const{ - StartingPolynomial sp; - if(start>p.start){sp.start=start;} - else{sp.start=p.start;} - sp.p=this->p*p.p; - return sp; - } - template - StartingPolynomial StartingPolynomial::scale(double s) const{ - StartingPolynomial q; - q.start=start*s; - q.p=p.scale(s); - return q; - } - template - StartingPolynomial StartingPolynomial::shift(double s) const{ - StartingPolynomial q; - q.start=start+s; - q.p=p.shift(s); - return q; - } - - - template - int StartingPolynomial::operator < (const StartingPolynomial& sp) const{ - if(start - int StartingPolynomial::Compare(const void* v1,const void* v2){ - double d=((StartingPolynomial*)(v1))->start-((StartingPolynomial*)(v2))->start; - if (d<0) {return -1;} - else if (d>0) {return 1;} - else {return 0;} - } - - ///////////////// - // PPolynomial // - ///////////////// - template - PPolynomial::PPolynomial(void){ - polyCount=0; - polys=NULL; - } - template - PPolynomial::PPolynomial(const PPolynomial& p){ - polyCount=0; - polys=NULL; - set(p.polyCount); - memcpy(polys,p.polys,sizeof(StartingPolynomial)*p.polyCount); - } - - template - PPolynomial::~PPolynomial(void){ - if(polyCount){free(polys);} - polyCount=0; - polys=NULL; - } - template - void PPolynomial::set(StartingPolynomial* sps,int count){ - int i,c=0; - set(count); - qsort(sps,count,sizeof(StartingPolynomial),StartingPolynomial::Compare); - for( i=0 ; i - int PPolynomial::size(void) const{return int(sizeof(StartingPolynomial)*polyCount);} - - template - void PPolynomial::set( size_t size ) - { - if(polyCount){free(polys);} - polyCount=0; - polys=NULL; - polyCount=size; - if(size){ - polys=(StartingPolynomial*)malloc(sizeof(StartingPolynomial)*size); - memset(polys,0,sizeof(StartingPolynomial)*size); - } - } - template - void PPolynomial::reset( size_t newSize ) - { - polyCount=newSize; - polys=(StartingPolynomial*)realloc(polys,sizeof(StartingPolynomial)*newSize); - } - - template - PPolynomial& PPolynomial::operator = (const PPolynomial& p){ - set(p.polyCount); - memcpy(polys,p.polys,sizeof(StartingPolynomial)*p.polyCount); - return *this; - } - - template - template - PPolynomial& PPolynomial::operator = (const PPolynomial& p){ - set(p.polyCount); - for(int i=0;i - double PPolynomial::operator ()( double t ) const - { - double v=0; - for( int i=0 ; ipolys[i].start ; i++ ) v+=polys[i].p(t); - return v; - } - - template - double PPolynomial::integral( double tMin , double tMax ) const - { - int m=1; - double start,end,s,v=0; - start=tMin; - end=tMax; - if(tMin>tMax){ - m=-1; - start=tMax; - end=tMin; - } - for(int i=0;i - double PPolynomial::Integral(void) const{return integral(polys[0].start,polys[polyCount-1].start);} - template - PPolynomial PPolynomial::operator + (const PPolynomial& p) const{ - PPolynomial q; - int i,j; - size_t idx=0; - q.set(polyCount+p.polyCount); - i=j=-1; - - while(idx=int(p.polyCount)-1) {q.polys[idx]= polys[++i];} - else if (i>=int( polyCount)-1) {q.polys[idx]=p.polys[++j];} - else if(polys[i+1].start - PPolynomial PPolynomial::operator - (const PPolynomial& p) const{ - PPolynomial q; - int i,j; - size_t idx=0; - q.set(polyCount+p.polyCount); - i=j=-1; - - while(idx=int(p.polyCount)-1) {q.polys[idx]= polys[++i];} - else if (i>=int( polyCount)-1) {q.polys[idx].start=p.polys[++j].start;q.polys[idx].p=p.polys[j].p*(-1.0);} - else if(polys[i+1].start - PPolynomial& PPolynomial::addScaled(const PPolynomial& p,double scale){ - int i,j; - StartingPolynomial* oldPolys=polys; - size_t idx=0,cnt=0,oldPolyCount=polyCount; - polyCount=0; - polys=NULL; - set(oldPolyCount+p.polyCount); - i=j=-1; - while(cnt=int( p.polyCount)-1) {polys[idx]=oldPolys[++i];} - else if (i>=int(oldPolyCount)-1) {polys[idx].start= p.polys[++j].start;polys[idx].p=p.polys[j].p*scale;} - else if (oldPolys[i+1].start - template - PPolynomial PPolynomial::operator * (const PPolynomial& p) const{ - PPolynomial q; - StartingPolynomial *sp; - int i,j,spCount=int(polyCount*p.polyCount); - - sp=(StartingPolynomial*)malloc(sizeof(StartingPolynomial)*spCount); - for(i=0;i - template - PPolynomial PPolynomial::operator * (const Polynomial& p) const{ - PPolynomial q; - q.set(polyCount); - for(int i=0;i - PPolynomial PPolynomial::scale( double s ) const - { - PPolynomial q; - q.set(polyCount); - for(size_t i=0;i - PPolynomial PPolynomial::shift( double s ) const - { - PPolynomial q; - q.set(polyCount); - for(size_t i=0;i - PPolynomial PPolynomial::derivative(void) const{ - PPolynomial q; - q.set(polyCount); - for(size_t i=0;i - PPolynomial PPolynomial::integral(void) const{ - int i; - PPolynomial q; - q.set(polyCount); - for(i=0;i - PPolynomial& PPolynomial::operator += ( double s ) {polys[0].p+=s;} - template - PPolynomial& PPolynomial::operator -= ( double s ) {polys[0].p-=s;} - template - PPolynomial& PPolynomial::operator *= ( double s ) - { - for(int i=0;i - PPolynomial& PPolynomial::operator /= ( double s ) - { - for(size_t i=0;i - PPolynomial PPolynomial::operator + ( double s ) const - { - PPolynomial q=*this; - q+=s; - return q; - } - template - PPolynomial PPolynomial::operator - ( double s ) const - { - PPolynomial q=*this; - q-=s; - return q; - } - template - PPolynomial PPolynomial::operator * ( double s ) const - { - PPolynomial q=*this; - q*=s; - return q; - } - template - PPolynomial PPolynomial::operator / ( double s ) const - { - PPolynomial q=*this; - q/=s; - return q; - } - - template - void PPolynomial::printnl(void) const{ - Polynomial p; - - if(!polyCount){ - Polynomial p; - printf("[-Infinity,Infinity]\n"); - } - else{ - for(size_t i=0;i - PPolynomial< 0 > PPolynomial< 0 >::BSpline( double radius ) - { - PPolynomial q; - q.set(2); - - q.polys[0].start=-radius; - q.polys[1].start= radius; - - q.polys[0].p.coefficients[0]= 1.0; - q.polys[1].p.coefficients[0]=-1.0; - return q; - } - template< int Degree > - PPolynomial< Degree > PPolynomial::BSpline( double radius ) - { - return PPolynomial< Degree-1 >::BSpline().MovingAverage( radius ); - } - template - PPolynomial PPolynomial::MovingAverage( double radius ) - { - PPolynomial A; - Polynomial p; - StartingPolynomial* sps; - - sps=(StartingPolynomial*)malloc(sizeof(StartingPolynomial)*polyCount*2); - - for(int i=0;i - void PPolynomial::getSolutions(double c,std::vector& roots,double EPS,double min,double max) const{ - Polynomial p; - std::vector tempRoots; - - p.setZero(); - for(size_t i=0;imax){break;} - if(ipolys[i].start && (i+1==polyCount || tempRoots[j]<=polys[i+1].start)){ - if(tempRoots[j]>min && tempRoots[j] - void PPolynomial::write(FILE* fp,int samples,double min,double max) const{ - fwrite(&samples,sizeof(int),1,fp); - for(int i=0;i - struct MatrixEntry - { - MatrixEntry( void ) { N =-1; Value = 0; } - MatrixEntry( int i ) { N = i; Value = 0; } - int N; - T Value; - }; - - template class SparseMatrix - { - private: - bool _contiguous; - int _maxEntriesPerRow; - static int UseAlloc; - public: - static Allocator > internalAllocator; - static int UseAllocator(void); - static void SetAllocator( int blockSize ); - - int rows; - int* rowSizes; - MatrixEntry** m_ppElements; - MatrixEntry< T >* operator[] ( int idx ) { return m_ppElements[idx]; } - const MatrixEntry< T >* operator[] ( int idx ) const { return m_ppElements[idx]; } - - SparseMatrix( void ); - SparseMatrix( int rows ); - SparseMatrix( int rows , int maxEntriesPerRow ); - void Resize( int rows ); - void Resize( int rows , int maxEntriesPerRow ); - void SetRowSize( int row , int count ); - int Entries( void ) const; - - SparseMatrix( const SparseMatrix& M ); - ~SparseMatrix(); - - void SetZero(); - void SetIdentity(); - - SparseMatrix& operator = (const SparseMatrix& M); - - SparseMatrix operator * (const T& V) const; - SparseMatrix& operator *= (const T& V); - - - SparseMatrix operator * (const SparseMatrix& M) const; - SparseMatrix Multiply( const SparseMatrix& M ) const; - SparseMatrix MultiplyTranspose( const SparseMatrix& Mt ) const; - - template - Vector operator * (const Vector& V) const; - template - Vector Multiply( const Vector& V ) const; - template - void Multiply( const Vector& In , Vector& Out , int threads=1 ) const; - - - SparseMatrix Transpose() const; - - static int Solve (const SparseMatrix& M,const Vector& b, int iters,Vector& solution,const T eps=1e-8); - - template - static int SolveSymmetric( const SparseMatrix& M , const Vector& b , int iters , Vector& solution , const T2 eps=1e-8 , int reset=1 , int threads=1 ); - - bool write( FILE* fp ) const; - bool write( const char* fileName ) const; - bool read( FILE* fp ); - bool read( const char* fileName ); - }; - - template< class T2 > - struct MapReduceVector - { - private: - int _dim; - public: - std::vector< T2* > out; - MapReduceVector( void ) { _dim = 0; } - ~MapReduceVector( void ) - { - if( _dim ) for( int t=0 ; t - class SparseSymmetricMatrix : public SparseMatrix< T > - { - public: - - template< class T2 > - Vector< T2 > operator * ( const Vector& V ) const; - - template< class T2 > - Vector< T2 > Multiply( const Vector& V ) const; - - template< class T2 > - void Multiply( const Vector& In, Vector& Out , bool addDCTerm=false ) const; - - template< class T2 > - void Multiply( const Vector& In, Vector& Out , MapReduceVector< T2 >& OutScratch , bool addDCTerm=false ) const; - - template< class T2 > - void Multiply( const Vector& In, Vector& Out , std::vector< T2* >& OutScratch , const std::vector< int >& bounds ) const; - - template< class T2 > - static int Solve( const SparseSymmetricMatrix& M , const Vector& b , int iters , Vector& solution , T2 eps=1e-8 , int reset=1 , int threads=0 , bool addDCTerm=false , bool solveNormal=false ); - - template< class T2 > - static int Solve( const SparseSymmetricMatrix& M , const Vector& b , int iters , Vector& solution , MapReduceVector& scratch , T2 eps=1e-8 , int reset=1 , bool addDCTerm=false , bool solveNormal=false ); -#if defined _WIN32 && !defined __MINGW32__ - template< class T2 > - static int SolveAtomic( const SparseSymmetricMatrix& M , const Vector& b , int iters , Vector& solution , T2 eps=1e-8 , int reset=1 , int threads=0 , bool solveNormal=false ); -#endif // _WIN32 || __MINGW32__ - template - static int Solve( const SparseSymmetricMatrix& M , const Vector& diagonal , const Vector& b , int iters , Vector& solution , int reset=1 ); - - template< class T2 > - void getDiagonal( Vector< T2 >& diagonal ) const; - }; - - - } -} - - -#include "sparse_matrix.hpp" - -#endif - diff --git a/vendor/poisson_surface/sparse_matrix.hpp b/vendor/poisson_surface/sparse_matrix.hpp deleted file mode 100644 index dd059bf5b1..0000000000 --- a/vendor/poisson_surface/sparse_matrix.hpp +++ /dev/null @@ -1,970 +0,0 @@ -/* -Copyright (c) 2006, Michael Kazhdan and Matthew Bolitho -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -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. - -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. - -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 -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 -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. -*/ - -#include -#ifdef _WIN32 -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif // WIN32_LEAN_AND_MEAN -# ifndef NOMINMAX -# define NOMINMAX -# endif // NOMINMAX -# include -#endif //_WIN32 - -/////////////////// -// SparseMatrix // -/////////////////// -/////////////////////////////////////////// -// Static Allocator Methods and Memebers // -/////////////////////////////////////////// - -namespace pcl -{ - namespace poisson - { - - - template int SparseMatrix::UseAlloc=0; - template Allocator > SparseMatrix::internalAllocator; - template int SparseMatrix::UseAllocator(void){return UseAlloc;} - template - void SparseMatrix::SetAllocator( int blockSize ) - { - if(blockSize>0){ - UseAlloc=1; - internalAllocator.set(blockSize); - } - else{UseAlloc=0;} - } - /////////////////////////////////////// - // SparseMatrix Methods and Memebers // - /////////////////////////////////////// - - template< class T > - SparseMatrix< T >::SparseMatrix( void ) - { - _contiguous = false; - _maxEntriesPerRow = 0; - rows = 0; - rowSizes = NULL; - m_ppElements = NULL; - } - - template< class T > SparseMatrix< T >::SparseMatrix( int rows ) : SparseMatrix< T >() { Resize( rows ); } - template< class T > SparseMatrix< T >::SparseMatrix( int rows , int maxEntriesPerRow ) : SparseMatrix< T >() { Resize( rows , maxEntriesPerRow ); } - - template< class T > - SparseMatrix< T >::SparseMatrix( const SparseMatrix& M ) : SparseMatrix< T >() - { - if( M._contiguous ) Resize( M.rows , M._maxEntriesPerRow ); - else Resize( M.rows ); - for( int i=0 ; i ) * rowSizes[i] ); - } - } - template - int SparseMatrix::Entries( void ) const - { - int e = 0; - for( int i=0 ; i - SparseMatrix& SparseMatrix::operator = (const SparseMatrix& M) - { - if( M._contiguous ) Resize( M.rows , M._maxEntriesPerRow ); - else Resize( M.rows ); - for( int i=0 ; i ) * rowSizes[i] ); - } - return *this; - } - - template - SparseMatrix::~SparseMatrix( void ){ Resize( 0 ); } - - template< class T > - bool SparseMatrix< T >::write( const char* fileName ) const - { - FILE* fp = fopen( fileName , "wb" ); - if( !fp ) return false; - bool ret = write( fp ); - fclose( fp ); - return ret; - } - template< class T > - bool SparseMatrix< T >::read( const char* fileName ) - { - FILE* fp = fopen( fileName , "rb" ); - if( !fp ) return false; - bool ret = read( fp ); - fclose( fp ); - return ret; - } - template< class T > - bool SparseMatrix< T >::write( FILE* fp ) const - { - if( fwrite( &rows , sizeof( int ) , 1 , fp )!=1 ) return false; - if( fwrite( rowSizes , sizeof( int ) , rows , fp )!=rows ) return false; - for( int i=0 ; i ) , rowSizes[i] , fp )!=rowSizes[i] ) return false; - return true; - } - template< class T > - bool SparseMatrix< T >::read( FILE* fp ) - { - int r; - if( fread( &r , sizeof( int ) , 1 , fp )!=1 ) return false; - Resize( r ); - if( fread( rowSizes , sizeof( int ) , rows , fp )!=rows ) return false; - for( int i=0 ; i ) , rowSizes[i] , fp )!=rowSizes[i] ) return false; - } - return true; - } - - - template< class T > - void SparseMatrix< T >::Resize( int r ) - { - if( rows>0 ) - { - - if( !UseAlloc ) - if( _contiguous ){ if( _maxEntriesPerRow ) free( m_ppElements[0] ); } - else for( int i=0 ; i** )malloc( sizeof( MatrixEntry< T >* ) * r ); - } - _contiguous = false; - _maxEntriesPerRow = 0; - } - template< class T > - void SparseMatrix< T >::Resize( int r , int e ) - { - if( rows>0 ) - { - if( !UseAlloc ) - if( _contiguous ){ if( _maxEntriesPerRow ) free( m_ppElements[0] ); } - else for( int i=0 ; i** )malloc( sizeof( MatrixEntry< T >* ) * r ); - m_ppElements[0] = ( MatrixEntry< T >* )malloc( sizeof( MatrixEntry< T > ) * r * e ); - for( int i=1 ; i - void SparseMatrix< T >::SetRowSize( int row , int count ) - { - if( _contiguous ) - { - if( count>_maxEntriesPerRow ) fprintf( stderr , "[ERROR] Cannot set row size on contiguous matrix: %d<=%d\n" , count , _maxEntriesPerRow ) , exit( 0 ); - rowSizes[row] = count; - } - else if( row>=0 && row0 ) m_ppElements[row] = ( MatrixEntry< T >* )malloc( sizeof( MatrixEntry< T > ) * count ); - } - } - } - - - template - void SparseMatrix::SetZero() - { - Resize(this->m_N, this->m_M); - } - - template - void SparseMatrix::SetIdentity() - { - SetZero(); - for(int ij=0; ij < Min( this->Rows(), this->Columns() ); ij++) - (*this)(ij,ij) = T(1); - } - - template - SparseMatrix SparseMatrix::operator * (const T& V) const - { - SparseMatrix M(*this); - M *= V; - return M; - } - - template - SparseMatrix& SparseMatrix::operator *= (const T& V) - { - for (int i=0; iRows(); i++) - { - for(int ii=0;ii - SparseMatrix SparseMatrix::Multiply( const SparseMatrix& M ) const - { - SparseMatrix R( this->Rows(), M.Columns() ); - for(int i=0; i - template - Vector SparseMatrix::Multiply( const Vector& V ) const - { - Vector R( rows ); - - for (int i=0; i - template - void SparseMatrix::Multiply( const Vector& In , Vector& Out , int threads ) const - { -#pragma omp parallel for num_threads( threads ) schedule( static ) - for( int i=0 ; i - SparseMatrix SparseMatrix::operator * (const SparseMatrix& M) const - { - return Multiply(M); - } - template - template - Vector SparseMatrix::operator * (const Vector& V) const - { - return Multiply(V); - } - - template - SparseMatrix SparseMatrix::Transpose() const - { - SparseMatrix M( this->Columns(), this->Rows() ); - - for (int i=0; iRows(); i++) - { - for(int ii=0;ii - template - int SparseMatrix::SolveSymmetric( const SparseMatrix& M , const Vector& b , int iters , Vector& solution , const T2 eps , int reset , int threads ) - { - if( reset ) - { - solution.Resize( b.Dimensions() ); - solution.SetZero(); - } - Vector< T2 > r; - r.Resize( solution.Dimensions() ); - M.Multiply( solution , r ); - r = b - r; - Vector< T2 > d = r; - double delta_new , delta_0; - for( int i=0 ; i q; - q.Resize( d.Dimensions() ); - for( ii=0; iieps*delta_0 ; ii++ ) - { - M.Multiply( d , q , threads ); - double dDotQ = 0 , alpha = 0; - for( int i=0 ; i - int SparseMatrix::Solve(const SparseMatrix& M,const Vector& b,int iters,Vector& solution,const T eps){ - SparseMatrix mTranspose=M.Transpose(); - Vector bb=mTranspose*b; - Vector d,r,Md; - T alpha,beta,rDotR; - int i; - - solution.Resize(M.Columns()); - solution.SetZero(); - - d=r=bb; - rDotR=r.Dot(r); - for(i=0;ieps;i++){ - T temp; - Md=mTranspose*(M*d); - alpha=rDotR/d.Dot(Md); - solution+=d*alpha; - r-=Md*alpha; - temp=r.Dot(r); - beta=temp/rDotR; - rDotR=temp; - d=r+d*beta; - } - return i; - } - - - - - /////////////////////////// - // SparseSymmetricMatrix // - /////////////////////////// - template - template - Vector SparseSymmetricMatrix::operator * (const Vector& V) const {return Multiply(V);} - template - template - Vector SparseSymmetricMatrix::Multiply( const Vector& V ) const - { - Vector R( SparseMatrix::rows ); - - for(int i=0; i::rows; i++){ - for(int ii=0;ii::rowSizes[i];ii++){ - int j=SparseMatrix::m_ppElements[i][ii].N; - R(i)+=SparseMatrix::m_ppElements[i][ii].Value * V.m_pV[j]; - R(j)+=SparseMatrix::m_ppElements[i][ii].Value * V.m_pV[i]; - } - } - return R; - } - - template - template - void SparseSymmetricMatrix::Multiply( const Vector& In , Vector& Out , bool addDCTerm ) const - { - Out.SetZero(); - const T2* in = &In[0]; - T2* out = &Out[0]; - T2 dcTerm = T2( 0 ); - if( addDCTerm ) - { - for( int i=0 ; i::rows ; i++ ) dcTerm += in[i]; - dcTerm /= SparseMatrix::rows; - } - for( int i=0 ; iSparseMatrix::rows ; i++ ) - { - const MatrixEntry* temp = SparseMatrix::m_ppElements[i]; - const MatrixEntry* end = temp + SparseMatrix::rowSizes[i]; - const T2& in_i_ = in[i]; - T2 out_i = T2(0); - for( ; temp!=end ; temp++ ) - { - int j=temp->N; - T2 v=temp->Value; - out_i += v * in[j]; - out[j] += v * in_i_; - } - out[i] += out_i; - } - if( addDCTerm ) for( int i=0 ; i::rows ; i++ ) out[i] += dcTerm; - } - template - template - void SparseSymmetricMatrix::Multiply( const Vector& In , Vector& Out , MapReduceVector< T2 >& OutScratch , bool addDCTerm ) const - { - int dim = int( In.Dimensions() ); - const T2* in = &In[0]; - int threads = OutScratch.threads(); - if( addDCTerm ) - { - T2 dcTerm = 0; -#pragma omp parallel for num_threads( threads ) reduction ( + : dcTerm ) - for( int t=0 ; t::rows*t)/threads ; i<(SparseMatrix::rows*(t+1))/threads ; i++ ) - { - const T2& in_i_ = in[i]; - T2& out_i_ = out[i]; - for( const MatrixEntry< T > *temp = SparseMatrix::m_ppElements[i] , *end = temp+SparseMatrix::rowSizes[i] ; temp!=end ; temp++ ) - { - int j = temp->N; - T2 v = temp->Value; - out_i_ += v * in[j]; - out[j] += v * in_i_; - } - dcTerm += in_i_; - } - } - dcTerm /= dim; - dim = int( Out.Dimensions() ); - T2* out = &Out[0]; -#pragma omp parallel for num_threads( threads ) schedule( static ) - for( int i=0 ; i::rows*t)/threads ; i<(SparseMatrix::rows*(t+1))/threads ; i++ ) - { - const T2& in_i_ = in[i]; - T2& out_i_ = out[i]; - for( const MatrixEntry< T > *temp = SparseMatrix::m_ppElements[i] , *end = temp+SparseMatrix::rowSizes[i] ; temp!=end ; temp++ ) - { - int j = temp->N; - T2 v = temp->Value; - out_i_ += v * in[j]; - out[j] += v * in_i_; - } - } - } - dim = int( Out.Dimensions() ); - T2* out = &Out[0]; -#pragma omp parallel for num_threads( threads ) schedule( static ) - for( int i=0 ; i - template - void SparseSymmetricMatrix::Multiply( const Vector& In , Vector& Out , std::vector< T2* >& OutScratch , const std::vector< int >& bounds ) const - { - int dim = In.Dimensions(); - const T2* in = &In[0]; - int threads = OutScratch.size(); -#pragma omp parallel for num_threads( threads ) - for( int t=0 ; t* temp = SparseMatrix::m_ppElements[i]; - const MatrixEntry* end = temp + SparseMatrix::rowSizes[i]; - const T2& in_i_ = in[i]; - T2& out_i_ = out[i]; - for( ; temp!=end ; temp++ ) - { - int j = temp->N; - T2 v = temp->Value; - out_i_ += v * in[j]; - out[j] += v * in_i_; - } - } - } - T2* out = &Out[0]; -#pragma omp parallel for num_threads( threads ) schedule( static ) - for( int i=0 ; i - void MultiplyAtomic( const SparseSymmetricMatrix< T >& A , const Vector< float >& In , Vector< float >& Out , int threads , const int* partition=NULL ) - { - Out.SetZero(); - const float* in = &In[0]; - float* out = &Out[0]; - if( partition ) -#pragma omp parallel for num_threads( threads ) - for( int t=0 ; t* temp = A[i]; - const MatrixEntry< T >* end = temp + A.rowSizes[i]; - const float& in_i = in[i]; - float out_i = 0.; - for( ; temp!=end ; temp++ ) - { - int j = temp->N; - float v = temp->Value; - out_i += v * in[j]; - AtomicIncrement( out+j , v * in_i ); - } - AtomicIncrement( out+i , out_i ); - } - else -#pragma omp parallel for num_threads( threads ) - for( int i=0 ; i* temp = A[i]; - const MatrixEntry< T >* end = temp + A.rowSizes[i]; - const float& in_i = in[i]; - float out_i = 0.f; - for( ; temp!=end ; temp++ ) - { - int j = temp->N; - float v = temp->Value; - out_i += v * in[j]; - AtomicIncrement( out+j , v * in_i ); - } - AtomicIncrement( out+i , out_i ); - } - } - template< class T > - void MultiplyAtomic( const SparseSymmetricMatrix< T >& A , const Vector< double >& In , Vector< double >& Out , int threads , const int* partition=NULL ) - { - Out.SetZero(); - const double* in = &In[0]; - double* out = &Out[0]; - - if( partition ) -#pragma omp parallel for num_threads( threads ) - for( int t=0 ; t* temp = A[i]; - const MatrixEntry< T >* end = temp + A.rowSizes[i]; - const double& in_i = in[i]; - double out_i = 0.; - for( ; temp!=end ; temp++ ) - { - int j = temp->N; - T v = temp->Value; - out_i += v * in[j]; - AtomicIncrement( out+j , v * in_i ); - } - AtomicIncrement( out+i , out_i ); - } - else -#pragma omp parallel for num_threads( threads ) - for( int i=0 ; i* temp = A[i]; - const MatrixEntry< T >* end = temp + A.rowSizes[i]; - const double& in_i = in[i]; - double out_i = 0.; - for( ; temp!=end ; temp++ ) - { - int j = temp->N; - T v = temp->Value; - out_i += v * in[j]; - AtomicIncrement( out+j , v * in_i ); - } - AtomicIncrement( out+i , out_i ); - } - } - - template< class T > - template< class T2 > - int SparseSymmetricMatrix< T >::SolveAtomic( const SparseSymmetricMatrix< T >& A , const Vector< T2 >& b , int iters , Vector< T2 >& x , T2 eps , int reset , int threads , bool solveNormal ) - { - eps *= eps; - int dim = b.Dimensions(); - if( reset ) - { - x.Resize( dim ); - x.SetZero(); - } - Vector< T2 > r( dim ) , d( dim ) , q( dim ); - Vector< T2 > temp; - if( solveNormal ) temp.Resize( dim ); - T2 *_x = &x[0] , *_r = &r[0] , *_d = &d[0] , *_q = &q[0]; - const T2* _b = &b[0]; - - std::vector< int > partition( threads+1 ); - { - int eCount = 0; - for( int i=0 ; i=eCount*(t+1) ) - { - partition[t+1] = i; - break; - } - } - } - partition[threads] = A.rows; - } - if( solveNormal ) - { - MultiplyAtomic( A , x , temp , threads , &partition[0] ); - MultiplyAtomic( A , temp , r , threads , &partition[0] ); - MultiplyAtomic( A , b , temp , threads , &partition[0] ); -#pragma omp parallel for num_threads( threads ) schedule( static ) - for( int i=0 ; ieps*delta_0 ; ii++ ) - { - if( solveNormal ) MultiplyAtomic( A , d , temp , threads , &partition[0] ) , MultiplyAtomic( A , temp , q , threads , &partition[0] ); - else MultiplyAtomic( A , d , q , threads , &partition[0] ); - double dDotQ = 0; - for( int i=0 ; i - template< class T2 > - int SparseSymmetricMatrix< T >::Solve( const SparseSymmetricMatrix& A , const Vector& b , int iters , Vector& x , MapReduceVector< T2 >& scratch , T2 eps , int reset , bool addDCTerm , bool solveNormal ) - { - int threads = scratch.threads(); - eps *= eps; - int dim = int( b.Dimensions() ); - Vector< T2 > r( dim ) , d( dim ) , q( dim ) , temp; - if( reset ) x.Resize( dim ); - if( solveNormal ) temp.Resize( dim ); - T2 *_x = &x[0] , *_r = &r[0] , *_d = &d[0] , *_q = &q[0]; - const T2* _b = &b[0]; - - double delta_new = 0 , delta_0; - if( solveNormal ) - { - A.Multiply( x , temp , scratch , addDCTerm ) , A.Multiply( temp , r , scratch , addDCTerm ) , A.Multiply( b , temp , scratch , addDCTerm ); -#pragma omp parallel for num_threads( threads ) reduction( + : delta_new ) - for( int i=0 ; ieps*delta_0 ; ii++ ) - { - if( solveNormal ) A.Multiply( d , temp , scratch , addDCTerm ) , A.Multiply( temp , q , scratch , addDCTerm ); - else A.Multiply( d , q , scratch , addDCTerm ); - double dDotQ = 0; -#pragma omp parallel for num_threads( threads ) reduction( + : dDotQ ) - for( int i=0 ; i - template< class T2 > - int SparseSymmetricMatrix::Solve( const SparseSymmetricMatrix& A , const Vector& b , int iters , Vector& x , T2 eps , int reset , int threads , bool addDCTerm , bool solveNormal ) - { - eps *= eps; - int dim = int( b.Dimensions() ); - MapReduceVector< T2 > outScratch; - if( threads<1 ) threads = 1; - if( threads>1 ) outScratch.resize( threads , dim ); - if( reset ) x.Resize( dim ); - Vector< T2 > r( dim ) , d( dim ) , q( dim ); - Vector< T2 > temp; - if( solveNormal ) temp.Resize( dim ); - T2 *_x = &x[0] , *_r = &r[0] , *_d = &d[0] , *_q = &q[0]; - const T2* _b = &b[0]; - - double delta_new = 0 , delta_0; - - if( solveNormal ) - { - if( threads>1 ) A.Multiply( x , temp , outScratch , addDCTerm ) , A.Multiply( temp , r , outScratch , addDCTerm ) , A.Multiply( b , temp , outScratch , addDCTerm ); - else A.Multiply( x , temp , addDCTerm ) , A.Multiply( temp , r , addDCTerm ) , A.Multiply( b , temp , addDCTerm ); -#pragma omp parallel for num_threads( threads ) reduction( + : delta_new ) - for( int i=0 ; i1 ) A.Multiply( x , r , outScratch , addDCTerm ); - else A.Multiply( x , r , addDCTerm ); -#pragma omp parallel for num_threads( threads ) reduction( + : delta_new ) - for( int i=0 ; ieps*delta_0 ; ii++ ) - { - if( solveNormal ) - { - if( threads>1 ) A.Multiply( d , temp , outScratch , addDCTerm ) , A.Multiply( temp , q , outScratch , addDCTerm ); - else A.Multiply( d , temp , addDCTerm ) , A.Multiply( temp , q , addDCTerm ); - } - else - { - if( threads>1 ) A.Multiply( d , q , outScratch , addDCTerm ); - else A.Multiply( d , q , addDCTerm ); - } - double dDotQ = 0; -#pragma omp parallel for num_threads( threads ) reduction( + : dDotQ ) - for( int i=0 ; i1 ) A.Multiply( x , temp , outScratch , addDCTerm ) , A.Multiply( temp , r , outScratch , addDCTerm ); - else A.Multiply( x , temp , addDCTerm ) , A.Multiply( temp , r , addDCTerm ); - } - else - { - if( threads>1 ) A.Multiply( x , r , outScratch , addDCTerm ); - else A.Multiply( x , r , addDCTerm ); - } -#pragma omp parallel for num_threads( threads ) reduction ( + : delta_new ) - for( int i=0 ; i - template - int SparseSymmetricMatrix::Solve( const SparseSymmetricMatrix& M , const Vector& diagonal , const Vector& b , int iters , Vector& solution , int reset ) - { - Vector d,r,Md; - - if(reset) - { - solution.Resize(b.Dimensions()); - solution.SetZero(); - } - Md.Resize(M.rows); - for( int i=0 ; i - template< class T2 > - void SparseSymmetricMatrix< T >::getDiagonal( Vector< T2 >& diagonal ) const - { - diagonal.Resize( SparseMatrix::rows ); - for( int i=0 ; i::rows ; i++ ) - { - diagonal[i] = 0.; - for( int j=0 ; j::rowSizes[i] ; j++ ) if( SparseMatrix::m_ppElements[i][j].N==i ) diagonal[i] += SparseMatrix::m_ppElements[i][j].Value * 2; - } - } - - } -} diff --git a/vendor/poisson_surface/vector.h b/vendor/poisson_surface/vector.h deleted file mode 100644 index bbf6b40fe7..0000000000 --- a/vendor/poisson_surface/vector.h +++ /dev/null @@ -1,155 +0,0 @@ -/* -Copyright (c) 2006, Michael Kazhdan and Matthew Bolitho -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -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. - -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. - -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 -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 -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. -*/ - -#ifndef __VECTOR_HPP -#define __VECTOR_HPP - -#define Assert assert -#include - - -namespace pcl -{ - namespace poisson - { - template - class Vector - { - public: - Vector(); - Vector( const Vector& V ); - Vector( size_t N ); - Vector( size_t N, T* pV ); - ~Vector(); - - const T& operator () (size_t i) const; - T& operator () (size_t i); - const T& operator [] (size_t i) const; - T& operator [] (size_t i); - - void SetZero(); - - size_t Dimensions() const; - void Resize( size_t N ); - - Vector operator * (const T& A) const; - Vector operator / (const T& A) const; - Vector operator - (const Vector& V) const; - Vector operator + (const Vector& V) const; - - Vector& operator *= (const T& A); - Vector& operator /= (const T& A); - Vector& operator += (const Vector& V); - Vector& operator -= (const Vector& V); - - Vector& AddScaled(const Vector& V,const T& scale); - Vector& SubtractScaled(const Vector& V,const T& scale); - static void Add(const Vector& V1,const T& scale1,const Vector& V2,const T& scale2,Vector& Out); - static void Add(const Vector& V1,const T& scale1,const Vector& V2,Vector& Out); - - Vector operator - () const; - - Vector& operator = (const Vector& V); - - T Dot( const Vector& V ) const; - - T Length() const; - - T Norm( size_t Ln ) const; - void Normalize(); - - bool write( FILE* fp ) const; - bool write( const char* fileName ) const; - bool read( FILE* fp ); - bool read( const char* fileName ); - - T* m_pV; - protected: - size_t m_N; - - }; - - template - class NVector - { - public: - NVector(); - NVector( const NVector& V ); - NVector( size_t N ); - NVector( size_t N, T* pV ); - ~NVector(); - - const T* operator () (size_t i) const; - T* operator () (size_t i); - const T* operator [] (size_t i) const; - T* operator [] (size_t i); - - void SetZero(); - - size_t Dimensions() const; - void Resize( size_t N ); - - NVector operator * (const T& A) const; - NVector operator / (const T& A) const; - NVector operator - (const NVector& V) const; - NVector operator + (const NVector& V) const; - - NVector& operator *= (const T& A); - NVector& operator /= (const T& A); - NVector& operator += (const NVector& V); - NVector& operator -= (const NVector& V); - - NVector& AddScaled(const NVector& V,const T& scale); - NVector& SubtractScaled(const NVector& V,const T& scale); - static void Add(const NVector& V1,const T& scale1,const NVector& V2,const T& scale2,NVector& Out); - static void Add(const NVector& V1,const T& scale1,const NVector& V2, NVector& Out); - - NVector operator - () const; - - NVector& operator = (const NVector& V); - - T Dot( const NVector& V ) const; - - T Length() const; - - T Norm( size_t Ln ) const; - void Normalize(); - - T* m_pV; - protected: - size_t m_N; - - }; - - } -} - - -#include "vector.hpp" - -#endif diff --git a/vendor/poisson_surface/vector.hpp b/vendor/poisson_surface/vector.hpp deleted file mode 100644 index f8a5bd8e6d..0000000000 --- a/vendor/poisson_surface/vector.hpp +++ /dev/null @@ -1,492 +0,0 @@ -/* -Copyright (c) 2006, Michael Kazhdan and Matthew Bolitho -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -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. - -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. - -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 -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 -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. -*/ - -#ifndef __VECTORIMPL_HPP -#define __VECTORIMPL_HPP - -//////////// -// Vector // -//////////// -namespace pcl -{ - namespace poisson - { - - - template - Vector::Vector() - { - m_N = 0; - m_pV = 0; - } - template - Vector::Vector( const Vector& V ) - { - m_N = 0; - m_pV = 0; - Resize(V.m_N); - memcpy( m_pV, V.m_pV, m_N*sizeof(T) ); - } - template - Vector::Vector( size_t N ) - { - m_N=0; - m_pV=0; - Resize(N); - } - template - void Vector::Resize( size_t N ) - { - if(m_N!=N){ - if(m_N){delete[] m_pV;} - m_pV=NULL; - m_N = N; - if(N){m_pV = new T[N];} - } - memset( m_pV, 0, N*sizeof(T) ); - } - template - Vector::Vector( size_t N, T* pV ) - { - Resize(N); - memcpy( m_pV, pV, N*sizeof(T) ); - } - template - Vector::~Vector(){Resize(0);} - template - Vector& Vector::operator = (const Vector& V) - { - Resize(V.m_N); - memcpy( m_pV, V.m_pV, m_N*sizeof(T) ); - return *this; - } - template - size_t Vector::Dimensions() const{return m_N;} - template - void Vector::SetZero(void){for (size_t i=0; i - const T& Vector::operator () (size_t i) const - { - Assert( i < m_N ); - return m_pV[i]; - } - template - T& Vector::operator () (size_t i) - { - return m_pV[i]; - } - template - const T& Vector::operator [] (size_t i) const - { - return m_pV[i]; - } - template - T& Vector::operator [] (size_t i) - { - return m_pV[i]; - } - template - Vector Vector::operator * (const T& A) const - { - Vector V(*this); - for (size_t i=0; i - Vector& Vector::operator *= (const T& A) - { - for (size_t i=0; i - Vector Vector::operator / (const T& A) const - { - Vector V(*this); - for (size_t i=0; i - Vector& Vector::operator /= (const T& A) - { - for (size_t i=0; i - Vector Vector::operator + (const Vector& V0) const - { - Vector V(m_N); - for (size_t i=0; i - Vector& Vector::AddScaled(const Vector& V,const T& scale) - { - for (size_t i=0; i - Vector& Vector::SubtractScaled(const Vector& V,const T& scale) - { - for (size_t i=0; i - void Vector::Add(const Vector& V1,const T& scale1,const Vector& V2,const T& scale2,Vector& Out){ - for (size_t i=0; i - void Vector::Add(const Vector& V1,const T& scale1,const Vector& V2,Vector& Out){ - for (size_t i=0; i - Vector& Vector::operator += (const Vector& V) - { - for (size_t i=0; i - Vector Vector::operator - (const Vector& V0) const - { - Vector V(m_N); - for (size_t i=0; i - Vector Vector::operator - (void) const - { - Vector V(m_N); - - for (size_t i=0; i - Vector& Vector::operator -= (const Vector& V) - { - for (size_t i=0; i - T Vector::Norm( size_t Ln ) const - { - T N = T(); - for (size_t i = 0; i - void Vector::Normalize() - { - T N = 1.0f/Norm(2); - for (size_t i = 0; i - T Vector::Length() const - { - T N = T(); - for (size_t i = 0; i - T Vector::Dot( const Vector& V ) const - { - T V0 = T(); - for (size_t i=0; i - bool Vector< T >::read( const char* fileName ) - { - FILE* fp = fopen( fileName , "rb" ); - if( !fp ) return false; - bool ret = read( fp ); - fclose( fp ); - return ret; - } - template< class T > - bool Vector< T >::write( const char* fileName ) const - { - FILE* fp = fopen( fileName , "wb" ); - if( !fp ) return false; - bool ret = write( fp ); - fclose( fp ); - return ret; - } - template< class T > - bool Vector< T >::read( FILE* fp ) - { - int d; - if( fread( &d , sizeof(int) , 1 , fp )!=1 ) return false; - Resize( d ); - if( fread( &(*this)[0] , sizeof( T ) , d , fp )!=d ) return false; - return true; - } - template< class T > - bool Vector< T >::write( FILE* fp ) const - { - if( fwrite( &m_N , sizeof( int ) , 1 , fp )!=1 ) return false; - if( fwrite( &(*this)[0] , sizeof( T ) , m_N , fp )!=m_N ) return false; - return true; - } - - - ///////////// - // NVector // - ///////////// - template - NVector::NVector() - { - m_N = 0; - m_pV = 0; - } - template - NVector::NVector( const NVector& V ) - { - m_N = 0; - m_pV = 0; - Resize(V.m_N); - memcpy( m_pV, V.m_pV, m_N*sizeof(T)*Dim ); - } - template - NVector::NVector( size_t N ) - { - m_N=0; - m_pV=0; - Resize(N); - } - template - void NVector::Resize( size_t N ) - { - if(m_N!=N){ - if(m_N){delete[] m_pV;} - m_pV=NULL; - m_N = N; - if(N){m_pV = new T[Dim*N];} - } - memset( m_pV, 0, N*sizeof(T)*Dim ); - } - template - NVector::NVector( size_t N, T* pV ) - { - Resize(N); - memcpy( m_pV, pV, N*sizeof(T)*Dim ); - } - template - NVector::~NVector(){Resize(0);} - template - NVector& NVector::operator = (const NVector& V) - { - Resize(V.m_N); - memcpy( m_pV, V.m_pV, m_N*sizeof(T)*Dim ); - return *this; - } - template - size_t NVector::Dimensions() const{return m_N;} - template - void NVector::SetZero(void){for (size_t i=0; i - const T* NVector::operator () (size_t i) const - { - Assert( i < m_N ); - return &m_pV[i*Dim]; - } - template - T* NVector::operator () (size_t i) - { - return &m_pV[i*Dim]; - } - template - const T* NVector::operator [] (size_t i) const - { - return &m_pV[i*Dim]; - } - template - T* NVector::operator [] (size_t i) - { - return &m_pV[i*Dim]; - } - template - NVector NVector::operator * (const T& A) const - { - NVector V(*this); - for (size_t i=0; i - NVector& NVector::operator *= (const T& A) - { - for (size_t i=0; i - NVector NVector::operator / (const T& A) const - { - NVector V(*this); - for (size_t i=0; i - NVector& NVector::operator /= (const T& A) - { - for (size_t i=0; i - NVector NVector::operator + (const NVector& V0) const - { - NVector V(m_N); - for (size_t i=0; i - NVector& NVector::AddScaled(const NVector& V,const T& scale) - { - for (size_t i=0; i - NVector& NVector::SubtractScaled(const NVector& V,const T& scale) - { - for (size_t i=0; i - void NVector::Add(const NVector& V1,const T& scale1,const NVector& V2,const T& scale2,NVector& Out){ - for (size_t i=0; i - void NVector::Add(const NVector& V1,const T& scale1,const NVector& V2,NVector& Out){ - for (size_t i=0; i - NVector& NVector::operator += (const NVector& V) - { - for (size_t i=0; i - NVector NVector::operator - (const NVector& V0) const - { - NVector V(m_N); - for (size_t i=0; i - NVector NVector::operator - (void) const - { - NVector V(m_N); - - for (size_t i=0; i - NVector& NVector::operator -= (const NVector& V) - { - for (size_t i=0; i - T NVector::Norm( size_t Ln ) const - { - T N = T(); - for (size_t i = 0; i - void NVector::Normalize() - { - T N = 1.0f/Norm(2); - for (size_t i = 0; i - T NVector::Length() const - { - T N = T(); - for (size_t i = 0; i - T NVector::Dot( const NVector& V ) const - { - T V0 = T(); - for (size_t i=0; i