// high level interface for MshSaver // // Copyright (C) 2020 Vladimir Fonov // // 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 "writeMSH.h" #include "MshSaver.h" #include "MshLoader.h" #include namespace igl { namespace internal { // helper function, appends contents of Eigen matrix to an std::vector, in RowMajor fashion template void append_mat_to_vec(std::vector &vec, const Eigen::MatrixBase & mat) { size_t st = vec.size(); vec.resize(st + mat.size()); // Iterate over the rows and columns in row-major order for (int i = 0; i < mat.rows(); ++i) { for (int j = 0; j < mat.cols(); ++j) { vec[st++] = mat(i, j); } } } } } template < typename DerivedX, typename DerivedTri, typename DerivedTet, typename DerivedTriTag, typename DerivedTetTag, typename MatrixXF, typename MatrixTriF, typename MatrixTetF > IGL_INLINE bool igl::writeMSH( const std::string &msh, const Eigen::MatrixBase &X, const Eigen::MatrixBase &Tri, const Eigen::MatrixBase &Tet, const Eigen::MatrixBase &TriTag, const Eigen::MatrixBase &TetTag, const std::vector &XFields, const std::vector &XF, const std::vector &EFields, const std::vector &TriF, const std::vector &TetF) { using namespace internal; try { // error checks if(!XFields.empty()) { if(XFields.size()!=XF.size()) throw std::invalid_argument("Vertex field count mismatch"); for(int i=0;i _X; append_mat_to_vec(_X, X); std::vector _Tri_Tet; append_mat_to_vec( _Tri_Tet, Tri); append_mat_to_vec( _Tri_Tet, Tet); std::vector _Tri_Tet_len(Tri.rows(), 3); //each is 3 elements long _Tri_Tet_len.insert(_Tri_Tet_len.end(), Tet.rows(), 4); std::vector _Tri_Tet_type(Tri.rows(), MshLoader::ELEMENT_TRI); _Tri_Tet_type.insert(_Tri_Tet_type.end(), Tet.rows(), MshLoader::ELEMENT_TET); std::vector _Tri_Tet_tag; // apparently TriTag and TetTag need to be present. Use zero arrays if their // empty if(TriTag.size() == 0) { append_mat_to_vec(_Tri_Tet_tag, Eigen::Matrix::Zero(Tri.rows())); }else { append_mat_to_vec(_Tri_Tet_tag, TriTag); } if(TetTag.size() == 0) { append_mat_to_vec(_Tri_Tet_tag, Eigen::Matrix::Zero(Tet.rows())); }else { append_mat_to_vec(_Tri_Tet_tag, TetTag); } igl::MshSaver msh_saver(msh, true); msh_saver.save_mesh( _X, _Tri_Tet, _Tri_Tet_len, _Tri_Tet_type, _Tri_Tet_tag); // append vertex data for(size_t i=0;i _XF; append_mat_to_vec(_XF, XF[i]); if(XF[i].cols() == 1) msh_saver.save_scalar_field(XFields[i], _XF ); else if(XF[i].cols() == 3) msh_saver.save_vector_field(XFields[i], _XF ); else { throw std::invalid_argument("unsupported vertex field dimensionality"); } } // append node data for(size_t i=0; i _EF; append_mat_to_vec(_EF, TriF[i]); append_mat_to_vec(_EF, TetF[i]); assert(_EF.size() == (TriF[i].size()+TetF[i].size())); if( TriF[i].cols() == 1 ) msh_saver.save_elem_scalar_field(EFields[i], _EF ); else if( TriF[i].cols() == 3 ) msh_saver.save_elem_vector_field(EFields[i], _EF ); else { throw std::invalid_argument("unsupported node field dimensionality"); } } } catch(const std::exception& e) { std::cerr << e.what() << std::endl; return false; } return true; } #ifdef IGL_STATIC_LIBRARY // Explicit template instantiation template bool igl::writeMSH, 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&, std::vector, std::allocator>, std::allocator, std::allocator>>> const&, std::vector, std::allocator>> const&, std::vector, std::allocator>, std::allocator, std::allocator>>> const&, std::vector, std::allocator>> const&, std::vector, std::allocator>> const&); #endif