mirror of https://github.com/CGAL/cgal
add tetrahedral mesh .tetra.am reader in C3t3_io_plugin
This commit is contained in:
parent
33816fa798
commit
53d8734ad2
|
|
@ -79,7 +79,7 @@ CGAL::Three::Scene_item* Surf_io_plugin::actual_load(QFileInfo fileinfo)
|
|||
return item;
|
||||
}
|
||||
std::vector<FaceGraph> patches;
|
||||
std::vector<MaterialData> material_data;
|
||||
std::vector<CGAL::MaterialData> material_data;
|
||||
CGAL::Bbox_3 grid_box;
|
||||
std::array<unsigned int, 3> grid_size = {{1, 1, 1}};
|
||||
boost::container::flat_set<Point_3> duplicated_points;
|
||||
|
|
|
|||
|
|
@ -19,9 +19,11 @@ class Polyhedron_demo_c3t3_binary_io_plugin :
|
|||
|
||||
public:
|
||||
QString name() const override { return "C3t3_io_plugin"; }
|
||||
QString nameFilters() const override { return "binary files (*.cgal);;ascii (*.mesh);;maya (*.ma)"; }
|
||||
QString saveNameFilters() const override { return "binary files (*.cgal);;ascii (*.mesh);;maya (*.ma);;avizo (*.am);;OFF files (*.off)"; }
|
||||
QString loadNameFilters() const override { return "binary files (*.cgal);;ascii (*.mesh)"; }
|
||||
QString nameFilters() const override { return "binary files (*.cgal);;ascii (*.mesh);;maya (*.ma);;avizo (*.tetra.am)"; }
|
||||
QString saveNameFilters() const override{
|
||||
return "binary files (*.cgal);;ascii (*.mesh);;maya (*.ma);;avizo (*.tetra.am);;OFF files (*.off)"; }
|
||||
QString loadNameFilters() const override {
|
||||
return "binary files (*.cgal);;ascii (*.mesh);;avizo (*.tetra.am)"; }
|
||||
bool canLoad(QFileInfo) const override;
|
||||
QList<Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) override;
|
||||
|
||||
|
|
@ -49,14 +51,21 @@ bool Polyhedron_demo_c3t3_binary_io_plugin::canLoad(QFileInfo fi) const {
|
|||
<< (const char*)fi.filePath().toUtf8() << std::endl;
|
||||
return false;
|
||||
}
|
||||
std::string line;
|
||||
std::istringstream iss;
|
||||
std::getline (in,line);
|
||||
iss.str(line);
|
||||
std::string keyword;
|
||||
if (iss >> keyword)
|
||||
if (keyword == "binary")
|
||||
return true;
|
||||
if (fi.suffix().toLower() == "cgal")
|
||||
{
|
||||
std::string line;
|
||||
std::istringstream iss;
|
||||
std::getline(in, line);
|
||||
iss.str(line);
|
||||
std::string keyword;
|
||||
if (iss >> keyword)
|
||||
if (keyword == "binary")
|
||||
return true;
|
||||
}
|
||||
else if (fi.suffix().toLower() == "am")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -88,7 +97,6 @@ Polyhedron_demo_c3t3_binary_io_plugin::load(
|
|||
{
|
||||
item->setName(fileinfo.baseName());
|
||||
|
||||
|
||||
if(item->load_binary(in)) {
|
||||
if(add_to_scene){
|
||||
item->resetCutPlane();
|
||||
|
|
@ -181,7 +189,27 @@ Polyhedron_demo_c3t3_binary_io_plugin::load(
|
|||
QMessageBox::Ok);
|
||||
}
|
||||
}
|
||||
else if (fileinfo.suffix().toLower() == "am")
|
||||
{
|
||||
if (CGAL::IO::internal::is_avizo_tetra_format(in, "ascii"))
|
||||
{
|
||||
in.close();
|
||||
in.open(fileinfo.filePath().toUtf8(), std::ios_base::in);//not binary
|
||||
CGAL_assertion(!(!in));
|
||||
}
|
||||
|
||||
item->setName(fileinfo.baseName());
|
||||
|
||||
if (CGAL::IO::read_AVIZO_TETRA(in, item->c3t3().triangulation()))
|
||||
{
|
||||
item->resetCutPlane();
|
||||
item->c3t3_changed();
|
||||
item->changed();
|
||||
if (add_to_scene)
|
||||
CGAL::Three::Three::scene()->addItem(item);
|
||||
return QList<Scene_item*>() << item;
|
||||
}
|
||||
}
|
||||
|
||||
// if all loading failed...
|
||||
delete item;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@
|
|||
#include <CGAL/Named_function_parameters.h>
|
||||
#include <CGAL/Polygon_mesh_processing/internal/named_params_helper.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
//a material is composed of an material Id and a material name.
|
||||
typedef std::pair<int, std::string> material;
|
||||
|
||||
|
|
@ -27,10 +29,11 @@ std::string to_lower_case(const std::string& str)
|
|||
return r;
|
||||
}
|
||||
|
||||
template <typename MaterialIdType>
|
||||
bool get_material_metadata(std::istream& input,
|
||||
std::string& line,
|
||||
material& _material,
|
||||
int material_id)
|
||||
MaterialIdType material_id)
|
||||
{
|
||||
std::istringstream iss;
|
||||
iss.str(line);
|
||||
|
|
@ -76,9 +79,10 @@ bool line_starts_with(const std::string& line, const char* cstr)
|
|||
namespace IO{
|
||||
namespace internal{
|
||||
|
||||
template<typename IdType>
|
||||
bool treat_surf_materials(std::istream& input,
|
||||
std::vector<material>& materials,
|
||||
int& material_id)
|
||||
IdType& material_id)
|
||||
{
|
||||
std::string line;
|
||||
while(std::getline(input, line))
|
||||
|
|
@ -571,3 +575,5 @@ bool read_surf(std::istream& input, std::vector<Mesh>& output,
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}//end namespace CGAL
|
||||
|
|
@ -17,13 +17,27 @@
|
|||
|
||||
|
||||
#include <CGAL/IO/File_medit.h>
|
||||
#include <CGAL/IO/read_surf_trianglemesh.h>
|
||||
#include <CGAL/SMDS_3/tet_soup_to_c3t3.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
|
||||
#include <CGAL/utility.h>
|
||||
#include <CGAL/Unique_hash_map.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
// ---------------------------------
|
||||
// Output C3t3 to Avizo tetra file format
|
||||
// ---------------------------------
|
||||
|
||||
namespace IO {
|
||||
|
||||
/**
|
||||
|
|
@ -144,12 +158,294 @@ output_to_avizo(std::ostream& os,
|
|||
|
||||
} // end output_to_avizo(...)
|
||||
|
||||
} // end namespace IO
|
||||
|
||||
#ifndef CGAL_NO_DEPRECATED_CODE
|
||||
using IO::output_to_avizo;
|
||||
#endif
|
||||
|
||||
// ---------------------------------
|
||||
// Read C3t3 from Avizo file format
|
||||
// ---------------------------------
|
||||
|
||||
namespace internal {
|
||||
template<typename Point_3>
|
||||
void read_points(std::istream& input,
|
||||
std::vector<Point_3>& points,
|
||||
const int& nb_points,
|
||||
const bool binary)
|
||||
{
|
||||
points.clear();
|
||||
points.reserve(nb_points);
|
||||
|
||||
if (binary)
|
||||
{
|
||||
std::vector<float> data(3 * nb_points);
|
||||
input.read(reinterpret_cast<char*>(&data[0]),
|
||||
3 * nb_points * sizeof(float));
|
||||
for (int i = 0; i < nb_points; ++i)
|
||||
points.push_back(Point_3(data[3 * i], data[3 * i + 1], data[3 * i + 2]));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < nb_points; ++i)
|
||||
{
|
||||
float x, y, z;
|
||||
input >> x >> y >> z;
|
||||
points.push_back(Point_3(x, y, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void read_tetrahedra(std::istream& input,
|
||||
std::vector<std::array<int, 4> >& tetrahedra,
|
||||
const int& nb_tets,
|
||||
const bool binary)
|
||||
{
|
||||
tetrahedra.clear();
|
||||
tetrahedra.reserve(nb_tets);
|
||||
|
||||
if (binary)
|
||||
{
|
||||
std::vector<int> data(4 * nb_tets);
|
||||
input.read(reinterpret_cast<char*>(&data[0]),
|
||||
4 * nb_tets * sizeof(int));
|
||||
for (int i = 0; i < nb_tets; ++i)
|
||||
{
|
||||
tetrahedra.push_back({ data[4 * i] - 1,
|
||||
data[4 * i + 1] - 1,
|
||||
data[4 * i + 2] - 1,
|
||||
data[4 * i + 3] - 1 });
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int n = 0; n < nb_tets; ++n)
|
||||
{
|
||||
int i, j, k, l;
|
||||
input >> i >> j >> k >> l;
|
||||
tetrahedra.push_back({ {i, j, k, l} });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Material_type>
|
||||
void read_materials(std::istream& input,
|
||||
std::vector<Material_type>& materials,
|
||||
const int& nb_tets,
|
||||
const bool binary)
|
||||
{
|
||||
materials.clear();
|
||||
materials.reserve(nb_tets);
|
||||
|
||||
if (binary)
|
||||
{
|
||||
std::vector<Material_type> data(nb_tets);
|
||||
input.read(reinterpret_cast<char*>(&data[0]),
|
||||
nb_tets * sizeof(Material_type));
|
||||
for (int i = 0; i < nb_tets; ++i)
|
||||
materials.push_back(data[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < nb_tets; ++i)
|
||||
{
|
||||
Material_type m;
|
||||
input >> m;
|
||||
materials.push_back(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct Data_def
|
||||
{
|
||||
std::string name;
|
||||
std::string type;
|
||||
std::string description;
|
||||
std::string at_label;
|
||||
};
|
||||
|
||||
void go_to_at_label(std::istream& input,
|
||||
std::string& line,
|
||||
const char* at_label)// "@1"
|
||||
{
|
||||
if (line_starts_with(line, at_label))
|
||||
return;
|
||||
|
||||
while (std::getline(input, line))
|
||||
{
|
||||
if (line_starts_with(line, at_label))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_avizo_tetra_format(std::istream& in, const char* binary_or_ascii)
|
||||
{
|
||||
std::string format(binary_or_ascii);
|
||||
boost::algorithm::to_lower(format);
|
||||
|
||||
std::string line;
|
||||
while (std::getline(in, line))
|
||||
{
|
||||
if (line.find("# AmiraMesh") != std::string::npos
|
||||
|| line.find("# Avizo 3D") != std::string::npos)
|
||||
{
|
||||
std::cout << "Amira format : " << line << std::endl;
|
||||
boost::algorithm::to_lower(line);
|
||||
|
||||
return line.find(format.c_str()) != std::string::npos;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename Tr>
|
||||
bool read_tetra_am(std::istream& input, Tr& tr)
|
||||
{
|
||||
using Material_type = unsigned char;
|
||||
using Point_3 = typename Tr::Geom_traits::Point_3;
|
||||
|
||||
int n_nodes, n_tets, n_edges;
|
||||
std::vector<Data_def> data;
|
||||
std::vector<material> materials; //material = std::pair<int, std::string>
|
||||
|
||||
Material_type material_id = 0;//byte
|
||||
bool materials_done = false;
|
||||
|
||||
std::vector<Point_3> points;
|
||||
std::vector<std::array<int, 4> > tetrahedra;
|
||||
std::vector<Material_type> labels;
|
||||
|
||||
bool binary = true;
|
||||
|
||||
std::string line;
|
||||
while (std::getline(input, line))
|
||||
{
|
||||
if (line.find("# AmiraMesh") != std::string::npos
|
||||
|| line.find("# Avizo 3D") != std::string::npos)
|
||||
{
|
||||
std::cout << "Amira format : " << line << std::endl;
|
||||
boost::algorithm::to_lower(line);
|
||||
if (line.find("ascii") != std::string::npos)
|
||||
binary = false;
|
||||
|
||||
continue;
|
||||
}
|
||||
if (line_starts_with(line, "nNodes"))
|
||||
{
|
||||
std::string nnodes;
|
||||
std::istringstream iss;
|
||||
iss.str(line);
|
||||
iss >> nnodes >> n_nodes;
|
||||
}
|
||||
else if (line_starts_with(line, "nTetrahedra"))
|
||||
{
|
||||
std::string ntetra;
|
||||
std::istringstream iss;
|
||||
iss.str(line);
|
||||
iss >> ntetra >> n_tets;
|
||||
}
|
||||
else if (line_starts_with(line, "nEdges"))
|
||||
{
|
||||
std::string nedges;
|
||||
std::istringstream iss;
|
||||
iss.str(line);
|
||||
iss >> nedges >> n_edges;
|
||||
}
|
||||
else if (!materials_done && line.find("Materials") != std::string::npos)
|
||||
{
|
||||
if (!IO::internal::treat_surf_materials(input, materials, material_id))
|
||||
return false;
|
||||
materials_done = true;
|
||||
}
|
||||
else if (line_starts_with(line, "Nodes"))
|
||||
{
|
||||
//Nodes { float[3] Coordinates } @1
|
||||
Data_def d;
|
||||
d.name = "Nodes";
|
||||
d.type = "float[3]";
|
||||
d.description = "Coordinates";
|
||||
|
||||
std::size_t i = line.find("@");
|
||||
d.at_label = line.substr(i);
|
||||
|
||||
data.push_back(d);
|
||||
}
|
||||
else if (line_starts_with(line, "Tetrahedra"))
|
||||
{
|
||||
//Tetrahedra{ int[4] Nodes } @3
|
||||
Data_def d;
|
||||
d.name = "Tetrahedra";
|
||||
d.type = "int[4]";
|
||||
d.description = "Nodes";
|
||||
|
||||
std::size_t i = line.find("@");
|
||||
d.at_label = line.substr(i);
|
||||
|
||||
data.push_back(d);
|
||||
}
|
||||
else if (line_starts_with(line, "TetrahedronData"))
|
||||
{
|
||||
//TetrahedronData{ byte Materials } @4
|
||||
Data_def d;
|
||||
d.name = "TetrahedronData";
|
||||
d.type = "byte";
|
||||
d.description = "Materials";
|
||||
|
||||
std::size_t i = line.find("@");
|
||||
d.at_label = line.substr(i);
|
||||
|
||||
data.push_back(d);
|
||||
}
|
||||
else if (line.find("Data section follows") != std::string::npos)
|
||||
{
|
||||
std::getline(input, line);
|
||||
for (auto d : data)
|
||||
{
|
||||
go_to_at_label(input, line, d.at_label.c_str());
|
||||
CGAL_assertion(line_starts_with(line, d.at_label.c_str()));
|
||||
|
||||
if (d.name.compare("Nodes") == 0)
|
||||
read_points(input, points, n_nodes, binary);
|
||||
else if (d.name.compare("Tetrahedra") == 0)
|
||||
read_tetrahedra(input, tetrahedra, n_tets, binary);
|
||||
else if (d.name.compare("TetrahedronData") == 0)
|
||||
read_materials(input, labels, n_tets, binary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boost::unordered_map<std::array<int, 3>,
|
||||
typename Tr::Cell::Surface_patch_index> empty_facets_map;
|
||||
|
||||
CGAL::SMDS_3::build_triangulation_with_subdomains_range(tr,
|
||||
points,
|
||||
tetrahedra,
|
||||
labels,
|
||||
empty_facets_map,
|
||||
true,//verbose
|
||||
false,//replace subdomain 0
|
||||
true);//allow non manifold
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}// end namespace internal
|
||||
|
||||
|
||||
template<typename T3>
|
||||
bool read_AVIZO_TETRA(std::istream& in, T3& tr)
|
||||
{
|
||||
if (!in)
|
||||
{
|
||||
std::cerr << "Cannot open file " << std::endl;
|
||||
return false;
|
||||
}
|
||||
return CGAL::IO::internal::read_tetra_am(in, tr);
|
||||
}
|
||||
|
||||
} // end namespace IO
|
||||
|
||||
} // end namespace CGAL
|
||||
|
||||
#endif // CGAL_IO_FILE_AVIZO_H
|
||||
|
|
|
|||
Loading…
Reference in New Issue