From 069afb4a8cc78504956808548562aa2ef5fab166 Mon Sep 17 00:00:00 2001 From: Thomas Fischer <thomas.fischer@ufz.de> Date: Tue, 18 Sep 2012 10:42:46 +0200 Subject: [PATCH] class TetGenInterface uses now new mesh structures (Node and Element) to read TetGen mesh removed unused experimental code for TetGen file output --- FileIO/MeshIO/TetGenInterface.cpp | 316 ++++++------------------------ FileIO/MeshIO/TetGenInterface.h | 24 ++- 2 files changed, 76 insertions(+), 264 deletions(-) diff --git a/FileIO/MeshIO/TetGenInterface.cpp b/FileIO/MeshIO/TetGenInterface.cpp index e0cb783304d..87faa8a7205 100644 --- a/FileIO/MeshIO/TetGenInterface.cpp +++ b/FileIO/MeshIO/TetGenInterface.cpp @@ -12,22 +12,22 @@ #include <cstddef> #include <string> -// FileIO -#include "MeshIO/TetGenInterface.h" - -// Base +// BaseLib #include "StringTools.h" -/* TODO6 -// MSH -#include "msh_elem.h" -#include "msh_mesh.h" -#include "msh_node.h" +// FileIO +#include "TetGenInterface.h" + +// MeshLib +#include "Mesh.h" +#include "Node.h" +#include "Elements/Element.h" +#include "Elements/Tet.h" namespace FileIO { TetGenInterface::TetGenInterface() : - _mesh (NULL), _zero_based_idx (false) + _nodes(), _elements(), _zero_based_idx (false) { } @@ -35,153 +35,7 @@ TetGenInterface::~TetGenInterface() { } -void TetGenInterface::writeTetGenMesh(std::string const& nodes_fname, std::string const& ele_fname, - MeshLib::Mesh const* const mesh) const -{ - writeTetGenNodes(nodes_fname, mesh); - writeTetGenElements(ele_fname, mesh); -} - -void TetGenInterface::writeTetGenNodes(std::string const& nodes_fname, MeshLib::Mesh const*const mesh) const -{ - std::ofstream out(nodes_fname.c_str()); - if (out) { - std::vector<MeshLib::CElem*> const& elements(mesh->getElementVector()); - const size_t n_elements(elements.size()); - size_t n_prisms(0); - for (size_t k(0); k<n_elements; k++) { - if (elements[k]->GetElementType() == MshElemType::PRISM) { - n_prisms++; - } - } - const size_t n_nodes(mesh->GetNodesNumber(false)); - out << n_nodes+4*n_prisms << " 3 0 0" << std::endl; - std::vector<MeshLib::CNode*> const& nodes(mesh->getNodeVector()); - for (size_t k(0); k<n_nodes; k++) { - double const*const node(nodes[k]->getData()); - out << k << " " << node[0] << " " << node[1] << " " << node[2] << std::endl; - } - // write additional nodes for prisms - std::vector<size_t> idxs; - for (size_t k(0), idx(n_nodes); k<n_elements; k++) { - if (elements[k]->GetElementType() == MshElemType::PRISM) { - elements[k]->getNodeIndices(idxs); - double const*const n0((nodes[idxs[0]])->getData()); - double const*const n1((nodes[idxs[1]])->getData()); - double const*const n2((nodes[idxs[2]])->getData()); - double const*const n3((nodes[idxs[3]])->getData()); - double const*const n4((nodes[idxs[4]])->getData()); - double const*const n5((nodes[idxs[5]])->getData()); - - idxs.clear(); - - // compute centroid of the prism - const double centroid[3] = {(n0[0]+n1[0]+n2[0]+n3[0]+n4[0]+n5[0])/6, - (n0[1]+n1[1]+n2[1]+n3[1]+n4[1]+n5[1])/6, - (n0[2]+n1[2]+n2[2]+n3[2]+n4[2]+n5[2])/6}; - - // center of first rectangle surface - const double center0[3] = {(n0[0]+n1[0]+n3[0]+n4[0])/4, (n0[1]+n1[1]+n3[1]+n4[1])/4, (n0[2]+n1[2]+n3[2]+n4[2])/4}; - // center of second rectangle surface - const double center1[3] = {(n1[0]+n2[0]+n4[0]+n5[0])/4, (n1[1]+n2[1]+n4[1]+n5[1])/4, (n1[2]+n2[2]+n4[2]+n5[2])/4}; - // center of third rectangle surface - const double center2[3] = {(n0[0]+n2[0]+n3[0]+n5[0])/4, (n0[1]+n2[1]+n3[1]+n5[1])/4, (n0[2]+n2[2]+n3[2]+n5[2])/4}; - - out << idx++ << " " << centroid[0] << " " << centroid[1] << " " << centroid[2] << std::endl; - out << idx++ << " " << center0[0] << " " << center0[1] << " " << center0[2] << std::endl; - out << idx++ << " " << center1[0] << " " << center1[1] << " " << center1[2] << std::endl; - out << idx++ << " " << center2[0] << " " << center2[1] << " " << center2[2] << std::endl; - } - } - out.close(); - } else { - std::cout << "cold not open file for writing nodes" << std::endl; - } -} - -void TetGenInterface::writeTetGenElements(std::string const& ele_fname, MeshLib::CFEMesh const*const mesh) const -{ - std::ofstream out(ele_fname.c_str()); - if (out) { - std::vector<MeshLib::CElem*> const& elements(mesh->getElementVector()); - const size_t n_elements(elements.size()); - // count number of prisms, tetrahedras, hexahedras - size_t n_prisms(0), n_tets(0), n_hexs(0); - for (size_t k(0); k<n_elements; k++) { - switch (elements[k]->GetElementType()) { - case MshElemType::PRISM: - n_prisms++; - break; - case MshElemType::TETRAHEDRON: - n_tets++; - break; - case MshElemType::HEXAHEDRON: - n_hexs++; - break; - default: - std::cout << "count elements - element type not yet supported" << std::endl; - } // end case - } // end for - - const size_t n_tetrahedras(n_tets+14*n_prisms); - const size_t nodes_offset(mesh->GetNodesNumber(false)); - size_t cnt_prisms(0); - std::vector<size_t> idxs; // node indices - out << n_tetrahedras << " 4 0 0" << std::endl; - for (size_t k(0), cnt(0); k<n_elements; k++) { - elements[k]->getNodeIndices(idxs); - switch (elements[k]->GetElementType()) { - case MshElemType::PRISM: - { - out << cnt++ << " " << idxs[0] << " " << idxs[1] << " " << idxs[2] << " " << nodes_offset+cnt_prisms*4 << std::endl; - out << cnt++ << " " << idxs[3] << " " << idxs[5] << " " << idxs[4] << " " << nodes_offset+cnt_prisms*4 << std::endl; - // - out << cnt++ << " " << idxs[0] << " " << nodes_offset+cnt_prisms*4+1 << " " << idxs[1] << " " << nodes_offset+cnt_prisms*4 << std::endl; - out << cnt++ << " " << idxs[1] << " " << nodes_offset+cnt_prisms*4+1 << " " << idxs[4] << " " << nodes_offset+cnt_prisms*4 << std::endl; - out << cnt++ << " " << idxs[4] << " " << nodes_offset+cnt_prisms*4+1 << " " << idxs[3] << " " << nodes_offset+cnt_prisms*4 << std::endl; - out << cnt++ << " " << idxs[3] << " " << nodes_offset+cnt_prisms*4+1 << " " << idxs[0] << " " << nodes_offset+cnt_prisms*4 << std::endl; - // - out << cnt++ << " " << idxs[1] << " " << nodes_offset+cnt_prisms*4+2 << " " << idxs[2] << " " << nodes_offset+cnt_prisms*4 << std::endl; - out << cnt++ << " " << idxs[4] << " " << nodes_offset+cnt_prisms*4+2 << " " << idxs[1] << " " << nodes_offset+cnt_prisms*4 << std::endl; - out << cnt++ << " " << idxs[5] << " " << nodes_offset+cnt_prisms*4+2 << " " << idxs[4] << " " << nodes_offset+cnt_prisms*4 << std::endl; - out << cnt++ << " " << idxs[2] << " " << nodes_offset+cnt_prisms*4+2 << " " << idxs[5] << " " << nodes_offset+cnt_prisms*4 << std::endl; - // - out << cnt++ << " " << idxs[2] << " " << nodes_offset+cnt_prisms*4+3 << " " << idxs[0] << " " << nodes_offset+cnt_prisms*4 << std::endl; - out << cnt++ << " " << idxs[5] << " " << nodes_offset+cnt_prisms*4+3 << " " << idxs[2] << " " << nodes_offset+cnt_prisms*4 << std::endl; - out << cnt++ << " " << idxs[3] << " " << nodes_offset+cnt_prisms*4+3 << " " << idxs[5] << " " << nodes_offset+cnt_prisms*4 << std::endl; - out << cnt++ << " " << idxs[0] << " " << nodes_offset+cnt_prisms*4+3 << " " << idxs[3] << " " << nodes_offset+cnt_prisms*4 << std::endl; - - cnt_prisms++; - - break; - } - case MshElemType::TETRAHEDRON: - out << cnt++ << " " << idxs[0] << " " << idxs[1] << " " << idxs[2] << " " << idxs[3] << std::endl; - break; - case MshElemType::HEXAHEDRON: - std::cout << "element type HEXAHEDRON not yet supported" << std::endl; - break; - case MshElemType::PYRAMID: - std::cout << "element type PYRAMID not yet supported" << std::endl; - break; - case MshElemType::LINE: - std::cout << "element type LINE not yet supported" << std::endl; - break; - case MshElemType::QUAD: - std::cout << "element type QUAD not yet supported" << std::endl; - break; - default: - std::cout << "element type not yet supported" << std::endl; - } // end case - idxs.clear(); - } // end for - out.close(); - } else { - std::cout << "cold not open file for writing elements" << std::endl; - } -} - -MeshLib::CFEMesh* TetGenInterface::readTetGenMesh (std::string const& nodes_fname, +MeshLib::Mesh* TetGenInterface::readTetGenMesh (std::string const& nodes_fname, std::string const& ele_fname) { std::ifstream ins_nodes (nodes_fname.c_str()); @@ -198,23 +52,27 @@ MeshLib::CFEMesh* TetGenInterface::readTetGenMesh (std::string const& nodes_fnam return NULL; } - _mesh = new MeshLib::CFEMesh(); - - if (!readNodesFromStream (ins_nodes)) - { - delete _mesh; + if (!readNodesFromStream (ins_nodes)) { + // remove nodes read until now + for (std::size_t k(0); k<_nodes.size(); k++) { + delete _nodes[k]; + } return NULL; } - _mesh->InitialNodesNumber(); - - if (!readElementsFromStream (ins_ele)) - { - delete _mesh; + if (!readElementsFromStream (ins_ele)) { + // remove elements read until now + for (std::size_t k(0); k<_elements.size(); k++) { + delete _elements[k]; + } + // remove nodes + for (std::size_t k(0); k<_nodes.size(); k++) { + delete _nodes[k]; + } return NULL; } - return _mesh; + return new MeshLib::Mesh(nodes_fname, _nodes, _elements); } bool TetGenInterface::readNodesFromStream (std::ifstream &ins) @@ -266,8 +124,7 @@ bool TetGenInterface::parseNodesFileHeader(std::string &line, n_nodes = str2number<size_t> (line.substr(pos_beg, pos_end - pos_beg)); else { - std::cout << - "TetGenInterface::parseNodesFileHeader could not correct read TetGen mesh header - number of nodes" + std::cout << "TetGenInterface::parseNodesFileHeader could not correct read TetGen mesh header - number of nodes" << std::endl; return false; } @@ -294,70 +151,49 @@ bool TetGenInterface::parseNodesFileHeader(std::string &line, bool TetGenInterface::parseNodes(std::ifstream& ins, size_t n_nodes, size_t dim) { - size_t pos_beg, pos_end; + std::size_t pos_beg, pos_end; std::string line; double* coordinates (static_cast<double*> (alloca (sizeof(double) * dim))); - for (size_t k(0); k < n_nodes && !ins.fail(); k++) - { - getline (ins, line); - if (!ins.fail()) - { - if (!line.empty()) - { + for (std::size_t k(0); k < n_nodes && !ins.fail(); k++) { + getline(ins, line); + if (!ins.fail()) { + if (!line.empty()) { pos_end = 0; // read id size_t id; pos_beg = line.find_first_not_of(" ", pos_end); pos_end = line.find_first_of(" \n", pos_beg); - if (pos_beg != std::string::npos && pos_end != std::string::npos) - { - id = - str2number<size_t>(line.substr(pos_beg, pos_end - - pos_beg)); + if (pos_beg != std::string::npos && pos_end != std::string::npos) { + id = str2number<size_t> (line.substr(pos_beg, pos_end - pos_beg)); if (k == 0 && id == 0) _zero_based_idx = true; - } - else - { - std::cout << "error reading id of node " << k << - " in TetGenInterface::parseNodes" << std::endl; + } else { + std::cout << "error reading id of node " << k + << " in TetGenInterface::parseNodes" << std::endl; return false; } // read coordinates - for (size_t i(0); i < dim; i++) - { + for (size_t i(0); i < dim; i++) { pos_beg = line.find_first_not_of(" ", pos_end); pos_end = line.find_first_of(" \n", pos_beg); - if (pos_end == std::string::npos) - pos_end = line.size(); + if (pos_end == std::string::npos) pos_end = line.size(); if (pos_beg != std::string::npos) - coordinates[i] = - str2number<double>(line.substr(pos_beg, - pos_end - - pos_beg)); - else - { - std::cout << "error reading coordinate " << i << - " of node " << k << - " in TetGenInterface::parseNodes" << - std::endl; + coordinates[i] = str2number<double> ( + line.substr(pos_beg, pos_end - pos_beg)); + else { + std::cout << "error reading coordinate " << i << " of node " << k + << " in TetGenInterface::parseNodes" << std::endl; return false; } } - if (!_zero_based_idx) - id--; + if (!_zero_based_idx) id--; // since CFEMesh is our friend we can access private data of mesh - _mesh->nod_vector.push_back(new MeshLib::CNode(id, coordinates[0], - coordinates[1], - coordinates[2])); + _nodes.push_back(new MeshLib::Node(coordinates, id)); // read attributes and boundary markers ... - at the moment we do not use this information } - } - else - { - std::cout << "error reading node " << k << - " in TetGenInterface::parseNodes" << std::endl; + } else { + std::cout << "error reading node " << k << " in TetGenInterface::parseNodes" << std::endl; return false; } } @@ -454,11 +290,8 @@ bool TetGenInterface::parseElements(std::ifstream& ins, size_t n_tets, size_t n_ pos_beg = line.find_first_not_of(" ", pos_end); pos_end = line.find_first_of(" \n", pos_beg); if (pos_beg != std::string::npos && pos_end != std::string::npos) - id = - str2number<size_t>(line.substr(pos_beg, pos_end - - pos_beg)); - else - { + id = str2number<size_t>(line.substr(pos_beg, pos_end - pos_beg)); + else { std::cout << "error reading id of tetrahedra " << k << " in TetGenInterface::parseElements" << std::endl; return false; @@ -472,54 +305,37 @@ bool TetGenInterface::parseElements(std::ifstream& ins, size_t n_tets, size_t n_ pos_end = line.size(); if (pos_beg != std::string::npos && pos_end != std::string::npos) - ids[i] = - str2number<size_t>(line.substr(pos_beg, - pos_end - - pos_beg)); + ids[i] = str2number<std::size_t>(line.substr(pos_beg, pos_end - pos_beg)); else { - std::cout << "error reading node " << i << - " of tetrahedra " << k << - " in TetGenInterface::parseElements" << - std::endl; + std::cout << "error reading node " << i << " of tetrahedra " << k << + " in TetGenInterface::parseElements" << std::endl; return false; } } - if (!_zero_based_idx) - { + if (!_zero_based_idx) { id--; for (size_t i(0); i < n_nodes_per_tet; i++) ids[i]--; } - // since CFEMesh is our friend we can access private data of mesh - MeshLib::CElem* elem (new MeshLib::CElem(id)); - elem->setElementProperties (MshElemType::TETRAHEDRON, false); - std::vector<MeshLib::CNode*> ele_nodes(n_nodes_per_tet); - for (size_t i(0); i < n_nodes_per_tet; i++) { - ele_nodes[i] = _mesh->nod_vector[ids[i]]; - } - elem->setNodes (ele_nodes); - _mesh->ele_vector.push_back(elem); + // read region attribute - this is something like material group - if (region_attribute) - { + unsigned region (0); + if (region_attribute) { pos_beg = line.find_first_not_of(" ", pos_end); pos_end = line.find_first_of(" ", pos_beg); - if (pos_end == std::string::npos) - pos_end = line.size(); - if (pos_beg != std::string::npos && pos_end != - std::string::npos) - elem->setPatchIndex (str2number<int>(line.substr( - pos_beg, - pos_end - - pos_beg))); - else - { + if (pos_end == std::string::npos) pos_end = line.size(); + if (pos_beg != std::string::npos && pos_end != std::string::npos) + region = str2number<unsigned> (line.substr(pos_beg, pos_end - pos_beg)); + else { std::cout << "error reading region attribute of tetrahedra " << k << " in TetGenInterface::parseElements" << std::endl; return false; } } + // insert new element into vector + _elements.push_back (new MeshLib::Tet(_nodes[ids[0]], _nodes[ids[1]], _nodes[ids[2]], _nodes[ids[3]], region)); + } } else @@ -531,6 +347,4 @@ bool TetGenInterface::parseElements(std::ifstream& ins, size_t n_tets, size_t n_ return true; } -} -*/ - +} // end namespace FileIO diff --git a/FileIO/MeshIO/TetGenInterface.h b/FileIO/MeshIO/TetGenInterface.h index ef52061de25..d5f621f8dff 100644 --- a/FileIO/MeshIO/TetGenInterface.h +++ b/FileIO/MeshIO/TetGenInterface.h @@ -12,9 +12,13 @@ #ifndef TETGENINTERFACE_H_ #define TETGENINTERFACE_H_ -// forward declaration of mesh class +#include <vector> + +// forward declaration of class Node and Element namespace MeshLib { + class Node; + class Element; class Mesh; } @@ -29,14 +33,6 @@ public: TetGenInterface(); virtual ~TetGenInterface(); - /** - * write a mesh into TetGen mesh file format - * @param nodes_fname - * @param ele_fname - * @param mesh - */ - void writeTetGenMesh (std::string const& nodes_fname, std::string const& ele_fname, MeshLib::Mesh const*const mesh) const; - /** * Method reads the TetGen mesh from node file and element file. * @param nodes_fname file name of the nodes file @@ -52,8 +48,6 @@ public: friend class MeshLib::Mesh; private: - void writeTetGenNodes(std::string const& nodes_fname, MeshLib::Mesh const*const mesh) const; - void writeTetGenElements(std::string const& ele_fname, MeshLib::Mesh const*const mesh) const; /** * Method reads the nodes from stream and stores them in the node vector of the mesh class. * For this purpose it uses methods parseNodesFileHeader() and parseNodes(). @@ -110,9 +104,13 @@ private: bool region_attribute); /** - * the mesh that is returned if all data is read + * the nodes later on handed over to the mesh are stored in this vector + */ + std::vector<MeshLib::Node*> _nodes; + /** + * the elements (tetrahedrons) later on handed over to the mesh are stored in this vector */ - MeshLib::Mesh* _mesh; + std::vector<MeshLib::Element*> _elements; /** * the value is true if the indexing is zero based, else false */ -- GitLab