Show
Ignore:
Timestamp:
01/20/11 13:23:04 (3 years ago)
Author:
robert
Message:

From Simon Julier, "I have been using the ply plugin to read files created by bundler and pmvs2 (http://grail.cs.washington.edu/software/pmvs/). This program generates models in the form of vertices only. However, the existing ply reader implementation was not able to handle the models generated in a satisfactory manner for two reasons:

1. It did not support normals applied to individual vertices.
2. It would only support red / green / blue colour triples, but the pmvs models are generated with diffuse colours. (The PLY format, http://local.wasp.uwa.edu.au/~pbourke/dataformats/ply/, lists specular and ambient colour forms as well.)

To partially overcome these limitations, please find attached modified versions of

src/osgPlugins/ply/vertexData.cpp
src/osgPlugins/ply/vertexData.h

The changes I've made are:

1. I have changed the boolean hasColor flag to a vertexField (which is a boolean operation on an enum) to indicate what fields are present in the ply file. (This is required because Turk's ply reader spits out warnings for every line where you try to read fields which do not exist.)
2. I have modified the code to apply valid normals to either triangles or vertices.
3. I have kludged in "support" for the various colour variants. Specifically, all the colour specified can be read from the file. However, they are all applied in the same way (namely as a colour array, bound to each vertex)."

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/src/osgPlugins/ply/vertexData.cpp

    r11237 r12104  
    4646    _normals = NULL; 
    4747    _triangles = NULL; 
    48      
     48    _diffuse = NULL; 
     49    _ambient = NULL; 
     50    _specular = NULL; 
    4951} 
    5052 
     
    5254/*  Read the vertex and (if available/wanted) color data from the open file.  */ 
    5355void VertexData::readVertices( PlyFile* file, const int nVertices,  
    54                                const bool readColors ) 
     56                               const int fields ) 
    5557{ 
    5658    // temporary vertex structure for ply loading 
     
    6062        float           y; 
    6163        float           z; 
    62         unsigned char   r; 
    63         unsigned char   g; 
    64         unsigned char   b; 
     64        float           nx; 
     65        float           ny; 
     66        float           nz; 
     67        unsigned char   red; 
     68        unsigned char   green; 
     69        unsigned char   blue; 
     70        unsigned char   ambient_red; 
     71        unsigned char   ambient_green; 
     72        unsigned char   ambient_blue; 
     73        unsigned char   diffuse_red; 
     74        unsigned char   diffuse_green; 
     75        unsigned char   diffuse_blue; 
     76        unsigned char   specular_red; 
     77        unsigned char   specular_green; 
     78        unsigned char   specular_blue; 
     79        float           specular_coeff; 
     80        float           specular_power; 
    6581    } vertex; 
    6682 
     
    7086        { "y", PLY_FLOAT, PLY_FLOAT, offsetof( _Vertex, y ), 0, 0, 0, 0 }, 
    7187        { "z", PLY_FLOAT, PLY_FLOAT, offsetof( _Vertex, z ), 0, 0, 0, 0 }, 
    72         { "red", PLY_UCHAR, PLY_UCHAR, offsetof( _Vertex, r ), 0, 0, 0, 0 }, 
    73         { "green", PLY_UCHAR, PLY_UCHAR, offsetof( _Vertex, g ), 0, 0, 0, 0 }, 
    74         { "blue", PLY_UCHAR, PLY_UCHAR, offsetof( _Vertex, b ), 0, 0, 0, 0 } 
     88        { "nx", PLY_FLOAT, PLY_FLOAT, offsetof( _Vertex, nx ), 0, 0, 0, 0 }, 
     89        { "ny", PLY_FLOAT, PLY_FLOAT, offsetof( _Vertex, ny ), 0, 0, 0, 0 }, 
     90        { "nz", PLY_FLOAT, PLY_FLOAT, offsetof( _Vertex, nz ), 0, 0, 0, 0 }, 
     91        { "red", PLY_UCHAR, PLY_UCHAR, offsetof( _Vertex, red ), 0, 0, 0, 0 }, 
     92        { "green", PLY_UCHAR, PLY_UCHAR, offsetof( _Vertex, green ), 0, 0, 0, 0 }, 
     93        { "blue", PLY_UCHAR, PLY_UCHAR, offsetof( _Vertex, blue ), 0, 0, 0, 0 }, 
     94        { "ambient_red", PLY_UCHAR, PLY_UCHAR, offsetof( _Vertex, ambient_red ), 0, 0, 0, 0 }, 
     95        { "ambient_green", PLY_UCHAR, PLY_UCHAR, offsetof( _Vertex, ambient_green ), 0, 0, 0, 0 }, 
     96        { "ambient_blue", PLY_UCHAR, PLY_UCHAR, offsetof( _Vertex, ambient_blue ), 0, 0, 0, 0 }, 
     97        { "diffuse_red", PLY_UCHAR, PLY_UCHAR, offsetof( _Vertex, diffuse_red ), 0, 0, 0, 0 }, 
     98        { "diffuse_green", PLY_UCHAR, PLY_UCHAR, offsetof( _Vertex, diffuse_green ), 0, 0, 0, 0 }, 
     99        { "diffuse_blue", PLY_UCHAR, PLY_UCHAR, offsetof( _Vertex, diffuse_blue ), 0, 0, 0, 0 }, 
     100        { "specular_red", PLY_UCHAR, PLY_UCHAR, offsetof( _Vertex, specular_red ), 0, 0, 0, 0 }, 
     101        { "specular_green", PLY_UCHAR, PLY_UCHAR, offsetof( _Vertex, specular_green ), 0, 0, 0, 0 }, 
     102        { "specular_blue", PLY_UCHAR, PLY_UCHAR, offsetof( _Vertex, specular_blue ), 0, 0, 0, 0 }, 
     103        { "specular_coeff", PLY_FLOAT, PLY_FLOAT, offsetof( _Vertex, specular_coeff ), 0, 0, 0, 0 }, 
     104        { "specular_power", PLY_FLOAT, PLY_FLOAT, offsetof( _Vertex, specular_power ), 0, 0, 0, 0 }, 
    75105    }; 
    76106     
    77107    // use all 6 properties when reading colors, only the first 3 otherwise 
    78     int limit = readColors ? 6 : 3; 
    79     for( int i = 0; i < limit; ++i )  
     108    for( int i = 0; i < 3; ++i )  
    80109        ply_get_property( file, "vertex", &vertexProps[i] ); 
    81110     
     111    if (fields & NORMALS) 
     112      for( int i = 3; i < 6; ++i )  
     113        ply_get_property( file, "vertex", &vertexProps[i] ); 
     114 
     115    if (fields & RGB) 
     116      for( int i = 6; i < 9; ++i )  
     117        ply_get_property( file, "vertex", &vertexProps[i] ); 
     118 
     119    if (fields & AMBIENT) 
     120      for( int i = 9; i < 12; ++i )  
     121        ply_get_property( file, "vertex", &vertexProps[i] ); 
     122 
     123    if (fields & DIFFUSE) 
     124      for( int i = 12; i < 15; ++i )  
     125        ply_get_property( file, "vertex", &vertexProps[i] ); 
     126 
     127    if (fields & SPECULAR) 
     128      for( int i = 15; i < 20; ++i )  
     129        ply_get_property( file, "vertex", &vertexProps[i] ); 
     130 
    82131    // check whether array is valid otherwise allocate the space 
    83132    if(!_vertices.valid()) 
    84133        _vertices = new osg::Vec3Array;  
     134 
     135    if( fields & NORMALS ) 
     136    { 
     137        if(!_normals.valid()) 
     138            _normals = new osg::Vec3Array; 
     139    } 
    85140     
    86141    // If read colors allocate space for color array 
    87     if( readColors ) 
     142    if( fields & RGB ) 
    88143    { 
    89144        if(!_colors.valid()) 
    90145            _colors = new osg::Vec4Array; 
    91146    } 
    92      
     147 
     148    if( fields & AMBIENT ) 
     149    { 
     150        if(!_ambient.valid()) 
     151            _ambient = new osg::Vec4Array; 
     152    } 
     153 
     154    if( fields & DIFFUSE ) 
     155    { 
     156        if(!_diffuse.valid()) 
     157            _diffuse = new osg::Vec4Array; 
     158    } 
     159     
     160    if( fields & SPECULAR ) 
     161    { 
     162        if(!_specular.valid()) 
     163            _specular = new osg::Vec4Array; 
     164    } 
     165 
    93166    // read in the vertices 
    94167    for( int i = 0; i < nVertices; ++i ) 
     
    96169        ply_get_element( file, static_cast< void* >( &vertex ) ); 
    97170        _vertices->push_back( osg::Vec3( vertex.x, vertex.y, vertex.z ) ); 
    98         if( readColors ) 
    99             _colors->push_back( osg::Vec4( (unsigned int) vertex.r / 256.0, (unsigned int) vertex.g / 256.0 , (unsigned int) vertex.b/ 256.0, 0.0 ) ); 
     171        if (fields & NORMALS) 
     172          _normals->push_back( osg::Vec3( vertex.nx, vertex.ny, vertex.nz ) ); 
     173        if( fields & RGB ) 
     174            _colors->push_back( osg::Vec4( (unsigned int) vertex.red / 256.0, 
     175                                           (unsigned int) vertex.green / 256.0 , 
     176                                           (unsigned int) vertex.blue / 256.0, 0.0 ) ); 
     177        if( fields & AMBIENT ) 
     178          _ambient->push_back( osg::Vec4( (unsigned int) vertex.ambient_red / 256.0, 
     179                                           (unsigned int) vertex.ambient_green / 256.0 , 
     180                                           (unsigned int) vertex.ambient_blue / 256.0, 0.0 ) ); 
     181 
     182        if( fields & DIFFUSE ) 
     183          _diffuse->push_back( osg::Vec4( (unsigned int) vertex.diffuse_red / 256.0, 
     184                                           (unsigned int) vertex.diffuse_green / 256.0 , 
     185                                           (unsigned int) vertex.diffuse_blue / 256.0, 0.0 ) ); 
     186 
     187        if( fields & SPECULAR ) 
     188          _specular->push_back( osg::Vec4( (unsigned int) vertex.specular_red / 256.0, 
     189                                           (unsigned int) vertex.specular_green / 256.0 , 
     190                                           (unsigned int) vertex.specular_blue / 256.0, 0.0 ) ); 
    100191    } 
    101192} 
     
    233324        if( equal_strings( elemNames[i], "vertex" ) ) 
    234325        { 
    235             bool hasColors = false; 
     326            int fields = NONE; 
    236327            // determine if the file stores vertex colors 
    237328            for( int j = 0; j < nProps; ++j ) 
     329              { 
    238330                // if the string have the red means color info is there 
     331                if( equal_strings( props[j]->name, "x" ) ) 
     332                    fields |= XYZ; 
     333                if( equal_strings( props[j]->name, "nx" ) ) 
     334                    fields |= NORMALS; 
    239335                if( equal_strings( props[j]->name, "red" ) ) 
    240                     hasColors = true; 
    241              
     336                    fields |= RGB; 
     337                if( equal_strings( props[j]->name, "ambient" ) ) 
     338                    fields |= AMBIENT; 
     339                if( equal_strings( props[j]->name, "diffuse_red" ) ) 
     340                    fields |= DIFFUSE; 
     341                if( equal_strings( props[j]->name, "specular_red" ) ) 
     342                    fields |= SPECULAR; 
     343              } 
     344 
    242345            if( ignoreColors ) 
     346              { 
     347                fields &= ~(XYZ | NORMALS); 
    243348                MESHINFO << "Colors in PLY file ignored per request." << endl; 
    244           
     349              } 
     350 
    245351            try {    
    246352                // Read vertices and store in a std::vector array 
    247                 readVertices( file, nElems, hasColors && !ignoreColors ); 
     353                readVertices( file, nElems, fields ); 
    248354                // Check whether all vertices are loaded or not 
    249355                MESHASSERT( _vertices->size() == static_cast< size_t >( nElems ) ); 
    250                 // Check all color elements read or not 
    251                 if( hasColors && !ignoreColors ) 
     356 
     357                // Check if all the optional elements were read or not 
     358                if( fields & NORMALS ) 
     359                { 
     360                    MESHASSERT( _normals->size() == static_cast< size_t >( nElems ) ); 
     361                } 
     362                if( fields & RGB ) 
    252363                { 
    253364                    MESHASSERT( _colors->size() == static_cast< size_t >( nElems ) ); 
     365                } 
     366                if( fields & AMBIENT ) 
     367                { 
     368                    MESHASSERT( _ambient->size() == static_cast< size_t >( nElems ) ); 
     369                } 
     370                if( fields & DIFFUSE ) 
     371                { 
     372                    MESHASSERT( _diffuse->size() == static_cast< size_t >( nElems ) ); 
     373                } 
     374                if( fields & SPECULAR ) 
     375                { 
     376                    MESHASSERT( _specular->size() == static_cast< size_t >( nElems ) ); 
    254377                } 
    255378 
     
    312435            if(!_normals.valid()) 
    313436                _calculateNormals(); 
    314  
    315             // set the normals 
     437        } 
     438 
     439        // Set the normals 
     440        if (_normals.valid()) 
     441        { 
    316442            geom->setNormalArray(_normals.get()); 
    317443            geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); 
    318444        } 
    319445         
    320         // Add the premetive set 
     446        // Add the primitive set 
    321447        if (_triangles.valid() && _triangles->size() > 0 ) 
    322448            geom->addPrimitiveSet(_triangles.get()); 
     
    324450            geom->addPrimitiveSet(new osg::DrawArrays(GL_POINTS, 0, _vertices->size())); 
    325451 
    326         // if color info is given set the color array 
     452 
     453        // Apply the colours to the model; at the moment this is a 
     454        // kludge because we only use one kind and apply them all the 
     455        // same way. Also, the priority order is completely arbitrary 
     456 
    327457        if(_colors.valid()) 
    328458        { 
    329459            geom->setColorArray(_colors.get()); 
    330460            geom->setColorBinding( osg::Geometry::BIND_PER_VERTEX ); 
    331              
    332         } 
    333  
    334          
     461        } 
     462        else if(_ambient.valid()) 
     463        { 
     464            geom->setColorArray(_ambient.get()); 
     465            geom->setColorBinding( osg::Geometry::BIND_PER_VERTEX ); 
     466        } 
     467        else if(_diffuse.valid()) 
     468        { 
     469            geom->setColorArray(_diffuse.get()); 
     470            geom->setColorBinding( osg::Geometry::BIND_PER_VERTEX ); 
     471        } 
     472        else if(_specular.valid()) 
     473        { 
     474            geom->setColorArray(_specular.get()); 
     475            geom->setColorBinding( osg::Geometry::BIND_PER_VERTEX ); 
     476        } 
     477 
    335478        // set flage true to activate the vertex buffer object of drawable 
    336479        geom->setUseVertexBufferObjects(true);