/**************************************************************************** * NanoPLY * * NanoPLY is a C++11 header-only library to read and write PLY file * * * * Copyright(C) 2014-2015 * * Visual Computing Lab * * ISTI - Italian National Research Council * * * * This Source Code Form is subject to the terms of the Mozilla Public * * License, v. 2.0. If a copy of the MPL was not distributed with this * * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * * ****************************************************************************/ #include #include #include #include #include struct Material { vcg::Point3f kd; vcg::Point3f ks; float rho; }; class MyVertex; class MyFace; class MyUsedTypes : public vcg::UsedTypes < vcg::Use< MyVertex >::AsVertexType, vcg::Use< MyFace >::AsFaceType>{}; class MyVertex : public vcg::Vertex < MyUsedTypes, vcg::vertex::Coord3f, vcg::vertex::Normal3f, vcg::vertex::Color4b, vcg::vertex::Radiusf, vcg::vertex::BitFlags>{}; class MyFace : public vcg::Face < MyUsedTypes, vcg::face::VertexRef, vcg::face::Normal3f, vcg::face::BitFlags>{}; class MyMesh : public vcg::tri::TriMesh < std::vector< MyVertex >, std::vector< MyFace > > { public: MyMesh::PerVertexAttributeHandle vertexMaterial; MyMesh::PerFaceAttributeHandle faceBarycenter; MyMesh::PerMeshAttributeHandle> material; MyMesh() { vertexMaterial = vcg::tri::Allocator::AddPerVertexAttribute(*this, std::string("materialId")); faceBarycenter = vcg::tri::Allocator::AddPerFaceAttribute(*this, std::string("barycenter")); material = vcg::tri::Allocator::AddPerMeshAttribute >(*this, std::string("material")); } void FillMesh() { vcg::tri::Icosahedron(*this); vcg::tri::UpdateNormal::PerFaceNormalized(*this); vcg::tri::UpdateNormal::PerVertexNormalized(*this); int tempC = 255 / vert.size(); for (size_t i = 0; i < vert.size(); i++) { if (i < 2) vertexMaterial[i] = -1; else if (i < vert.size() / 2) vertexMaterial[i] = 0; else vertexMaterial[i] = 1; vert[i].R() = i*i / 2.0f; vert[i].C() = vcg::Color4b(tempC*i, tempC*i, tempC*i, 255); } for (size_t i = 0; i < face.size(); i++) faceBarycenter[i] = vcg::Barycenter(face[i]); material().resize(2); material()[0] = { vcg::Point3f(0.1f, 0.2f, 0.3f), vcg::Point3f(0.3f, 0.3f, 0.3f), 5.0f }; material()[1] = { vcg::Point3f(0.1f, 0.1f, 0.1f), vcg::Point3f(0.5f, 0.3f, 0.4f), 50.0f }; } }; bool Load(const char* filename, MyMesh& mesh) { //Create the data descriport for the custom attributes nanoply::NanoPlyWrapper::CustomAttributeDescriptor customAttrib; customAttrib.GetMeshAttrib(filename); int count = customAttrib.meshAttribCnt["material"]; mesh.material().resize(count); customAttrib.AddVertexAttribDescriptor(std::string("materialId"), nanoply::NNP_INT32, NULL); customAttrib.AddFaceAttribDescriptor(std::string("barycenter"), nanoply::NNP_LIST_UINT8_FLOAT32, NULL); if (count > 0) { customAttrib.AddMeshAttribDescriptor(std::string("material"), std::string("kd"), nanoply::NNP_FLOAT32, mesh.material()[0].kd.V()); customAttrib.AddMeshAttribDescriptor(std::string("material"), std::string("ks"), nanoply::NNP_FLOAT32, mesh.material()[0].ks.V()); customAttrib.AddMeshAttribDescriptor(std::string("material"), std::string("rho"), nanoply::NNP_FLOAT32, &mesh.material()[0].rho); } //Load the ply file unsigned int mask = 0; mask |= nanoply::NanoPlyWrapper::IO_VERTCOORD; mask |= nanoply::NanoPlyWrapper::IO_VERTNORMAL; mask |= nanoply::NanoPlyWrapper::IO_VERTCOLOR; mask |= nanoply::NanoPlyWrapper::IO_VERTRADIUS; mask |= nanoply::NanoPlyWrapper::IO_VERTATTRIB; mask |= nanoply::NanoPlyWrapper::IO_FACEINDEX; mask |= nanoply::NanoPlyWrapper::IO_FACENORMAL; mask |= nanoply::NanoPlyWrapper::IO_FACEATTRIB; mask |= nanoply::NanoPlyWrapper::IO_MESHATTRIB; return (nanoply::NanoPlyWrapper::LoadModel(filename, mesh, mask, customAttrib) != 0); } bool Save(const char* filename, MyMesh& mesh, bool binary) { //Create the data descriport for the custom attributes nanoply::NanoPlyWrapper::CustomAttributeDescriptor customAttrib; customAttrib.AddVertexAttribDescriptor(std::string("materialId"), nanoply::NNP_INT32, &mesh.vertexMaterial[0]); customAttrib.AddFaceAttribDescriptor(std::string("barycenter"), nanoply::NNP_LIST_UINT8_FLOAT32, mesh.faceBarycenter[0].V()); if (mesh.material().size() > 0) { customAttrib.AddMeshAttrib(std::string("material"), mesh.material().size()); customAttrib.AddMeshAttribDescriptor(std::string("material"), std::string("kd"), nanoply::NNP_LIST_UINT8_FLOAT32, mesh.material()[0].kd.V()); customAttrib.AddMeshAttribDescriptor(std::string("material"), std::string("ks"), nanoply::NNP_LIST_UINT8_FLOAT32, mesh.material()[0].ks.V()); customAttrib.AddMeshAttribDescriptor(std::string("material"), std::string("rho"), nanoply::NNP_FLOAT32, &mesh.material()[0].rho); } //Save the ply file unsigned int mask = 0; mask |= nanoply::NanoPlyWrapper::IO_VERTCOORD; mask |= nanoply::NanoPlyWrapper::IO_VERTNORMAL; mask |= nanoply::NanoPlyWrapper::IO_VERTCOLOR; mask |= nanoply::NanoPlyWrapper::IO_VERTRADIUS; mask |= nanoply::NanoPlyWrapper::IO_VERTATTRIB; mask |= nanoply::NanoPlyWrapper::IO_FACEINDEX; mask |= nanoply::NanoPlyWrapper::IO_FACENORMAL; mask |= nanoply::NanoPlyWrapper::IO_FACEATTRIB; mask |= nanoply::NanoPlyWrapper::IO_MESHATTRIB; return nanoply::NanoPlyWrapper::SaveModel(filename, mesh, mask, customAttrib, binary); } int main() { MyMesh mesh1; mesh1.FillMesh(); Save("example_ascii.ply", mesh1, false); Save("example_binary.ply", mesh1, true); MyMesh mesh2, mesh3; Load("example_ascii.ply", mesh2); Load("example_binary.ply", mesh3); return 0; }