/**************************************************************************** * 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/. * * * ****************************************************************************/ #ifndef NANOPLY_WRAPPER_VCG_H #define NANOPLY_WRAPPER_VCG_H #include #include #include namespace nanoply { template class NanoPlyWrapper{ private: typedef typename MeshType::PointerToAttribute PointerToAttribute; typedef typename MeshType::ScalarType ScalarType; typedef typename MeshType::VertexType VertexType; typedef typename MeshType::VertexType::ScalarType VertexCoordScalar; typedef typename MeshType::VertexType::NormalType::ScalarType VertexNormScalar; typedef typename MeshType::VertexType::ColorType::ScalarType VertexColorScalar; typedef typename MeshType::VertexType::QualityType VertexQuality; typedef typename MeshType::VertexType::RadiusType VertexRadius; typedef typename MeshType::VertexType::FlagType VertexFlag; typedef typename MeshType::VertexType::TexCoordType::ScalarType VertexTexScalar; typedef typename MeshType::VertexType::CurvatureType::ScalarType VertexCurScalar; typedef typename MeshType::VertexType::CurScalarType VertexDirCurScalar; typedef typename MeshType::VertexType::CurVecType::ScalarType VertexDirCurVecScalar; typedef typename MeshType::EdgeType EdgeType; typedef typename MeshType::EdgeType::ColorType::ScalarType EdgeColorScalar; typedef typename MeshType::EdgeType::QualityType EdgeQuality; typedef typename MeshType::EdgeType::FlagType EdgeFlag; typedef typename MeshType::FaceType FaceType; typedef typename MeshType::FaceType::NormalType::ScalarType FaceNormScalar; typedef typename MeshType::FaceType::ColorType::ScalarType FaceColorScalar; typedef typename MeshType::FaceType::QualityType FaceQuality; typedef typename MeshType::FaceType::FlagType FaceFlag; typedef typename MeshType::FaceType::TexCoordType::ScalarType FaceTexScalar; typedef typename MeshType::FaceType::CurScalarType FaceDirCurScalar; typedef typename MeshType::FaceType::CurVecType::ScalarType FaceDirCurVecScalar; typedef typename MeshType::FaceType::WedgeColorType::ScalarType WedgeColorScalar; typedef typename MeshType::FaceType::WedgeNormalType::ScalarType WedgeNormalScalar; template static PlyType getEntity() { return NNP_UNKNOWN_TYPE }; template<> static PlyType getEntity(){ return NNP_UINT8; }; template<> static PlyType getEntity(){ return NNP_INT8; }; template<> static PlyType getEntity(){ return NNP_UINT16; }; template<> static PlyType getEntity(){ return NNP_INT16; }; template<> static PlyType getEntity(){ return NNP_UINT32; }; template<> static PlyType getEntity(){ return NNP_INT32; }; template<> static PlyType getEntity(){ return NNP_FLOAT32; }; template<> static PlyType getEntity(){ return NNP_FLOAT64; }; template static PlyType getEntityList() { return NNP_UNKNOWN_TYPE; }; template<> static PlyType getEntityList(){ return NNP_LIST_UINT8_UINT8; }; template<> static PlyType getEntityList(){ return NNP_LIST_UINT8_INT8; }; template<> static PlyType getEntityList(){ return NNP_LIST_UINT8_UINT16; }; template<> static PlyType getEntityList(){ return NNP_LIST_UINT8_INT16; }; template<> static PlyType getEntityList(){ return NNP_LIST_UINT8_UINT32; }; template<> static PlyType getEntityList(){ return NNP_LIST_UINT8_INT32; }; template<> static PlyType getEntityList(){ return NNP_LIST_UINT8_FLOAT32; }; template<> static PlyType getEntityList(){ return NNP_LIST_UINT8_FLOAT64; }; template inline static void PushDescriport(std::vector& prop, ElementDescriptor& elem, PlyEntity entity, void* ptr) { prop.push_back(PlyProperty(getEntity(), entity)); DescriptorInterface* di = new DataDescriptor(entity, ptr); elem.dataDescriptor.push_back(di); } template inline static void PushDescriportList(std::vector& prop, ElementDescriptor& elem, PlyEntity entity, void* ptr) { prop.push_back(PlyProperty(getEntityList(), entity)); DescriptorInterface* di = new DataDescriptor(entity, ptr); elem.dataDescriptor.push_back(di); } template inline static void PushDescriport(std::vector& prop, ElementDescriptor& elem, std::string& name, void* ptr) { prop.push_back(PlyProperty(getEntity(), name)); DescriptorInterface* di = new DataDescriptor(name, ptr); elem.dataDescriptor.push_back(di); } template inline static void PushDescriportList(std::vector& prop, ElementDescriptor& elem, std::string& name, void* ptr) { prop.push_back(PlyProperty(getEntityList(), name)); DescriptorInterface* di = new DataDescriptor(name, ptr); elem.dataDescriptor.push_back(di); } public: typedef enum { IO_NONE = 0x00000000, IO_VERTCOORD = 0x00000001, IO_VERTFLAGS = 0x00000002, IO_VERTCOLOR = 0x00000004, IO_VERTQUALITY = 0x00000008, IO_VERTNORMAL = 0x00000010, IO_VERTTEXCOORD = 0x00000020, IO_VERTRADIUS = 0x00000040, IO_VERTCURV = 0x00000080, IO_VERTCURVDIR = 0x00000100, IO_VERTATTRIB = 0x00000200, IO_FACEINDEX = 0x00000400, IO_FACEFLAGS = 0x00000800, IO_FACECOLOR = 0x00001000, IO_FACEQUALITY = 0x00002000, IO_FACENORMAL = 0x00004000, IO_FACECURVDIR = 0x00008000, IO_FACEATTRIB = 0x00010000, IO_EDGEINDEX = 0x00020000, IO_EDGEQUALITY = 0x00040000, IO_EDGECOLOR = 0x00080000, IO_EDGEFLAGS = 0x00100000, IO_EDGEATTRIB = 0x00200000, IO_WEDGCOLOR = 0x00400000, IO_WEDGTEXCOORD = 0x00800000, IO_WEDGTEXMULTI = 0x01000000, // when textrue index is explicit IO_WEDGNORMAL = 0x02000000, IO_BITPOLYGONAL = 0x04000000, // loads explicit polygonal mesh IO_CAMERA = 0x08000000, IO_MESHATTRIB = 0x10000000, IO_FLAGS = IO_VERTFLAGS | IO_FACEFLAGS, IO_ALL = 0xFFFFFFFF }BitMask; class CustomAttributeDescriptor { public: typedef std::map MapMeshAttrib; typedef std::map::iterator MapMeshAttribIter; typedef std::map> MapMeshAttribProp; typedef std::map>::iterator MapMeshAttribPropIter; ElementDescriptor::PropertyDescriptor vertexAttrib; ElementDescriptor::PropertyDescriptor faceAttrib; ElementDescriptor::PropertyDescriptor edgeAttrib; std::vector vertexAttribProp; std::vector faceAttribProp; std::vector edgeAttribProp; MapMeshAttrib meshAttrib; MapMeshAttribProp meshAttribProp; std::map meshAttribCnt; CustomAttributeDescriptor::~CustomAttributeDescriptor() { for (int i = 0; i < vertexAttrib.size(); i++) delete vertexAttrib[i]; for (int i = 0; i < edgeAttrib.size(); i++) delete edgeAttrib[i]; for (int i = 0; i < faceAttrib.size(); i++) delete faceAttrib[i]; CustomAttributeDescriptor::MapMeshAttribIter iter = meshAttrib.begin(); for (; iter != meshAttrib.end(); iter++) for (int i = 0; i < (*iter).second.size(); i++) delete (*iter).second[i]; } template void AddVertexAttribDescriptor(std::string& name, PlyType type, void* ptr) { vertexAttrib.push_back(new DataDescriptor(name, ptr)); vertexAttribProp.push_back(PlyProperty(type, name)); } template void AddEdgeAttribDescriptor(std::string& name, PlyType type, void* ptr) { edgeAttrib.push_back(new DataDescriptor(name, ptr)); edgeAttribProp.push_back(PlyProperty(type, name)); } template void AddFaceAttribDescriptor(std::string& name, PlyType type, void* ptr) { faceAttrib.push_back(new DataDescriptor(name, ptr)); faceAttribProp.push_back(PlyProperty(type, name)); } template void AddMeshAttribDescriptor(std::string& nameAttrib, std::string& nameProp, PlyType type, void* ptr) { meshAttrib[nameAttrib].push_back(new DataDescriptor(nameProp, ptr)); meshAttribProp[nameAttrib].push_back(PlyProperty(type, nameProp)); } void AddMeshAttrib(std::string& name, int cnt) { meshAttribCnt[name] = cnt; } void GetMeshAttrib(std::string filename) { nanoply::Info info(filename); if (info.errInfo == nanoply::NNP_OK) { for (int i = 0; i < info.elemVec.size(); i++) { if (info.elemVec[i].plyElem == NNP_UNKNOWN_ELEM && info.elemVec[i].name != "camera") meshAttribCnt[info.elemVec[i].name] = info.elemVec[i].cnt; } } } }; static int LoadModel(const char* filename, MeshType& mesh, unsigned int bitMask, CustomAttributeDescriptor& custom) { nanoply::Info info(filename); if (info.errInfo != nanoply::NNP_OK) return info.errInfo; //Camera ElementDescriptor cameraDescr(std::string("camera")); vcg::Point3 tra; vcg::Matrix44 rot; size_t count = info.GetElementCount(std::string("camera")); if (count > 0 && (bitMask & BitMask::IO_CAMERA)) { cameraDescr.dataDescriptor.push_back(new DataDescriptor(std::string("view_px"), &tra[0])); cameraDescr.dataDescriptor.push_back(new DataDescriptor(std::string("view_py"), &tra[1])); cameraDescr.dataDescriptor.push_back(new DataDescriptor(std::string("view_pz"), &tra[2])); cameraDescr.dataDescriptor.push_back(new DataDescriptor(std::string("x_axisx"), &rot[0][0])); cameraDescr.dataDescriptor.push_back(new DataDescriptor(std::string("x_axisy"), &rot[0][1])); cameraDescr.dataDescriptor.push_back(new DataDescriptor(std::string("x_axisz"), &rot[0][2])); cameraDescr.dataDescriptor.push_back(new DataDescriptor(std::string("y_axisx"), &rot[1][0])); cameraDescr.dataDescriptor.push_back(new DataDescriptor(std::string("y_axisy"), &rot[1][1])); cameraDescr.dataDescriptor.push_back(new DataDescriptor(std::string("y_axisz"), &rot[1][2])); cameraDescr.dataDescriptor.push_back(new DataDescriptor(std::string("z_axisx"), &rot[2][0])); cameraDescr.dataDescriptor.push_back(new DataDescriptor(std::string("z_axisy"), &rot[2][1])); cameraDescr.dataDescriptor.push_back(new DataDescriptor(std::string("z_axisz"), &rot[2][2])); cameraDescr.dataDescriptor.push_back(new DataDescriptor(std::string("focal"), &mesh.shot.Intrinsics.FocalMm)); cameraDescr.dataDescriptor.push_back(new DataDescriptor(std::string("scalex"), &mesh.shot.Intrinsics.PixelSizeMm[0])); cameraDescr.dataDescriptor.push_back(new DataDescriptor(std::string("scaley"), &mesh.shot.Intrinsics.PixelSizeMm[1])); cameraDescr.dataDescriptor.push_back(new DataDescriptor(std::string("centerx"), &mesh.shot.Intrinsics.CenterPx[0])); cameraDescr.dataDescriptor.push_back(new DataDescriptor(std::string("centery"), &mesh.shot.Intrinsics.CenterPx[1])); cameraDescr.dataDescriptor.push_back(new DataDescriptor(std::string("viewportx"), &mesh.shot.Intrinsics.ViewportPx[0])); cameraDescr.dataDescriptor.push_back(new DataDescriptor(std::string("viewporty"), &mesh.shot.Intrinsics.ViewportPx[1])); cameraDescr.dataDescriptor.push_back(new DataDescriptor(std::string("k1"), &mesh.shot.Intrinsics.k[0])); cameraDescr.dataDescriptor.push_back(new DataDescriptor(std::string("k2"), &mesh.shot.Intrinsics.k[1])); cameraDescr.dataDescriptor.push_back(new DataDescriptor(std::string("k3"), &mesh.shot.Intrinsics.k[2])); cameraDescr.dataDescriptor.push_back(new DataDescriptor(std::string("k4"), &mesh.shot.Intrinsics.k[3])); } //Vertex std::vector nameList; VertexType::Name(nameList); ElementDescriptor vertexDescr(NNP_VERTEX_ELEM); count = info.GetVertexCount(); if (nameList.size() > 0 && count > 0) { vcg::tri::Allocator::AddVertices(mesh, count); if ((bitMask & BitMask::IO_VERTCOORD) && VertexType::HasCoord()) vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_PXYZ, (*mesh.vert.begin()).P().V())); if ((bitMask & BitMask::IO_VERTNORMAL) && vcg::tri::HasPerVertexNormal(mesh)) vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_NXYZ, (*mesh.vert.begin()).N().V())); if ((bitMask & BitMask::IO_VERTCOLOR) && vcg::tri::HasPerVertexColor(mesh)) vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_CRGBA, (*mesh.vert.begin()).C().V())); if ((bitMask & BitMask::IO_VERTQUALITY) && vcg::tri::HasPerVertexQuality(mesh)) vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_QUALITY, &(*mesh.vert.begin()).Q())); if ((bitMask & BitMask::IO_VERTFLAGS) && vcg::tri::HasPerVertexFlags(mesh)) vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_BITFLAG, &(*mesh.vert.begin()).Flags())); if ((bitMask & BitMask::IO_VERTRADIUS) && vcg::tri::HasPerVertexRadius(mesh)) vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_DENSITY, &(*mesh.vert.begin()).R())); if ((bitMask & BitMask::IO_VERTTEXCOORD) && vcg::tri::HasPerVertexTexCoord(mesh)) vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_TEXTURE2D, (*mesh.vert.begin()).T().P().V())); if ((bitMask & BitMask::IO_VERTCURV) && vcg::tri::HasPerVertexCurvature(mesh)) { vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KG, &(*mesh.vert.begin()).Kg())); vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KH, &(*mesh.vert.begin()).Kh())); } if ((bitMask & BitMask::IO_VERTCURVDIR) && vcg::tri::HasPerVertexCurvatureDir(mesh)) { vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K1, &(*mesh.vert.begin()).K1())); vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K2, &(*mesh.vert.begin()).K2())); vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K1DIR, (*mesh.vert.begin()).PD1().V())); vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K2DIR, (*mesh.vert.begin()).PD2().V())); } if ((bitMask & BitMask::IO_VERTATTRIB) && custom.vertexAttrib.size() > 0) { for (int i = 0; i < custom.vertexAttrib.size(); i++) { std::set::iterator ai; for (ai = mesh.vert_attr.begin(); ai != mesh.vert_attr.end(); ++ai) { if ((*custom.vertexAttrib[i]).name == (*ai)._name) { custom.vertexAttrib[i]->base = ai->_handle->DataBegin(); break; } } vertexDescr.dataDescriptor.push_back(custom.vertexAttrib[i]); } } } //Edge nameList.clear(); EdgeType::Name(nameList); ElementDescriptor edgeDescr(NNP_EDGE_ELEM); count = info.GetEdgeCount(); std::vector edgeIndex; if (nameList.size() > 0 && count > 0) { vcg::tri::Allocator::AddEdges(mesh, count); if ((bitMask & BitMask::IO_EDGEINDEX) && MeshType::EdgeType::HasVertexRef()) { edgeIndex.resize(count); edgeDescr.dataDescriptor.push_back(new DataDescriptor(NNP_EDGE_V1, &(*edgeIndex.begin()).V()[0])); edgeDescr.dataDescriptor.push_back(new DataDescriptor(NNP_EDGE_V2, &(*edgeIndex.begin()).V()[1])); } if ((bitMask & BitMask::IO_EDGEQUALITY) && vcg::tri::HasPerEdgeQuality(mesh)) edgeDescr.dataDescriptor.push_back(new DataDescriptor(NNP_QUALITY, &(*mesh.edge.begin()).Q())); if ((bitMask & BitMask::IO_EDGECOLOR) && vcg::tri::HasPerEdgeColor(mesh)) edgeDescr.dataDescriptor.push_back(new DataDescriptor(NNP_CRGBA, (*mesh.edge.begin()).C().V())); if ((bitMask & BitMask::IO_EDGEFLAGS) && vcg::tri::HasPerEdgeFlags(mesh)) edgeDescr.dataDescriptor.push_back(new DataDescriptor(NNP_BITFLAG, &(*mesh.edge.begin()).Flags())); if ((bitMask & BitMask::IO_EDGEATTRIB) && custom.edgeAttrib.size() > 0) { for (int i = 0; i < custom.edgeAttrib.size(); i++) { std::set::iterator ai; for (ai = mesh.edge_attr.begin(); ai != mesh.edge_attr.end(); ++ai) { if ((*custom.edgeAttrib[i]).name == (*ai)._name) { custom.edgeAttrib[i]->base = ai->_handle->DataBegin(); break; } } edgeDescr.dataDescriptor.push_back(custom.edgeAttrib[i]); } } } //Face nameList.clear(); FaceType::Name(nameList); ElementDescriptor faceDescr(NNP_FACE_ELEM); count = info.GetFaceCount(); std::vector faceIndex; std::vector> wedgeTexCoord; if (nameList.size() > 0 && count > 0) { vcg::tri::Allocator::AddFaces(mesh, count); if ((bitMask & BitMask::IO_FACEINDEX) && FaceType::HasVertexRef()) { faceIndex.resize(count); faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_FACE_VERTEX_LIST, (*faceIndex.begin()).V())); } if ((bitMask & BitMask::IO_FACEFLAGS) && vcg::tri::HasPerFaceFlags(mesh)) faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_BITFLAG, &(*mesh.face.begin()).Flags())); if ((bitMask & BitMask::IO_FACECOLOR) && vcg::tri::HasPerFaceColor(mesh)) faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_CRGBA, (*mesh.face.begin()).C().V())); if ((bitMask & BitMask::IO_FACEQUALITY) && vcg::tri::HasPerFaceQuality(mesh)) faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_QUALITY, &(*mesh.face.begin()).Q())); if ((bitMask & BitMask::IO_FACENORMAL) && vcg::tri::HasPerFaceNormal(mesh)) faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_NXYZ, (*mesh.face.begin()).N().V())); if ((bitMask & BitMask::IO_VERTCURVDIR) && vcg::tri::HasPerFaceCurvatureDir(mesh)) { faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K1, &(*mesh.face.begin()).K1())); faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K2, &(*mesh.face.begin()).K2())); faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K1DIR, (*mesh.face.begin()).PD1().V())); faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K2DIR, (*mesh.face.begin()).PD2().V())); } if (((bitMask & BitMask::IO_WEDGTEXCOORD) || (bitMask & BitMask::IO_WEDGTEXMULTI)) && vcg::tri::HasPerWedgeTexCoord(mesh)) { wedgeTexCoord.resize(count); faceDescr.dataDescriptor.push_back(new DataDescriptor, 6, FaceTexScalar>(NNP_FACE_WEDGE_TEX, (*wedgeTexCoord.begin()).V())); } if ((bitMask & BitMask::IO_WEDGTEXMULTI) && vcg::tri::HasPerWedgeTexCoord(mesh)) faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_TEXTUREINDEX, &(*mesh.face.begin()).WT(0).N())); if ((bitMask & BitMask::IO_WEDGCOLOR) && vcg::tri::HasPerWedgeColor(mesh)) faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_FACE_WEDGE_COLOR, (*mesh.face.begin()).WC(0).V())); if ((bitMask & BitMask::IO_WEDGNORMAL) && vcg::tri::HasPerWedgeNormal(mesh)) faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_FACE_WEDGE_NORMAL, (*mesh.face.begin()).WN(0).V())); if ((bitMask & BitMask::IO_FACEATTRIB) && custom.faceAttrib.size() > 0) { for (int i = 0; i < custom.faceAttrib.size(); i++) { std::set::iterator ai; for (ai = mesh.face_attr.begin(); ai != mesh.face_attr.end(); ++ai) { if ((*custom.faceAttrib[i]).name == (*ai)._name) { custom.faceAttrib[i]->base = ai->_handle->DataBegin(); break; } } faceDescr.dataDescriptor.push_back(custom.faceAttrib[i]); } } } std::vector meshDescr; meshDescr.push_back(&cameraDescr); meshDescr.push_back(&vertexDescr); meshDescr.push_back(&edgeDescr); meshDescr.push_back(&faceDescr); //Mesh attribute if ((bitMask & BitMask::IO_MESHATTRIB)) { CustomAttributeDescriptor::MapMeshAttribIter iter = custom.meshAttrib.begin(); for (; iter != custom.meshAttrib.end(); iter++) { std::string name((*iter).first); meshDescr.push_back(new ElementDescriptor(name)); count = info.GetElementCount(name); if (count > 1) { meshDescr.back()->dataDescriptor = (*iter).second; } } } if (!OpenModel(info, meshDescr)) return info.errInfo; mesh.shot.SetViewPoint(tra); mesh.shot.Extrinsics.SetRot(rot); for (int i = 0; i < faceIndex.size(); i++) for (int j = 0; j < 3; j++) mesh.face[i].V(j) = &mesh.vert[faceIndex[i][j]]; for (int i = 0; i < wedgeTexCoord.size(); i++) { for (int j = 0; j < 3; j++) { mesh.face[i].WT(j).U() = wedgeTexCoord[i][j * 2]; mesh.face[i].WT(j).V() = wedgeTexCoord[i][j * 2 + 1]; } } for (int i = 0; i < edgeIndex.size(); i++) { mesh.edge[i].V(0) = &mesh.vert[edgeIndex[i].X()]; mesh.edge[i].V(1) = &mesh.vert[edgeIndex[i].Y()]; } for (int i = 0; i < cameraDescr.dataDescriptor.size(); i++) delete cameraDescr.dataDescriptor[i]; for (int i = 0; i < vertexDescr.dataDescriptor.size(); i++) if (vertexDescr.dataDescriptor[i]->elem != NNP_UNKNOWN_ENTITY) delete vertexDescr.dataDescriptor[i]; for (int i = 0; i < edgeDescr.dataDescriptor.size(); i++) if (edgeDescr.dataDescriptor[i]->elem != NNP_UNKNOWN_ENTITY) delete edgeDescr.dataDescriptor[i]; for (int i = 0; i < faceDescr.dataDescriptor.size(); i++) if (faceDescr.dataDescriptor[i]->elem != NNP_UNKNOWN_ENTITY) delete faceDescr.dataDescriptor[i]; mesh.textures = info.textureFile; return info.errInfo; } static int LoadModel(const char* filename, MeshType& mesh, unsigned int bitMask) { CustomAttributeDescriptor custom; return LoadModel(filename, mesh, bitMask, custom); } static bool SaveModel(const char* filename, MeshType& mesh, unsigned int bitMask, CustomAttributeDescriptor& custom, bool binary) { //Camera std::vector cameraProp; ElementDescriptor cameraDescr(std::string("camera")); vcg::Point3 tra = mesh.shot.Extrinsics.Tra(); vcg::Matrix44 rot = mesh.shot.Extrinsics.Rot(); if (bitMask & BitMask::IO_CAMERA) { PushDescriport(cameraProp, cameraDescr, std::string("view_px"), &tra[0]); PushDescriport(cameraProp, cameraDescr, std::string("view_py"), &tra[1]); PushDescriport(cameraProp, cameraDescr, std::string("view_pz"), &tra[2]); PushDescriport(cameraProp, cameraDescr, std::string("x_axisx"), &rot[0][0]); PushDescriport(cameraProp, cameraDescr, std::string("x_axisy"), &rot[0][1]); PushDescriport(cameraProp, cameraDescr, std::string("x_axisz"), &rot[0][2]); PushDescriport(cameraProp, cameraDescr, std::string("y_axisx"), &rot[1][0]); PushDescriport(cameraProp, cameraDescr, std::string("y_axisy"), &rot[1][1]); PushDescriport(cameraProp, cameraDescr, std::string("y_axisz"), &rot[1][2]); PushDescriport(cameraProp, cameraDescr, std::string("z_axisx"), &rot[2][0]); PushDescriport(cameraProp, cameraDescr, std::string("z_axisy"), &rot[2][1]); PushDescriport(cameraProp, cameraDescr, std::string("z_axisz"), &rot[2][2]); PushDescriport(cameraProp, cameraDescr, std::string("focal"), &mesh.shot.Intrinsics.FocalMm); PushDescriport(cameraProp, cameraDescr, std::string("scalex"), &mesh.shot.Intrinsics.PixelSizeMm[0]); PushDescriport(cameraProp, cameraDescr, std::string("scaley"), &mesh.shot.Intrinsics.PixelSizeMm[1]); PushDescriport(cameraProp, cameraDescr, std::string("centerx"), &mesh.shot.Intrinsics.CenterPx[0]); PushDescriport(cameraProp, cameraDescr, std::string("centery"), &mesh.shot.Intrinsics.CenterPx[1]); PushDescriport(cameraProp, cameraDescr, std::string("viewportx"), &mesh.shot.Intrinsics.ViewportPx[0]); PushDescriport(cameraProp, cameraDescr, std::string("viewporty"), &mesh.shot.Intrinsics.ViewportPx[1]); PushDescriport(cameraProp, cameraDescr, std::string("k1"), &mesh.shot.Intrinsics.k[0]); PushDescriport(cameraProp, cameraDescr, std::string("k2"), &mesh.shot.Intrinsics.k[1]); PushDescriport(cameraProp, cameraDescr, std::string("k3"), &mesh.shot.Intrinsics.k[2]); PushDescriport(cameraProp, cameraDescr, std::string("k4"), &mesh.shot.Intrinsics.k[3]); } //Vertex std::vector nameList; VertexType::Name(nameList); std::vector vertexProp; ElementDescriptor vertexDescr(NNP_VERTEX_ELEM); if (nameList.size() > 0 && mesh.vert.size() > 0) { if ((bitMask & BitMask::IO_VERTCOORD) && VertexType::HasCoord()) PushDescriport(vertexProp, vertexDescr, NNP_PXYZ, (*mesh.vert.begin()).P().V()); if ((bitMask & BitMask::IO_VERTNORMAL) && vcg::tri::HasPerVertexNormal(mesh)) PushDescriport(vertexProp, vertexDescr, NNP_NXYZ, (*mesh.vert.begin()).N().V()); if ((bitMask & BitMask::IO_VERTCOLOR) && vcg::tri::HasPerVertexColor(mesh)) PushDescriport(vertexProp, vertexDescr, NNP_CRGBA, (*mesh.vert.begin()).C().V()); if ((bitMask & BitMask::IO_VERTQUALITY) && vcg::tri::HasPerVertexQuality(mesh)) PushDescriport(vertexProp, vertexDescr, NNP_QUALITY, &(*mesh.vert.begin()).Q()); if ((bitMask & BitMask::IO_VERTFLAGS) && vcg::tri::HasPerVertexFlags(mesh)) PushDescriport(vertexProp, vertexDescr, NNP_BITFLAG, &(*mesh.vert.begin()).Flags()); if ((bitMask & BitMask::IO_VERTRADIUS) && vcg::tri::HasPerVertexRadius(mesh)) PushDescriport(vertexProp, vertexDescr, NNP_DENSITY, &(*mesh.vert.begin()).R()); if ((bitMask & BitMask::IO_VERTTEXCOORD) && vcg::tri::HasPerVertexTexCoord(mesh)) PushDescriport(vertexProp, vertexDescr, NNP_TEXTURE2D, (*mesh.vert.begin()).T().P().V()); if ((bitMask & BitMask::IO_VERTCURV) && vcg::tri::HasPerVertexCurvature(mesh)) { PushDescriport(vertexProp, vertexDescr, NNP_KG, &(*mesh.vert.begin()).Kg()); PushDescriport(vertexProp, vertexDescr, NNP_KH, &(*mesh.vert.begin()).Kh()); } if ((bitMask & BitMask::IO_VERTCURVDIR) && vcg::tri::HasPerVertexCurvatureDir(mesh)) { PushDescriport(vertexProp, vertexDescr, NNP_K1, &(*mesh.vert.begin()).K1()); PushDescriport(vertexProp, vertexDescr, NNP_K2, &(*mesh.vert.begin()).K2()); PushDescriportList(vertexProp, vertexDescr, NNP_K1DIR, (*mesh.vert.begin()).PD1().V()); PushDescriportList(vertexProp, vertexDescr, NNP_K2DIR, (*mesh.vert.begin()).PD2().V()); } if ((bitMask & BitMask::IO_VERTATTRIB) && custom.vertexAttrib.size() > 0) { for (int i = 0; i < custom.vertexAttrib.size(); i++) { vertexProp.push_back(custom.vertexAttribProp[i]); vertexDescr.dataDescriptor.push_back(custom.vertexAttrib[i]); } } } //Edge nameList.clear(); EdgeType::Name(nameList); std::vector edgeProp; ElementDescriptor edgeDescr(NNP_VERTEX_ELEM); std::vector edgeIndex; for (int i = 0; i < mesh.edge.size(); i++) edgeIndex.push_back(vcg::Point2i(vcg::tri::Index(mesh, mesh.edge[i].V(0)), vcg::tri::Index(mesh, mesh.edge[i].V(1)))); if (nameList.size() > 0 && mesh.edge.size() > 0) { if ((bitMask & BitMask::IO_EDGEINDEX) && EdgeType::HasVertexRef()) { PushDescriport(edgeProp, edgeDescr, NNP_EDGE_V1, &(*edgeIndex.begin()).V()[0]); PushDescriport(edgeProp, edgeDescr, NNP_EDGE_V2, &(*edgeIndex.begin()).V()[1]); } if ((bitMask & BitMask::IO_EDGEQUALITY) && vcg::tri::HasPerEdgeQuality(mesh)) PushDescriport(edgeProp, edgeDescr, NNP_QUALITY, &(*mesh.edge.begin()).Q()); if ((bitMask & BitMask::IO_EDGECOLOR) && vcg::tri::HasPerEdgeColor(mesh)) PushDescriport(edgeProp, edgeDescr, NNP_CRGBA, (*mesh.edge.begin()).C().V()); if ((bitMask & BitMask::IO_EDGEFLAGS) && vcg::tri::HasPerEdgeFlags(mesh)) PushDescriport(edgeProp, edgeDescr, NNP_BITFLAG, &(*mesh.edge.begin()).Flags()); if ((bitMask & BitMask::IO_EDGEATTRIB) && custom.edgeAttrib.size() > 0) { for (int i = 0; i < custom.edgeAttrib.size(); i++) { edgeProp.push_back(custom.edgeAttribProp[i]); edgeDescr.dataDescriptor.push_back(custom.edgeAttrib[i]); } } } //Face nameList.clear(); FaceType::Name(nameList); std::vector faceProp; ElementDescriptor faceDescr(NNP_FACE_ELEM); std::vector faceIndex; std::vector> wedgeTexCoord; for (int i = 0; i < mesh.face.size(); i++) faceIndex.push_back(vcg::Point3i(vcg::tri::Index(mesh, mesh.face[i].V(0)), vcg::tri::Index(mesh, mesh.face[i].V(1)), vcg::tri::Index(mesh, mesh.face[i].V(2)))); if (((bitMask & BitMask::IO_WEDGTEXCOORD) || (bitMask & BitMask::IO_WEDGTEXMULTI)) && vcg::tri::HasPerWedgeTexCoord(mesh)) { for (int i = 0; i < mesh.face.size(); i++) { wedgeTexCoord.push_back(vcg::ndim::Point<6, FaceTexScalar>()); for (int j = 0; j < 3; j++) { wedgeTexCoord.back()[j * 2] = mesh.face[i].WT(j).U(); wedgeTexCoord.back()[j * 2 + 1] = mesh.face[i].WT(j).V(); } } } if (nameList.size() > 0 && mesh.face.size() > 0) { if ((bitMask & BitMask::IO_FACEINDEX) && FaceType::HasVertexRef()) PushDescriportList(faceProp, faceDescr, NNP_FACE_VERTEX_LIST, (*faceIndex.begin()).V()); if ((bitMask & BitMask::IO_FACEFLAGS) && vcg::tri::HasPerFaceFlags(mesh)) PushDescriport(faceProp, faceDescr, NNP_BITFLAG, &(*mesh.face.begin()).Flags()); if ((bitMask & BitMask::IO_FACECOLOR) && vcg::tri::HasPerFaceColor(mesh)) PushDescriport(faceProp, faceDescr, NNP_CRGBA, (*mesh.face.begin()).C().V()); if ((bitMask & BitMask::IO_FACEQUALITY) && vcg::tri::HasPerFaceQuality(mesh)) PushDescriport(faceProp, faceDescr, NNP_QUALITY, &(*mesh.face.begin()).Q()); if ((bitMask & BitMask::IO_FACENORMAL) && vcg::tri::HasPerFaceNormal(mesh)) PushDescriport(faceProp, faceDescr, NNP_NXYZ, (*mesh.face.begin()).N().V()); if ((bitMask & BitMask::IO_VERTCURVDIR) && vcg::tri::HasPerFaceCurvatureDir(mesh)) { PushDescriport(faceProp, faceDescr, NNP_K1, &(*mesh.face.begin()).K1()); PushDescriport(faceProp, faceDescr, NNP_K2, &(*mesh.face.begin()).K2()); PushDescriportList(faceProp, faceDescr, NNP_K1DIR, (*mesh.face.begin()).PD1().V()); PushDescriportList(faceProp, faceDescr, NNP_K2DIR, (*mesh.face.begin()).PD2().V()); } if (((bitMask & BitMask::IO_WEDGTEXCOORD) || (bitMask & BitMask::IO_WEDGTEXMULTI)) && vcg::tri::HasPerWedgeTexCoord(mesh)) PushDescriportList, FaceTexScalar, 6>(faceProp, faceDescr, NNP_FACE_WEDGE_TEX, (*wedgeTexCoord.begin()).V()); if ((bitMask & BitMask::IO_WEDGTEXMULTI) && vcg::tri::HasPerWedgeTexCoord(mesh)) PushDescriport(faceProp, faceDescr, NNP_TEXTUREINDEX, &(*mesh.face.begin()).WT(0).N()); if ((bitMask & BitMask::IO_WEDGCOLOR) && vcg::tri::HasPerWedgeColor(mesh)) PushDescriportList(faceProp, faceDescr, NNP_FACE_WEDGE_COLOR, (*mesh.face.begin()).WC(0).V()); if ((bitMask & BitMask::IO_WEDGNORMAL) && vcg::tri::HasPerWedgeNormal(mesh)) PushDescriportList(faceProp, faceDescr, NNP_FACE_WEDGE_NORMAL, (*mesh.face.begin()).WN(0).V()); if ((bitMask & BitMask::IO_FACEATTRIB) && custom.faceAttrib.size() > 0) { for (int i = 0; i < custom.faceAttrib.size(); i++) { faceProp.push_back(custom.faceAttribProp[i]); faceDescr.dataDescriptor.push_back(custom.faceAttrib[i]); } } } Info infoSave; infoSave.filename = filename; infoSave.binary = binary; PlyElement cameraElem(std::string("camera"), cameraProp, 1); PlyElement vertexElem(NNP_VERTEX_ELEM, vertexProp, mesh.vert.size()); PlyElement edgeElem(NNP_EDGE_ELEM, edgeProp, mesh.edge.size()); PlyElement faceElem(NNP_FACE_ELEM, faceProp, mesh.face.size()); infoSave.AddPlyElement(cameraElem); infoSave.AddPlyElement(vertexElem); infoSave.AddPlyElement(edgeElem); infoSave.AddPlyElement(faceElem); infoSave.textureFile = mesh.textures; std::vector meshDescr; meshDescr.push_back(&cameraDescr); meshDescr.push_back(&vertexDescr); meshDescr.push_back(&edgeDescr); meshDescr.push_back(&faceDescr); //Mesh attribute if ((bitMask & BitMask::IO_MESHATTRIB)) { CustomAttributeDescriptor::MapMeshAttribIter iter = custom.meshAttrib.begin(); CustomAttributeDescriptor::MapMeshAttribPropIter iterProp = custom.meshAttribProp.begin(); for (; iter != custom.meshAttrib.end(); iter++, iterProp++) { std::string name((*iter).first); PlyElement customElem(name, (*iterProp).second, custom.meshAttribCnt[(*iter).first]); infoSave.AddPlyElement(customElem); meshDescr.push_back(new ElementDescriptor(name)); meshDescr.back()->dataDescriptor = (*iter).second; } } bool flag = nanoply::SaveModel(infoSave.filename, meshDescr, infoSave); for (int i = 0; i < cameraDescr.dataDescriptor.size(); i++) delete cameraDescr.dataDescriptor[i]; for (int i = 0; i < vertexDescr.dataDescriptor.size(); i++) if (vertexDescr.dataDescriptor[i]->elem != NNP_UNKNOWN_ENTITY) delete vertexDescr.dataDescriptor[i]; for (int i = 0; i < edgeDescr.dataDescriptor.size(); i++) if (edgeDescr.dataDescriptor[i]->elem != NNP_UNKNOWN_ENTITY) delete edgeDescr.dataDescriptor[i]; for (int i = 0; i < faceDescr.dataDescriptor.size(); i++) if (faceDescr.dataDescriptor[i]->elem != NNP_UNKNOWN_ENTITY) delete faceDescr.dataDescriptor[i]; return flag; } static bool SaveModel(const char* filename, MeshType& mesh, unsigned int bitMask, bool binary) { CustomAttributeDescriptor custom; return SaveModel(filename, mesh, bitMask, custom, binary); } }; } #endif