#include "writePLY.h" #include #include "tinyply.h" #include namespace igl { template tinyply::Type tynyply_type(); template <> tinyply::Type IGL_INLINE tynyply_type(){ return tinyply::Type::INT8; } template <> tinyply::Type IGL_INLINE tynyply_type(){ return tinyply::Type::INT16; } template <> tinyply::Type IGL_INLINE tynyply_type(){ return tinyply::Type::INT32; } template <> tinyply::Type IGL_INLINE tynyply_type(){ return tinyply::Type::UINT8; } template <> tinyply::Type IGL_INLINE tynyply_type(){ return tinyply::Type::UINT16; } template <> tinyply::Type IGL_INLINE tynyply_type(){ return tinyply::Type::UINT32; } template <> tinyply::Type IGL_INLINE tynyply_type(){ return tinyply::Type::FLOAT32; } template <> tinyply::Type IGL_INLINE tynyply_type(){ return tinyply::Type::FLOAT64; } template < typename DerivedV, typename DerivedF, typename DerivedE, typename DerivedN, typename DerivedUV, typename DerivedVD, typename DerivedFD, typename DerivedED > bool writePLY( std::ostream & ply_stream, const Eigen::MatrixBase & V, const Eigen::MatrixBase & F, const Eigen::MatrixBase & E, const Eigen::MatrixBase & N, const Eigen::MatrixBase & UV, const Eigen::MatrixBase & VD, const std::vector & VDheader, const Eigen::MatrixBase & FD, const std::vector & FDheader, const Eigen::MatrixBase & ED, const std::vector & EDheader, const std::vector & comments, FileEncoding encoding ) { typedef typename DerivedV::Scalar VScalar; typedef typename DerivedN::Scalar NScalar; typedef typename DerivedUV::Scalar UVScalar; typedef typename DerivedF::Scalar FScalar; typedef typename DerivedE::Scalar EScalar; typedef typename DerivedVD::Scalar VDScalar; typedef typename DerivedFD::Scalar FDScalar; typedef typename DerivedED::Scalar EDScalar; // temporary storage for data to be passed to tinyply internals std::vector _v; std::vector _n; std::vector _uv; std::vector _vd; std::vector _fd; std::vector _ev; std::vector _ed; // check dimensions if( V.cols()!=3) { std::cerr << "writePLY: unexpected dimensions " << std::endl; return false; } tinyply::PlyFile file; _v.resize(V.size()); Eigen::Map< Eigen::Matrix >( &_v[0], V.rows(), V.cols() ) = V; file.add_properties_to_element("vertex", { "x", "y", "z" }, tynyply_type(), V.rows(), reinterpret_cast( &_v[0] ), tinyply::Type::INVALID, 0); if(N.rows()>0) { _n.resize(N.size()); Eigen::Map >( &_n[0], N.rows(), N.cols() ) = N; file.add_properties_to_element("vertex", { "nx", "ny", "nz" }, tynyply_type(), N.rows(), reinterpret_cast( &_n[0] ),tinyply::Type::INVALID, 0); } if(UV.rows()>0) { _uv.resize(UV.size()); Eigen::Map >( &_uv[0], UV.rows(), UV.cols() ) = UV; file.add_properties_to_element("vertex", { "u", "v" }, tynyply_type(), UV.rows() , reinterpret_cast( &_uv[0] ), tinyply::Type::INVALID, 0); } if(VD.cols()>0) { assert(VD.cols() == VDheader.size()); assert(VD.rows() == V.rows()); _vd.resize(VD.size()); Eigen::Map< Eigen::Matrix >( &_vd[0], VD.rows(), VD.cols() ) = VD; file.add_properties_to_element("vertex", VDheader, tynyply_type(), VD.rows(), reinterpret_cast( &_vd[0] ), tinyply::Type::INVALID, 0); } std::vector _f(F.size()); Eigen::Map >( &_f[0], F.rows(), F.cols() ) = F; file.add_properties_to_element("face", { "vertex_indices" }, tynyply_type(), F.rows(), reinterpret_cast(&_f[0]), tinyply::Type::UINT8, F.cols() ); if(FD.cols()>0) { assert(FD.rows()==F.rows()); assert(FD.cols() == FDheader.size()); _fd.resize(FD.size()); Eigen::Map >( &_fd[0], FD.rows(), FD.cols() ) = FD; file.add_properties_to_element("face", FDheader, tynyply_type(), FD.rows(), reinterpret_cast( &_fd[0] ), tinyply::Type::INVALID, 0); } if(E.rows()>0) { assert(E.cols()==2); _ev.resize(E.size()); Eigen::Map >( &_ev[0], E.rows(), E.cols() ) = E; file.add_properties_to_element("edge", { "vertex1", "vertex2" }, tynyply_type(), E.rows() , reinterpret_cast( &_ev[0] ), tinyply::Type::INVALID, 0); } if(ED.cols()>0) { assert(ED.rows()==E.rows()); assert(ED.cols() == EDheader.size()); _ed.resize(ED.size()); Eigen::Map >( &_ed[0], ED.rows(), ED.cols() ) = ED; file.add_properties_to_element("edge", EDheader, tynyply_type(), ED.rows(), reinterpret_cast( &_ed[0] ), tinyply::Type::INVALID, 0); } for(auto a:comments) file.get_comments().push_back(a); // Write a binary file file.write(ply_stream, (encoding == FileEncoding::Binary)); return true; } template < typename DerivedV, typename DerivedF, typename DerivedE, typename DerivedN, typename DerivedUV, typename DerivedVD, typename DerivedFD, typename DerivedED > bool writePLY( const std::string & filename, const Eigen::MatrixBase & V, const Eigen::MatrixBase & F, const Eigen::MatrixBase & E, const Eigen::MatrixBase & N, const Eigen::MatrixBase & UV, const Eigen::MatrixBase & VD, const std::vector & VDheader, const Eigen::MatrixBase & FD, const std::vector & FDheader, const Eigen::MatrixBase & ED, const std::vector & EDheader, const std::vector & comments, FileEncoding encoding ) { try { if(encoding == FileEncoding::Binary) { std::filebuf fb_binary; fb_binary.open(filename , std::ios::out | std::ios::binary); std::ostream outstream_binary(&fb_binary); if (outstream_binary.fail()) { std::cerr << "writePLY: Error opening file " << filename << std::endl; return false; //throw std::runtime_error("failed to open " + filename); } return writePLY(outstream_binary,V,F,E,N,UV,VD,VDheader,FD,FDheader,ED,EDheader,comments,encoding); } else { std::filebuf fb_ascii; fb_ascii.open(filename, std::ios::out); std::ostream outstream_ascii(&fb_ascii); if (outstream_ascii.fail()) { std::cerr << "writePLY: Error opening file " << filename << std::endl; return false; //throw std::runtime_error("failed to open " + filename); } return writePLY(outstream_ascii,V,F,E,N,UV,VD,VDheader,FD,FDheader,ED,EDheader,comments,encoding); } } catch(const std::exception& e) { std::cerr << "writePLY error: " << filename << e.what() << std::endl; } return false; } template < typename DerivedV, typename DerivedF > bool writePLY( const std::string & filename, const Eigen::MatrixBase & V, const Eigen::MatrixBase & F ) { Eigen::MatrixXd _dummy; std::vector _dummy_header; return writePLY(filename,V,F,_dummy, _dummy, _dummy, _dummy, _dummy_header, _dummy, _dummy_header, _dummy, _dummy_header, _dummy_header, FileEncoding::Binary); } template < typename DerivedV, typename DerivedF, typename DerivedE > bool writePLY( const std::string & filename, const Eigen::MatrixBase & V, const Eigen::MatrixBase & F, const Eigen::MatrixBase & E ) { Eigen::MatrixXd _dummy; std::vector _dummy_header; return writePLY(filename,V,F,E, _dummy, _dummy, _dummy, _dummy_header, _dummy, _dummy_header, _dummy, _dummy_header, _dummy_header, FileEncoding::Binary); } template < typename DerivedV, typename DerivedF, typename DerivedN, typename DerivedUV > bool writePLY( const std::string & filename, const Eigen::MatrixBase & V, const Eigen::MatrixBase & F, const Eigen::MatrixBase & N, const Eigen::MatrixBase & UV ) { Eigen::MatrixXd _dummy; std::vector _dummy_header; return writePLY(filename,V,F,_dummy, N,UV, _dummy, _dummy_header, _dummy, _dummy_header, _dummy, _dummy_header, _dummy_header, FileEncoding::Binary); } template < typename DerivedV, typename DerivedF, typename DerivedE, typename DerivedN, typename DerivedUV > bool writePLY( const std::string & filename, const Eigen::MatrixBase & V, const Eigen::MatrixBase & F, const Eigen::MatrixBase & E, const Eigen::MatrixBase & N, const Eigen::MatrixBase & UV ) { Eigen::MatrixXd _dummy; std::vector _dummy_header; return writePLY(filename,V,F,E, N,UV, _dummy, _dummy_header, _dummy, _dummy_header, _dummy, _dummy_header, _dummy_header, FileEncoding::Binary); } template < typename DerivedV, typename DerivedF > bool writePLY( const std::string & filename, const Eigen::MatrixBase & V, const Eigen::MatrixBase & F, FileEncoding encoding ) { Eigen::MatrixXd _dummy(0,0); std::vector _dummy_header; return writePLY(filename,V,F,_dummy, _dummy,_dummy, _dummy, _dummy_header, _dummy, _dummy_header, _dummy, _dummy_header, _dummy_header, encoding); } template < typename DerivedV, typename DerivedF, typename DerivedE > bool writePLY( const std::string & filename, const Eigen::MatrixBase & V, const Eigen::MatrixBase & F, const Eigen::MatrixBase & E, FileEncoding encoding ) { Eigen::MatrixXd _dummy(0,0); std::vector _dummy_header; return writePLY(filename,V,F,E, _dummy,_dummy, _dummy, _dummy_header, _dummy, _dummy_header, _dummy, _dummy_header, _dummy_header, encoding); } template < typename DerivedV, typename DerivedF, typename DerivedN, typename DerivedUV, typename DerivedVD > bool writePLY( const std::string & filename, const Eigen::MatrixBase & V, const Eigen::MatrixBase & F, const Eigen::MatrixBase & N, const Eigen::MatrixBase & UV, const Eigen::MatrixBase & VD, const std::vector & VDheader, const std::vector & comments ) { Eigen::MatrixXd _dummy(0,0); std::vector _dummy_header; return writePLY(filename,V,F,_dummy, N, UV, VD, VDheader, _dummy, _dummy_header, _dummy, _dummy_header, comments, FileEncoding::Binary); } template < typename DerivedV, typename DerivedF, typename DerivedE, typename DerivedN, typename DerivedUV, typename DerivedVD > bool writePLY( const std::string & filename, const Eigen::MatrixBase & V, const Eigen::MatrixBase & F, const Eigen::MatrixBase & E, const Eigen::MatrixBase & N, const Eigen::MatrixBase & UV, const Eigen::MatrixBase & VD, const std::vector & VDheader, const std::vector & comments ) { Eigen::MatrixXd _dummy(0,0); std::vector _dummy_header; return writePLY(filename,V,F,E, N, UV, VD, VDheader, _dummy, _dummy_header, _dummy, _dummy_header, comments, FileEncoding::Binary); } } #ifdef IGL_STATIC_LIBRARY // Explicit template instantiation // generated by autoexplicit.sh // generated by autoexplicit.sh template bool igl::writePLY, Eigen::Matrix >(std::basic_string, std::allocator > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&); // generated by autoexplicit.sh template bool igl::writePLY, Eigen::Matrix >(std::basic_string, std::allocator > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, igl::FileEncoding); // generated by autoexplicit.sh template bool igl::writePLY, Eigen::Matrix >(std::basic_string, std::allocator > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, igl::FileEncoding); // generated by autoexplicit.sh template bool igl::writePLY, Eigen::Matrix >(std::basic_string, std::allocator > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, igl::FileEncoding); // generated by autoexplicit.sh template bool igl::writePLY, Eigen::Matrix >(std::basic_string, std::allocator > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, igl::FileEncoding); // generated by autoexplicit.sh template bool igl::writePLY, Eigen::Matrix >(std::basic_string, std::allocator > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, igl::FileEncoding); template bool igl::writePLY, Eigen::Matrix >(std::basic_string, std::allocator > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&); template bool igl::writePLY, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(std::basic_string, std::allocator > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, std::vector, std::allocator >, std::allocator, std::allocator > > > const&, Eigen::MatrixBase > const&, std::vector, std::allocator >, std::allocator, std::allocator > > > const&, Eigen::MatrixBase > const&, std::vector, std::allocator >, std::allocator, std::allocator > > > const&, std::vector, std::allocator >, std::allocator, std::allocator > > > const&, igl::FileEncoding); template bool igl::writePLY, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(std::basic_string, std::allocator > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, std::vector, std::allocator >, std::allocator, std::allocator > > > const&, Eigen::MatrixBase > const&, std::vector, std::allocator >, std::allocator, std::allocator > > > const&, Eigen::MatrixBase > const&, std::vector, std::allocator >, std::allocator, std::allocator > > > const&, std::vector, std::allocator >, std::allocator, std::allocator > > > const&, igl::FileEncoding); #endif