mirror of https://github.com/CGAL/cgal
213 lines
5.0 KiB
C++
213 lines
5.0 KiB
C++
#include "Scene_polyhedron_item.h"
|
|
#include "Scene_polygon_soup_item.h"
|
|
#include "Kernel_type.h"
|
|
#include "Polyhedron_type.h"
|
|
|
|
#include <CGAL/Modifier_base.h>
|
|
#include <CGAL/Polyhedron_incremental_builder_3.h>
|
|
#include "Polyhedron_demo_io_plugin_interface.h"
|
|
#include <fstream>
|
|
|
|
#include <boost/tuple/tuple.hpp>
|
|
|
|
#include <QColor>
|
|
|
|
typedef Kernel::Point_3 Point_3;
|
|
typedef std::vector<Point_3> Points_3;
|
|
typedef boost::tuple<int,int,int> Facet;
|
|
typedef std::vector<Facet> Surface;
|
|
|
|
|
|
|
|
template <class HDS>
|
|
class Build_from_stl : public CGAL::Modifier_base<HDS> {
|
|
std::istream& is;
|
|
int counter;
|
|
Points_3 meshPoints;
|
|
Surface mesh;
|
|
|
|
public:
|
|
|
|
std::string name, color;
|
|
|
|
|
|
Build_from_stl(std::istream& is_)
|
|
: is(is_), counter(0)
|
|
{}
|
|
|
|
void operator()( HDS& hds) {
|
|
if(!read(is, meshPoints, mesh)) return;
|
|
|
|
CGAL::Polyhedron_incremental_builder_3<Polyhedron::HalfedgeDS> B(hds);
|
|
B.begin_surface( meshPoints.size(), mesh.size());
|
|
typedef typename Points_3::size_type size_type;
|
|
|
|
for(size_type i=0; i < meshPoints.size(); i++){
|
|
B.add_vertex( meshPoints[i]);
|
|
}
|
|
for(size_type i=0; i < mesh.size(); i++){
|
|
B.begin_facet();
|
|
B.add_vertex_to_facet( mesh[i].get<0>());
|
|
B.add_vertex_to_facet( mesh[i].get<1>());
|
|
B.add_vertex_to_facet( mesh[i].get<2>());
|
|
B.end_facet();
|
|
}
|
|
if(B.error())
|
|
{
|
|
std::cerr << "An error occured while creating a Polyhedron" << std::endl;
|
|
B.rollback();
|
|
}
|
|
|
|
B.end_surface();
|
|
}
|
|
|
|
bool
|
|
read(std::istream& input, Points_3& points, Surface& surface, int /*offset*/ = 0)
|
|
{
|
|
std::string s, solid("solid"), facet("facet"), outer("outer"), loop("loop"), vertex("vertex"), endloop("endloop"), endsolid("endsolid");
|
|
|
|
std::map<Point_3, int> vertex_index;
|
|
int index = 0;
|
|
int ijk[3];
|
|
Point_3 p;
|
|
|
|
input >> s;
|
|
if(s == solid){
|
|
std::getline(input, s);
|
|
} else {
|
|
std::cerr << "We expect keyword 'solid'" << std::endl;
|
|
return false;
|
|
}
|
|
|
|
while(input >> s){
|
|
if(s == endsolid){
|
|
//std::cerr << "found endsolid" << std::endl;
|
|
} else if(s == facet){
|
|
//std::cerr << "found facet" << std::endl;
|
|
std::getline(input, s); // ignore the normal
|
|
input >> s;
|
|
if(s != outer){
|
|
std::cerr << "Expect 'outer' and got " << s << std::endl;
|
|
return false;
|
|
}
|
|
input >> s;
|
|
if(s != loop){
|
|
std::cerr << "Expect 'loop' and got " << s << std::endl;
|
|
return false;
|
|
}
|
|
int count = 0;
|
|
do {
|
|
input >> s;
|
|
if(s == vertex){
|
|
// std::cerr << "found vertex" << std::endl;
|
|
if(count < 3){
|
|
input >> p;
|
|
if(vertex_index.find(p) == vertex_index.end()){
|
|
ijk[count] = index;
|
|
vertex_index[p] = index++;
|
|
points.push_back(p);
|
|
} else {
|
|
ijk[count] = vertex_index[p];
|
|
}
|
|
++count;
|
|
} else {
|
|
std::cerr << "We can only read triangulated surfaces" << std::endl;
|
|
return false;
|
|
}
|
|
}
|
|
}while(s != endloop);
|
|
|
|
surface.push_back(boost::make_tuple(ijk[0], ijk[1], ijk[2]));
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
};
|
|
|
|
class Polyhedron_demo_stl_plugin :
|
|
public QObject,
|
|
public Polyhedron_demo_io_plugin_interface
|
|
{
|
|
Q_OBJECT
|
|
Q_INTERFACES(Polyhedron_demo_io_plugin_interface)
|
|
|
|
public:
|
|
QString nameFilters() const;
|
|
QString name() const { return "stl_plugin"; }
|
|
bool canLoad() const;
|
|
Scene_item* load(QFileInfo fileinfo);
|
|
|
|
bool canSave(const Scene_item*);
|
|
bool save(const Scene_item*, QFileInfo fileinfo);
|
|
};
|
|
|
|
QString Polyhedron_demo_stl_plugin::nameFilters() const {
|
|
return "STL files (*.stl)";
|
|
};
|
|
|
|
bool Polyhedron_demo_stl_plugin::canLoad() const {
|
|
return true;
|
|
}
|
|
|
|
|
|
Scene_item*
|
|
Polyhedron_demo_stl_plugin::load(QFileInfo fileinfo) {
|
|
|
|
// Open file
|
|
std::ifstream in(fileinfo.filePath().toUtf8());
|
|
if(!in) {
|
|
std::cerr << "Error! Cannot open file " << (const char*)fileinfo.filePath().toUtf8() << std::endl;
|
|
return NULL;
|
|
}
|
|
|
|
// Try to read STL file in a polyhedron
|
|
Polyhedron P;
|
|
//Scene_polyhedron_item* item = new Scene_polyhedron_item(P);
|
|
//item->setName(fileinfo.baseName());
|
|
|
|
Build_from_stl<Polyhedron::HalfedgeDS> builder(in);
|
|
// item->polyhedron()->
|
|
|
|
P.delegate(builder);
|
|
|
|
if(! P.is_valid()){
|
|
std::cerr << "Error: Invalid polyhedron" << std::endl;
|
|
return 0;
|
|
}
|
|
|
|
if(P.empty()){
|
|
return 0;
|
|
}
|
|
|
|
Scene_polyhedron_item* item = new Scene_polyhedron_item(P);
|
|
if(builder.name.size() == 0){
|
|
item->setName(fileinfo.baseName());
|
|
} else {
|
|
item->setName(builder.name.c_str());
|
|
}
|
|
QColor color(builder.color.c_str());
|
|
if(color.isValid())
|
|
{
|
|
item->setColor(color);
|
|
item->changed();
|
|
}
|
|
|
|
|
|
return item;
|
|
}
|
|
|
|
bool Polyhedron_demo_stl_plugin::canSave(const Scene_item*)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool Polyhedron_demo_stl_plugin::save(const Scene_item*, QFileInfo)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
#include <QtPlugin>
|
|
Q_EXPORT_PLUGIN2(Polyhedron_demo_stl_plugin, Polyhedron_demo_stl_plugin)
|
|
#include "Polyhedron_demo_stl_plugin.moc"
|