Add plugin to read OpenMesh .om files

This commit is contained in:
Andreas Fabri 2024-08-22 11:40:27 +01:00
parent 5d4ba30a10
commit 4832f06ae4
4 changed files with 242 additions and 2 deletions

View File

@ -6,13 +6,12 @@
#include <CGAL/boost/graph/graph_traits_PolyMesh_ArrayKernelT.h>
#include <CGAL/boost/graph/iterator.h>
#include <CGAL/IO/polygon_mesh_io.h>
#include <CXGAL/IO/OM.h>
#include <CGAL/property_map.h>
#include <CGAL/Surface_mesh.h>
#include <iostream>
#include <fstream>
#include "read_OM.h"
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;

View File

@ -43,6 +43,16 @@ target_link_libraries(surf_io_plugin PUBLIC scene_surface_mesh_item)
cgal_lab_plugin(lcc_io_plugin lcc_io_plugin KEYWORDS Viewer)
target_link_libraries(lcc_io_plugin PUBLIC scene_lcc_item)
find_package(OpenMesh)
if(OpenMesh_FOUND)
include(UseOpenMesh)
cgal_lab_plugin(om_plugin OM_io_plugin KEYWORDS Viewer PMP)
target_link_libraries(om_plugin PUBLIC scene_surface_mesh_item scene_polygon_soup_item)
target_link_libraries(om_plugin PRIVATE ${OPENMESH_LIBRARIES})
else()
message(STATUS "NOTICE: the OM IO plugin needs OpenMesh libraries and will not be compiled.")
endif()
find_package(VTK 9.0 QUIET COMPONENTS CommonCore IOCore IOLegacy IOXML FiltersCore FiltersSources)
set_package_properties(
VTK PROPERTIES

View File

@ -0,0 +1,169 @@
#include "SMesh_type.h"
#include "Scene_surface_mesh_item.h"
#include "Scene_polygon_soup_item.h"
#include "Kernel_type.h"
#include "Scene.h"
#include <CGAL/Three/CGAL_Lab_io_plugin_interface.h>
#include <CGAL/Three/Three.h>
#include <CGAL/IO/OM.h>
#include <CGAL/boost/graph/io.h>
#include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h>
#include <QColor>
#include <QString>
#include <QStringList>
#include <QMainWindow>
#include <QInputDialog>
#include <boost/property_map/function_property_map.hpp>
#include <cstdint>
#include <fstream>
#include <iostream>
#include <limits>
#include <vector>
using namespace CGAL::Three;
class CGAL_Lab_om_plugin :
public QObject,
public CGAL_Lab_io_plugin_interface
{
Q_OBJECT
Q_INTERFACES(CGAL::Three::CGAL_Lab_io_plugin_interface)
Q_PLUGIN_METADATA(IID "com.geometryfactory.CGALLab.IOPluginInterface/1.90" FILE "om_io_plugin.json")
public:
QString nameFilters() const;
QString name() const { return "om_plugin"; }
bool canLoad(QFileInfo fileinfo) const;
QList<Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true);
bool canSave(const CGAL::Three::Scene_item*);
bool save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>&);
};
QString CGAL_Lab_om_plugin::nameFilters() const {
return "om files (*.om)";
}
bool CGAL_Lab_om_plugin::canLoad(QFileInfo) const {
return true;
}
QList<Scene_item*>
CGAL_Lab_om_plugin::
load(QFileInfo fileinfo, bool& ok, bool add_to_scene){
// Open file
std::ifstream in(fileinfo.filePath().toUtf8(), std::ios::in | std::ios::binary);
if(!in) {
std::cerr << "Error! Cannot open file " << (const char*)fileinfo.filePath().toUtf8() << std::endl;
ok = false;
return QList<Scene_item*>();
}
in.close();
if(fileinfo.size() == 0)
{
CGAL::Three::Three::warning( tr("The file you are trying to load is empty."));
Scene_surface_mesh_item* item = new Scene_surface_mesh_item();
item->setName(fileinfo.completeBaseName());
ok = true;
if(add_to_scene)
CGAL::Three::Three::scene()->addItem(item);
return QList<Scene_item*>()<<item;
}
try
{
typedef boost::graph_traits<SMesh>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<SMesh>::edge_descriptor edge_descriptor;
std::map<vertex_descriptor,bool> sm_selected_map;
auto sm_selected_pmap = boost::make_assoc_property_map(sm_selected_map);
std::map<edge_descriptor,bool> sm_feature_map;
auto sm_feature_pmap = boost::make_assoc_property_map(sm_feature_map);
// Try building a surface_mesh
SMesh* SM = new SMesh();
if (CGAL::IO::read_OM((const char*)fileinfo.filePath().toUtf8(), *SM, sm_selected_pmap, sm_feature_pmap))
{/*
std::cout << "vertex selection values:\n";
for(auto v : vertices(*SM)){
std::cout << std::boolalpha << get(sm_selected_pmap, v) << std::endl;
}
std::cout << "edge feature values:\n";
for(auto e : edges(*SM)){
std::cout << std::boolalpha << get(sm_feature_pmap, e) << std::endl;
}
*/
}
if(!SM->is_valid() || SM->is_empty()){
std::cerr << "Error: Invalid facegraph" << std::endl;
}
else{
Scene_surface_mesh_item* item = new Scene_surface_mesh_item(SM);
item->setName(fileinfo.completeBaseName());
ok = true;
if(add_to_scene)
CGAL::Three::Three::scene()->addItem(item);
return QList<Scene_item*>()<<item;
}
}
catch(...){}
ok = false;
return QList<Scene_item*>();
}
bool CGAL_Lab_om_plugin::canSave(const CGAL::Three::Scene_item* item)
{
return qobject_cast<const Scene_surface_mesh_item*>(item);
}
bool CGAL_Lab_om_plugin::
save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>& items)
{
#if 0
Scene_item* item = items.front();
const Scene_surface_mesh_item* sm_item =
qobject_cast<const Scene_surface_mesh_item*>(item);
if(!sm_item)
return false;
QStringList list;
list << tr("Binary");
list << tr("Ascii");
bool ok = false;
QString choice
= QInputDialog::getItem(nullptr, tr("Save om file"), tr("Format"), list, 0, false, &ok);
if (!ok)
return false;
std::ofstream out(fileinfo.filePath().toUtf8(), std::ios::out | std::ios::binary);
if ( choice == tr("Binary") )
CGAL::IO::set_mode(out, CGAL::IO::BINARY);
else
{
CGAL::IO::set_mode(out, CGAL::IO::ASCII);
out.precision (std::numeric_limits<double>::digits10 + 2);
}
if (sm_item)
{
CGAL::IO::write_om(out, *sm_item->face_graph());
items.pop_front();
return true;
}
#endif
return false;
}
#include "om_io_plugin.moc"

View File

@ -0,0 +1,62 @@
#pragma once
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
#include <CGAL/boost/graph/graph_traits_PolyMesh_ArrayKernelT.h>
#include <CGAL/boost/graph/iterator.h>
#include <CGAL/property_map.h>
#include <iostream>
#include <fstream>
#include <map>
namespace CGAL {
namespace IO {
template <typename SM, typename VSelectionPM, typename EFeaturePM>
bool read_OM(std::string fname, SM& sm, VSelectionPM vspm, EFeaturePM efpm)
{
typedef OpenMesh::PolyMesh_ArrayKernelT<> OMesh;
typedef boost::graph_traits<OMesh>::vertex_descriptor om_vertex_descriptor;
typedef boost::graph_traits<SM>::vertex_descriptor sm_vertex_descriptor;
typedef boost::graph_traits<OMesh>::halfedge_descriptor om_halfedge_descriptor;
typedef boost::graph_traits<SM>::halfedge_descriptor sm_halfedge_descriptor;
OMesh omesh;
OpenMesh::IO::Options options = OpenMesh::IO::Options::Status;
bool ok = OpenMesh::IO::read_mesh(omesh, fname, options);
if(! ok){
return false;
}
std::map<om_vertex_descriptor,sm_vertex_descriptor> v2v;
auto v2vpmap = boost::make_assoc_property_map(v2v);
std::map<om_halfedge_descriptor,sm_halfedge_descriptor> h2h;
auto h2hpmap = boost::make_assoc_property_map(h2h);
CGAL::copy_face_graph<OMesh,SM>(omesh, sm, CGAL::parameters::vertex_to_vertex_map(v2vpmap).halfedge_to_halfedge_map(h2hpmap));
if(options.vertex_has_status()){
for(auto v : vertices(omesh)){
put(vspm, v2v[v], omesh.status(v).selected());
}
}else{
std::cout << "no vertex status" << std::endl;
}
if(options.edge_has_status()){
for(auto e : edges(omesh)){
auto sme = edge(h2h[halfedge(e,omesh)], sm);
put(efpm, sme , omesh.status(OpenMesh::EdgeHandle(e.idx())).feature());
}
}else{
std::cout << "no edge status" << std::endl;
}
return true;
}
} // namespace IO
} // namespace CGAL