Skip to content
Snippets Groups Projects
Commit 069afb4a authored by Tom Fischer's avatar Tom Fischer
Browse files

class TetGenInterface uses now new mesh structures (Node and Element) to read TetGen mesh

removed unused experimental code for TetGen file output
parent c646b7b3
No related branches found
No related tags found
No related merge requests found
......@@ -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
......@@ -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
*/
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment