diff --git a/src/osgPlugins/ply/ply.h b/src/osgPlugins/ply/ply.h index 1ae2c6afc..cc9c8f539 100644 --- a/src/osgPlugins/ply/ply.h +++ b/src/osgPlugins/ply/ply.h @@ -33,9 +33,8 @@ WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. #ifndef __PLY_H__ #define __PLY_H__ -#ifdef __cplusplus -extern "C" { -#endif +// include to quieten down silly VS warnings +#include #include #include @@ -69,7 +68,7 @@ extern "C" { typedef struct PlyProperty { /* description of a property */ - char *name; /* property name */ + const char *name; /* property name */ int external_type; /* file's data type */ int internal_type; /* program's data type */ int offset; /* offset bytes of prop in a struct */ @@ -150,7 +149,7 @@ extern PlyFile *ply_read(FILE *, int *, char ***); extern PlyFile *ply_open_for_reading( char *, int *, char ***, int *, float *); extern PlyProperty **ply_get_element_description(PlyFile *, char *, int*, int*); extern void ply_get_element_setup( PlyFile *, char *, int, PlyProperty *); -extern void ply_get_property(PlyFile *, char *, PlyProperty *); +extern void ply_get_property(PlyFile *, const char *, PlyProperty *); extern PlyOtherProp *ply_get_other_properties(PlyFile *, char *, int); extern void ply_get_element(PlyFile *, void *); extern char **ply_get_comments(PlyFile *, int *); @@ -164,9 +163,5 @@ extern void ply_free_other_elements (PlyOtherElems *); extern int equal_strings(const char *, const char *); - -#ifdef __cplusplus -} -#endif #endif /* !__PLY_H__ */ diff --git a/src/osgPlugins/ply/plyfile.cpp b/src/osgPlugins/ply/plyfile.cpp index d1705622d..979cc94fd 100644 --- a/src/osgPlugins/ply/plyfile.cpp +++ b/src/osgPlugins/ply/plyfile.cpp @@ -39,11 +39,19 @@ WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. */ #include "ply.h" +#include"typedefs.h" + #include #include #include #include +#include + +#if defined(_MSC_VER) && defined(OSG_DISABLE_MSVC_WARNINGS) + #pragma warning( disable : 4996 ) +#endif + #ifdef WIN32 # ifndef LITTLE_ENDIAN # define LITTLE_ENDIAN @@ -315,6 +323,8 @@ PlyFile *ply_open_for_writing( /* create the actual PlyFile structure */ plyfile = ply_write (fp, nelems, elem_names, file_type); + + // If the plyfile could not load return NULL if (plyfile == NULL) return (NULL); @@ -353,8 +363,9 @@ void ply_describe_element( /* look for appropriate element */ elem = find_element (plyfile, elem_name); if (elem == NULL) { - fprintf(stderr,"ply_describe_element: can't find element '%s'\n",elem_name); - exit (-1); + char error[100]; + sprintf (error, "ply_describe_element: can't find element '%s'\n",elem_name); + throw ply::MeshException( error ); } elem->num = nelems; @@ -500,8 +511,9 @@ void ply_element_count( /* look for appropriate element */ elem = find_element (plyfile, elem_name); if (elem == NULL) { - fprintf(stderr,"ply_element_count: can't find element '%s'\n",elem_name); - exit (-1); + char error[100]; + sprintf (error, "ply_element_count: can't find element '%s'\n",elem_name); + throw ply::MeshException( error ); } elem->num = nelems; @@ -536,9 +548,10 @@ void ply_header_complete(PlyFile *plyfile) fprintf (fp, "format binary_little_endian 1.0\n"); break; default: - fprintf (stderr, "ply_header_complete: bad file type = %d\n", + char error[100]; + sprintf (error, "ply_header_complete: bad file type = %d\n", plyfile->file_type); - exit (-1); + throw ply::MeshException( error ); } /* write out the comments */ @@ -595,8 +608,9 @@ void ply_put_element_setup(PlyFile *plyfile, const char *elem_name) elem = find_element (plyfile, elem_name); if (elem == NULL) { - fprintf(stderr, "ply_elements_setup: can't find element '%s'\n", elem_name); - exit (-1); + char error[100]; + sprintf (error, "ply_elements_setup: can't find element '%s'\n", elem_name); + throw ply::MeshException( error ); } plyfile->which_elem = elem; @@ -845,7 +859,7 @@ PlyFile *ply_read(FILE *fp, int *nelems, char ***elem_names) free (words); return (NULL); } - plyfile->version = atof (words[2]); + plyfile->version = osg::asciiToDouble (words[2]); } else if (equal_strings (words[0], "element")) add_element (plyfile, words, nwords); @@ -940,6 +954,12 @@ PlyFile *ply_open_for_reading( plyfile = ply_read (fp, nelems, elem_names); + if(!plyfile) + { + std::cout<<"Ply File Error : Could not read file"<file_type; @@ -1059,7 +1079,7 @@ Entry: void ply_get_property( PlyFile *plyfile, - char *elem_name, + const char *elem_name, PlyProperty *prop ) { @@ -1330,9 +1350,9 @@ PlyOtherElems *ply_get_other_element ( /* look for appropriate element */ elem = find_element (plyfile, elem_name); if (elem == NULL) { - fprintf (stderr, - "ply_get_other_element: can't find element '%s'\n", elem_name); - exit (-1); + char error[100]; + sprintf (error, "ply_get_other_element: can't find element '%s'\n", elem_name); + throw ply::MeshException( error ); } /* create room for the new "other" element, initializing the */ @@ -1650,8 +1670,9 @@ void ascii_get_element(PlyFile *plyfile, char *elem_ptr) words = get_words (plyfile->fp, &nwords, &orig_line); if (words == NULL) { - fprintf (stderr, "ply_get_element: unexpected end of file\n"); - exit (-1); + char error[100]; + sprintf (error, "ply_get_element: unexpected end of file\n"); + throw ply::MeshException( error ); } which_word = 0; @@ -1847,8 +1868,9 @@ void write_scalar_type (FILE *fp, int code) /* make sure this is a valid code */ if (code <= PLY_START_TYPE || code >= PLY_END_TYPE) { - fprintf (stderr, "write_scalar_type: bad data code = %d\n", code); - exit (-1); + char error[100]; + sprintf (error, "write_scalar_type: bad data code = %d\n", code); + throw ply::MeshException( error ); } /* write the code to a file */ @@ -2118,8 +2140,9 @@ void write_binary_item(PlyFile *plyfile, fwrite (&double_val, 8, 1, fp); break; default: - fprintf (stderr, "write_binary_item: bad type = %d\n", type); - exit (-1); + char error[100]; + sprintf (error, "write_binary_item: bad type = %d\n", type); + throw ply::MeshException( error ); } } @@ -2162,8 +2185,9 @@ void write_ascii_item( fprintf (fp, "%g ", double_val); break; default: - fprintf (stderr, "write_ascii_item: bad type = %d\n", type); - exit (-1); + char error[100]; + sprintf (error, "write_ascii_item: bad type = %d\n", type); + throw ply::MeshException( error ); } } @@ -2234,8 +2258,9 @@ void get_stored_item( *uint_val = (unsigned int) *double_val; break; default: - fprintf (stderr, "get_stored_item: bad type = %d\n", type); - exit (-1); + char error[100]; + sprintf (error, "get_stored_item: bad type = %d\n", type); + throw ply::MeshException( error ); } } @@ -2266,23 +2291,39 @@ void get_binary_item( void *ptr; ptr = (void *) c; + size_t result = 0; switch (type) { case PLY_CHAR: - fread (ptr, 1, 1, plyfile->fp); + result = fread (ptr, 1, 1, plyfile->fp); + if(result < 1) + { + throw ply::MeshException( "Error in reading PLY file." + "fread not succeeded." ); + } *int_val = *((char *) ptr); *uint_val = *int_val; *double_val = *int_val; break; case PLY_UCHAR: case PLY_UINT8: - fread (ptr, 1, 1, plyfile->fp); + result = fread (ptr, 1, 1, plyfile->fp); + if(result < 1) + { + throw ply::MeshException( "Error in reading PLY file." + "fread not succeeded." ); + } *uint_val = *((unsigned char *) ptr); *int_val = *uint_val; *double_val = *uint_val; break; case PLY_SHORT: - fread (ptr, 2, 1, plyfile->fp); + result = fread (ptr, 2, 1, plyfile->fp); + if(result < 1 ) + { + throw ply::MeshException( "Error in reading PLY file." + "fread not succeeded." ); + } if( plyfile->file_type == PLY_BINARY_BE ) { swap2BE(ptr); @@ -2296,7 +2337,12 @@ void get_binary_item( *double_val = *int_val; break; case PLY_USHORT: - fread (ptr, 2, 1, plyfile->fp); + result = fread (ptr, 2, 1, plyfile->fp); + if(result < 1) + { + throw ply::MeshException( "Error in reading PLY file." + "fread not succeeded." ); + } if( plyfile->file_type == PLY_BINARY_BE ) { swap2BE(ptr); @@ -2311,7 +2357,12 @@ void get_binary_item( break; case PLY_INT: case PLY_INT32: - fread (ptr, 4, 1, plyfile->fp); + result = fread (ptr, 4, 1, plyfile->fp); + if(result < 1) + { + throw ply::MeshException( "Error in reading PLY file." + "fread not succeeded." ); + } if( plyfile->file_type == PLY_BINARY_BE ) { swap4BE(ptr); @@ -2325,7 +2376,12 @@ void get_binary_item( *double_val = *int_val; break; case PLY_UINT: - fread (ptr, 4, 1, plyfile->fp); + result = fread (ptr, 4, 1, plyfile->fp); + if(result < 1) + { + throw ply::MeshException( "Error in reading PLY file." + "fread not succeeded." ); + } if( plyfile->file_type == PLY_BINARY_BE ) { swap4BE(ptr); @@ -2340,7 +2396,12 @@ void get_binary_item( break; case PLY_FLOAT: case PLY_FLOAT32: - fread (ptr, 4, 1, plyfile->fp); + result = fread (ptr, 4, 1, plyfile->fp); + if(result < 1) + { + throw ply::MeshException( "Error in reading PLY file." + "fread not succeeded." ); + } if( plyfile->file_type == PLY_BINARY_BE ) { swap4BE(ptr); @@ -2354,22 +2415,28 @@ void get_binary_item( *uint_val = (unsigned int) *double_val; break; case PLY_DOUBLE: - fread (ptr, 8, 1, plyfile->fp); - if( plyfile->file_type == PLY_BINARY_BE ) - { - swap8BE(ptr); - } - else - { - swap8LE(ptr); - } - *double_val = *((double *) ptr); - *int_val = (int) *double_val; - *uint_val = (unsigned int) *double_val; - break; + result = fread (ptr, 8, 1, plyfile->fp); + if(result < 1) + { + throw ply::MeshException( "Error in reading PLY file." + "fread not succeeded." ); + } + if( plyfile->file_type == PLY_BINARY_BE ) + { + swap8BE(ptr); + } + else + { + swap8LE(ptr); + } + *double_val = *((double *) ptr); + *int_val = (int) *double_val; + *uint_val = (unsigned int) *double_val; + break; default: - fprintf (stderr, "get_binary_item: bad type = %d\n", type); - exit (-1); + char error[100]; + sprintf (error, "get_binary_item: bad type = %d\n", type); + throw ply::MeshException( error ); } } @@ -2418,14 +2485,15 @@ void get_ascii_item( case PLY_FLOAT: case PLY_FLOAT32: case PLY_DOUBLE: - *double_val = atof (word); + *double_val = osg::asciiToDouble(word); *int_val = (int) *double_val; *uint_val = (unsigned int) *double_val; break; default: - fprintf (stderr, "get_ascii_item: bad type = %d\n", type); - exit (-1); + char error[100]; + sprintf (error, "get_ascii_item: bad type = %d\n", type); + throw ply::MeshException( error ); } } @@ -2496,8 +2564,9 @@ void store_item ( *pdouble = double_val; break; default: - fprintf (stderr, "store_item: bad type = %d\n", type); - exit (-1); + char error[100]; + sprintf (error, "store_item: bad type = %d\n", type); + throw ply::MeshException( error ); } } diff --git a/src/osgPlugins/ply/typedefs.h b/src/osgPlugins/ply/typedefs.h index b5c01b236..abf27d8b3 100644 --- a/src/osgPlugins/ply/typedefs.h +++ b/src/osgPlugins/ply/typedefs.h @@ -12,19 +12,25 @@ #ifndef MESH_TYPEDEFS_H #define MESH_TYPEDEFS_H -# ifdef WIN32 +# if defined(_MSC_VER) # include # include # endif # include -# include -# define MESHASSERT assert + +#ifdef NDEBUG +# define MESHASSERT( x ) +#else +# define MESHASSERT(x) { if( !(x) ) \ + osg::notify(osg::WARN) << "Ply Loader ##### Assert: " << #x << " #####" << std::endl; } +#endif + # define MESHERROR osg::notify(osg::WARN) # define MESHWARN osg::notify(osg::WARN) # define MESHINFO osg::notify(osg::INFO) -#ifdef WIN32 +#if defined(_MSC_VER) typedef int socklen_t; typedef UINT64 uint64_t; @@ -37,7 +43,7 @@ typedef UINT8 uint8_t; typedef SSIZE_T ssize_t; # endif -#endif // Win32 +#endif // defined(_MSC_VER) #include #include diff --git a/src/osgPlugins/ply/vertexData.cpp b/src/osgPlugins/ply/vertexData.cpp index 66ae3d302..13ad93b64 100644 --- a/src/osgPlugins/ply/vertexData.cpp +++ b/src/osgPlugins/ply/vertexData.cpp @@ -9,9 +9,9 @@ /** note, derived from Equalizer LGPL source.*/ #include "typedefs.h" - #include "vertexData.h" #include "ply.h" + #include #include #include @@ -126,8 +126,8 @@ void VertexData::readTriangles( PlyFile* file, const int nFaces ) // read in the faces, asserting that they are only triangles - uint8_t ind1 = _invertFaces ? 2 : 0; - uint8_t ind3 = _invertFaces ? 0 : 2; + int ind1 = _invertFaces ? 2 : 0; + int ind3 = _invertFaces ? 0 : 2; for( int i = 0; i < nFaces; ++i ) { ply_get_element( file, static_cast< void* >( &face ) ); @@ -157,12 +157,23 @@ osg::Node* VertexData::readPlyFile( const char* filename, const bool ignoreColor int fileType; float version; bool result = false; - int nComments; - char** comments; + int nComments; + char** comments; - PlyFile* file = ply_open_for_reading( const_cast< char* >( filename ), + PlyFile* file = NULL; + + // Try to open ply file as for reading + try{ + file = ply_open_for_reading( const_cast< char* >( filename ), &nPlyElems, &elemNames, &fileType, &version ); + } + // Catch the if any exception thrown + catch( exception& e ) + { + MESHERROR << "Unable to read PLY file, an exception occured: " + << e.what() << endl; + } if( !file ) { @@ -172,6 +183,7 @@ osg::Node* VertexData::readPlyFile( const char* filename, const bool ignoreColor } MESHASSERT( elemNames != 0 ); + nComments = file->num_comments; comments = file->comments; @@ -195,8 +207,16 @@ osg::Node* VertexData::readPlyFile( const char* filename, const bool ignoreColor int nElems; int nProps; - PlyProperty** props = ply_get_element_description( file, elemNames[i], - &nElems, &nProps ); + PlyProperty** props = NULL; + try{ + props = ply_get_element_description( file, elemNames[i], + &nElems, &nProps ); + } + catch( exception& e ) + { + MESHERROR << "Unable to get PLY file description, an exception occured: " + << e.what() << endl; + } MESHASSERT( props != 0 ); #ifndef NDEBUG @@ -221,14 +241,29 @@ osg::Node* VertexData::readPlyFile( const char* filename, const bool ignoreColor if( ignoreColors ) MESHINFO << "Colors in PLY file ignored per request." << endl; - - // Read vertices and store in a std::vector array - readVertices( file, nElems, hasColors && !ignoreColors ); - // Check whether all vertices are loaded or not - MESHASSERT( _vertices->size() == static_cast< size_t >( nElems ) ); - // Check all color elements read or not - if( hasColors && !ignoreColors ) - MESHASSERT( _colors->size() == static_cast< size_t >( nElems ) ); + + try { + // Read vertices and store in a std::vector array + readVertices( file, nElems, hasColors && !ignoreColors ); + // Check whether all vertices are loaded or not + MESHASSERT( _vertices->size() == static_cast< size_t >( nElems ) ); + // Check all color elements read or not + if( hasColors && !ignoreColors ) + { + MESHASSERT( _colors->size() == static_cast< size_t >( nElems ) ); + } + + result = true; + } + catch( exception& e ) + { + MESHERROR << "Unable to read vertex in PLY file, an exception occured: " + << e.what() << endl; + // stop for loop by setting the loop variable to break condition + // this way resources still get released even on error cases + i = nPlyElems; + + } } // If the string is face means triangle info started else if( equal_strings( elemNames[i], "face" ) ) @@ -272,16 +307,21 @@ osg::Node* VertexData::readPlyFile( const char* filename, const bool ignoreColor geom->setVertexArray(_vertices.get()); // If the normals are not calculated calculate the normals for faces - if(!_normals.valid()) - _calculateNormals(); + if(_triangles.valid()) + { + if(!_normals.valid()) + _calculateNormals(); - - // set the normals - geom->setNormalArray(_normals.get()); - geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); + // set the normals + geom->setNormalArray(_normals.get()); + geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); + } // Add the premetive set - geom->addPrimitiveSet(_triangles.get()); + if (_triangles.valid() && _triangles->size() > 0 ) + geom->addPrimitiveSet(_triangles.get()); + else + geom->addPrimitiveSet(new osg::DrawArrays(GL_POINTS, 0, _vertices->size())); // if color info is given set the color array if(_colors.valid()) diff --git a/src/osgPlugins/ply/vertexData.h b/src/osgPlugins/ply/vertexData.h index 173ecefd6..a02c6c97f 100644 --- a/src/osgPlugins/ply/vertexData.h +++ b/src/osgPlugins/ply/vertexData.h @@ -26,7 +26,7 @@ /////////////////////////////////////////////////////////////////////////////// // defined elsewhere -class PlyFile; +struct PlyFile; namespace ply {