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


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:31:58