00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
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
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
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
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
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
00170 std::vector<nanoply::ElementDescriptor*> meshDescr;
00171 meshDescr.push_back(&vertex);
00172 meshDescr.push_back(&face);
00173 meshDescr.push_back(&material);
00174
00175
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
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
00199 std::vector<nanoply::PlyProperty> faceProp;
00200 faceProp.push_back(nanoply::PlyProperty(nanoply::NNP_LIST_UINT8_UINT32, nanoply::NNP_FACE_VERTEX_LIST));
00201
00202
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
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
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
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
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
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
00247 std::vector<nanoply::ElementDescriptor*> meshDescr;
00248 meshDescr.push_back(&vertex);
00249 meshDescr.push_back(&face);
00250 meshDescr.push_back(&material);
00251
00252
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 }