Catch exception when failing to write image.

Output transformation when writing grid.
This commit is contained in:
mkazhdan
2019-01-27 18:16:08 -05:00
parent f4f47883db
commit 3107d150fb
6 changed files with 83 additions and 59 deletions
+17 -17
View File
@@ -91,10 +91,10 @@ The file is written in <a href="http://www.cc.gatech.edu/projects/large_models/p
</dd><dt>[<b>--tree</b> &lt;<i>output octree and coefficients</i>&gt;]
</dt><dd> This string is the name of the file to which the the octree and solution coefficients are to be written.
</dd><dt>[<b>--voxel</b> &lt;<i>output voxel grid</i>&gt;]
</dd><dt>[<b>--grid</b> &lt;<i>output grid</i>&gt;]
</dt><dd> This string is the name of the file to which the sampled implicit function will be written.
The file is written out in binary, with the first 4 bytes corresponding to the (integer) sampling resolution, 2^<i>d</i>,
and the next 4 x 2^<i>d</i> x 2^<i>d</i> x 2^<i>d</i> bytes corresponding to the (single precision) floating point values
and the next 4 x 2^<i>d</i> x 2^<i>d</i> x ... bytes corresponding to the (single precision) floating point values
of the implicit function.
</dd><dt>[<b>--degree</b> &lt;<i>B-spline degree</i>&gt;]
@@ -113,8 +113,8 @@ The default value for this parameter is 3 (Neumann).
</dd><dt>[<b>--depth</b> &lt;<i>reconstruction depth</i>&gt;]
</dt><dd> This integer is the maximum depth of the tree that will be used for surface reconstruction.
Running at depth <i>d</i> corresponds to solving on a voxel grid whose resolution is no larger than
2^<i>d</i> x 2^<i>d</i> x 2^<i>d</i>. Note that since the reconstructor adapts the octree to the
Running at depth <i>d</i> corresponds to solving on a grid whose resolution is no larger than
2^<i>d</i> x 2^<i>d</i> x ... Note that since the reconstructor adapts the octree to the
sampling density, the specified reconstruction depth is only an upper bound.<br>
The default value for this parameter is 8.
@@ -166,8 +166,8 @@ The default value for this parameter is 0.
</dt><dd> This floating point value specifies the exponent to be applied to a point's confidence to bias the resolution at which the sample contributes to the linear system. (Points with lower confidence are biased to contribute at coarser resolutions.)<BR>
The default value for this parameter is 0.
</dd><dt>[<b>--primalVoxel</b>]
</dt><dd> Enabling this flag when outputing to a voxel file has the reconstructor sample the implicit function at the corners of the grid, rather than the centers of the cells.
</dd><dt>[<b>--primalGrid</b>]
</dt><dd> Enabling this flag when outputing to a grid file has the reconstructor sample the implicit function at the corners of the grid, rather than the centers of the cells.
</dd><dt>[<b>--linearFit</b>]
</dt><dd> Enabling this flag has the reconstructor use linear interpolation to estimate the positions of iso-vertices.
@@ -225,10 +225,10 @@ The file is written in <a href="http://www.cc.gatech.edu/projects/large_models/p
</dd><dt>[<b>--tree</b> &lt;<i>output octree and coefficients</i>&gt;]
</dt><dd> This string is the name of the file to which the the octree and solution coefficients are to be written.
</dd><dt>[<b>--voxel</b> &lt;<i>output voxel grid</i>&gt;]
</dd><dt>[<b>--grid</b> &lt;<i>output grid</i>&gt;]
</dt><dd> This string is the name of the file to which the sampled implicit function will be written.
The file is wrtten out in binary, with the first 4 bytes corresponding to the (integer) sampling resolution, 2^<i>d</i>,
and the next 4 x 2^<i>d</i> x 2^<i>d</i> x 2^<i>d</i> bytes corresponding to the (single precision) floating point values
and the next 4 x 2^<i>d</i> x 2^<i>d</i> x ... bytes corresponding to the (single precision) floating point values
of the implicit function.
</dd><dt>[<b>--degree</b> &lt;<i>B-spline degree</i>&gt;]
@@ -238,8 +238,8 @@ The default value for this parameter is 2.
</dd><dt>[<b>--depth</b> &lt;<i>reconstruction depth</i>&gt;]
</dt><dd> This integer is the maximum depth of the tree that will be used for surface reconstruction.
Running at depth <i>d</i> corresponds to solving on a voxel grid whose resolution is no larger than
2^<i>d</i> x 2^<i>d</i> x 2^<i>d</i>. Note that since the reconstructor adapts the octree to the
Running at depth <i>d</i> corresponds to solving on a grid whose resolution is no larger than
2^<i>d</i> x 2^<i>d</i> x ... Note that since the reconstructor adapts the octree to the
sampling density, the specified reconstruction depth is only an upper bound.<br>
The default value for this parameter is 8.
@@ -300,8 +300,8 @@ The default value for this parameter is 0.
</dt><dd> This floating point value specifies the exponent to be applied to a point's confidence to bias the resolution at which the sample contributes to the linear system. (Points with lower confidence are biased to contribute at coarser resolutions.)<BR>
The default value for this parameter is 0.
</dd><dt>[<b>--primalVoxel</b>]
</dt><dd> Enabling this flag when outputing to a voxel file has the reconstructor sample the implicit function at the corners of the grid, rather than the centers of the cells.
</dd><dt>[<b>--primalGrid</b>]
</dt><dd> Enabling this flag when outputing to a grid file has the reconstructor sample the implicit function at the corners of the grid, rather than the centers of the cells.
</dd><dt>[<b>--nonLinearFit</b>]
</dt><dd> Enabling this flag has the reconstructor use quadratic interpolation to estimate the positions of iso-vertices.
@@ -444,8 +444,8 @@ The default value for this parameter is 1.
</dd><dt>[<b>--depth</b> &lt;<i>edt depth</i>&gt;]
</dt><dd> This integer is the maximum depth of the tree that will be used for computing the Euclidean Distance Transform.
Running at depth <i>d</i> corresponds to solving on a voxel grid whose resolution is no larger than
2^<i>d</i> x 2^<i>d</i> x 2^<i>d</i>.<br>
Running at depth <i>d</i> corresponds to solving on a grid whose resolution is no larger than
2^<i>d</i> x 2^<i>d</i> x ...<br>
The default value for this parameter is 8.
</dd><dt>[<b>--scale</b> &lt;<i>scale factor</i>&gt;]
@@ -503,7 +503,7 @@ Extracts iso-surfaces and a sampling on a regular grid from an implicit function
</dt><dd> This string is the name of the file from which the tree and implicit functions coefficients are to be read.
</dd><dt>[<b>--grid</b> &lt;<i>output value grid</i>&gt;]
</dt><dd> This string is the name of the file to which the sampling of the implicit along a regular voxel grid will be written.<BR>
</dt><dd> This string is the name of the file to which the sampling of the implicit along a regular grid will be written.<BR>
The file is written out in binary, with the first 4 bytes corresponding to the (integer) sampling resolution, <i>R</i>,
and the next 4 x <I>R</I>^<i>D</i> bytes corresponding to the (single precision) floating point values of the implicit function. (Here, <i>D</I> is the dimension.)
@@ -742,8 +742,8 @@ To obtain a sampling of the implicit function over a regular grid:
(Note that as the B-spline degree is a template parameter, only degree 1 through 4 are supported.
If higher order degrees are desired, additional template parameters can be easily added in the body of the <u>Execute</u> function inside of <i>PoissonRecon.cpp</i>.
Similarly, to reduce compilation times, support for specific degrees can be removed.)
</li><li> Added the <b>--primalVoxel</b> flag to support to extraction of a voxel grid using primal sampling.
</li><li> Changed the implementation of the voxel sampling so that computation is now linear, rather than log-linear, in the number of samples.
</li><li> Added the <b>--primalGrid</b> flag to support to extraction of a grid using primal sampling.
</li><li> Changed the implementation of the grid sampling so that computation is now linear, rather than log-linear, in the number of samples.
</li></ol>
<a href="http://www.cs.jhu.edu/~misha/Code/PoissonRecon/Version9.0/">Version 9.0</a>:
+4 -5
View File
@@ -118,7 +118,9 @@ bool WriteImage( const Real *values , int res , const char *fileName , bool verb
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;
}
bool success = ImageWriter::Write( fileName , pixels , res , res , 3 );
bool success = true;
try{ ImageWriter::Write( fileName , pixels , res , res , 3 ); }
catch( MKExceptions::Exception & ){ success = false; }
delete[] pixels;
return success;
}
@@ -129,9 +131,8 @@ void WriteGrid( const Real *values , int res , const char *fileName )
int resolution = 1;
for( int d=0 ; d<Dim ; d++ ) resolution *= res;
char *ext = GetFileExtension( fileName );
FILE *fp = fopen( fileName , "wb" );
if( !fp ) ERROR_OUT( "Failed to open voxel file for writing: %s" , fileName );
if( !fp ) ERROR_OUT( "Failed to open grid file for writing: %s" , fileName );
else
{
fwrite( &res , sizeof(int) , 1 , fp );
@@ -144,9 +145,7 @@ void WriteGrid( const Real *values , int res , const char *fileName )
delete[] fValues;
}
fclose( fp );
DeletePointer( values );
}
delete[] ext;
}
template< unsigned int Dim , class Real , unsigned int FEMSig >
+11 -4
View File
@@ -64,13 +64,11 @@ struct ImageWriter
{
virtual unsigned int nextRow( const unsigned char* row ) = 0;
virtual unsigned int nextRows( const unsigned char* rows , unsigned int rowNum ){ unsigned int row ; for( unsigned int r=0 ; r<rowNum ; r++ ) row = nextRow( rows + _width * _channels * r ) ; return row; }
static bool Write( const char* fileName , const unsigned char* pixels , unsigned int width , unsigned int height , unsigned int channels , ImageWriterParams params=ImageWriterParams() )
static void Write( const char* fileName , const unsigned char* pixels , unsigned int width , unsigned int height , unsigned int channels , ImageWriterParams params=ImageWriterParams() )
{
ImageWriter* writer = Get( fileName , width , height , channels , params );
if( !writer ) return false;
for( unsigned int j=0 ; j<height ; j++ ) writer->nextRow( pixels + j*width*channels );
delete writer;
return true;
}
static ImageWriter* Get( const char* fileName , unsigned int width , unsigned int height , unsigned int channels , ImageWriterParams params=ImageWriterParams() );
virtual ~ImageWriter( void ){ }
@@ -176,6 +174,11 @@ inline ImageReader* ImageReader::Get( const char* fileName )
else if( !strcasecmp( ext , "png" ) ) reader = new PNGReader( fileName , width , height , channels );
else if( !strcasecmp( ext , "iGrid" ) ) reader = new TiledImageReader( fileName , width , height , channels );
#endif // WIN32
else
{
delete[] ext;
THROW( "failed to get image reader for: %s" , fileName );
}
reader->_width = width;
reader->_height = height;
reader->_channels = channels;
@@ -214,7 +217,11 @@ inline ImageWriter* ImageWriter::Get( const char* fileName , unsigned int width
else if( !strcasecmp( ext , "iGrid" ) ) writer = new TiledImageWriter( fileName , width , height , channels , params );
#endif // SUPPORT_TILES
#endif // WIN32
else ERROR_OUT( "Unrecognized file extension: %s" , ext );
else
{
delete[] ext;
THROW( "failed to get image writer for: %s" , fileName );
}
writer->_width = width;
writer->_height = height;
writer->_channels = channels;
+1 -1
View File
@@ -139,7 +139,7 @@ struct RGBPixel
void WriteImage( char* fileName , RGBPixel* pixels , int w , int h )
{
unsigned int _w = w , _h = h , _c = 3;
if( !ImageWriter::Write( fileName , (const unsigned char*)pixels , _w , _h , _c ) ) ERROR_OUT( "Could not write image to: %s" , fileName );
ImageWriter::Write( fileName , (const unsigned char*)pixels , _w , _h , _c );
}
struct Profiler
+25 -16
View File
@@ -58,7 +58,7 @@ cmdLineParameter< char* >
In( "in" ) ,
Out( "out" ) ,
TempDir( "tempDir" ) ,
VoxelGrid( "voxel" ) ,
Grid( "grid" ) ,
Tree( "tree" ) ,
Transform( "xForm" );
@@ -71,7 +71,7 @@ cmdLineReadable
ASCII( "ascii" ) ,
Density( "density" ) ,
LinearFit( "linearFit" ) ,
PrimalVoxel( "primalVoxel" ) ,
PrimalGrid( "primalGrid" ) ,
ExactInterpolation( "exact" ) ,
Normals( "normals" ) ,
Colors( "colors" ) ,
@@ -116,7 +116,7 @@ cmdLineReadable* params[] =
&ConfidenceBias ,
&BaseDepth , &BaseVCycles ,
&PointWeight ,
&VoxelGrid , &Threads ,
&Grid , &Threads ,
&Tree ,
&Density ,
&FullDepth ,
@@ -125,7 +125,7 @@ cmdLineReadable* params[] =
&Colors ,
&Normals ,
&LinearFit ,
&PrimalVoxel ,
&PrimalGrid ,
&TempDir ,
&ExactInterpolation ,
&Performance ,
@@ -139,7 +139,7 @@ void ShowUsage(char* ex)
printf( "Usage: %s\n" , ex );
printf( "\t --%s <input points>\n" , In.name );
printf( "\t[--%s <ouput triangle mesh>]\n" , Out.name );
printf( "\t[--%s <ouput voxel grid>]\n" , VoxelGrid.name );
printf( "\t[--%s <ouput grid>]\n" , Grid.name );
printf( "\t[--%s <ouput fem tree>]\n" , Tree.name );
#ifndef FAST_COMPILE
printf( "\t[--%s <b-spline degree>=%d]\n" , Degree.name , Degree.value );
@@ -147,7 +147,7 @@ void ShowUsage(char* ex)
for( int i=0 ; i<BOUNDARY_COUNT ; i++ ) printf( "\t\t%d] %s\n" , i+1 , BoundaryNames[i] );
#endif // !FAST_COMPILE
printf( "\t[--%s <maximum reconstruction depth>=%d]\n" , Depth.name , Depth.value );
printf( "\t[--%s <voxel width>]\n" , Width.name );
printf( "\t[--%s <grid width>]\n" , Width.name );
printf( "\t[--%s <full depth>=%d]\n" , FullDepth.name , FullDepth.value );
printf( "\t[--%s <coarse MG solver depth>=%d]\n" , BaseDepth.name , BaseDepth.value );
printf( "\t[--%s <coarse MG solver v-cycles>=%d]\n" , BaseVCycles.name , BaseVCycles.value );
@@ -171,7 +171,7 @@ void ShowUsage(char* ex)
printf( "\t[--%s]\n" , Performance.name );
printf( "\t[--%s]\n" , Density.name );
printf( "\t[--%s]\n" , LinearFit.name );
printf( "\t[--%s]\n" , PrimalVoxel.name );
printf( "\t[--%s]\n" , PrimalGrid.name );
printf( "\t[--%s]\n" , ASCII.name );
printf( "\t[--%s]\n" , NoComments.name );
printf( "\t[--%s]\n" , TempDir.name );
@@ -380,7 +380,9 @@ bool WriteImage( const Real *values , int res , const char *fileName , bool verb
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;
}
bool success = ImageWriter::Write( fileName , pixels , res , res , 3 );
bool success = true;
try{ ImageWriter::Write( fileName , pixels , res , res , 3 ); }
catch( MKExceptions::Exception & ){ success = false; }
delete[] pixels;
return success;
}
@@ -391,9 +393,8 @@ void WriteGrid( const Real *values , int res , const char *fileName )
int resolution = 1;
for( int d=0 ; d<Dim ; d++ ) resolution *= res;
char *ext = GetFileExtension( fileName );
FILE *fp = fopen( fileName , "wb" );
if( !fp ) ERROR_OUT( "Failed to open voxel file for writing: %s" , fileName );
if( !fp ) ERROR_OUT( "Failed to open grid file for writing: %s" , fileName );
else
{
fwrite( &res , sizeof(int) , 1 , fp );
@@ -406,9 +407,7 @@ void WriteGrid( const Real *values , int res , const char *fileName )
delete[] fValues;
}
fclose( fp );
DeletePointer( values );
}
delete[] ext;
}
template< class Real , typename ... SampleData , unsigned int ... FEMSigs >
@@ -660,18 +659,28 @@ void Execute( int argc , char* argv[] , UIntPack< FEMSigs ... > )
fclose( fp );
}
if( VoxelGrid.set )
if( Grid.set )
{
int res = 0;
profiler.start();
Pointer( Real ) values = tree.template regularGridEvaluate< true >( solution , res , -1 , PrimalVoxel.set );
Pointer( Real ) values = tree.template regularGridEvaluate< true >( solution , res , -1 , PrimalGrid.set );
int resolution = 1;
for( int d=0 ; d<Dim ; d++ ) resolution *= res;
#pragma omp parallel for
for( int i=0 ; i<resolution ; i++ ) values[i] -= isoValue;
profiler.dumpOutput( "Got voxel grid:" );
if( !WriteImage< Real , DIMENSION >( values , res , VoxelGrid.value , Verbose.set ) ) WriteGrid< Real , DIMENSION >( values , res , VoxelGrid.value );
profiler.dumpOutput( "Got grid:" );
if( !WriteImage< Real , DIMENSION >( values , res , Grid.value , Verbose.set ) ) WriteGrid< Real , DIMENSION >( values , res , Grid.value );
DeletePointer( values );
if( Verbose.set )
{
printf( "Transform:\n" );
for( int i=0 ; i<Dim+1 ; i++ )
{
printf( "\t" );
for( int j=0 ; j<Dim+1 ; j++ ) printf( " %f" , iXForm(j,i) );
printf( "\n" );
}
}
}
if( Out.set )
+25 -16
View File
@@ -58,7 +58,7 @@ cmdLineParameter< char* >
In( "in" ) ,
Out( "out" ) ,
TempDir( "tempDir" ) ,
VoxelGrid( "voxel" ) ,
Grid( "grid" ) ,
Tree( "tree" ) ,
Transform( "xForm" );
@@ -71,7 +71,7 @@ cmdLineReadable
ASCII( "ascii" ) ,
Density( "density" ) ,
NonLinearFit( "nonLinearFit" ) ,
PrimalVoxel( "primalVoxel" ) ,
PrimalGrid( "primalGrid" ) ,
ExactInterpolation( "exact" ) ,
Normals( "normals" ) ,
Colors( "colors" ) ,
@@ -118,7 +118,7 @@ cmdLineReadable* params[] =
&KernelDepth , &SamplesPerNode , &Confidence , &NonManifold , &PolygonMesh , &ASCII , &ShowResidual ,
&ConfidenceBias ,
&ValueWeight , &GradientWeight , &BiLapWeight ,
&VoxelGrid , &Threads ,
&Grid , &Threads ,
&Tree ,
&Density ,
&FullDepth ,
@@ -128,7 +128,7 @@ cmdLineReadable* params[] =
&Colors ,
&Normals ,
&NonLinearFit ,
&PrimalVoxel ,
&PrimalGrid ,
&TempDir ,
&ExactInterpolation ,
&Performance ,
@@ -142,7 +142,7 @@ void ShowUsage(char* ex)
printf( "Usage: %s\n" , ex );
printf( "\t --%s <input points>\n" , In.name );
printf( "\t[--%s <ouput triangle mesh>]\n" , Out.name );
printf( "\t[--%s <ouput voxel grid>]\n" , VoxelGrid.name );
printf( "\t[--%s <ouput grid>]\n" , Grid.name );
printf( "\t[--%s <ouput fem tree>]\n" , Tree.name );
#ifndef FAST_COMPILE
printf( "\t[--%s <b-spline degree>=%d]\n" , Degree.name , Degree.value );
@@ -150,7 +150,7 @@ void ShowUsage(char* ex)
for( int i=0 ; i<BOUNDARY_COUNT ; i++ ) printf( "\t\t%d] %s\n" , i+1 , BoundaryNames[i] );
#endif // !FAST_COMPILE
printf( "\t[--%s <maximum reconstruction depth>=%d]\n" , Depth.name , Depth.value );
printf( "\t[--%s <voxel width>]\n" , Width.name );
printf( "\t[--%s <grid width>]\n" , Width.name );
printf( "\t[--%s <full depth>=%d]\n" , FullDepth.name , FullDepth.value );
printf( "\t[--%s <coarse MG solver depth>=%d]\n" , BaseDepth.name , BaseDepth.value );
printf( "\t[--%s <coarse MG solver v-cycles>=%d]\n" , BaseVCycles.name , BaseVCycles.value );
@@ -176,7 +176,7 @@ void ShowUsage(char* ex)
printf( "\t[--%s]\n" , Performance.name );
printf( "\t[--%s]\n" , Density.name );
printf( "\t[--%s]\n" , NonLinearFit.name );
printf( "\t[--%s]\n" , PrimalVoxel.name );
printf( "\t[--%s]\n" , PrimalGrid.name );
printf( "\t[--%s]\n" , ASCII.name );
printf( "\t[--%s]\n" , NoComments.name );
printf( "\t[--%s]\n" , TempDir.name );
@@ -404,7 +404,9 @@ bool WriteImage( const Real *values , int res , const char *fileName , bool verb
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;
}
bool success = ImageWriter::Write( fileName , pixels , res , res , 3 );
bool success = true;
try{ ImageWriter::Write( fileName , pixels , res , res , 3 ); }
catch( MKExceptions::Exception & ){ success = false; }
delete[] pixels;
return success;
}
@@ -415,9 +417,8 @@ void WriteGrid( const Real *values , int res , const char *fileName )
int resolution = 1;
for( int d=0 ; d<Dim ; d++ ) resolution *= res;
char *ext = GetFileExtension( fileName );
FILE *fp = fopen( fileName , "wb" );
if( !fp ) ERROR_OUT( "Failed to open voxel file for writing: %s" , fileName );
if( !fp ) ERROR_OUT( "Failed to open grid file for writing: %s" , fileName );
else
{
fwrite( &res , sizeof(int) , 1 , fp );
@@ -430,9 +431,7 @@ void WriteGrid( const Real *values , int res , const char *fileName )
delete[] fValues;
}
fclose( fp );
DeletePointer( values );
}
delete[] ext;
}
template< class Real , typename ... SampleData , unsigned int ... FEMSigs >
@@ -665,18 +664,28 @@ void Execute( int argc , char* argv[] , UIntPack< FEMSigs ... > )
fclose( fp );
}
if( VoxelGrid.set )
if( Grid.set )
{
int res = 0;
profiler.start();
Pointer( Real ) values = tree.template regularGridEvaluate< true >( solution , res , -1 , PrimalVoxel.set );
Pointer( Real ) values = tree.template regularGridEvaluate< true >( solution , res , -1 , PrimalGrid.set );
int resolution = 1;
for( int d=0 ; d<Dim ; d++ ) resolution *= res;
#pragma omp parallel for
for( int i=0 ; i<resolution ; i++ ) values[i] -= isoValue;
profiler.dumpOutput( "Got voxel grid:" );
if( !WriteImage< Real , DIMENSION >( values , res , VoxelGrid.value , Verbose.set ) ) WriteGrid< Real , DIMENSION >( values , res , VoxelGrid.value );
profiler.dumpOutput( "Got grid:" );
if( !WriteImage< Real , DIMENSION >( values , res , Grid.value , Verbose.set ) ) WriteGrid< Real , DIMENSION >( values , res , Grid.value );
DeletePointer( values );
if( Verbose.set )
{
printf( "Transform:\n" );
for( int i=0 ; i<Dim+1 ; i++ )
{
printf( "\t" );
for( int j=0 ; j<Dim+1 ; j++ ) printf( " %f" , iXForm(j,i) );
printf( "\n" );
}
}
}
if( Out.set )