diff --git a/README.md b/README.md
index b73caf5..d6920ca 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-
Adaptive Multigrid Solvers (Version 10.06)
+Adaptive Multigrid Solvers (Version 10.07)
links
executables
@@ -27,10 +27,11 @@ This code-base was born from the Poisson Surface Reconstruction code. It has evo
[Kazhdan and Hoppe, 2013]
Executables:
-Win64
+Win64
Source Code:
-ZIP GitHub
+ZIP GitHub
Older Versions:
+V10.06,
V10.05,
V10.04,
V10.03,
@@ -805,6 +806,12 @@ Similarly, to reduce compilation times, support for specific degrees can be remo
Modified the 2D implementations of PoissonRecon, SSDRecon, and AdaptiveTreeVisualization to support ouput to .jpg and .png image files.
+Version 10.06:
+
+- Removed a bug that would cause memory access errors when some slices were empty.
+g image files.
+
+
diff --git a/Src/AdaptiveTreeVisualization.cpp b/Src/AdaptiveTreeVisualization.cpp
index 9f2e7b5..6720cdc 100644
--- a/Src/AdaptiveTreeVisualization.cpp
+++ b/Src/AdaptiveTreeVisualization.cpp
@@ -91,61 +91,59 @@ void ShowUsage( char* ex )
}
template< typename Real , unsigned int Dim >
-bool WriteImage( const Real *values , int res , const char *fileName , bool verbose )
+void WriteGrid( ConstPointer( Real ) values , int res , const char *fileName )
{
- if( Dim!=2 ) return false;
int resolution = 1;
for( int d=0 ; d [0,255]\n" , avg - 2*std , avg + 2*std );
-
- unsigned char *pixels = new unsigned char[ resolution*3 ];
-#pragma omp parallel for
- for( int i=0 ; i( (Real)1. , std::max< Real >( (Real)-1. , ( values[i] - avg ) / (2*std ) ) );
- v = (Real)( ( v + 1. ) / 2. * 256. );
- unsigned char color = (unsigned char )std::min< Real >( (Real)255. , std::max< Real >( (Real)0. , v ) );
- for( int c=0 ; c<3 ; c++ ) pixels[i*3+c ] = color;
+ Real avg = 0;
+#pragma omp parallel for reduction( + : avg )
+ for( int i=0 ; i [0,255]\n" , avg - 2*std , avg + 2*std );
+
+ unsigned char *pixels = new unsigned char[ resolution*3 ];
+#pragma omp parallel for
+ for( int i=0 ; i( (Real)1. , std::max< Real >( (Real)-1. , ( values[i] - avg ) / (2*std ) ) );
+ v = (Real)( ( v + 1. ) / 2. * 256. );
+ unsigned char color = (unsigned char )std::min< Real >( (Real)255. , std::max< Real >( (Real)0. , v ) );
+ for( int c=0 ; c<3 ; c++ ) pixels[i*3+c ] = color;
+ }
+ ImageWriter::Write( fileName , pixels , res , res , 3 );
+ delete[] pixels;
}
- bool success = true;
- try{ ImageWriter::Write( fileName , pixels , res , res , 3 ); }
- catch( MKExceptions::Exception & ){ success = false; }
- delete[] pixels;
- return success;
-}
-
-template< typename Real , unsigned int Dim >
-void WriteGrid( const Real *values , int res , const char *fileName )
-{
- int resolution = 1;
- for( int d=0 ; d
@@ -163,7 +161,7 @@ void _Execute( const FEMTree< Dim , Real >* tree , FILE* fp )
double t = Time();
Pointer( Real ) values = tree->template regularGridEvaluate< true >( coefficients , res , -1 , PrimalGrid.set );
if( Verbose.set ) printf( "Got grid: %.2f(s)\n" , Time()-t );
- if( !WriteImage< Real , Dim >( values , res , OutGrid.value , Verbose.set ) ) WriteGrid< Real , Dim >( values , res , OutGrid.value );
+ WriteGrid< Real , Dim >( values , res , OutGrid.value );
DeletePointer( values );
}
diff --git a/Src/FEMTree.h b/Src/FEMTree.h
index 767403c..a15a254 100644
--- a/Src/FEMTree.h
+++ b/Src/FEMTree.h
@@ -42,7 +42,7 @@ DAMAGE.
#ifndef FEM_TREE_INCLUDED
#define FEM_TREE_INCLUDED
-#define VERSION "10.06"
+#define VERSION "10.07"
#define MEMORY_ALLOCATOR_BLOCK_SIZE 1<<12
#define NEW_CODE
diff --git a/Src/Image.h b/Src/Image.h
index 315ba51..345a3d7 100644
--- a/Src/Image.h
+++ b/Src/Image.h
@@ -37,6 +37,7 @@ struct ImageReader
return pixels;
}
+ static bool ValidExtension( const char *ext );
static ImageReader* Get( const char* fileName );
static void GetInfo( const char* fileName , unsigned int& width , unsigned int& height , unsigned int& channels );
virtual ~ImageReader( void ){ }
@@ -70,6 +71,8 @@ struct ImageWriter
for( unsigned int j=0 ; jnextRow( pixels + j*width*channels );
delete writer;
}
+
+ static bool ValidExtension( const char *ext );
static ImageWriter* Get( const char* fileName , unsigned int width , unsigned int height , unsigned int channels , ImageWriterParams params=ImageWriterParams() );
virtual ~ImageWriter( void ){ }
unsigned int width( void ) const { return _width; }
@@ -160,6 +163,20 @@ protected:
}
};
+inline bool ImageReader::ValidExtension( const char *ext )
+{
+#ifdef WIN32
+ if ( !_stricmp( ext , "jpeg" ) || !_stricmp( ext , "jpg" ) ) return true;
+ else if( !_stricmp( ext , "png" ) ) return true;
+ else if( !_stricmp( ext , "iGrid" ) ) return true;
+#else // !WIN32
+ if( !strcasecmp( ext , "jpeg" ) || !strcasecmp( ext , "jpg" ) ) return true;
+ else if( !strcasecmp( ext , "png" ) ) return true;
+ else if( !strcasecmp( ext , "iGrid" ) ) return true;
+#endif // WIN32
+ return false;
+}
+
inline ImageReader* ImageReader::Get( const char* fileName )
{
unsigned int width , height , channels;
@@ -200,6 +217,25 @@ inline void ImageReader::GetInfo( const char* fileName , unsigned int& width , u
#endif // WIN32
delete[] ext;
}
+
+inline bool ImageWriter::ValidExtension( const char *ext )
+{
+#ifdef WIN32
+ if( !_stricmp( ext , "jpeg" ) || !_stricmp( ext , "jpg" ) ) return true;
+ else if( !_stricmp( ext , "png" ) ) return true;
+#ifdef SUPPORT_TILES
+ else if( !_stricmp( ext , "iGrid" ) ) return true;
+#endif // SUPPORT_TILES
+#else // !WIN32
+ if( !strcasecmp( ext , "jpeg" ) || !strcasecmp( ext , "jpg" ) ) return true;
+ else if( !strcasecmp( ext , "png" ) ) return true;
+#ifdef SUPPORT_TILES
+ else if( !strcasecmp( ext , "iGrid" ) ) return true;
+#endif // SUPPORT_TILES
+#endif // WIN32
+ return false;
+}
+
inline ImageWriter* ImageWriter::Get( const char* fileName , unsigned int width , unsigned int height , unsigned int channels , ImageWriterParams params )
{
ImageWriter* writer = NULL;
diff --git a/Src/PoissonRecon.cpp b/Src/PoissonRecon.cpp
index bdaafb7..d6a194d 100644
--- a/Src/PoissonRecon.cpp
+++ b/Src/PoissonRecon.cpp
@@ -353,63 +353,62 @@ void ExtractMesh( UIntPack< FEMSigs ... > , std::tuple< SampleData ... > , FEMTr
}
template< typename Real , unsigned int Dim >
-bool WriteImage( const Real *values , int res , const char *fileName , bool verbose )
+void WriteGrid( ConstPointer( Real ) values , int res , const char *fileName )
{
- if( Dim!=2 ) return false;
int resolution = 1;
for( int d=0 ; d [0,255]\n" , avg - 2*std , avg + 2*std );
-
- unsigned char *pixels = new unsigned char[ resolution*3 ];
-#pragma omp parallel for
- for( int i=0 ; i( (Real)1. , std::max< Real >( (Real)-1. , ( values[i] - avg ) / (2*std ) ) );
- v = (Real)( ( v + 1. ) / 2. * 256. );
- unsigned char color = (unsigned char )std::min< Real >( (Real)255. , std::max< Real >( (Real)0. , v ) );
- for( int c=0 ; c<3 ; c++ ) pixels[i*3+c ] = color;
+ Real avg = 0;
+#pragma omp parallel for reduction( + : avg )
+ for( int i=0 ; i [0,255]\n" , avg - 2*std , avg + 2*std );
+
+ unsigned char *pixels = new unsigned char[ resolution*3 ];
+#pragma omp parallel for
+ for( int i=0 ; i( (Real)1. , std::max< Real >( (Real)-1. , ( values[i] - avg ) / (2*std ) ) );
+ v = (Real)( ( v + 1. ) / 2. * 256. );
+ unsigned char color = (unsigned char )std::min< Real >( (Real)255. , std::max< Real >( (Real)0. , v ) );
+ for( int c=0 ; c<3 ; c++ ) pixels[i*3+c ] = color;
+ }
+ ImageWriter::Write( fileName , pixels , res , res , 3 );
+ delete[] pixels;
}
- bool success = true;
- try{ ImageWriter::Write( fileName , pixels , res , res , 3 ); }
- catch( MKExceptions::Exception & ){ success = false; }
- delete[] pixels;
- return success;
-}
-
-template< typename Real , unsigned int Dim >
-void WriteGrid( const Real *values , int res , const char *fileName )
-{
- int resolution = 1;
- for( int d=0 ; d
void Execute( int argc , char* argv[] , UIntPack< FEMSigs ... > )
{
@@ -669,7 +668,7 @@ void Execute( int argc , char* argv[] , UIntPack< FEMSigs ... > )
#pragma omp parallel for
for( int i=0 ; i( values , res , Grid.value , Verbose.set ) ) WriteGrid< Real , DIMENSION >( values , res , Grid.value );
+ WriteGrid< Real , DIMENSION >( values , res , Grid.value );
DeletePointer( values );
if( Verbose.set )
{
diff --git a/Src/SSDRecon.cpp b/Src/SSDRecon.cpp
index cc92e44..e966acd 100644
--- a/Src/SSDRecon.cpp
+++ b/Src/SSDRecon.cpp
@@ -377,63 +377,62 @@ void ExtractMesh( UIntPack< FEMSigs ... > , std::tuple< SampleData ... > , FEMTr
}
template< typename Real , unsigned int Dim >
-bool WriteImage( const Real *values , int res , const char *fileName , bool verbose )
+void WriteGrid( ConstPointer( Real ) values , int res , const char *fileName )
{
- if( Dim!=2 ) return false;
int resolution = 1;
for( int d=0 ; d [0,255]\n" , avg - 2*std , avg + 2*std );
-
- unsigned char *pixels = new unsigned char[ resolution*3 ];
-#pragma omp parallel for
- for( int i=0 ; i( (Real)1. , std::max< Real >( (Real)-1. , ( values[i] - avg ) / (2*std ) ) );
- v = (Real)( ( v + 1. ) / 2. * 256. );
- unsigned char color = (unsigned char )std::min< Real >( (Real)255. , std::max< Real >( (Real)0. , v ) );
- for( int c=0 ; c<3 ; c++ ) pixels[i*3+c ] = color;
+ Real avg = 0;
+#pragma omp parallel for reduction( + : avg )
+ for( int i=0 ; i [0,255]\n" , avg - 2*std , avg + 2*std );
+
+ unsigned char *pixels = new unsigned char[ resolution*3 ];
+#pragma omp parallel for
+ for( int i=0 ; i( (Real)1. , std::max< Real >( (Real)-1. , ( values[i] - avg ) / (2*std ) ) );
+ v = (Real)( ( v + 1. ) / 2. * 256. );
+ unsigned char color = (unsigned char )std::min< Real >( (Real)255. , std::max< Real >( (Real)0. , v ) );
+ for( int c=0 ; c<3 ; c++ ) pixels[i*3+c ] = color;
+ }
+ ImageWriter::Write( fileName , pixels , res , res , 3 );
+ delete[] pixels;
}
- bool success = true;
- try{ ImageWriter::Write( fileName , pixels , res , res , 3 ); }
- catch( MKExceptions::Exception & ){ success = false; }
- delete[] pixels;
- return success;
-}
-
-template< typename Real , unsigned int Dim >
-void WriteGrid( const Real *values , int res , const char *fileName )
-{
- int resolution = 1;
- for( int d=0 ; d
void Execute( int argc , char* argv[] , UIntPack< FEMSigs ... > )
{
@@ -674,7 +673,7 @@ void Execute( int argc , char* argv[] , UIntPack< FEMSigs ... > )
#pragma omp parallel for
for( int i=0 ; i( values , res , Grid.value , Verbose.set ) ) WriteGrid< Real , DIMENSION >( values , res , Grid.value );
+ WriteGrid< Real , DIMENSION >( values , res , Grid.value );
DeletePointer( values );
if( Verbose.set )
{
diff --git a/Src/SparseMatrix.inl b/Src/SparseMatrix.inl
index d912c1d..d7a6d1c 100644
--- a/Src/SparseMatrix.inl
+++ b/Src/SparseMatrix.inl
@@ -598,13 +598,18 @@ template< class T , class IndexType , size_t MaxRowSize >
template< class T2 >
void SparseMatrix< T , IndexType , MaxRowSize >::operator() ( const T2* in , T2* out ) const { Interface::multiply( in , out ); }
-template< class T , class IndexType , size_t MaxRowSize > SparseMatrix< T , IndexType , MaxRowSize >::~SparseMatrix( void ) { resize( 0 ); }
+template< class T , class IndexType , size_t MaxRowSize >
+SparseMatrix< T , IndexType , MaxRowSize >::~SparseMatrix( void )
+{
+ FreePointer( _rowSizes );
+ FreePointer( _entries );
+}
template< class T , class IndexType , size_t MaxRowSize >
void SparseMatrix< T , IndexType , MaxRowSize >::resize( size_t rowNum )
{
_rowNum = rowNum;
- if( !rowNum || rowNum>_maxRows )
+ if( rowNum>_maxRows )
{
FreePointer( _rowSizes );
FreePointer( _entries );