diff --git a/Apps/Examples/viewer.cpp b/Apps/Examples/viewer.cpp index 608f67b534388d5de3ac1364caba3578a43393d6..6dd4435c82f5cc571a18e4232fe983d285c54dd3 100644 --- a/Apps/Examples/viewer.cpp +++ b/Apps/Examples/viewer.cpp @@ -234,7 +234,11 @@ void Viewer::exportMesh(std::string& filename) if (extension == std::string(".off")) Algo::Export::exportOFF(myMap, position, filename.c_str(), allDarts) ; else if (extension.compare(0, 4, std::string(".ply")) == 0) - Algo::Export::exportPLY(myMap, position, filename.c_str(), true, allDarts) ; + { + std::vector attributes ; + attributes.push_back(position) ; + Algo::Export::exportPLYnew(myMap, attributes, filename.c_str(), true, allDarts) ; + } else if (extension == std::string(".map")) myMap.saveMapBin(filename) ; else diff --git a/include/Algo/Export/export.h b/include/Algo/Export/export.h index 1f5f5949a4d4de7eb1187993afaad79c68911082..e1277cd574d15b52b3d486bbd7f34af9e02090d3 100644 --- a/include/Algo/Export/export.h +++ b/include/Algo/Export/export.h @@ -39,6 +39,7 @@ namespace Export /** * export the map into a PLY file * @param the_map map to be exported +* @param position the position container * @param filename filename of ply file * @param binary write in binary mode * @return true @@ -46,6 +47,17 @@ namespace Export template bool exportPLY(typename PFP::MAP& map, const typename PFP::TVEC3& position, const char* filename, const bool binary, const FunctorSelect& good = allDarts) ; +/** +* export the map into a PLY file +* @param the_map map to be exported +* @param vertexAttrNames the vertex attribute names +* @param filename filename of ply file +* @param binary write in binary mode +* @return true +*/ +template +bool exportPLYnew(typename PFP::MAP& map, const std::vector& attributeHandlers, const char* filename, const bool binary, const FunctorSelect& good = allDarts) ; + /** * export the map into a OFF file * @param the_map map to be exported diff --git a/include/Algo/Export/export.hpp b/include/Algo/Export/export.hpp index 5816aa4a6f54f1932380fabd4887376b0245b61c..1d0253d00de50b57fff283f8c4545162f92fca77 100644 --- a/include/Algo/Export/export.hpp +++ b/include/Algo/Export/export.hpp @@ -117,9 +117,9 @@ bool exportPLY(typename PFP::MAP& map, const typename PFP::TVEC3& position, cons // Position property if (position.isValid()) { - out << "property " << nameOfTypePly(position[0][0]) << 8 * sizeof(position[0][0]) <<" x" << std::endl ; - out << "property " << nameOfTypePly(position[0][1]) << 8 * sizeof(position[0][1]) <<" y" << std::endl ; - out << "property " << nameOfTypePly(position[0][2]) << 8 * sizeof(position[0][2]) <<" z" << std::endl ; + out << "property " << nameOfTypePly(position[0][0]) << " x" << std::endl ; + out << "property " << nameOfTypePly(position[0][1]) << " y" << std::endl ; + out << "property " << nameOfTypePly(position[0][2]) << " z" << std::endl ; } // Face element out << "element face " << facesSize.size() << std::endl ; @@ -164,6 +164,161 @@ bool exportPLY(typename PFP::MAP& map, const typename PFP::TVEC3& position, cons return true ; } +template +bool exportPLYnew(typename PFP::MAP& map, const std::vector& attributeHandlers, const char* filename, bool binary, const FunctorSelect& good) +{ + typedef typename PFP::MAP MAP; + typedef typename PFP::VEC3 VEC3; + + // open file + std::ofstream out ; + if (!binary) + out.open(filename, std::ios::out) ; + else + out.open(filename, std::ios::out | std::ios::binary) ; + + if (!out.good()) + { + CGoGNerr << "Unable to open file " << CGoGNendl ; + return false ; + } + + unsigned int nbDarts = map.getNbDarts() ; + std::vector facesSize ; + std::vector > facesIdx ; + facesSize.reserve(nbDarts/3) ; + facesIdx.reserve(nbDarts/3) ; + std::map vIndex ; + unsigned int vCpt = 0 ; + std::vector vertices ; + vertices.reserve(nbDarts/6) ; + + // Go over all faces + CellMarker markV(map, VERTEX) ; + TraversorF t(map, good) ; + for(Dart d = t.begin(); d != t.end(); d = t.next()) + { + std::vector fidx ; + fidx.reserve(8) ; + unsigned int degree = 0 ; + Traversor2FV tfv(map, d) ; + for(Dart it = tfv.begin(); it != tfv.end(); it = tfv.next()) + { + ++degree ; + unsigned int vNum = map.getEmbedding(VERTEX, it) ; + if(!markV.isMarked(it)) + { + markV.mark(it) ; + vIndex[vNum] = vCpt++ ; + vertices.push_back(vNum) ; + } + fidx.push_back(vIndex[vNum]) ; + } + facesSize.push_back(degree) ; + facesIdx.push_back(fidx) ; + } + + // Start writing the file + out << "ply" << std::endl ; + // ascii or binary + if (!binary) + out << "format ascii 1.0" << std::endl ; + else + { // test endianness + union + { + uint32_t i ; + char c[4] ; + } bint = {0x01020304} ; + if (bint.c[0] == 1) // big endian + out << "format binary_big_endian 1.0" << std::endl ; + else + out << "format binary_little_endian 1.0" << std::endl ; + } + + out << "comment File generated by the CGoGN library" << std::endl ; + out << "comment See : http://cgogn.unistra.fr/" << std::endl ; + out << "comment or contact : cgogn@unistra.fr" << std::endl ; + // Vertex elements + out << "element vertex " << vertices.size() << std::endl ; + for (typename std::vector::const_iterator attrHandler = attributeHandlers.begin() ; attrHandler != attributeHandlers.end() ; ++attrHandler) + { + if (attrHandler->isValid() && (attrHandler->getOrbit() == VERTEX) ) + { + if (attrHandler->name().compare("position") == 0) // Vertex position property + { + out << "property " << nameOfTypePly((*attrHandler)[0][0]) << " x" << std::endl ; + out << "property " << nameOfTypePly((*attrHandler)[0][1]) << " y" << std::endl ; + out << "property " << nameOfTypePly((*attrHandler)[0][2]) << " z" << std::endl ; + } + else if (attrHandler->name().compare("normal") == 0) // normal property + { + out << "property " << nameOfTypePly((*attrHandler)[0][0]) << " nx" << std::endl ; + out << "property " << nameOfTypePly((*attrHandler)[0][1]) << " ny" << std::endl ; + out << "property " << nameOfTypePly((*attrHandler)[0][2]) << " nz" << std::endl ; + } + else if (attrHandler->name().compare("color") == 0) // vertex color property + { + out << "property " << nameOfTypePly((*attrHandler)[0][0]) << " red" << std::endl ; + out << "property " << nameOfTypePly((*attrHandler)[0][1]) << " green" << std::endl ; + out << "property " << nameOfTypePly((*attrHandler)[0][2]) << " blue" << std::endl ; + } + else // other vertex properties + { + out << "property " << nameOfTypePly((*attrHandler)[0][0]) << " " << attrHandler->name() << "_0" << std::endl ; + out << "property " << nameOfTypePly((*attrHandler)[0][1]) << " " << attrHandler->name() << "_1" << std::endl ; + out << "property " << nameOfTypePly((*attrHandler)[0][2]) << " " << attrHandler->name() << "_2" << std::endl ; + } + } + } + + // Face element + out << "element face " << facesSize.size() << std::endl ; + out << "property list uint8 uint" << 8 * sizeof(facesIdx[0][0]) << " vertex_indices" << std::endl ; + out << "end_header" << std::endl ; + + if (!binary) // ascii + { + // ascii vertices + for(unsigned int i = 0; i < vertices.size(); ++i) + for (typename std::vector::const_iterator attrHandler = attributeHandlers.begin() ; attrHandler != attributeHandlers.end() ; ++attrHandler) + if (attrHandler->isValid() && attrHandler->getOrbit() == VERTEX) + out << (*attrHandler)[vertices[i]] << std::endl ; + + // ascii faces + for(unsigned int i = 0; i < facesSize.size(); ++i) + { + out << facesSize[i] ; + for(unsigned int j = 0; j < facesIdx[i].size(); ++j) + out << " " << facesIdx[i][j] ; + out << std::endl ; + } + } + else // binary + { + // binary vertices + for(unsigned int i = 0; i < vertices.size(); ++i) + for (typename std::vector::const_iterator attrHandler = attributeHandlers.begin() ; attrHandler != attributeHandlers.end() ; ++attrHandler) + if (attrHandler->isValid() && attrHandler->getOrbit() == VERTEX) + { + const typename PFP::VEC3& v = (*attrHandler)[vertices[i]] ; + out.write((char*)(&(v[0])), sizeof(v)) ; + } + + // binary faces + for(unsigned int i = 0; i < facesSize.size(); ++i) + { + unsigned char nbe = facesSize[i] ; + out.write((char*)(&nbe), sizeof(unsigned char)) ; + out.write((char*)(&(facesIdx[i][0])), facesSize[i] * sizeof(facesIdx[i][0])) ; + } + } + + out.close() ; + + return true ; +} + template bool exportOFF(typename PFP::MAP& map, const typename PFP::TVEC3& position, const char* filename, const FunctorSelect& good) { diff --git a/include/Utils/nameTypes.h b/include/Utils/nameTypes.h index 140c2758a6f7a516e40308ab5a2c14cd815e93e4..53e1157aafa14a367512bbe056d38a088cc8d695 100644 --- a/include/Utils/nameTypes.h +++ b/include/Utils/nameTypes.h @@ -77,7 +77,7 @@ template <> inline std::string nameOfTypePly(const long int& v) { return "invali template <> inline std::string nameOfTypePly(const unsigned char& v) { return "uint8"; } -template <> inline std::string nameOfType(const unsigned short int& v) { return "uint16"; } +template <> inline std::string nameOfTypePly(const unsigned short int& v) { return "uint16"; } template <> inline std::string nameOfTypePly(const unsigned int& v) { return "uint32"; }