1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
/* high level interface for MshSaver*/
/* Copyright (C) 2020 Vladimir Fonov <vladimir.fonov@gmail.com> */
/*
/* 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 <iostream>
namespace igl {
namespace internal {
// helper function, appends contents of Eigen matrix to an std::vector, in RowMajor fashion
template <typename T, typename Derived>
void append_mat_to_vec(std::vector<T> &vec, const Eigen::PlainObjectBase<Derived> & mat)
{
size_t st = vec.size();
vec.resize(st + mat.size());
Eigen::Map< Eigen::Matrix<typename Derived::Scalar, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> >
_map_vec( reinterpret_cast<T *>( 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<std::string> &XFields,
const std::vector<Eigen::MatrixXd> &XF,
const std::vector<std::string> &EFields,
const std::vector<Eigen::MatrixXd> &TriF,
const std::vector<Eigen::MatrixXd> &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<XFields.size();++i)
if(XF[i].rows()!=X.rows())
throw std::invalid_argument("Vertex field size mismatch");
}
if(!EFields.empty())
{
if(EFields.size()!=TriF.size())
throw std::invalid_argument("Triangle field count mismatch");
if(EFields.size()!=TetF.size())
throw std::invalid_argument("Tetrahedra field count mismatch");
for(int i=0;i<EFields.size();++i)
{
if(TriF[i].rows()!=Tri.rows())
throw std::invalid_argument("Triangle field size mismatch");
if(TetF[i].rows()!=Tet.rows())
throw std::invalid_argument("Tetrahedra field size mismatch");
}
}
// this is not the most optimal , it would be faster to modify RRMshSaver to work with Eiged data types
std::vector<double> _X;
append_mat_to_vec(_X, X);
std::vector<int> _Tri_Tet;
append_mat_to_vec( _Tri_Tet, Tri);
append_mat_to_vec( _Tri_Tet, Tet);
std::vector<int> _Tri_Tet_len(Tri.rows(), 3); //each is 3 elements long
_Tri_Tet_len.insert(_Tri_Tet_len.end(), Tet.rows(), 4);
std::vector<int> _Tri_Tet_type(Tri.rows(), MshLoader::ELEMENT_TRI);
_Tri_Tet_type.insert(_Tri_Tet_type.end(), Tet.rows(), MshLoader::ELEMENT_TET);
std::vector<int> _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<XFields.size();++i)
{
assert(X.rows()==XF[i].rows());
std::vector<double> _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<EFields.size(); ++i)
{
assert(TriF[i].cols() == TetF[i].cols());
assert(TriF[i].rows() == Tri.rows());
assert(TetF[i].rows() == Tet.rows());
std::vector<double> _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;
}
|