Jafar
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
jfr_import_ply.h
00001 /***************************************************************/
00002 /* This is a modified version of the import_ply.h from VCGLib. */
00003 /* The original license is below                               */
00004 /***************************************************************/
00005 
00006 /****************************************************************************
00007  * VCGLib                                                            o o     *
00008  * Visual and Computer Graphics Library                            o     o   *
00009  *                                                                _   O  _   *
00010  * Copyright(C) 2004                                                \/)\/    *
00011  * Visual Computing Lab                                            /\/|      *
00012  * ISTI - Italian National Research Council                           |      *
00013  *                                                                    \      *
00014  * All rights reserved.                                                      *
00015  *                                                                           *
00016  * This program is free software; you can redistribute it and/or modify      *   
00017  * it under the terms of the GNU General Public License as published by      *
00018  * the Free Software Foundation; either version 2 of the License, or         *
00019  * (at your option) any later version.                                       *
00020  *                                                                           *
00021  * This program is distributed in the hope that it will be useful,           *
00022  * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
00023  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
00024  * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
00025  * for more details.                                                         *
00026  *                                                                           *
00027  ****************************************************************************/
00028 
00029 #ifndef _JFR_VCGLIB_IMPORTERPLY
00030 #define _JFR_VCGLIB_IMPORTERPLY
00031 
00032 #include<wrap/callback.h>
00033 #include<wrap/ply/plylib.h>
00034 #include "modeler/jfr_io_mask.h"
00035 #include<wrap/io_trimesh/io_ply.h>
00036 #include<vcg/complex/trimesh/allocate.h>
00037 #include<vcg/complex/trimesh/create/platonic.h>
00038 #include<vcg/space/color4.h>
00039 #include <vector>
00040 
00041 namespace vcg {
00042   namespace tri {
00043     namespace io {
00044 
00045       template <class TYPE>
00046         int PlyType ()  { return 0;}
00047 
00048 
00049       // 10/6/05 Cignoni this specialization must be inlined becouse otherwise if we include this 
00050       // .h in two different cpp we should get a double definition error during linking
00051 
00052       template <> inline int PlyType <float >()  { return ply::T_FLOAT; }
00053       template <> inline int PlyType <double>()  { return ply::T_DOUBLE; }
00054       template <> inline int PlyType <int   >()  { return ply::T_INT; } 
00055       template <> inline int PlyType <short >()  { return ply::T_SHORT; }
00056       template <> inline int PlyType <unsigned char>()  { return ply::T_UCHAR; }
00057       template <> inline int PlyType <unsigned int >()  { return ply::T_UINT; }
00058 
00063       template <class OpenMeshType>
00064         class JfrImporterPLY
00065         {
00066         public:
00067 
00068           typedef ::vcg::ply::PropDescriptor PropDescriptor ;
00069           typedef typename OpenMeshType::VertexPointer VertexPointer;
00070           typedef typename OpenMeshType::ScalarType ScalarType;
00071           typedef typename OpenMeshType::VertexType VertexType;
00072           typedef typename OpenMeshType::FaceType FaceType;
00073           typedef typename OpenMeshType::VertexIterator VertexIterator;
00074           typedef typename OpenMeshType::FaceIterator FaceIterator;
00075 
00076           //template <class T> int PlyType () { assert(0);  return 0;}
00077 
00078 #define MAX_USER_DATA 256
00079           // Struttura ausiliaria per la lettura del file ply
00080           struct LoadPly_FaceAux
00081           {
00082             unsigned char size;
00083             int v[512];
00084             int flags;
00085             float q;
00086             float texcoord[32];
00087             unsigned char ntexcoord;
00088             int texcoordind;
00089             float colors[32];
00090             unsigned char ncolors;
00091   
00092             unsigned char r;
00093             unsigned char g;
00094             unsigned char b;
00095 
00096             unsigned char data[MAX_USER_DATA];  
00097           };
00098 
00099           struct LoadPly_TristripAux
00100           {
00101             int size;
00102             int *v;
00103             unsigned char data[MAX_USER_DATA];  
00104           };
00105 
00106 
00107           // Yet another auxiliary data structure for loading some strange ply files 
00108           // the original stanford range data...
00109           struct LoadPly_RangeGridAux {
00110             unsigned char num_pts;
00111             int pts[5];
00112           };
00113 
00114 
00115           // Struttura ausiliaria per la lettura del file ply
00116           template<class S>
00117             struct LoadPly_VertAux
00118             {
00119               S p[3];
00120               S n[3];
00121               int flags;
00122               float q; // the confidence
00123               float intensity;
00124               unsigned char r;
00125               unsigned char g;
00126               unsigned char b;
00127               unsigned char data[MAX_USER_DATA];  
00128               float radius;
00129               float u,v,w;
00130               unsigned int id;
00131               unsigned int size;
00132               int ft[MAX_USER_DATA];
00133             };
00134 
00135           // Struttura ausiliaria caricamento camera
00136           struct LoadPly_Camera
00137           {
00138             int id;
00139             float view_px;
00140             float view_py;
00141             float view_pz;
00142             float x_axisx;
00143             float x_axisy;
00144             float x_axisz;
00145             float y_axisx;
00146             float y_axisy;
00147             float y_axisz;
00148             float z_axisx;
00149             float z_axisy;
00150             float z_axisz;
00151             float focal;
00152             float scalex;
00153             float scaley;
00154             float centerx;
00155             float centery;
00156             int   viewportx;
00157             int   viewporty;
00158             float k1;
00159             float k2;
00160             float k3;
00161             float k4;
00162           };
00163           // structure of a feature
00164           struct LoadPly_Feature
00165           {
00166             double u;
00167             double v;
00168             unsigned int id;
00169             unsigned int index;
00170             double quality;
00171             unsigned int parent_id;
00172             float coef;
00173             unsigned int desc_length;
00174             float desc[MAX_USER_DATA];
00175           };
00176 
00177 #define _VERTDESC_LAST_  24
00178           static const  PropDescriptor &VertDesc(int i)  
00179           {
00180             static const PropDescriptor pv[_VERTDESC_LAST_]={
00181               /*00*/ {"vertex", "x",         ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p),0,0,0,0,0  ,0},
00182               /*01*/ {"vertex", "y",         ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p) + sizeof(ScalarType),0,0,0,0,0  ,0},
00183               /*02*/ {"vertex", "z",         ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p) + 2*sizeof(ScalarType),0,0,0,0,0  ,0},
00184               /*03*/ {"vertex", "flags",     ply::T_INT,   ply::T_INT,           offsetof(LoadPly_VertAux<ScalarType>,flags),0,0,0,0,0  ,0},
00185               /*04*/ {"vertex", "quality",   ply::T_FLOAT, ply::T_FLOAT,         offsetof(LoadPly_VertAux<ScalarType>,q),0,0,0,0,0  ,0},
00186               /*05*/ {"vertex", "red"  ,     ply::T_UCHAR, ply::T_UCHAR,         offsetof(LoadPly_VertAux<ScalarType>,r),0,0,0,0,0  ,0},
00187               /*06*/ {"vertex", "green",     ply::T_UCHAR, ply::T_UCHAR,         offsetof(LoadPly_VertAux<ScalarType>,g),0,0,0,0,0  ,0},
00188               /*07*/ {"vertex", "blue" ,     ply::T_UCHAR, ply::T_UCHAR,         offsetof(LoadPly_VertAux<ScalarType>,b),0,0,0,0,0  ,0},
00189               /*08*/ {"vertex", "diffuse_red"  ,     ply::T_UCHAR, ply::T_UCHAR,         offsetof(LoadPly_VertAux<ScalarType>,r),0,0,0,0,0  ,0},
00190               /*09*/ {"vertex", "diffuse_green",     ply::T_UCHAR, ply::T_UCHAR,         offsetof(LoadPly_VertAux<ScalarType>,g),0,0,0,0,0  ,0},
00191               /*10*/ {"vertex", "diffuse_blue" ,     ply::T_UCHAR, ply::T_UCHAR,         offsetof(LoadPly_VertAux<ScalarType>,b),0,0,0,0,0  ,0},
00192               /*11*/ {"vertex", "confidence",ply::T_FLOAT, ply::T_FLOAT,         offsetof(LoadPly_VertAux<ScalarType>,q),0,0,0,0,0  ,0},
00193               /*12*/ {"vertex", "nx",         ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,n)                       ,0,0,0,0,0  ,0},
00194               /*13*/ {"vertex", "ny",         ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,n) + 1*sizeof(ScalarType),0,0,0,0,0  ,0},
00195               /*14*/ {"vertex", "nz",         ply::T_FLOAT, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,n) + 2*sizeof(ScalarType),0,0,0,0,0  ,0},
00196               /*15*/ {"vertex", "radius",     ply::T_FLOAT, ply::T_FLOAT,         offsetof(LoadPly_VertAux<ScalarType>,radius),0,0,0,0,0  ,0},
00197               /*16*/ {"vertex", "texture_u",    ply::T_FLOAT, ply::T_FLOAT,         offsetof(LoadPly_VertAux<ScalarType>,u),0,0,0,0,0  ,0},
00198               /*17*/ {"vertex", "texture_v",    ply::T_FLOAT, ply::T_FLOAT,         offsetof(LoadPly_VertAux<ScalarType>,v),0,0,0,0,0  ,0},
00199               /*18*/ {"vertex", "texture_w",    ply::T_FLOAT, ply::T_FLOAT,         offsetof(LoadPly_VertAux<ScalarType>,w),0,0,0,0,0  ,0},
00200               /*19*/ {"vertex", "intensity",    ply::T_FLOAT, ply::T_FLOAT,         offsetof(LoadPly_VertAux<ScalarType>,intensity),0,0,0,0,0  ,0},
00201               /*20*/ {"vertex", "s",    ply::T_FLOAT, ply::T_FLOAT,         offsetof(LoadPly_VertAux<ScalarType>,u),0,0,0,0,0  ,0},
00202               /*21*/ {"vertex", "t",    ply::T_FLOAT, ply::T_FLOAT,         offsetof(LoadPly_VertAux<ScalarType>,v),0,0,0,0,0  ,0},
00203               /*22*/ {"vertex", "vertex_id", ply::T_UINT, ply::T_UINT, offsetof(LoadPly_VertAux<ScalarType>,id),0,0,0,0,0  ,0},
00204               /*23*/ {"vertex", "feature_indices", ply::T_UINT, ply::T_UINT, offsetof(LoadPly_VertAux<ScalarType>,ft),1,0,ply::T_UINT,ply::T_UINT,offsetof(LoadPly_VertAux<ScalarType>,size)  ,0},
00205             };
00206             return pv[i];
00207           }
00208 
00209 #define _FACEDESC_FIRST_  9 // the first descriptor with possible vertex indices
00210 #define _FACEDESC_LAST_  20
00211           static const  PropDescriptor &FaceDesc(int i)  
00212           {   
00213             static const  PropDescriptor qf[_FACEDESC_LAST_]=
00214               {
00215                 /*                                       on file       on memory                                             on file       on memory */
00216                 /*  0 */ {"face", "vertex_indices", ply::T_INT,   ply::T_INT,   offsetof(LoadPly_FaceAux,v),1,0,ply::T_UCHAR,ply::T_UCHAR,offsetof(LoadPly_FaceAux,size)   ,0},
00217                 /*  1 */ {"face", "flags",          ply::T_INT,   ply::T_INT,   offsetof(LoadPly_FaceAux,flags),     0,0,0,0,0  ,0},
00218                 /*  2 */ {"face", "quality",        ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_FaceAux,q),         0,0,0,0,0  ,0},
00219                 /*  3 */ {"face", "texcoord", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_FaceAux,texcoord), 1,0,ply::T_UCHAR,ply::T_UCHAR,offsetof(LoadPly_FaceAux,ntexcoord),0},
00220                 /*  4 */ {"face", "color",    ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_FaceAux,colors),    1,0,ply::T_UCHAR,ply::T_UCHAR,offsetof(LoadPly_FaceAux,ncolors),0},
00221                 /*  5 */ {"face", "texnumber",      ply::T_INT,   ply::T_INT,   offsetof(LoadPly_FaceAux,texcoordind), 0,0,0,0,0  ,0},
00222                 /*  6 */ {"face", "red"  ,          ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_FaceAux,r), 0,0,0,0,0  ,0},
00223                 /*  7 */ {"face", "green",          ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_FaceAux,g), 0,0,0,0,0  ,0},
00224                 /*  8 */ {"face", "blue" ,          ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_FaceAux,b), 0,0,0,0,0  ,0},
00225                 /*  9 */ {"face", "vertex_index",  ply::T_INT,  ply::T_INT,  offsetof(LoadPly_FaceAux,v), 1,0,ply::T_UCHAR,ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0},
00226                 /* 10 */ {"face", "vertex_index", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,v),      1,0,ply::T_CHAR, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0},
00227                 /* 11 */ {"face", "vertex_index", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,v),     1,0,ply::T_INT, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0},
00228 
00229                 /* 12 */ {"face", "vertex_indices", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,v),     1,0,ply::T_CHAR, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0},
00230                 /* 13 */ {"face", "vertex_indices", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,v),     1,0,ply::T_INT, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0},
00231                 /* 14 */ {"face", "vertex_indices", ply::T_UINT, ply::T_INT, offsetof(LoadPly_FaceAux,v),    1,0,ply::T_UCHAR,ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0},
00232                 /* 15 */ {"face", "vertex_indices", ply::T_UINT, ply::T_INT, offsetof(LoadPly_FaceAux,v),    1,0,ply::T_CHAR, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0},
00233                 /* 16 */ {"face", "vertex_indices", ply::T_UINT, ply::T_INT, offsetof(LoadPly_FaceAux,v),    1,0,ply::T_INT, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0},
00234                 /* 17 */ {"face", "vertex_indices", ply::T_SHORT, ply::T_INT, offsetof(LoadPly_FaceAux,v),     1,0,ply::T_CHAR, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0},
00235                 /* 18 */ {"face", "vertex_indices", ply::T_SHORT, ply::T_INT, offsetof(LoadPly_FaceAux,v),     1,0,ply::T_UCHAR,ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0},
00236                 /* 19 */ {"face", "vertex_indices", ply::T_SHORT, ply::T_INT, offsetof(LoadPly_FaceAux,v),     1,0,ply::T_INT, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0}
00237               };
00238             return qf[i];
00239           }
00240           static const  PropDescriptor &TristripDesc(int i)  
00241           {   
00242             static const  PropDescriptor qf[1]=
00243               {
00244                 {"tristrips","vertex_indices", ply::T_INT,  ply::T_INT,  offsetof(LoadPly_TristripAux,v),     1,1,ply::T_INT,ply::T_INT,offsetof(LoadPly_TristripAux,size) ,0},       
00245               };
00246             return qf[i];
00247           }
00248 
00249           // Descriptor for the Stanford Data Repository Range Maps.
00250           // In practice a grid with some invalid elements. Coords are saved only for good elements
00251           static const  PropDescriptor &RangeDesc(int i)  
00252           {   
00253             static const PropDescriptor range_props[1] = {
00254               {"range_grid","vertex_indices", ply::T_INT, ply::T_INT, offsetof(LoadPly_RangeGridAux,pts), 1, 0, ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_RangeGridAux,num_pts),0},
00255             };
00256             return range_props[i];
00257           }
00258 
00259           static const  PropDescriptor &CameraDesc(int i)  
00260           {   
00261             static const PropDescriptor cad[24] =
00262               {
00263                 {"camera","id",ply::T_UINT,ply::T_UINT,offsetof(LoadPly_Camera,id),0,0,0,0,0  ,0},
00264                 {"camera","view_px",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,view_px),0,0,0,0,0  ,0},
00265                 {"camera","view_py",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,view_py),0,0,0,0,0  ,0},
00266                 {"camera","view_pz",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,view_pz),0,0,0,0,0  ,0},
00267                 {"camera","x_axisx",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,x_axisx),0,0,0,0,0  ,0},
00268                 {"camera","x_axisy",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,x_axisy),0,0,0,0,0  ,0},
00269                 {"camera","x_axisz",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,x_axisz),0,0,0,0,0  ,0},
00270                 {"camera","y_axisx",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,y_axisx),0,0,0,0,0  ,0},
00271                 {"camera","y_axisy",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,y_axisy),0,0,0,0,0  ,0},
00272                 {"camera","y_axisz",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,y_axisz),0,0,0,0,0  ,0},
00273                 {"camera","z_axisx",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,z_axisx),0,0,0,0,0  ,0},
00274                 {"camera","z_axisy",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,z_axisy),0,0,0,0,0  ,0},
00275                 {"camera","z_axisz",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,z_axisz),0,0,0,0,0  ,0},
00276                 {"camera","focal"  ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,focal  ),0,0,0,0,0  ,0},
00277                 {"camera","scalex" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,scalex ),0,0,0,0,0  ,0},
00278                 {"camera","scaley" ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,scaley ),0,0,0,0,0  ,0},
00279                 {"camera","centerx",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,centerx),0,0,0,0,0  ,0},
00280                 {"camera","centery",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,centery),0,0,0,0,0  ,0},
00281                 {"camera","viewportx",ply::T_INT,ply::T_INT  ,offsetof(LoadPly_Camera,viewportx),0,0,0,0,0  ,0},
00282                 {"camera","viewporty",ply::T_INT,ply::T_INT  ,offsetof(LoadPly_Camera,viewporty),0,0,0,0,0  ,0},
00283                 {"camera","k1"     ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,k1 ),0,0,0,0,0  ,0},
00284                 {"camera","k2"     ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,k2 ),0,0,0,0,0  ,0},
00285                 {"camera","k3"     ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,k3 ),0,0,0,0,0  ,0},
00286                 {"camera","k4"     ,ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Camera,k4 ),0,0,0,0,0  ,0}
00287               };
00288             return cad[i];
00289           }
00290 
00291           static const  PropDescriptor &FeatureDesc(int i)
00292           {   
00293             static const PropDescriptor ftd[8] =
00294               {
00295                 {"feature","u",ply::T_DOUBLE,ply::T_DOUBLE,offsetof(LoadPly_Feature,u),0,0,0,0,0,0},
00296                 {"feature","v",ply::T_DOUBLE,ply::T_DOUBLE,offsetof(LoadPly_Feature,v),0,0,0,0,0,0},
00297                 {"feature","id" ,ply::T_UINT,ply::T_UINT,offsetof(LoadPly_Feature,id),0,0,0,0,0,0},
00298                 {"feature","index" ,ply::T_UINT,ply::T_UINT,offsetof(LoadPly_Feature,index),0,0,0,0,0,0},
00299                 {"feature","quality",ply::T_DOUBLE,ply::T_DOUBLE,offsetof(LoadPly_Feature,quality),0,0,0,0,0,0},
00300                 {"feature","parent_id",ply::T_UINT,ply::T_UINT,offsetof(LoadPly_Feature,parent_id),0,0,0,0,0,0},
00301                 {"feature","coef",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Feature,coef),0,0,0,0,0,0},
00302                 {"feature","desc",ply::T_FLOAT,ply::T_FLOAT,offsetof(LoadPly_Feature,desc),1,0,ply::T_UINT,ply::T_UINT,offsetof(LoadPly_Feature,desc_length),0}
00303               };
00304             return ftd[i];
00305           }
00307           static const char *ErrorMsg(int error)
00308           {
00309             static std::vector<std::string> ply_error_msg;
00310             if(ply_error_msg.empty())
00311               {
00312                 ply_error_msg.resize(PlyInfo::E_MAXPLYINFOERRORS );
00313                 ply_error_msg[ply::E_NOERROR        ]="No errors";
00314                 ply_error_msg[ply::E_CANTOPEN       ]="Can't open file";
00315                 ply_error_msg[ply::E_NOTHEADER ]="Header not found";
00316                 ply_error_msg[ply::E_UNESPECTEDEOF  ]="Eof in header";
00317                 ply_error_msg[ply::E_NOFORMAT       ]="Format not found";
00318                 ply_error_msg[ply::E_SYNTAX       ]="Syntax error on header";
00319                 ply_error_msg[ply::E_PROPOUTOFELEMENT]="Property without element";
00320                 ply_error_msg[ply::E_BADTYPENAME    ]="Bad type name";
00321                 ply_error_msg[ply::E_ELEMNOTFOUND   ]="Element not found";
00322                 ply_error_msg[ply::E_PROPNOTFOUND   ]="Property not found";
00323                 ply_error_msg[ply::E_BADTYPE        ]="Bad type on addtoread";
00324                 ply_error_msg[ply::E_INCOMPATIBLETYPE]="Incompatible type";
00325                 ply_error_msg[ply::E_BADCAST        ]="Bad cast";
00326 
00327                 ply_error_msg[PlyInfo::E_NO_VERTEX      ]="No vertex field found";
00328                 ply_error_msg[PlyInfo::E_NO_FACE        ]="No face field found";
00329                 ply_error_msg[PlyInfo::E_SHORTFILE      ]="Unespected eof";
00330                 ply_error_msg[PlyInfo::E_NO_3VERTINFACE ]="Face with more than 3 vertices";
00331                 ply_error_msg[PlyInfo::E_BAD_VERT_INDEX ]="Bad vertex index in face";
00332                 ply_error_msg[PlyInfo::E_NO_6TCOORD     ]="Face with no 6 texture coordinates";
00333                 ply_error_msg[PlyInfo::E_DIFFER_COLORS  ]="Number of color differ from vertices";
00334               }
00335 
00336             if(error>PlyInfo::E_MAXPLYINFOERRORS || error<0) return "Unknown error";
00337             else return ply_error_msg[error].c_str();
00338           };
00339 
00340           // to check if a given error is critical or not.
00341           static bool ErrorCritical(int err)
00342           { 
00343             if(err == PlyInfo::E_NO_FACE) return false;
00344             return true;
00345           }
00346   
00347 
00349           static int Open( OpenMeshType &m, const char * filename, CallBackPos *cb=0)
00350           {
00351             PlyInfo pi;
00352             pi.cb=cb; 
00353             return Open(m, filename, pi);
00354           }
00355 
00360           static int Open( OpenMeshType &m, const char * filename, int & loadmask, CallBackPos *cb =0)
00361           {
00362             PlyInfo pi;
00363             pi.cb=cb; 
00364             int r =  Open(m, filename,pi);
00365             loadmask=pi.mask;
00366             return r;
00367           }
00368 
00369 
00371           static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi )
00372           {
00373             assert(filename!=0);
00374             std::vector<VertexPointer> index;
00375             LoadPly_FaceAux fa;
00376             LoadPly_TristripAux tsa;
00377             LoadPly_VertAux<ScalarType> va;
00378             LoadPly_Feature fta;
00379             LoadPly_Camera ca;
00380             LoadPly_RangeGridAux rga;
00381             std::vector<int> RangeGridAuxVec;
00382             int RangeGridCols=0;
00383             int RangeGridRows=0;
00384   
00385   
00386             pi.mask = 0;
00387             bool hasIntensity = false; // the intensity is a strange way to code single channel color used sometimes in rangemap. it is a kind of color. so it do not need another entry in the IOM mask.
00388             bool multit = false; // true if texture has a per face int spec the texture index
00389 
00390             va.flags = 42;
00391 
00392             pi.status = ::vcg::ply::E_NOERROR;
00393 
00394             /*
00395             // TO BE REMOVED: tv not used AND "spurious" vertex declaration causes error if ocf
00396 
00397             // init defaults
00398             VertexType tv;
00399             //tv.ClearFlags();
00400 
00401             if (vcg::tri::HasPerVertexQuality(m)) tv.Q() = (typename OpenMeshType::VertexType::QualityType)1.0;
00402             if (vcg::tri::HasPerVertexColor  (m)) tv.C() = Color4b(Color4b::White);
00403             */
00404 
00405             // Descrittori delle strutture
00406 
00407             //bool isvflags = false;  // Il file contiene i flags 
00408 
00409 
00410             // The main descriptor of the ply file 
00411             vcg::ply::PlyFile pf;
00412   
00413             // Open the file and parse the header
00414             if( pf.Open(filename,vcg::ply::PlyFile::MODE_READ)==-1 )
00415               {
00416                 pi.status = pf.GetError();
00417                 return pi.status;
00418               }
00419             pi.header = pf.GetHeader();
00420 
00421             // Descrittori della camera
00422             {  // Check that all the camera properties are present.
00423               bool found = true;
00424               for(int i=0;i<24;++i)
00425                 {
00426                   if( pf.AddToRead(CameraDesc(i))==-1 ) {
00427                     found = false;
00428                     break;
00429                   }
00430                 }
00431               if(found) pi.mask |= JfrMask::IOM_CAMERA;
00432             }
00433             // Feature descriptor
00434             {
00435               bool found = true;
00436               for(int i=0;i<8;++i)
00437                 {
00438                   if( pf.AddToRead(FeatureDesc(i))==-1 ) {
00439                     found = false;
00440                     break;
00441                   }
00442                 }
00443               if(found) pi.mask |= JfrMask::IOM_VERTORIGINES;
00444             }
00445 
00446             // Descrittori dati standard (vertex coord e faces)
00447             if( pf.AddToRead(VertDesc(0))==-1 ) { pi.status = PlyInfo::E_NO_VERTEX; return pi.status; }
00448             if( pf.AddToRead(VertDesc(1))==-1 ) { pi.status = PlyInfo::E_NO_VERTEX; return pi.status; }
00449             if( pf.AddToRead(VertDesc(2))==-1 ) { pi.status = PlyInfo::E_NO_VERTEX; return pi.status; }
00450             if( pf.AddToRead(FaceDesc(0))==-1 ) // Se fallisce si prova anche la sintassi di rapidform con index al posto di indices
00451               {
00452                 int ii; 
00453                 for(ii=_FACEDESC_FIRST_;ii< _FACEDESC_LAST_;++ii)
00454                   if( pf.AddToRead(FaceDesc(ii))!=-1 ) break;
00455       
00456                 if(ii==_FACEDESC_LAST_) 
00457                   if(pf.AddToRead(TristripDesc(0))==-1) // Se fallisce tutto si prova a vedere se ci sono tristrip alla levoy.
00458                     if(pf.AddToRead(RangeDesc(0))==-1) // Se fallisce tutto si prova a vedere se ci sono rangemap alla levoy.
00459                       { 
00460                         pi.status = PlyInfo::E_NO_FACE;   
00461                         //return pi.status;  no face is not a critical error. let's continue.
00462                       }
00463       
00464               }
00465             // Descrittori facoltativi dei flags
00466   
00467             if(VertexType::HasFlags() && pf.AddToRead(VertDesc(3))!=-1 ) 
00468               pi.mask |= JfrMask::IOM_VERTFLAGS;
00469 
00470             if( VertexType::HasNormal() )
00471               {
00472                 if(   pf.AddToRead(VertDesc(12))!=-1 
00473                       && pf.AddToRead(VertDesc(13))!=-1 
00474                       && pf.AddToRead(VertDesc(14))!=-1 )
00475                   pi.mask |= JfrMask::IOM_VERTNORMAL;
00476               }
00477    
00478             if( VertexType::HasQuality() )
00479               {
00480                 if( pf.AddToRead(VertDesc(4))!=-1 ||
00481                     pf.AddToRead(VertDesc(11))!=-1 )
00482                   pi.mask |= JfrMask::IOM_VERTQUALITY;
00483               }
00484 
00485             if( VertexType::HasColor() )
00486               {
00487                 if( pf.AddToRead(VertDesc(5))!=-1 )
00488                   {
00489                     pf.AddToRead(VertDesc(6));
00490                     pf.AddToRead(VertDesc(7));
00491                     pi.mask |= JfrMask::IOM_VERTCOLOR;
00492                   }
00493                 if( pf.AddToRead(VertDesc(8))!=-1 )
00494                   {
00495                     pf.AddToRead(VertDesc(9));
00496                     pf.AddToRead(VertDesc(10));
00497                     pi.mask |= JfrMask::IOM_VERTCOLOR;
00498                   }
00499                 if( pf.AddToRead(VertDesc(19))!=-1 )
00500                   {
00501                     hasIntensity = true; 
00502                     pi.mask |= JfrMask::IOM_VERTCOLOR;
00503                   }
00504 
00505               }
00506             if( tri::HasPerVertexTexCoord(m) )
00507               {
00508                 if(( pf.AddToRead(VertDesc(20))!=-1 )&&  (pf.AddToRead(VertDesc(21))!=-1))
00509                   {
00510                     pi.mask |= JfrMask::IOM_VERTTEXCOORD;
00511                   }
00512                 if(( pf.AddToRead(VertDesc(16))!=-1 )&&  (pf.AddToRead(VertDesc(17))!=-1))
00513                   {
00514                     pi.mask |= JfrMask::IOM_VERTTEXCOORD;
00515                   }
00516               }
00517             if(tri::HasPerVertexRadius(m))
00518               {
00519                 if( pf.AddToRead(VertDesc(15))!=-1 )
00520                   pi.mask |= JfrMask::IOM_VERTRADIUS;
00521               }
00522             if( vcg::tri::HasPerVertexAttribute(m, "Id") )
00523               {
00524                 if(pf.AddToRead(VertDesc(22))!=-1)
00525                   pi.mask |= JfrMask::IOM_VERTID;
00526               }
00527             if( vcg::tri::HasPerVertexAttribute(m, "Origines") )
00528               {
00529                 if(pf.AddToRead(VertDesc(23))!=-1)
00530                   pi.mask |= JfrMask::IOM_VERTORIGINES;
00531               }
00532             // se ci sono i flag per vertice ci devono essere anche i flag per faccia
00533             if( pf.AddToRead(FaceDesc(1))!=-1 )
00534               pi.mask |= JfrMask::IOM_FACEFLAGS;
00535 
00536             if( FaceType::HasFaceQuality())
00537               {
00538                 if( pf.AddToRead(FaceDesc(2))!=-1 )
00539                   pi.mask |= JfrMask::IOM_FACEQUALITY;
00540               }
00541 
00542             if( FaceType::HasFaceColor() )
00543               {
00544                 if( pf.AddToRead(FaceDesc(6))!=-1 )
00545                   {
00546                     pf.AddToRead(FaceDesc(7));
00547                     pf.AddToRead(FaceDesc(8));
00548                     pi.mask |= JfrMask::IOM_FACECOLOR;
00549                   }
00550               }
00551 
00552 
00553             if( FaceType::HasWedgeTexCoord() )
00554               {
00555                 if( pf.AddToRead(FaceDesc(3))!=-1 )
00556                   {
00557                     if(pf.AddToRead(FaceDesc(5))==0) {
00558                       multit=true; // try to read also the multi texture indicies
00559                       pi.mask |= JfrMask::IOM_WEDGTEXMULTI;
00560                     }
00561                     pi.mask |= JfrMask::IOM_WEDGTEXCOORD;
00562                   }
00563               }
00564 
00565             if( FaceType::HasWedgeColor() || FaceType::HasFaceColor() || VertexType::HasColor())
00566               {
00567                 if( pf.AddToRead(FaceDesc(4))!=-1 )
00568                   {
00569                     pi.mask |= JfrMask::IOM_WEDGCOLOR;
00570                   }
00571               }
00572 
00573             // Descrittori definiti dall'utente, 
00574             std::vector<PropDescriptor> VPV(pi.vdn); // property descriptor relative al tipo LoadPly_VertexAux
00575             std::vector<PropDescriptor> FPV(pi.fdn); // property descriptor relative al tipo LoadPly_FaceAux
00576             if(pi.vdn>0){
00577               // Compute the total size needed to load additional per vertex data.
00578               size_t totsz=0;
00579               for(int i=0;i<pi.vdn;i++){
00580                 VPV[i] = pi.VertexData[i];
00581                 VPV[i].offset1=offsetof(LoadPly_VertAux<ScalarType>,data)+totsz;
00582                 totsz+=pi.VertexData[i].memtypesize();
00583                 if( pf.AddToRead(VPV[i])==-1 ) { pi.status = pf.GetError(); return pi.status; }
00584               }
00585               if(totsz > MAX_USER_DATA) 
00586                 { 
00587                   pi.status = vcg::ply::E_BADTYPE; 
00588                   return pi.status; 
00589                 }
00590             }
00591             if(pi.fdn>0){
00592               size_t totsz=0;
00593               for(int i=0;i<pi.fdn;i++){
00594                 FPV[i] = pi.FaceData[i];
00595                 FPV[i].offset1=offsetof(LoadPly_FaceAux,data)+totsz;
00596                 totsz+=pi.FaceData[i].memtypesize();
00597                 if( pf.AddToRead(FPV[i])==-1 ) { pi.status = pf.GetError(); return pi.status; }
00598               }
00599               if(totsz > MAX_USER_DATA) 
00600                 { 
00601                   pi.status = vcg::ply::E_BADTYPE; 
00602                   return pi.status; 
00603                 }
00604             }
00605 
00606             /**************************************************************/
00607             /* Main Reading Loop */
00608             /**************************************************************/
00609             m.Clear();
00610             for(int i=0;i<int(pf.elements.size());i++)
00611               {
00612                 int n = pf.ElemNumber(i);
00613                 if( !strcmp( pf.ElemName(i),"camera" ) )
00614                   {
00615                     int scnt;
00616                     pf.SetCurElement(i);
00617                     //                    LoadPly_Camera ca;
00618                     for(scnt = 0; scnt < n; ++scnt)
00619                       {
00620                         int res = pf.Read((void*) &(ca));
00621                         if( res ==-1 )
00622                           {
00623                             pi.status = PlyInfo::E_SHORTFILE;
00624                             return pi.status;
00625                           } 
00626                         //camera.valid     = true;
00627                         // extrinsic
00628                         m.shots[ca.id].Extrinsics.SetIdentity();
00629                         // view point
00630                         m.shots[ca.id].Extrinsics.SetTra(Point3<ScalarType>( -ca.view_px,-ca.view_py,-ca.view_pz));
00631   
00632                         // axis (i.e. rotation).
00633                         Matrix44<ScalarType> rm;
00634                         rm.SetIdentity();
00635                         rm[0][0] = ca.x_axisx;
00636                         rm[0][1] = ca.x_axisy;
00637                         rm[0][2] = ca.x_axisz;
00638                         
00639                         rm[1][0] = ca.y_axisx;
00640                         rm[1][1] = ca.y_axisy;
00641                         rm[1][2] = ca.y_axisz;
00642                         
00643                         rm[2][0] = ca.z_axisx;
00644                         rm[2][1] = ca.z_axisy;
00645                         rm[2][2] = ca.z_axisz;
00646                         
00647                         m.shots[ca.id].Extrinsics.SetRot(rm);
00648                         
00649                         //intrinsic
00650                         m.shots[ca.id].Intrinsics.FocalMm        = ca.focal;
00651                         m.shots[ca.id].Intrinsics.PixelSizeMm[0] = ca.scalex;
00652                         m.shots[ca.id].Intrinsics.PixelSizeMm[1] = ca.scaley;
00653                         m.shots[ca.id].Intrinsics.CenterPx[0]    = ca.centerx;
00654                         m.shots[ca.id].Intrinsics.CenterPx[1]    = ca.centery;
00655                         m.shots[ca.id].Intrinsics.ViewportPx[0]  = ca.viewportx;
00656                         m.shots[ca.id].Intrinsics.ViewportPx[1]  = ca.viewporty;
00657                         m.shots[ca.id].Intrinsics.k[0]           = ca.k1;
00658                         m.shots[ca.id].Intrinsics.k[1]           = ca.k2;
00659                         m.shots[ca.id].Intrinsics.k[2]           = ca.k3;
00660                         m.shots[ca.id].Intrinsics.k[3]           = ca.k4;
00661                       }
00662                     m.sn = scnt;
00663                   }
00664                 else if( !strcmp( pf.ElemName(i),"feature" ) )
00665                   {
00666                     pf.SetCurElement(i);
00667                     int ftcnt;
00668                     //                    LoadPly_Feature fta; 
00669                     for(ftcnt=0; ftcnt<n; ++ftcnt )
00670                       {
00671                         if( pf.Read( (void *)&(fta) )==-1 )
00672                           {
00673                             pi.status = PlyInfo::E_SHORTFILE;
00674                             return pi.status;                           
00675                           }
00676                         fdetect_v2::InterestFeature<fdetect_v2::FloatDescriptor> *ft = new fdetect_v2::InterestFeature<fdetect_v2::FloatDescriptor>(fta.u, fta.v);
00677                         ft->setId(fta.id);
00678                         ft->setIndex(fta.index);
00679                         ft->setQuality(fta.quality);
00680                         ft->parent_id = fta.parent_id;
00681                         fdetect_v2::FloatDescriptor fd(&fta.desc[0], (fta.desc +fta.desc_length), fta.coef);
00682                         ft->setDescriptor(fd);
00683                         m.addFeature(ft);
00684                       }
00685                     m.ftn = ftcnt;
00686                   }
00687                 else if( !strcmp( pf.ElemName(i),"vertex" ) )
00688                   {
00689                     int j;
00690 
00691                     pf.SetCurElement(i);
00692                     VertexIterator vi=Allocator<OpenMeshType>::AddVertices(m,n);
00693       
00694                     for(j=0;j<n;++j)
00695                       {
00696                         if(pi.cb && (j%1000)==0) pi.cb(j*50/n,"Vertex Loading");
00697                         //(*vi).UberFlags()=0; // No more necessary, since 9/2005 flags are set to zero in the constuctor.
00698                         if( pf.Read( (void *)&(va) )==-1 )
00699                           {
00700                             pi.status = PlyInfo::E_SHORTFILE;
00701                             return pi.status;
00702                           }
00703         
00704                         (*vi).P()[0] = va.p[0];
00705                         (*vi).P()[1] = va.p[1];
00706                         (*vi).P()[2] = va.p[2];
00707 
00708                         if( m.HasPerVertexFlags() &&  (pi.mask & JfrMask::IOM_VERTFLAGS) )
00709                           (*vi).UberFlags() = va.flags;
00710 
00711                         if( pi.mask & JfrMask::IOM_VERTQUALITY )
00712                           (*vi).Q() = (typename OpenMeshType::VertexType::QualityType)va.q;
00713 
00714                         if( pi.mask & JfrMask::IOM_VERTNORMAL )
00715                           {
00716                             (*vi).N()[0]=va.n[0];
00717                             (*vi).N()[1]=va.n[1];
00718                             (*vi).N()[2]=va.n[2];
00719                           }
00720 
00721                         if( pi.mask & JfrMask::IOM_VERTTEXCOORD )
00722                           {
00723                             (*vi).T().P().X() = va.u;
00724                             (*vi).T().P().Y() = va.v;
00725                           }
00726         
00727                         if( pi.mask & JfrMask::IOM_VERTCOLOR )
00728                           {
00729                             if(hasIntensity)
00730                               (*vi).C().SetGrayShade(va.intensity);
00731                             else
00732                               {
00733                                 (*vi).C()[0] = va.r;
00734                                 (*vi).C()[1] = va.g;
00735                                 (*vi).C()[2] = va.b;
00736                                 (*vi).C()[3] = 255;
00737                               }
00738                           }
00739                         if( pi.mask & JfrMask::IOM_VERTRADIUS )
00740                           (*vi).R() = va.radius; 
00741                         if( vcg::tri::HasPerVertexAttribute(m, "Id") )
00742                           {
00743                             m.id_setter[vi] = va.id;
00744                           }
00745                         if( vcg::tri::HasPerVertexAttribute(m, "Origines") )
00746                           {
00747                             for(unsigned int i = 0; i < va.size; ++i)
00748                               m.origines_setter[vi].push_back(va.ft[i]);
00749                           }
00750 
00751                         for(int k=0;k<pi.vdn;k++) 
00752                           memcpy((char *)(&*vi) + pi.VertexData[k].offset1,
00753                                  (char *)(&va) + VPV[k].offset1, 
00754                                  VPV[k].memtypesize());
00755                         ++vi;
00756                       }
00757 
00758                     index.resize(n);
00759                     for(j=0,vi=m.vert.begin();j<n;++j,++vi)
00760                       index[j] = &*vi;
00761                   }
00762                 else if( !strcmp( pf.ElemName(i),"face") && (n>0) )/************************************************************/
00763                   {
00764                     int j;
00765       
00766                     FaceIterator fi=Allocator<OpenMeshType>::AddFaces(m,n);
00767                     pf.SetCurElement(i);
00768 
00769                     for(j=0;j<n;++j)
00770                       {
00771                         int k;
00772 
00773                         if(pi.cb && (j%1000)==0) pi.cb(50+j*50/n,"Face Loading");
00774                         if( pf.Read(&fa)==-1 )
00775                           {
00776                             pi.status = PlyInfo::E_SHORTFILE;
00777                             return pi.status;
00778                           }
00779                         if(fa.size!=3)
00780                           { // Non triangular face are manageable ONLY if there are no Per Wedge attributes
00781                             if( ( pi.mask & JfrMask::IOM_WEDGCOLOR ) || ( pi.mask & JfrMask::IOM_WEDGTEXCOORD ) )
00782                               { 
00783                                 pi.status = PlyInfo::E_NO_3VERTINFACE;
00784                                 return pi.status;
00785                               }
00786                           }
00787         
00788                         if(m.HasPolyInfo()) (*fi).Alloc(3);
00789 
00790                         if(m.HasPerFaceFlags() &&( pi.mask & JfrMask::IOM_FACEFLAGS) )
00791                           {
00792                             (*fi).UberFlags() = fa.flags;
00793                           }
00794 
00795                         if( pi.mask & JfrMask::IOM_FACEQUALITY )
00796                           {
00797                             (*fi).Q() = (typename OpenMeshType::FaceType::QualityType) fa.q;
00798                           }
00799 
00800                         if( pi.mask & JfrMask::IOM_FACECOLOR )
00801                           {
00802                             (*fi).C()[0] = fa.r;
00803                             (*fi).C()[1] = fa.g;
00804                             (*fi).C()[2] = fa.b;
00805                             (*fi).C()[3] = 255;
00806                           }
00807 
00808                         if( pi.mask & JfrMask::IOM_WEDGTEXCOORD )
00809                           {
00810                             for(int k=0;k<3;++k)
00811                               {
00812                                 (*fi).WT(k).u() = fa.texcoord[k*2+0];
00813                                 (*fi).WT(k).v() = fa.texcoord[k*2+1];
00814                                 if(multit) (*fi).WT(k).n() = fa.texcoordind;
00815                                 else (*fi).WT(k).n()=0; // safely intialize texture index
00816                               }
00817                           }
00818 
00819                         if( pi.mask & JfrMask::IOM_WEDGCOLOR )
00820                           {
00821                             if(FaceType::HasWedgeColor()){
00822                               for(int k=0;k<3;++k)
00823                                 {
00824                                   (*fi).WC(k)[0] = (unsigned char)(fa.colors[k*3+0]*255);
00825                                   (*fi).WC(k)[1] = (unsigned char)(fa.colors[k*3+1]*255);
00826                                   (*fi).WC(k)[2] = (unsigned char)(fa.colors[k*3+2]*255);
00827                                 }
00828                             }
00829                             //if(FaceType::HasFaceColor()){
00830                             //if(pi.mask & JfrMask::IOM_FACECOLOR){
00831                             if(HasPerFaceColor(m))  {
00832                               (*fi).C()[0] = (unsigned char)((fa.colors[0*3+0]*255+fa.colors[1*3+0]*255+fa.colors[2*3+0]*255)/3.0f);
00833                               (*fi).C()[1] = (unsigned char)((fa.colors[0*3+1]*255+fa.colors[1*3+1]*255+fa.colors[2*3+1]*255)/3.0f);
00834                               (*fi).C()[2] = (unsigned char)((fa.colors[0*3+2]*255+fa.colors[1*3+2]*255+fa.colors[2*3+2]*255)/3.0f);
00835                             }
00836                           }
00839                         for(k=0;k<3;++k)
00840                           {
00841                             if( fa.v[k]<0 || fa.v[k]>=m.vn )
00842                               {
00843                                 pi.status = PlyInfo::E_BAD_VERT_INDEX;
00844                                 return pi.status;
00845                               }
00846                             (*fi).V(k) = index[ fa.v[k] ];
00847                           }
00848 
00849                         // tag faux vertices of first face
00850                         if (fa.size>3) fi->SetF(2); 
00851 
00852                         for(k=0;k<pi.fdn;k++) 
00853                           memcpy((char *)(&(*fi)) + pi.FaceData[k].offset1,
00854                                  (char *)(&fa) + FPV[k].offset1, 
00855                                  FPV[k].memtypesize());
00856 
00857 
00858                         ++fi;
00859     
00860                         // Non Triangular Faces Loop
00861                         // It performs a simple fan triangulation.
00862                         if(fa.size>3)
00863                           {
00864                             int curpos=int(fi-m.face.begin());
00865                             Allocator<OpenMeshType>::AddFaces(m,fa.size-3);
00866                             fi=m.face.begin()+curpos;
00867                             pi.mask |= JfrMask::IOM_BITPOLYGONAL;
00868                           }     
00869                         for(int qq=0;qq<fa.size-3;++qq)
00870                           {
00871                             (*fi).V(0) = index[ fa.v[0] ];
00872                             for(k=1;k<3;++k)
00873                               {
00874                                 if( fa.v[2+qq]<0 || fa.v[2+qq]>=m.vn )
00875                                   {
00876                                     pi.status = PlyInfo::E_BAD_VERT_INDEX;
00877                                     return pi.status;
00878                                   }
00879                                 (*fi).V(k) = index[ fa.v[1+qq+k] ];
00880             
00881                               }
00882   
00883                             // tag faux vertices of extra faces
00884                             fi->SetF(0);
00885                             if (qq!=fa.size-3) fi->SetF(2);
00886           
00887                             for(k=0;k<pi.fdn;k++) 
00888                               memcpy((char *)(&(*fi)) + pi.FaceData[k].offset1,
00889                                      (char *)(&fa) + FPV[k].offset1, FPV[k].memtypesize());
00890                             ++fi;
00891                           }
00892 
00893                       }
00894                   }else if( !strcmp( pf.ElemName(i),"tristrips") )
00895                   { 
00896                     // Warning the parsing of tristrips could not work if OCF types are used
00897                     FaceType tf;  
00898                     if( HasPerFaceQuality(m) )  tf.Q()=(typename OpenMeshType::FaceType::QualityType)1.0;
00899                     if( FaceType::HasWedgeColor() )   tf.WC(0)=tf.WC(1)=tf.WC(2)=Color4b(Color4b::White);
00900                     if( HasPerFaceColor(m) )    tf.C()=Color4b(Color4b::White);     
00901 
00902                     int j;
00903                     pf.SetCurElement(i);
00904                     int numvert_tmp = (int)m.vert.size();
00905                     for(j=0;j<n;++j)
00906                       {
00907                         int k;
00908                         if(pi.cb && (j%1000)==0) pi.cb(50+j*50/n,"Tristrip Face Loading");
00909                         if( pf.Read(&tsa)==-1 )
00910                           {
00911                             pi.status = PlyInfo::E_SHORTFILE;
00912                             return pi.status;
00913                           }
00914                         int remainder=0;
00915                         //int startface=m.face.size();
00916                         for(k=0;k<tsa.size-2;++k)
00917                           {
00918                             if(pi.cb && (k%1000)==0) pi.cb(50+k*50/tsa.size,"Tristrip Face Loading");       
00919                             if(tsa.v[k]<0 || tsa.v[k]>=numvert_tmp )  {
00920                               pi.status = PlyInfo::E_BAD_VERT_INDEX;
00921                               return pi.status;
00922                             }
00923                             if(tsa.v[k+2]==-1)
00924                               {
00925                                 k+=2;
00926                                 if(k%2) remainder=0;
00927                                 else remainder=1;
00928                                 continue;
00929                               }
00930                             tf.V(0) = index[ tsa.v[k+0] ];
00931                             tf.V(1) = index[ tsa.v[k+1] ];
00932                             tf.V(2) = index[ tsa.v[k+2] ];
00933                             if((k+remainder)%2) math::Swap (tf.V(0), tf.V(1) );
00934                             m.face.push_back( tf );
00935                           }
00936                       }
00937                   }
00938                 else if( !strcmp( pf.ElemName(i),"range_grid") )
00939                   {
00940                     //qDebug("Starting Reading of Range Grid");
00941                     if(RangeGridCols==0) // not initialized. 
00942                       {
00943                         for(int co=0;co<int(pf.comments.size());++co)
00944                           {
00945                             std::string num_cols = "num_cols";
00946                             std::string num_rows = "num_rows";
00947                             std::string &c = pf.comments[co];
00948                             std::string bufstr,bufclean;
00949                             if( num_cols == c.substr(0,num_cols.length()) ) 
00950                               {
00951                                 bufstr = c.substr(num_cols.length()+1);
00952                                 RangeGridCols = atoi(bufstr.c_str());
00953                               }
00954                             if( num_rows == c.substr(0,num_cols.length()) ) 
00955                               {
00956                                 bufstr = c.substr(num_rows.length()+1);
00957                                 RangeGridRows = atoi(bufstr.c_str());
00958                               }
00959                           }
00960                         //qDebug("Rows %i Cols %i",RangeGridRows,RangeGridCols);
00961                       }
00962                     int totPnt = RangeGridCols*RangeGridRows;
00963                     // standard reading;
00964                     pf.SetCurElement(i);
00965                     for(int j=0;j<totPnt;++j)
00966                       {
00967                         if(pi.cb && (j%1000)==0) pi.cb(50+j*50/totPnt,"RangeMap Face Loading");
00968                         if( pf.Read(&rga)==-1 )
00969                           {
00970                             //qDebug("Error after loading %i elements",j);
00971                             pi.status = PlyInfo::E_SHORTFILE;
00972                             return pi.status;
00973                           }
00974                         else 
00975                           {
00976                             if(rga.num_pts == 0)
00977                               RangeGridAuxVec.push_back(-1);
00978                             else 
00979                               RangeGridAuxVec.push_back(rga.pts[0]);
00980                           }
00981                       } 
00982                     //qDebug("Completed the reading of %i indexes",RangeGridAuxVec.size());
00983                     tri::FaceGrid(m, RangeGridAuxVec, RangeGridCols,RangeGridRows);
00984                   }
00985                 else
00986                   {
00987                     // Skippaggio elementi non gestiti
00988                     int n = pf.ElemNumber(i);
00989                     pf.SetCurElement(i);
00990 
00991                     for(int j=0;j<n;j++)
00992                       {
00993                         if( pf.Read(0)==-1)
00994                           {
00995                             pi.status = PlyInfo::E_SHORTFILE;
00996                             return pi.status;
00997                           }
00998                       }
00999                   }
01000               }
01001 
01002             // Parsing texture names
01003             m.textures.clear();
01004             m.normalmaps.clear();
01005 
01006             for(int co=0;co<int(pf.comments.size());++co)
01007               {
01008                 std::string TFILE = "TextureFile";
01009                 std::string NFILE = "TextureNormalFile";
01010                 std::string &c = pf.comments[co];
01011                 //    char buf[256];
01012                 std::string bufstr,bufclean;
01013                 int i,n;
01014 
01015                 if( TFILE == c.substr(0,TFILE.length()) ) 
01016                   {
01017                     bufstr = c.substr(TFILE.length()+1);
01018                     n = static_cast<int>(bufstr.length());
01019                     for(i=0;i<n;i++)
01020                       if( bufstr[i]!=' ' && bufstr[i]!='\t' && bufstr[i]>32 && bufstr[i]<125 )  bufclean.push_back(bufstr[i]);
01021       
01022                     char buf2[255];
01023                     ply::interpret_texture_name( bufclean.c_str(),filename,buf2 );
01024                     m.textures.push_back( std::string(buf2) );
01025                   }
01026                 /*if( !strncmp(c,NFILE,strlen(NFILE)) )
01027                   {
01028                   strcpy(buf,c+strlen(NFILE)+1);
01029                   n = strlen(buf);
01030                   for(i=j=0;i<n;i++)
01031                   if( buf[i]!=' ' && buf[i]!='\t' && buf[i]>32 && buf[i]<125 )  buf[j++] = buf[i];
01032       
01033                   buf[j] = 0;
01034                   char buf2[255];
01035                   __interpret_texture_name( buf,filename,buf2 );
01036                   m.normalmaps.push_back( string(buf2) );
01037                   }*/
01038               }
01039 
01040             // vn and fn should be correct but if someone wrongly saved some deleted elements they can be wrong.
01041             m.vn = 0;
01042             VertexIterator vi;
01043             for(vi=m.vert.begin();vi!=m.vert.end();++vi)
01044               if( ! (*vi).IsD() )
01045                 ++m.vn;
01046 
01047             m.fn = 0;
01048             FaceIterator fi;
01049             for(fi=m.face.begin();fi!=m.face.end();++fi)
01050               if( ! (*fi).IsD() )
01051                 ++m.fn;
01052 
01053             return 0;
01054           }
01055 
01056 
01057           // Caricamento camera da un ply
01058           int LoadCamera(const char * filename)
01059           {
01060             vcg::ply::PlyFile pf;
01061             if( pf.Open(filename,vcg::ply::PlyFile::MODE_READ)==-1 )
01062               {
01063                 this->pi.status = pf.GetError();
01064                 return this->pi.status;
01065               }
01066 
01067 
01068             bool found = true;
01069             int i;
01070             for(i=0;i<23;++i)
01071               {
01072                 if( pf.AddToRead(CameraDesc(i))==-1 )
01073                   {
01074                     found = false;
01075                     break;
01076                   }
01077               }
01078 
01079             if(!found)
01080               return this->pi.status;
01081 
01082             for(i=0;i<int(pf.elements.size());i++)
01083               {
01084                 int n = pf.ElemNumber(i);
01085 
01086                 if( !strcmp( pf.ElemName(i),"camera" ) )
01087                   {
01088                     pf.SetCurElement(i);
01089 
01090                     LoadPly_Camera ca;
01091 
01092                     for(int j=0;j<n;++j)
01093                       {
01094                         if( pf.Read( (void *)&(ca) )==-1 )
01095                           {
01096                             this->pi.status = PlyInfo::E_SHORTFILE;
01097                             return this->pi.status;
01098                           } 
01099                         this->camera.valid     = true;
01100                         this->camera.view_p[0] = ca.view_px;
01101                         this->camera.view_p[1] = ca.view_py;
01102                         this->camera.view_p[2] = ca.view_pz;
01103                         this->camera.x_axis[0] = ca.x_axisx;
01104                         this->camera.x_axis[1] = ca.x_axisy;
01105                         this->camera.x_axis[2] = ca.x_axisz;
01106                         this->camera.y_axis[0] = ca.y_axisx;
01107                         this->camera.y_axis[1] = ca.y_axisy;
01108                         this->camera.y_axis[2] = ca.y_axisz;
01109                         this->camera.z_axis[0] = ca.z_axisx;
01110                         this->camera.z_axis[1] = ca.z_axisy;
01111                         this->camera.z_axis[2] = ca.z_axisz;
01112                         this->camera.f         = ca.focal;
01113                         this->camera.s[0]      = ca.scalex;
01114                         this->camera.s[1]      = ca.scaley;
01115                         this->camera.c[0]      = ca.centerx;
01116                         this->camera.c[1]      = ca.centery;
01117                         this->camera.viewport[0] = ca.viewportx;
01118                         this->camera.viewport[1] = ca.viewporty;
01119                         this->camera.k[0]      = ca.k1;
01120                         this->camera.k[1]      = ca.k2;
01121                         this->camera.k[2]      = ca.k3;
01122                         this->camera.k[3]      = ca.k4;
01123                       }
01124                     break;
01125                   }
01126               }
01127 
01128             return 0;
01129           }
01130 
01131 
01132           static bool LoadJfrMask(const char * filename, int &mask)
01133           {
01134             PlyInfo pi;
01135             return LoadJfrMask(filename, mask,pi);
01136           }
01137           static bool LoadJfrMask(const char * filename, int &mask, PlyInfo &pi)
01138           {
01139             mask=0;
01140             vcg::ply::PlyFile pf;
01141             if( pf.Open(filename,vcg::ply::PlyFile::MODE_READ)==-1 )
01142               {
01143                 pi.status = pf.GetError();
01144                 return false;
01145               }
01146 
01147             if( pf.AddToRead(VertDesc(0))!=-1 && 
01148                 pf.AddToRead(VertDesc(1))!=-1 && 
01149                 pf.AddToRead(VertDesc(2))!=-1 )   mask |= JfrMask::IOM_VERTCOORD;
01150 
01151             if( pf.AddToRead(VertDesc(12))!=-1 && 
01152                 pf.AddToRead(VertDesc(13))!=-1 && 
01153                 pf.AddToRead(VertDesc(14))!=-1 )   mask |= JfrMask::IOM_VERTNORMAL;
01154 
01155             if( pf.AddToRead(VertDesc(3))!=-1 )   mask |= JfrMask::IOM_VERTFLAGS;
01156             if( pf.AddToRead(VertDesc(4))!=-1 )   mask |= JfrMask::IOM_VERTQUALITY;
01157             if( pf.AddToRead(VertDesc(11))!=-1 )  mask |= JfrMask::IOM_VERTQUALITY;
01158             if( pf.AddToRead(VertDesc(15))!=-1 )  mask |= JfrMask::IOM_VERTRADIUS;
01159             if( ( pf.AddToRead(VertDesc( 5))!=-1 ) && 
01160                 ( pf.AddToRead(VertDesc( 6))!=-1 ) &&
01161                 ( pf.AddToRead(VertDesc( 7))!=-1 )  )  mask |= JfrMask::IOM_VERTCOLOR;
01162             if( ( pf.AddToRead(VertDesc( 8))!=-1 ) && 
01163                 ( pf.AddToRead(VertDesc( 9))!=-1 ) &&
01164                 ( pf.AddToRead(VertDesc(10))!=-1 )  )  mask |= JfrMask::IOM_VERTCOLOR;
01165             if(   pf.AddToRead(VertDesc(19))!=-1 )     mask |= JfrMask::IOM_VERTCOLOR;
01166   
01167             if(( pf.AddToRead(VertDesc(20))!=-1 ) &&  (pf.AddToRead(VertDesc(21))!=-1))
01168               mask |= JfrMask::IOM_VERTTEXCOORD;
01169      
01170             if(( pf.AddToRead(VertDesc(16))!=-1 ) &&  (pf.AddToRead(VertDesc(17))!=-1))
01171               mask |= JfrMask::IOM_VERTTEXCOORD;
01172     
01173             if( pf.AddToRead(FaceDesc(0))!=-1 ) mask |= JfrMask::IOM_FACEINDEX;
01174             if( pf.AddToRead(FaceDesc(1))!=-1 ) mask |= JfrMask::IOM_FACEFLAGS;
01175 
01176             if( pf.AddToRead(FaceDesc(2))!=-1 ) mask |= JfrMask::IOM_FACEQUALITY;
01177             if( pf.AddToRead(FaceDesc(3))!=-1 ) mask |= JfrMask::IOM_WEDGTEXCOORD;
01178             if( pf.AddToRead(FaceDesc(5))!=-1 ) mask |= JfrMask::IOM_WEDGTEXMULTI;
01179             if( pf.AddToRead(FaceDesc(4))!=-1 ) mask |= JfrMask::IOM_WEDGCOLOR;
01180             if( ( pf.AddToRead(FaceDesc(6))!=-1 ) && 
01181                 ( pf.AddToRead(FaceDesc(7))!=-1 ) &&
01182                 ( pf.AddToRead(FaceDesc(8))!=-1 )  )  mask |= JfrMask::IOM_FACECOLOR;
01183 
01184 
01185             return true;
01186           }
01187 
01188 
01189         }; // end class
01190 
01191 
01192 
01193     } // end namespace tri
01194   } // end namespace io
01195 } // end namespace vcg
01196 
01197 #endif
01198 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Wed Oct 15 2014 00:37:25 for Jafar by doxygen 1.7.6.1
LAAS-CNRS