Hi Brig
I recently noticed that cleaver2 is open source. When I checked before it was still only available as an executable.
I have been playing around with cleaver2 and am accumulating small changes that might be useful "improvements":
1. Better implementation of the writeVtkUnstructuredGrid function (see below). Unlike the original code it saves real tetrahedra, instead of 4 triangles per tetrahedra. A single (binary) VTK file with labels attached as a cell data field would be even nicer (http://www.vtk.org/wp-content/uploads/2015/04/file-formats.pdf).
2. Small example showing how to use the library with implicit functions derived from AbstractScalarField.
I noticed that some tetrahedra on the boundary are assigned to an "inside" material but should really have been "background". These tetrahedra have 3 nodes "on" the surface and one which is clearly outside. Are you aware of such problems.
I can send the example mentioned above, if you are interested in adding it to the repo.
Cheers, Bryn
void TetMesh::writeVtkUnstructuredGrid(const std::string &filename, bool verbose)
{
std::string path = filename.substr(0,filename.find_last_of("/")+1);
std::string name = filename.substr(filename.find_last_of("/")+1,filename.size() - 1);
if (path.empty()) {
char cCurrentPath[FILENAME_MAX];
if(GetCurrentDir(cCurrentPath, sizeof(cCurrentPath))){}
cCurrentPath[sizeof(cCurrentPath) - 1] = '\0';
path = std::string(cCurrentPath) + "/";
}
// get the number of files/mats
std::vector<std::ofstream*> output;
std::vector<size_t> numTetsPerMat;
for(size_t i = 0; i < this->tets.size(); i++) {
size_t label = tets.at(i)->mat_label;
if (label + 1 > numTetsPerMat.size())
numTetsPerMat.resize(label+1);
numTetsPerMat.at(label)++;
}
size_t num = 0;
std::vector<std::string> filenames;
while (numTetsPerMat.size() != filenames.size()) {
std::stringstream ss;
ss << path << name << num++ << ".vtk" ;
filenames.push_back(ss.str());
std::cout << "\t" << ss.str() << std:: endl;
}
if(verbose) {
std::cout << "Writing VTK mesh files(tets): \n";
for(size_t i = 0; i < filenames.size(); i++)
std::cout << "\t" << filenames.at(i) << std::endl;
}
//-----------------------------------
// Write Headers
//-----------------------------------
for(size_t i=0; i < numTetsPerMat.size(); i++) {
output.push_back(new std::ofstream(filenames.at(i).c_str()));
*output.at(i) << "# vtk DataFile Version 2.0\n";
*output.at(i) << filenames.at(i) << " Tet Mesh\n";
*output.at(i) << "ASCII\n";
*output.at(i) << "DATASET UNSTRUCTURED_GRID\n";
*output.at(i) << "POINTS " << this->verts.size() << " float\n";
}
//-----------------------------------
// Write Vertex List
//-----------------------------------
for(size_t f=0; f < numTetsPerMat.size(); f++) {
for(size_t i=0; i < this->verts.size(); i++)
{
*output.at(f) << this->verts[i]->pos().x << " "
<< this->verts[i]->pos().y << " "
<< this->verts[i]->pos().z << std::endl;
}
size_t num_tets = numTetsPerMat.at(f);
*output.at(f) << "CELLS " << num_tets << " " << num_tets*5 << "\n";
}
//-----------------------------------
// Write Cell/Face List
//-----------------------------------
for(size_t f=0; f < this->tets.size(); f++)
{
Tet* t = this->tets.at(f);
size_t v1 = t->verts[0]->tm_v_index;
size_t v2 = t->verts[1]->tm_v_index;
size_t v3 = t->verts[2]->tm_v_index;
size_t v4 = t->verts[3]->tm_v_index;
*output.at(t->mat_label) << 4 << " " << v1 << " " << v2 << " " << v3 << " " << v4 << "\n";
}
for(size_t f=0; f < numTetsPerMat.size(); f++) {
size_t num_tets = numTetsPerMat.at(f);
*output.at(f) << "CELL_TYPES " << num_tets << "\n";
}
for(size_t f=0; f < this->tets.size(); f++)
{
Tet* t = this->tets.at(f);
*output.at(t->mat_label) << 10 << "\n";
}
//CLOSE
for(size_t i=0; i < numTetsPerMat.size(); i++) {
(*output.at(i)).close();
delete output.at(i);
}
}
Archive powered by MHonArc 2.6.18.