main.cpp
Go to the documentation of this file.
00001 /****************************************************************************
00002 * NanoPLY                                                                   *
00003 * NanoPLY is a C++11 header-only library to read and write PLY file         *
00004 *                                                                           *
00005 * Copyright(C) 2014-2015                                                    *
00006 * Visual Computing Lab                                                      *
00007 * ISTI - Italian National Research Council                                  *
00008 *                                                                           *
00009 * This Source Code Form is subject to the terms of the Mozilla Public       *
00010 * License, v. 2.0. If a copy of the MPL was not distributed with this       *
00011 * file, You can obtain one at http://mozilla.org/MPL/2.0/.                  *
00012 *                                                                           *
00013 ****************************************************************************/
00014 
00015 #include <iostream>
00016 #include <nanoply.hpp>
00017 
00018 template<typename T, int N>
00019 struct Container
00020 {
00021 
00022 public:
00023   T data[N];
00024 
00025   Container(){}
00026 
00027   Container(T* temp, int n)
00028   {
00029     for (int i = 0; i < std::min(n, N); i++)
00030       data[i] = temp[i];
00031   }
00032 
00033   T* V()
00034   {
00035     return data;
00036   }
00037 
00038   bool operator == (Container<T, N> const & m) const
00039   {
00040     bool flag = true;
00041     for (int i = 0; i < N; i++)
00042       flag = flag && (data[i] == m.data[i]);
00043     return flag;
00044   }
00045 };
00046 
00047 
00048 typedef Container<float, 3> Point3f;
00049 typedef Container<unsigned char, 4> Color4f;
00050 typedef Container<int, 3> VertexIndex;
00051 
00052 struct MyVertexInfo
00053 {
00054   Color4f c;
00055   float density;
00056   int materialId;
00057 
00058   bool operator == (MyVertexInfo const & m) const
00059   {
00060     return (c == m.c && m.density == density && m.materialId == materialId);
00061   }
00062 
00063 };
00064 
00065 struct MyMaterialInfo
00066 {
00067   Point3f kd;
00068   Point3f ks;
00069   float rho;
00070 
00071   bool operator == (MyMaterialInfo const & m) const
00072   {
00073     return (kd == m.kd && ks == m.ks && rho == m.rho);
00074   }
00075 };
00076 
00077 
00078 class MyMesh
00079 {
00080 public:
00081   std::vector<Point3f> coordVec;
00082   std::vector<Point3f> normalVec;
00083   std::vector<MyVertexInfo> infoVec;
00084   std::vector<VertexIndex> faceIndex;
00085   std::vector<MyMaterialInfo> material;
00086 
00087   void FillMesh()
00088   {
00089     float pos[] = { 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0 };
00090     int index[] = { 0, 1, 2, 0, 2, 3, 0, 3, 1, 3, 2, 1 };
00091     float norm[] = { 0.57735, 0.57735, 0.57735, -0.57735, 0.57735, -0.57735, -0.57735, -0.57735, 0.57735, 0.57735, -0.57735, -0.57735 };
00092     unsigned char color[] = { 68, 68, 68, 255, 177, 68, 177, 255, 177, 177, 68, 255, 68, 177, 177 };
00093     float density[] = { 3.5, 2.0, 4.0, 3.0 };
00094     float materialId[] = { 1, 0, -1, 1 };
00095     float materialValue[] = { 0.2, 0.3, 0.2, 0.5, 0.5, 0.6, 20.0, 0.1, 0.1, 0.1, 0.7, 0.5, 0.4, 1.0 };
00096     coordVec.push_back(Point3f(pos, 3)); coordVec.push_back(Point3f(&pos[3], 3)); coordVec.push_back(Point3f(&pos[6], 3)); coordVec.push_back(Point3f(&pos[9], 3));
00097     normalVec.push_back(Point3f(norm, 3)); normalVec.push_back(Point3f(&norm[3], 3)); normalVec.push_back(Point3f(&norm[6], 3)); normalVec.push_back(Point3f(&norm[9], 3));
00098     MyVertexInfo info1 = { Color4f(color, 4), density[0], materialId[0] }; infoVec.push_back(info1);
00099     MyVertexInfo info2 = { Color4f(&color[4], 4), density[1], materialId[1] }; infoVec.push_back(info2);
00100     MyVertexInfo info3 = { Color4f(&color[8], 4), density[2], materialId[2] }; infoVec.push_back(info3);
00101     MyVertexInfo info4 = { Color4f(&color[12], 4), density[3], materialId[3] }; infoVec.push_back(info4);
00102     faceIndex.push_back(VertexIndex(index, 3)); faceIndex.push_back(VertexIndex(&index[3], 3)); faceIndex.push_back(VertexIndex(&index[6], 3)); faceIndex.push_back(VertexIndex(&index[9], 3));
00103     MyMaterialInfo mat1 = { Point3f(materialValue, 3), Point3f(&materialValue[3], 3), materialValue[6] }; material.push_back(mat1);
00104     MyMaterialInfo mat2 = { Point3f(&materialValue[7], 3), Point3f(&materialValue[10], 3), materialValue[13] }; material.push_back(mat2);
00105   }
00106 
00107   bool operator == (MyMesh& m)
00108   {
00109     bool flag = (coordVec == m.coordVec);
00110     flag = flag && (normalVec == m.normalVec);
00111     flag = flag && (infoVec == m.infoVec);
00112     flag = flag && (faceIndex == m.faceIndex);
00113     flag = flag && (material == m.material);
00114     return flag;
00115   }
00116 };
00117 
00118 
00119 bool Load(const char* filename, MyMesh& mesh)
00120 {
00121   //Get file info
00122   nanoply::Info info(filename);
00123   if (info.errInfo != nanoply::NNP_OK)
00124   {
00125     std::cout << "Invalid file format" << std::endl;
00126     return false;
00127   }
00128 
00129   //Resize the element containers
00130   int vertCnt = info.GetVertexCount();
00131   if (vertCnt <= 0)
00132   {
00133     std::cout << "The file does't contain any vertex." << std::endl;
00134     return false;
00135   }
00136   mesh.coordVec.resize(vertCnt);
00137   mesh.normalVec.resize(vertCnt);
00138   mesh.infoVec.resize(vertCnt);
00139   int faceCnt = info.GetFaceCount();
00140   mesh.faceIndex.resize(faceCnt);
00141   int materialCnt = info.GetElementCount(std::string("material"));
00142   mesh.material.resize(2);
00143 
00144   //Create the vertex properties descriptor (what ply property and where to save its data)
00145   nanoply::ElementDescriptor vertex(nanoply::NNP_VERTEX_ELEM);
00146   if (vertCnt > 0)
00147   {
00148     vertex.dataDescriptor.push_back(new nanoply::DataDescriptor<Point3f, 3, float>(nanoply::NNP_PXYZ, (*mesh.coordVec.begin()).V()));
00149     vertex.dataDescriptor.push_back(new nanoply::DataDescriptor<Point3f, 3, float>(nanoply::NNP_NXYZ, (*mesh.normalVec.begin()).V()));
00150     vertex.dataDescriptor.push_back(new nanoply::DataDescriptor<MyVertexInfo, 4, unsigned char>(nanoply::NNP_CRGBA, (*mesh.infoVec.begin()).c.V()));
00151     vertex.dataDescriptor.push_back(new nanoply::DataDescriptor<MyVertexInfo, 1, float>(nanoply::NNP_DENSITY, &(*mesh.infoVec.begin()).density));
00152     vertex.dataDescriptor.push_back(new nanoply::DataDescriptor<MyVertexInfo, 1, int>(std::string("materialId"), &(*mesh.infoVec.begin()).materialId));
00153   }
00154 
00155   //Create the face properties descriptor (what ply property and where the data is stored)
00156   nanoply::ElementDescriptor face(nanoply::NNP_FACE_ELEM);
00157   if (mesh.faceIndex.size() > 0)
00158     face.dataDescriptor.push_back(new nanoply::DataDescriptor<VertexIndex, 3, int>(nanoply::NNP_FACE_VERTEX_LIST, (*mesh.faceIndex.begin()).V()));
00159 
00160   //Create the material properties descriptor (what ply property and where the data is stored)
00161   nanoply::ElementDescriptor material(std::string("material"));
00162   if (mesh.material.size() > 0)
00163   {
00164     material.dataDescriptor.push_back(new nanoply::DataDescriptor<MyMaterialInfo, 3, float>(std::string("kd"), (*mesh.material.begin()).kd.V()));
00165     material.dataDescriptor.push_back(new nanoply::DataDescriptor<MyMaterialInfo, 3, float>(std::string("ks"), (*mesh.material.begin()).ks.V()));
00166     material.dataDescriptor.push_back(new nanoply::DataDescriptor<MyMaterialInfo, 1, float>(std::string("rho"), &(*mesh.material.begin()).rho));
00167   }
00168 
00169   //Create the mesh descriptor
00170   std::vector<nanoply::ElementDescriptor*> meshDescr;
00171   meshDescr.push_back(&vertex);
00172   meshDescr.push_back(&face);
00173   meshDescr.push_back(&material);
00174 
00175   //Open the file and save the element data according the relative element descriptor
00176   OpenModel(info, meshDescr);
00177   for (int i = 0; i < vertex.dataDescriptor.size(); i++)
00178     delete vertex.dataDescriptor[i];
00179   for (int i = 0; i < face.dataDescriptor.size(); i++)
00180     delete face.dataDescriptor[i];
00181   for (int i = 0; i < material.dataDescriptor.size(); i++)
00182     delete material.dataDescriptor[i];
00183   return (info.errInfo == nanoply::NNP_OK);
00184 }
00185 
00186 
00187 
00188 bool Save(const char* filename, MyMesh& mesh, bool binary)
00189 {
00190   //Create the vector of vertex properties to save in the file
00191   std::vector<nanoply::PlyProperty> vertexProp;
00192   vertexProp.push_back(nanoply::PlyProperty(nanoply::NNP_FLOAT32, nanoply::NNP_PXYZ));
00193   vertexProp.push_back(nanoply::PlyProperty(nanoply::NNP_FLOAT32, nanoply::NNP_NXYZ));
00194   vertexProp.push_back(nanoply::PlyProperty(nanoply::NNP_FLOAT32, nanoply::NNP_DENSITY));
00195   vertexProp.push_back(nanoply::PlyProperty(nanoply::NNP_FLOAT32, nanoply::NNP_CRGBA));
00196   vertexProp.push_back(nanoply::PlyProperty(nanoply::NNP_INT32, "materialId"));
00197 
00198   //Create the vector of face properties to save in the file
00199   std::vector<nanoply::PlyProperty> faceProp;
00200   faceProp.push_back(nanoply::PlyProperty(nanoply::NNP_LIST_UINT8_UINT32, nanoply::NNP_FACE_VERTEX_LIST));
00201 
00202   //Create the vector of material properties to save in the file
00203   std::vector<nanoply::PlyProperty> materialProp;
00204   materialProp.push_back(nanoply::PlyProperty(nanoply::NNP_LIST_UINT8_FLOAT32, "kd"));
00205   materialProp.push_back(nanoply::PlyProperty(nanoply::NNP_LIST_UINT8_FLOAT32, "ks"));
00206   materialProp.push_back(nanoply::PlyProperty(nanoply::NNP_FLOAT32, "rho"));
00207 
00208   //Create the PlyElement
00209   nanoply::PlyElement vertexElem(nanoply::NNP_VERTEX_ELEM, vertexProp, mesh.coordVec.size());
00210   nanoply::PlyElement faceElem(nanoply::NNP_FACE_ELEM, faceProp, mesh.faceIndex.size());
00211   nanoply::PlyElement materialElem(std::string("material"), materialProp, mesh.material.size());
00212 
00213   //Create the Info object with the data to save in the header
00214   nanoply::Info infoSave;
00215   infoSave.filename = filename;
00216   infoSave.binary = binary;
00217   infoSave.AddPlyElement(vertexElem);
00218   infoSave.AddPlyElement(faceElem);
00219   infoSave.AddPlyElement(materialElem);
00220 
00221   //Create the vertex properties descriptor (what ply property and where the data is stored)
00222   nanoply::ElementDescriptor vertex(nanoply::NNP_VERTEX_ELEM);
00223   if (mesh.coordVec.size() > 0)
00224   {
00225     vertex.dataDescriptor.push_back(new nanoply::DataDescriptor<Point3f, 3, float>(nanoply::NNP_PXYZ, (*mesh.coordVec.begin()).V()));
00226     vertex.dataDescriptor.push_back(new nanoply::DataDescriptor<Point3f, 3, float>(nanoply::NNP_NXYZ, (*mesh.normalVec.begin()).V()));
00227     vertex.dataDescriptor.push_back(new nanoply::DataDescriptor<MyVertexInfo, 4, unsigned char>(nanoply::NNP_CRGBA, (*mesh.infoVec.begin()).c.V()));
00228     vertex.dataDescriptor.push_back(new nanoply::DataDescriptor<MyVertexInfo, 1, float>(nanoply::NNP_DENSITY, &(*mesh.infoVec.begin()).density));
00229     vertex.dataDescriptor.push_back(new nanoply::DataDescriptor<MyVertexInfo, 1, int>(std::string("materialId"), &(*mesh.infoVec.begin()).materialId));
00230   }
00231 
00232   //Create the face properties descriptor (what ply property and where the data is stored)
00233   nanoply::ElementDescriptor face(nanoply::NNP_FACE_ELEM);
00234   if (mesh.faceIndex.size() > 0)
00235     face.dataDescriptor.push_back(new nanoply::DataDescriptor<VertexIndex, 3, int>(nanoply::NNP_FACE_VERTEX_LIST, (*mesh.faceIndex.begin()).V()));
00236 
00237   //Create the material properties descriptor (what ply property and where the data is stored)
00238   nanoply::ElementDescriptor material(std::string("material"));
00239   if (mesh.material.size() > 0)
00240   {
00241     material.dataDescriptor.push_back(new nanoply::DataDescriptor<MyMaterialInfo, 3, float>(std::string("kd"), (*mesh.material.begin()).kd.V()));
00242     material.dataDescriptor.push_back(new nanoply::DataDescriptor<MyMaterialInfo, 3, float>(std::string("ks"), (*mesh.material.begin()).ks.V()));
00243     material.dataDescriptor.push_back(new nanoply::DataDescriptor<MyMaterialInfo, 1, float>(std::string("rho"), &(*mesh.material.begin()).rho));
00244   }
00245 
00246   //Create the mesh descriptor
00247   std::vector<nanoply::ElementDescriptor*> meshDescr;
00248   meshDescr.push_back(&vertex);
00249   meshDescr.push_back(&face);
00250   meshDescr.push_back(&material);
00251 
00252   //Save the file
00253   bool result = nanoply::SaveModel(infoSave.filename, meshDescr, infoSave);
00254 
00255   for (int i = 0; i < vertex.dataDescriptor.size(); i++)
00256     delete vertex.dataDescriptor[i];
00257   for (int i = 0; i < face.dataDescriptor.size(); i++)
00258     delete face.dataDescriptor[i];
00259   for (int i = 0; i < material.dataDescriptor.size(); i++)
00260     delete material.dataDescriptor[i];
00261   return result;
00262 }
00263 
00264 
00265 
00266 int main()
00267 {
00268   MyMesh mesh1;
00269   mesh1.FillMesh();
00270   Save("example_ascii.ply", mesh1, false);
00271   Save("example_binary.ply", mesh1, true);
00272   MyMesh mesh2, mesh3;
00273   Load("example_ascii.ply", mesh2);
00274   Load("example_binary.ply", mesh3);
00275   if (mesh2 == mesh1)
00276     std::cout << "Write and read ASCII ply file:  SUCCESS\n";
00277   else
00278     std::cout << "Write and read ASCII ply file:  FAIL\n";
00279   if (mesh3 == mesh1)
00280     std::cout << "Write and read binary ply file:  SUCCESS\n";
00281   else
00282     std::cout << "Write and read binary ply file:  FAIL\n";
00283   return true;
00284 }


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