# Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics

[Home] [Tutorials] [All Classes] [Grouped Classes]

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# D:/VL/BuildSystem/VL_DISTRO/Visualization_Library_SDK/src/vlGraphics/plugins/vlPLY.cpp

Go to the documentation of this file.

    00001 /**************************************************************************************/
    00002 /*                                                                                    */
    00003 /*  Visualization Library                                                             */
    00004 /*  http://www.visualizationlibrary.com                                               */
    00005 /*                                                                                    */
    00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
    00007 /*  All rights reserved.                                                              */
    00008 /*                                                                                    */
    00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
    00010 /*  are permitted provided that the following conditions are met:                     */
    00011 /*                                                                                    */
    00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
    00013 /*  list of conditions and the following disclaimer.                                  */
    00014 /*                                                                                    */
    00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
    00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
    00017 /*  other materials provided with the distribution.                                   */
    00018 /*                                                                                    */
    00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
    00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
    00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
    00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
    00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
    00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
    00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
    00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
    00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
    00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
    00029 /*                                                                                    */
    00030 /**************************************************************************************/
    00031
    00032 #include "vlPLY.hpp"
    00033 #include <vlCore/Log.hpp>
    00034 #include <vlCore/Say.hpp>
    00035 #include <vlCore/VisualizationLibrary.hpp>
    00036 #include <vlCore/FileSystem.hpp>
    00037 #include <vlCore/TextStream.hpp>
    00038 #include <vlCore/VirtualFile.hpp>
    00039 #include <vlGraphics/Effect.hpp>
    00040 #include <vlGraphics/Actor.hpp>
    00041 #include <vlCore/LoadWriterManager.hpp>
    00042
    00043 using namespace vl;
    00044 //-----------------------------------------------------------------------------
    00045 ref<ResourceDatabase> vl::loadPLY(const String& path)
    00046 {
    00047   ref<VirtualFile> file = defFileSystem()->locateFile(path);
    00048
    00049   if (file)
    00050     return loadPLY( file.get() );
    00051   else
    00052   {
    00053     Log::error( Say("Could not locate '%s'.\n") << path );
    00054     return NULL;
    00055   }
    00056 }
    00057 //-----------------------------------------------------------------------------
    00058 ref<ResourceDatabase> vl::loadPLY(VirtualFile* file)
    00059 {
    00060   PlyLoader ply;
    00061   ref<ResourceDatabase> res_db = ply.loadPly(file);
    00062   return res_db;
    00063 }
    00064 //-----------------------------------------------------------------------------
    00065 void PlyLoader::PlyScalar::read(VirtualFile* file, bool le)
    00066 {
    00067   switch(scalarType())
    00068   {
    00069     case PlyChar:   mData.mChar   = file->readSInt8(); break;
    00070     case PlyUChar:  mData.mUChar  = file->readUInt8(); break;
    00071     case PlyShort:  mData.mShort  = file->readSInt16(le); break;
    00072     case PlyUShort: mData.mUShort = file->readUInt16(le); break;
    00073     case PlyInt:    mData.mInt    = file->readSInt32(le); break;
    00074     case PlyUInt:   mData.mUInt   = file->readUInt32(le); break;
    00075     case PlyFloat:  mData.mFloat  = file->readFloat(le); break;
    00076     case PlyDouble: mData.mDouble = file->readDouble(le); break;
    00077     default:
    00078       Log::error("PlyLoader: scalar read error.\n");
    00079   }
    00080 }
    00081 void PlyLoader::PlyScalar::read(TextStream* text)
    00082 {
    00083   int idata;
    00084   double ddata;
    00085   switch(scalarType())
    00086   {
    00087     case PlyChar:   text->readInt(idata); mData.mChar   = (char)idata; break;
    00088     case PlyUChar:  text->readInt(idata); mData.mUChar  = (unsigned char)idata; break;
    00089     case PlyShort:  text->readInt(idata); mData.mShort  = (short)idata; break;
    00090     case PlyUShort: text->readInt(idata); mData.mUShort = (unsigned short)idata; break;
    00091     case PlyInt:    text->readInt(idata); mData.mInt    = (int)idata; break;
    00092     case PlyUInt:   text->readInt(idata); mData.mUInt   = (unsigned int)idata; break;
    00093     case PlyFloat:  text->readDouble(ddata); mData.mFloat  = (float)ddata; break;
    00094     case PlyDouble: text->readDouble(ddata); mData.mDouble = (double)ddata; break;
    00095     default:
    00096       Log::error("PlyLoader: scalar read error.\n");
    00097   }
    00098 }
    00099 float PlyLoader::PlyScalar::getAsFloat() const
    00100 {
    00101   switch(scalarType())
    00102   {
    00103     case PlyChar:   return (float)mData.mChar;
    00104     case PlyUChar:  return (float)mData.mUChar;
    00105     case PlyShort:  return (float)mData.mShort;
    00106     case PlyUShort: return (float)mData.mUShort;
    00107     case PlyInt:    return (float)mData.mInt;
    00108     case PlyUInt:   return (float)mData.mUInt;
    00109     case PlyFloat:  return mData.mFloat;
    00110     case PlyDouble: return (float)mData.mDouble;
    00111     default:
    00112       Log::error("PlyLoader: getAsFloat() error.\n");
    00113       return 0.0f;
    00114   }
    00115 }
    00116 int PlyLoader::PlyScalar::getAsInt() const
    00117 {
    00118   switch(scalarType())
    00119   {
    00120     case PlyChar:   return (int)mData.mChar;
    00121     case PlyUChar:  return (int)mData.mUChar;
    00122     case PlyShort:  return (int)mData.mShort;
    00123     case PlyUShort: return (int)mData.mUShort;
    00124     case PlyInt:    return (int)mData.mInt;
    00125     case PlyUInt:   return (int)mData.mUInt;
    00126     case PlyFloat:  return (int)mData.mFloat;
    00127     case PlyDouble: return (int)mData.mDouble;
    00128     default:
    00129       Log::error("PlyLoader: getAsFloat() error.\n");
    00130       return 0;
    00131   }
    00132 }
    00133 void PlyLoader::PlyElement::analyze()
    00134 {
    00135   mVertex.resize(3);
    00136   mNormal.resize(3);
    00137   mColor.resize(4);
    00138   if (name() == "vertex")
    00139   {
    00140     for(unsigned int j=0; j<properties().size(); ++j)
    00141     {
    00142       PlyScalar* scalar = dynamic_cast<PlyScalar*>(properties()[j].get());
    00143       if (scalar)
    00144       {
    00145         if (scalar->name() == "x")
    00146           mVertex[0] = scalar;
    00147         else
    00148         if (scalar->name() == "y")
    00149           mVertex[1] = scalar;
    00150         else
    00151         if (scalar->name() == "z")
    00152           mVertex[2] = scalar;
    00153         else
    00154         if (scalar->name() == "nx")
    00155           mNormal[0] = scalar;
    00156         else
    00157         if (scalar->name() == "ny")
    00158           mNormal[1] = scalar;
    00159         else
    00160         if (scalar->name() == "nz")
    00161           mNormal[2] = scalar;
    00162         else
    00163         if (scalar->name() == "red")
    00164           mColor[0] = scalar;
    00165         else
    00166         if (scalar->name() == "green")
    00167           mColor[1] = scalar;
    00168         else
    00169         if (scalar->name() == "blue")
    00170           mColor[2] = scalar;
    00171         else
    00172         if (scalar->name() == "alpha")
    00173           mColor[3] = scalar;
    00174       }
    00175     }
    00176   }
    00177 }
    00178 void PlyLoader::readElements(VirtualFile* file)
    00179 {
    00180   // reposition to the correct location
    00181   file->seekSet(0);
    00182   std::string str;
    00183   do
    00184   {
    00185     unsigned char ch = file->readUInt8();
    00186     if (ch == '\n' && str == "end_header")
    00187       break;
    00188     if (ch == '\n')
    00189     {
    00190       str.clear();
    00191       continue;
    00192     }
    00193     str.push_back( ch );
    00194   } while(true);
    00195
    00196   for(unsigned i=0; i<mElements.size(); ++i)
    00197     for(int j=0; j<mElements[i]->elemCount(); ++j)
    00198     {
    00199       mElements[i]->read(file, littleEndian());
    00200       newElement(mElements[i].get());
    00201     }
    00202 }
    00203 void PlyLoader::readElements(TextStream* text)
    00204 {
    00205   for(unsigned i=0; i<mElements.size(); ++i)
    00206     for(int j=0; j<mElements[i]->elemCount(); ++j)
    00207     {
    00208       mElements[i]->read(text);
    00209       newElement(mElements[i].get());
    00210     }
    00211 }
    00212 void PlyLoader::newElement(PlyElement*el)
    00213 {
    00214   if (el->name() == "vertex")
    00215   {
    00216     for(unsigned int j=0; j<el->properties().size(); ++j)
    00217     {
    00218       if (mVerts)
    00219         mVerts->at(mVertexIndex)   = el->getVertex();
    00220       if (mNormals)
    00221         mNormals->at(mVertexIndex) = el->getNormal();
    00222       if (mColors)
    00223         mColors->at(mVertexIndex)  = el->getColor();
    00224     }
    00225
    00226     ++mVertexIndex;
    00227   }
    00228   else
    00229   if (el->name() == "face")
    00230   {
    00231     for(unsigned int j=0; j<el->properties().size(); ++j)
    00232     {
    00233       PlyScalarList* list = dynamic_cast<PlyScalarList*>(el->properties()[j].get());
    00234       if (list && list->name() == "vertex_indices")
    00235       {
    00236         for(int i=1; i<(int)list->scalars().size()-1; ++i)
    00237         {
    00238           if (mIndices.capacity() - mIndices.size() == 0)
    00239             mIndices.reserve( mIndices.capacity() * 2 );
    00240           mIndices.push_back( list->scalars()[0].getAsInt());
    00241           mIndices.push_back( list->scalars()[i].getAsInt());
    00242           mIndices.push_back( list->scalars()[i+1].getAsInt());
    00243         }
    00244       }
    00245     }
    00246   }
    00247 }
    00248 PlyLoader::EType PlyLoader::translateType(const String& type)
    00249 {
    00250   if (type == "int8")   return PlyChar; else
    00251   if (type == "char")   return PlyChar; else
    00252   if (type == "uint8")   return PlyChar; else
    00253   if (type == "uchar")  return PlyUChar; else
    00254   if (type == "ushort") return PlyUShort; else
    00255   if (type == "uint16") return PlyUShort; else
    00256   if (type == "short")  return PlyShort; else
    00257   if (type == "int16")  return PlyShort; else
    00258   if (type == "int")    return PlyInt; else
    00259   if (type == "int32")    return PlyInt; else
    00260   if (type == "uint")   return PlyUInt; else
    00261   if (type == "uint32")   return PlyUInt; else
    00262   if (type == "float")  return PlyFloat; else
    00263   if (type == "float32")  return PlyFloat; else
    00264   if (type == "float64")  return PlyDouble; else
    00265   if (type == "double") return PlyDouble;
    00266   else
    00267   {
    00268     Log::error("PlyLoader: type parse error.\n");
    00269     return PlyError;
    00270   }
    00271 }
    00272 void PlyLoader::analyzeHeader()
    00273 {
    00274   // allocate space for vertices, normals and colors.
    00275   for(unsigned int i=0; i<elements().size(); ++i)
    00276   {
    00277     if (elements()[i]->name() == "vertex")
    00278     {
    00279       for(unsigned int j=0; j<elements()[i]->properties().size(); ++j)
    00280       {
    00281         if (elements()[i]->properties()[j]->name() == "x")
    00282         {
    00283           mVerts = new ArrayFloat3;
    00284           mVerts->resize( elements()[i]->elemCount() );
    00285         }
    00286         if (elements()[i]->properties()[j]->name() == "nx")
    00287         {
    00288           mNormals = new ArrayFloat3;
    00289           mNormals->resize( elements()[i]->elemCount() );
    00290         }
    00291         if (elements()[i]->properties()[j]->name() == "red")
    00292         {
    00293           mColors = new ArrayUByte4;
    00294           mColors->resize( elements()[i]->elemCount() );
    00295           memset(mColors->ptr(), 0xFF, sizeof(mColors->at(0))*mColors->size());
    00296         }
    00297       }
    00298       elements()[i]->analyze();
    00299     }
    00300   }
    00301   if (mVerts->size() == 0)
    00302   {
    00303     Log::error("PlyLoader: no vertices found.\n");
    00304   }
    00305 }
    00306 bool PlyLoader::readHeader(TextStream* line_reader)
    00307 {
    00308   mVerts   = NULL;
    00309   mNormals = NULL;
    00310   mColors  = NULL;
    00311   mIndices.reserve(100);
    00312   bool ok = true;
    00313   elements().clear();
    00314   String str;
    00315   // ply loader
    00316   line_reader->readLineLF(str);
    00317   if (str.trim() != "ply")
    00318     return false;
    00319   // format
    00320   line_reader->readLineLF(str);
    00321   if (str.trim() == "format ascii 1.0")
    00322   {
    00323     mBinary = false;
    00324   }
    00325   else
    00326   if (str.trim() == "format binary_little_endian 1.0")
    00327   {
    00328     mBinary = true;
    00329     mLittleEndian = true;
    00330   }
    00331   else
    00332   if (str.trim() == "format binary_big_endian 1.0")
    00333   {
    00334     mBinary = true;
    00335     mLittleEndian = false;
    00336   }
    00337   else
    00338     return false;
    00339   // read elements
    00340   while ( (line_reader->readLineLF(str)) && str.trim() != "end_header")
    00341   {
    00342     if (str.startsWith("comment"))
    00343       continue;
    00344     else
    00345     if (str.startsWith("element"))
    00346     {
    00347       elements().push_back(new PlyElement);
    00348       elements().back()->setName( str.field(' ',1) );
    00349       elements().back()->setElemCount( str.field(' ',2).toInt() );
    00350     }
    00351     else
    00352     if (str.startsWith("property"))
    00353     {
    00354       String prop_type = str.field(' ',1);
    00355       ref<PlyScalar> prop;
    00356       ref<PlyScalarList> scalar_list;
    00357       if (prop_type == "list")
    00358       {
    00359         String num_type = str.field(' ',2);
    00360         String idx_type = str.field(' ',3);
    00361         String name     = str.field(' ',4);
    00362         if (name.empty())
    00363         {
    00364           Log::error("PLY parse error #5.\n");
    00365           return false;
    00366         }
    00367
    00368         scalar_list = new PlyScalarList;
    00369         elements().back()->properties().push_back(scalar_list);
    00370
    00371         scalar_list->setCountType(translateType(num_type));
    00372         scalar_list->setScalarType(translateType(idx_type));
    00373         scalar_list->setName(name);
    00374       }
    00375       else
    00376       {
    00377         prop = new PlyScalar;
    00378         elements().back()->properties().push_back(prop);
    00379         prop->setName( str.field(' ',2) );
    00380         prop->setScalarType(translateType(prop_type));
    00381       }
    00382     }
    00383     else
    00384     {
    00385       Log::error("PLY parse error #2.\n");
    00386       return false;
    00387     }
    00388   }
    00389   analyzeHeader();
    00390   mVertexIndex = 0;
    00391   return ok;
    00392 }
    00393 ref<ResourceDatabase> PlyLoader::loadPly(VirtualFile* file)
    00394 {
    00395   ref<TextStream> line_reader = new TextStream;
    00396   line_reader->setInputFile(file);
    00397   readHeader(line_reader.get());
    00398   if (binary())
    00399     readElements(file);
    00400   else
    00401     readElements(line_reader.get());
    00402   file->close();
    00403   if (mIndices.empty() || !mVerts)
    00404     return NULL;
    00405   ref<Geometry> geom = new Geometry;
    00406   geom->setVertexArray(mVerts.get());
    00407   geom->setNormalArray(mNormals.get());
    00408   geom->setColorArray(mColors.get());
    00409   ref<DrawElementsUInt> de = new DrawElementsUInt(PT_TRIANGLES);
    00410   geom->drawCalls()->push_back(de.get());
    00411   de->indices()->resize(mIndices.size());
    00412   memcpy(de->indices()->ptr(), &mIndices[0], sizeof(unsigned int)*mIndices.size());
    00413   ref<ResourceDatabase> res_db = new ResourceDatabase;
    00414   ref<Effect> effect = new Effect;
    00415   if (mColors)
    00416     effect->shader()->gocMaterial()->setColorMaterialEnabled(true);
    00417   res_db->resources().push_back( geom );
    00418   res_db->resources().push_back( new Actor(geom.get(), effect.get(), NULL ) );
    00419   res_db->resources().push_back( effect.get() );
    00420   return res_db;
    00421 }
    00422 //-----------------------------------------------------------------------------

Visualization Library v2011.05.1142 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 26 2011 22:51:24.
Permission is granted to use this page to write and publish articles regarding Visualization Library.