vcglib/wrap/nanoply/nanoply_vcg/main.cpp

154 lines
6.9 KiB
C++

/****************************************************************************
* 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 <iostream>
#include <wrap/nanoply/include/nanoplyWrapper.hpp>
#include <vcg/complex/complex.h>
#include <vcg/complex/algorithms/create/platonic.h>
#include <vcg/complex/algorithms/update/normal.h>
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<int> vertexMaterial;
MyMesh::PerFaceAttributeHandle<MyVertex::CoordType> faceBarycenter;
MyMesh::PerMeshAttributeHandle<std::vector<Material>> material;
MyMesh()
{
vertexMaterial = vcg::tri::Allocator<MyMesh>::AddPerVertexAttribute<int>(*this, std::string("materialId"));
faceBarycenter = vcg::tri::Allocator<MyMesh>::AddPerFaceAttribute<MyVertex::CoordType>(*this, std::string("barycenter"));
material = vcg::tri::Allocator<MyMesh>::AddPerMeshAttribute<std::vector<Material>>(*this, std::string("material"));
}
void FillMesh()
{
vcg::tri::Icosahedron(*this);
vcg::tri::UpdateNormal<MyMesh>::PerFaceNormalized(*this);
vcg::tri::UpdateNormal<MyMesh>::PerVertexNormalized(*this);
int tempC = 255 / vert.size();
for (int 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 (int 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<MyMesh>::CustomAttributeDescriptor customAttrib;
customAttrib.GetMeshAttrib(filename);
int count = customAttrib.meshAttribCnt["material"];
mesh.material().resize(count);
customAttrib.AddVertexAttribDescriptor<int, int, 1>(std::string("materialId"), nanoply::NNP_INT32, NULL);
customAttrib.AddFaceAttribDescriptor<vcg::Point3f, float, 3>(std::string("barycenter"), nanoply::NNP_LIST_UINT8_FLOAT32, NULL);
if (count > 0)
{
customAttrib.AddMeshAttribDescriptor<Material, float, 3>(std::string("material"), std::string("kd"), nanoply::NNP_FLOAT32, mesh.material()[0].kd.V());
customAttrib.AddMeshAttribDescriptor<Material, float, 3>(std::string("material"), std::string("ks"), nanoply::NNP_FLOAT32, mesh.material()[0].ks.V());
customAttrib.AddMeshAttribDescriptor<Material, float, 1>(std::string("material"), std::string("rho"), nanoply::NNP_FLOAT32, &mesh.material()[0].rho);
}
//Load the ply file
unsigned int mask = 0;
mask |= nanoply::NanoPlyWrapper<MyMesh>::IO_VERTCOORD;
mask |= nanoply::NanoPlyWrapper<MyMesh>::IO_VERTNORMAL;
mask |= nanoply::NanoPlyWrapper<MyMesh>::IO_VERTCOLOR;
mask |= nanoply::NanoPlyWrapper<MyMesh>::IO_VERTRADIUS;
mask |= nanoply::NanoPlyWrapper<MyMesh>::IO_VERTATTRIB;
mask |= nanoply::NanoPlyWrapper<MyMesh>::IO_FACEINDEX;
mask |= nanoply::NanoPlyWrapper<MyMesh>::IO_FACENORMAL;
mask |= nanoply::NanoPlyWrapper<MyMesh>::IO_FACEATTRIB;
mask |= nanoply::NanoPlyWrapper<MyMesh>::IO_MESHATTRIB;
return (nanoply::NanoPlyWrapper<MyMesh>::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<MyMesh>::CustomAttributeDescriptor customAttrib;
customAttrib.AddVertexAttribDescriptor<int, int, 1>(std::string("materialId"), nanoply::NNP_INT32, &mesh.vertexMaterial[0]);
customAttrib.AddFaceAttribDescriptor<vcg::Point3f, float, 3>(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<Material, float, 3>(std::string("material"), std::string("kd"), nanoply::NNP_LIST_UINT8_FLOAT32, mesh.material()[0].kd.V());
customAttrib.AddMeshAttribDescriptor<Material, float, 3>(std::string("material"), std::string("ks"), nanoply::NNP_LIST_UINT8_FLOAT32, mesh.material()[0].ks.V());
customAttrib.AddMeshAttribDescriptor<Material, float, 1>(std::string("material"), std::string("rho"), nanoply::NNP_FLOAT32, &mesh.material()[0].rho);
}
//Save the ply file
unsigned int mask = 0;
mask |= nanoply::NanoPlyWrapper<MyMesh>::IO_VERTCOORD;
mask |= nanoply::NanoPlyWrapper<MyMesh>::IO_VERTNORMAL;
mask |= nanoply::NanoPlyWrapper<MyMesh>::IO_VERTCOLOR;
mask |= nanoply::NanoPlyWrapper<MyMesh>::IO_VERTRADIUS;
mask |= nanoply::NanoPlyWrapper<MyMesh>::IO_VERTATTRIB;
mask |= nanoply::NanoPlyWrapper<MyMesh>::IO_FACEINDEX;
mask |= nanoply::NanoPlyWrapper<MyMesh>::IO_FACENORMAL;
mask |= nanoply::NanoPlyWrapper<MyMesh>::IO_FACEATTRIB;
mask |= nanoply::NanoPlyWrapper<MyMesh>::IO_MESHATTRIB;
return nanoply::NanoPlyWrapper<MyMesh>::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 true;
}