// 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::PlainObjectBase & mat) { size_t st = vec.size(); vec.resize(st + mat.size()); Eigen::Map< Eigen::Matrix > _map_vec( reinterpret_cast( vec.data() + st ), mat.rows(), mat.cols() ); _map_vec = mat; } } } IGL_INLINE bool igl::writeMSH( const std::string &msh, const Eigen::MatrixXd &X, const Eigen::MatrixXi &Tri, const Eigen::MatrixXi &Tet, const Eigen::MatrixXi &TriTag, const Eigen::MatrixXi &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; append_mat_to_vec(_Tri_Tet_tag, TriTag); 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; }