diff --git a/wrap/io_tetramesh/import_msh.h b/wrap/io_tetramesh/import_msh.h index cc7cbf24..8d0a0857 100644 --- a/wrap/io_tetramesh/import_msh.h +++ b/wrap/io_tetramesh/import_msh.h @@ -3,12 +3,118 @@ #include -namespace vcg -{ -namespace tetra -{ -namespace io +namespace vcg { +namespace tetra { +namespace io { + +template +class MshInfo { + typedef std::map FieldMap; + + FieldMap nodeFields; + FieldMap elemFields; + + + template + struct AttribTraits + { + typedef std::vector Type; + enum { Dimension = Dimensions }; + }; + + template + struct AttribTraits + { + typedef Scalar Type; + enum { Dimension = 1 }; + }; + + template + struct AttribHelper + { + static void assign(AttrHandle & handle, int index, const double * data) + { + for (int i=0; i + struct AttribHelper + { + static void assign(AttrHandle & handle, int index, const double * data) + { + handle[index] = Scalar(data[index]); + } + }; + + template + static void fillMeshAttributes(const std::string & attrib_name, int attrib_dim, MeshType & mesh, const double * data) + { + if (PerNode) + { + switch(attrib_dim) + { + case 1 : fillMeshWithAttributePerNode(attrib_name, mesh, data); break; + case 2 : fillMeshWithAttributePerNode(attrib_name, mesh, data); break; + case 3 : fillMeshWithAttributePerNode(attrib_name, mesh, data); break; + case 4 : fillMeshWithAttributePerNode(attrib_name, mesh, data); break; + case 5 : fillMeshWithAttributePerNode(attrib_name, mesh, data); break; + case 6 : fillMeshWithAttributePerNode(attrib_name, mesh, data); break; + case 7 : fillMeshWithAttributePerNode(attrib_name, mesh, data); break; + case 8 : fillMeshWithAttributePerNode(attrib_name, mesh, data); break; + case 9 : fillMeshWithAttributePerNode(attrib_name, mesh, data); break; + default : throw std::string("Dimension of custom attribute vector unsupported"); + } + } + else + { + switch(attrib_dim) + { + case 1 : fillMeshWithAttributePerElement(attrib_name, mesh, data); break; + case 2 : fillMeshWithAttributePerElement(attrib_name, mesh, data); break; + case 3 : fillMeshWithAttributePerElement(attrib_name, mesh, data); break; + case 4 : fillMeshWithAttributePerElement(attrib_name, mesh, data); break; + case 5 : fillMeshWithAttributePerElement(attrib_name, mesh, data); break; + case 6 : fillMeshWithAttributePerElement(attrib_name, mesh, data); break; + case 7 : fillMeshWithAttributePerElement(attrib_name, mesh, data); break; + case 8 : fillMeshWithAttributePerElement(attrib_name, mesh, data); break; + case 9 : fillMeshWithAttributePerElement(attrib_name, mesh, data); break; + default : throw std::string("Dimension of custom attribute vector unsupported"); + } + } + } + + template + static void fillMeshWithAttributePerNode(const std::string & attrib_name, MeshType & mesh, const double * data) + { + typedef typename AttribTraits::Type AttrType; + typedef typename MeshType::template PerVertexAttributeHandle AttrHandle; + + AttrHandle handle = vcg::tetra::Allocator::template GetPerVertexAttribute(mesh, attrib_name); + size_t num_nodes = size_t(mesh.VN()); + + for (int i=0; i::assign(handle, i, data); + } + + template + static void fillMeshWithAttributePerElement(const std::string & attrib_name, MeshType & mesh, const double * data) + { + typedef typename AttribTraits::Type AttrType; + typedef typename MeshType::template PerFaceAttributeHandle AttrHandle; + + AttrHandle handle = vcg::tetra::Allocator::template GetPerFaceAttribute(mesh, attrib_name); + size_t num_elements = size_t(mesh.TN()); + + for (int i=0; i::assign(handle, i, data); + } +}; + template class ImporterMSH { @@ -266,12 +372,12 @@ class ImporterMSH } } - static int parseNodeData(MeshType &m, std::ifstream &fin, bool binary) + static int parseNodeData(MeshType &m, MshInfo & info, std::ifstream &fin, bool binary) { return parseDataField(m, fin, binary); } - static int parseElementData(MeshType &m, std::ifstream &fin, bool binary) + static int parseElementData(MeshType &m, MshInfo & info, std::ifstream &fin, bool binary) { return parseDataField(m, fin, binary); } @@ -288,7 +394,7 @@ class ImporterMSH fin >> buf; } - static int parseMshMesh(MeshType &m, std::string &filename) + static int parseMshMesh(MeshType &m, std::string &filename, MshInfo & info) { std::ifstream fin(filename.c_str(), std::ios::in | std::ios::binary); @@ -362,14 +468,14 @@ class ImporterMSH } else if (lookAhead == "$NodeData") { - parseNodeData(m, fin, binary); + parseNodeData(m, info, fin, binary); fin >> lookAhead; if (lookAhead != "$EndNodeData") return INVALID_FORMAT; } else if (lookAhead == "$ElementData") { - parseElementData(m, fin, binary); + parseElementData(m, info, fin, binary); fin >> lookAhead; if (lookAhead != "$EndElementData") return INVALID_FORMAT; @@ -388,11 +494,17 @@ class ImporterMSH return 0; } - public: +public: static int Open(MeshType &m, const char *filename, CallBackPos *cb = 0) + { + MshInfo info; + return Open(m, filename, info, cb); + } + + static int Open(MeshType &m, const char *filename, MshInfo & info, CallBackPos *cb = 0) { std::string name(filename); - return parseMshMesh(m, name); + return parseMshMesh(m, name, info); } }; } // namespace io