mirror of https://github.com/CGAL/cgal
Add CGAL::IO::read_OM() (#8427)
## Summary of Changes Add a function to read an OpenMesh file ( `*.om` ) in CGALlab. This file format stores also edges and vertices marked as features. For the moment the function itself is not documented. ## Release Management * License and copyright ownership: GeometryFactory
This commit is contained in:
commit
74ea8b1f6c
|
|
@ -482,6 +482,10 @@ the requirement for traversal of all faces in a graph.
|
|||
/// I/O Functions for the \ref IOStreamOBJ
|
||||
/// \ingroup PkgBGLIOFct
|
||||
|
||||
/// \defgroup PkgBGLIoFuncsOM OM I/O Functions
|
||||
/// I/O Functions for the \ref IOStreamOM
|
||||
/// \ingroup PkgBGLIOFct
|
||||
|
||||
/// \defgroup PkgBGLIoFuncsOFF OFF I/O Functions
|
||||
/// I/O Functions for the \ref IOStreamOFF
|
||||
/// \ingroup PkgBGLIOFct
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@ if(OpenMesh_FOUND)
|
|||
include(CGAL_OpenMesh_support)
|
||||
create_single_source_cgal_program("TriMesh.cpp")
|
||||
target_link_libraries(TriMesh PRIVATE CGAL::OpenMesh_support)
|
||||
create_single_source_cgal_program("PolyMesh.cpp")
|
||||
target_link_libraries(PolyMesh PRIVATE CGAL::OpenMesh_support)
|
||||
|
||||
else()
|
||||
message("NOTICE: This project requires OpenMesh and will not be compiled.")
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,85 @@
|
|||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>
|
||||
|
||||
#include <CGAL/boost/graph/graph_traits_PolyMesh_ArrayKernelT.h>
|
||||
#include <CGAL/boost/graph/iterator.h>
|
||||
#include <CGAL/IO/polygon_mesh_io.h>
|
||||
#include <CGAL/property_map.h>
|
||||
#include <CGAL/Surface_mesh.h>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
||||
|
||||
typedef OpenMesh::PolyMesh_ArrayKernelT</* MyTraits*/> OMesh;
|
||||
typedef CGAL::Surface_mesh<Kernel::Point_3> SM;
|
||||
typedef boost::graph_traits<OMesh>::vertex_descriptor vertex_descriptor;
|
||||
typedef boost::graph_traits<OMesh>::halfedge_descriptor halfedge_descriptor;
|
||||
|
||||
typedef boost::graph_traits<SM>::vertex_descriptor sm_vertex_descriptor;
|
||||
typedef boost::graph_traits<SM>::edge_descriptor sm_edge_descriptor;
|
||||
|
||||
int main(int argc, char** argv )
|
||||
{
|
||||
OMesh omesh;
|
||||
|
||||
const std::string filename = (argc>1)?argv[1]:CGAL::data_file_path("meshes/cube-meshed.off");
|
||||
|
||||
if (!CGAL::IO::read_polygon_mesh(filename, omesh))
|
||||
{
|
||||
std::cerr << "Cannot read " << filename << "\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
omesh.request_vertex_status();
|
||||
omesh.request_edge_status();
|
||||
|
||||
int i = 0;
|
||||
for(auto v : vertices(omesh))
|
||||
{
|
||||
omesh.status(v).set_feature((i%2) == 0);
|
||||
++i;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
for(auto eit = omesh.edges_begin(); eit != omesh.edges_end(); ++eit)
|
||||
{
|
||||
omesh.status(*eit).set_feature((i%2) == 0);
|
||||
++i;
|
||||
}
|
||||
|
||||
const char* outname= (argc>2)?argv[2]:"out.om";
|
||||
OpenMesh::IO::write_mesh(omesh, outname, OpenMesh::IO::Options::Status);
|
||||
|
||||
SM sm;
|
||||
|
||||
std::map<sm_vertex_descriptor,bool> sm_selected_map;
|
||||
auto sm_selected_pmap = boost::make_assoc_property_map(sm_selected_map);
|
||||
|
||||
std::map<sm_edge_descriptor,bool> sm_feature_map;
|
||||
auto sm_feature_pmap = boost::make_assoc_property_map(sm_feature_map);
|
||||
|
||||
CGAL::IO::read_OM(outname, sm, CGAL::parameters::vertex_is_constrained_map(sm_selected_pmap)
|
||||
.edge_is_constrained_map(sm_feature_pmap));
|
||||
|
||||
|
||||
int nbv=0, nbfv=0;
|
||||
for(auto v : vertices(sm)){
|
||||
++nbv;
|
||||
if (get(sm_selected_pmap, v)) ++nbfv;
|
||||
}
|
||||
std::cout << nbfv << " feature vertices out of " << nbv << "\n";
|
||||
|
||||
int nbe=0, nbfe=0;
|
||||
for(auto e : edges(sm)){
|
||||
++nbe;
|
||||
if (get(sm_feature_pmap, e)) ++nbfe;
|
||||
}
|
||||
std::cout << nbfe << " feature edges out of " << nbe << "\n";
|
||||
|
||||
assert(nbv>1 || nbfv!=0);
|
||||
assert(nbe>1 || nbfe!=0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,17 +1,18 @@
|
|||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <OpenMesh/Core/IO/MeshIO.hh>
|
||||
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
|
||||
|
||||
#include <CGAL/boost/graph/graph_traits_TriMesh_ArrayKernelT.h>
|
||||
#include <CGAL/boost/graph/properties_TriMesh_ArrayKernelT.h>
|
||||
|
||||
#include <CGAL/boost/graph/iterator.h>
|
||||
#include <CGAL/boost/graph/Euler_operations.h>
|
||||
#include <CGAL/IO/polygon_mesh_io.h>
|
||||
|
||||
#include <CGAL/boost/graph/Euler_operations.h>
|
||||
#include <CGAL/mesh_segmentation.h>
|
||||
#include <CGAL/property_map.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include <CGAL/boost/graph/IO/INP.h>
|
||||
#include <CGAL/boost/graph/IO/OBJ.h>
|
||||
#include <CGAL/boost/graph/IO/OFF.h>
|
||||
#include <CGAL/boost/graph/IO/OM.h>
|
||||
#include <CGAL/boost/graph/IO/PLY.h>
|
||||
#include <CGAL/boost/graph/IO/STL.h>
|
||||
#include <CGAL/boost/graph/IO/VTK.h>
|
||||
|
|
@ -80,6 +81,7 @@ bool read_polygon_mesh(std::istream& is,
|
|||
* Supported file formats are the following:
|
||||
* - \ref IOStreamOFF (`.off`)
|
||||
* - \ref IOStreamOBJ (`.obj`)
|
||||
* - \ref IOStreamOM (`.om`)
|
||||
* - \ref IOStreamSTL (`.stl`)
|
||||
* - \ref IOStreamPLY (`.ply`)
|
||||
* - \ref IOStreamGocad (`.ts`)
|
||||
|
|
@ -138,6 +140,10 @@ bool read_polygon_mesh(const std::string& fname,
|
|||
return read_OBJ(fname, g, np);
|
||||
else if(ext == "off")
|
||||
return read_OFF(fname, g, np);
|
||||
#ifdef CGAL_USE_OPENMESH
|
||||
else if(ext == "om")
|
||||
return read_OM(fname, g, np);
|
||||
#endif
|
||||
else if(ext == "ply")
|
||||
return read_PLY(fname, g, np);
|
||||
else if(ext == "stl")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,239 @@
|
|||
// Copyright (c) 2024 GeometryFactory
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org);
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
// Author(s) : Andreas Fabri
|
||||
|
||||
#ifndef CGAL_BGL_IO_OM_H
|
||||
#define CGAL_BGL_IO_OM_H
|
||||
|
||||
#if defined(CGAL_USE_OPENMESH) || defined(DOXYGEN_RUNNING)
|
||||
|
||||
#include <OpenMesh/Core/IO/MeshIO.hh>
|
||||
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
|
||||
|
||||
#include <CGAL/boost/graph/copy_face_graph.h>
|
||||
#include <CGAL/boost/graph/graph_traits_PolyMesh_ArrayKernelT.h>
|
||||
#include <CGAL/boost/graph/iterator.h>
|
||||
#include <CGAL/property_map.h>
|
||||
#include <CGAL/Named_function_parameters.h>
|
||||
#include <CGAL/boost/graph/named_params_helper.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
|
||||
namespace CGAL {
|
||||
namespace IO {
|
||||
|
||||
namespace internal {
|
||||
template <typename Graph, typename VPM, typename VFeaturePM, typename EFeaturePM>
|
||||
bool read_OM(const std::string& fname, Graph& g, VPM vpm, VFeaturePM vfpm, EFeaturePM efpm)
|
||||
{
|
||||
typedef OpenMesh::PolyMesh_ArrayKernelT<> OMesh;
|
||||
typedef typename boost::graph_traits<OMesh>::vertex_descriptor om_vertex_descriptor;
|
||||
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<OMesh>::halfedge_descriptor om_halfedge_descriptor;
|
||||
typedef typename boost::graph_traits<Graph>::halfedge_descriptor 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, vertex_descriptor> v2v;
|
||||
auto v2vpmap = boost::make_assoc_property_map(v2v);
|
||||
|
||||
std::map<om_halfedge_descriptor, halfedge_descriptor> h2h;
|
||||
auto h2hpmap = boost::make_assoc_property_map(h2h);
|
||||
|
||||
CGAL::copy_face_graph<OMesh,Graph>(omesh, g,
|
||||
CGAL::parameters::vertex_to_vertex_map(v2vpmap)
|
||||
.halfedge_to_halfedge_map(h2hpmap),
|
||||
CGAL::parameters::vertex_point_map(vpm));
|
||||
if(options.vertex_has_status()){
|
||||
for(auto v : vertices(omesh)){
|
||||
put(vfpm, v2v[v], omesh.status(v).feature());
|
||||
}
|
||||
}
|
||||
|
||||
if(options.edge_has_status()){
|
||||
for(auto e : edges(omesh)){
|
||||
auto sme = edge(h2h[halfedge(e,omesh)], g);
|
||||
put(efpm, sme , omesh.status(OpenMesh::EdgeHandle(e.idx())).feature());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Graph, typename VPM, typename VFeaturePM, typename EFeaturePM>
|
||||
bool write_OM(std::string fname, const Graph& g, VPM vpm, VFeaturePM vfpm, EFeaturePM efpm)
|
||||
{
|
||||
typedef OpenMesh::PolyMesh_ArrayKernelT<> OMesh;
|
||||
typedef typename boost::graph_traits<OMesh>::vertex_descriptor om_vertex_descriptor;
|
||||
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<OMesh>::halfedge_descriptor om_halfedge_descriptor;
|
||||
typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor;
|
||||
|
||||
std::map<vertex_descriptor, om_vertex_descriptor> v2v;
|
||||
auto v2vpmap = boost::make_assoc_property_map(v2v);
|
||||
|
||||
std::map<halfedge_descriptor, om_halfedge_descriptor> h2h;
|
||||
auto h2hpmap = boost::make_assoc_property_map(h2h);
|
||||
|
||||
OMesh omesh;
|
||||
CGAL::copy_face_graph<Graph, OMesh>(g, omesh,
|
||||
CGAL::parameters::vertex_point_map(vpm)
|
||||
.vertex_to_vertex_map(v2vpmap)
|
||||
.halfedge_to_halfedge_map(h2hpmap));
|
||||
omesh.request_edge_status();
|
||||
omesh.request_vertex_status();
|
||||
|
||||
for (auto h : halfedges(g))
|
||||
{
|
||||
om_halfedge_descriptor omh = h2h.at(h);
|
||||
const bool isfeature = get(efpm, edge(h, g));
|
||||
omesh.status(omesh.edge_handle(omh)).set_feature(isfeature);
|
||||
}
|
||||
for (auto v : vertices(g))
|
||||
{
|
||||
auto omv = v2v.at(v);
|
||||
const bool isfeature = get(vfpm, v);
|
||||
omesh.status(omv).set_feature(isfeature);
|
||||
}
|
||||
|
||||
return OpenMesh::IO::write_mesh(omesh, fname, OpenMesh::IO::Options::Status);
|
||||
}
|
||||
} // end of internal namespace
|
||||
|
||||
/*!
|
||||
\ingroup PkgBGLIoFuncsOM
|
||||
|
||||
\brief reads the graph `g` from the file `fname`, using the \ref IOStreamOM.
|
||||
|
||||
The data is expected to represent a 2-manifold (possibly with borders).
|
||||
|
||||
\attention The graph `g` is not cleared, and the data from the file are appended.
|
||||
|
||||
\note This function is only available if OpenMesh is available (`CGAL_USE_OPENMESH` is defined or CMake target is linked with `CGAL::OpenMesh_support`).
|
||||
|
||||
\tparam Graph a model of `MutableFaceGraph`
|
||||
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||
|
||||
\param fname the name of the input file
|
||||
\param g the graph to be built from the input data
|
||||
\param np optional \ref bgl_namedparameters "Named Parameters" described below
|
||||
|
||||
\cgalNamedParamsBegin
|
||||
\cgalParamNBegin{vertex_point_map}
|
||||
\cgalParamDescription{a property map associating points to the vertices of `g`}
|
||||
\cgalParamType{a class model of `WritablePropertyMap` with `boost::graph_traits<Graph>::%vertex_descriptor`
|
||||
as key type and `%Point_3` as value type}
|
||||
\cgalParamDefault{`boost::get(CGAL::vertex_point, g)`}
|
||||
\cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t`
|
||||
must be available in `Graph`.}
|
||||
\cgalParamNEnd
|
||||
\cgalParamNBegin{edge_is_constrained_map}
|
||||
\cgalParamDescription{a property map containing the feature-or-not status of each edge of `g` to be filled by the reader}
|
||||
\cgalParamType{a class model of `WritablePropertyMap` with `boost::graph_traits<Graph>::%edge_descriptor`
|
||||
as key type and `bool` as value type.}
|
||||
\cgalParamDefault{a default property map where no edge is marked as feature}
|
||||
\cgalParamNEnd
|
||||
\cgalParamNBegin{vertex_is_constrained_map}
|
||||
\cgalParamDescription{a property map containing the feature-or-not status of each vertex of `g` to be filled by the reader}
|
||||
\cgalParamType{a class model of `WritablePropertyMap` with `boost::graph_traits<Graph>::%vertex_descriptor`
|
||||
as key type and `bool` as value type.}
|
||||
\cgalParamDefault{a default property map where no vertex is marked as feature}
|
||||
\cgalParamNEnd
|
||||
\cgalNamedParamsEnd
|
||||
|
||||
\returns `true` if reading was successful and the resulting mesh is valid, `false` otherwise.
|
||||
*/
|
||||
template <typename Graph, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||
bool read_OM(const std::string& fname,
|
||||
Graph& g,
|
||||
const CGAL_NP_CLASS& np = parameters::default_values())
|
||||
{
|
||||
using vertex_descriptor = typename boost::graph_traits<Graph>::vertex_descriptor;
|
||||
using edge_descriptor = typename boost::graph_traits<Graph>::edge_descriptor;
|
||||
|
||||
using CGAL::parameters::get_parameter;
|
||||
using CGAL::parameters::choose_parameter;
|
||||
using Default_vfmap = Static_boolean_property_map<vertex_descriptor, false>;
|
||||
using Default_efmap = Static_boolean_property_map<edge_descriptor, false>;
|
||||
auto vfpm = choose_parameter<Default_vfmap>(get_parameter(np, internal_np::vertex_is_constrained));
|
||||
auto efpm = choose_parameter<Default_efmap>(get_parameter(np, internal_np::edge_is_constrained));
|
||||
auto vpm = choose_parameter(get_parameter(np, internal_np::vertex_point),
|
||||
get_property_map(vertex_point, g));
|
||||
return internal::read_OM(fname, g, vpm, vfpm, efpm);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\ingroup PkgBGLIoFuncsOM
|
||||
|
||||
\brief writes the graph `g` into a file named `fname`, using the \ref IOStreamOM.
|
||||
|
||||
\note This function is only available if OpenMesh is available (`CGAL_USE_OPENMESH` is defined or CMake target is linked with `CGAL::OpenMesh_support`).
|
||||
|
||||
\tparam Graph a model of `FaceListGraph` and `HalfedgeListGraph`
|
||||
\tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||
|
||||
\param fname the output file
|
||||
\param g the graph to be written
|
||||
\param np optional \ref bgl_namedparameters "Named Parameters" described below
|
||||
|
||||
\cgalNamedParamsBegin
|
||||
\cgalParamNBegin{vertex_point_map}
|
||||
\cgalParamDescription{a property map associating points to the vertices of `g`}
|
||||
\cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits<Graph>::%vertex_descriptor`
|
||||
as key type and `%Point_3` as value type}
|
||||
\cgalParamDefault{`boost::get(CGAL::vertex_point, g)`}
|
||||
\cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t`
|
||||
must be available in `Graph`.}
|
||||
\cgalParamNEnd
|
||||
\cgalParamNBegin{edge_is_constrained_map}
|
||||
\cgalParamDescription{a property map containing the feature-or-not status of each edge of `g`}
|
||||
\cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits<Graph>::%edge_descriptor`
|
||||
as key type and `bool` as value type.}
|
||||
\cgalParamNEnd
|
||||
\cgalParamNBegin{vertex_is_constrained_map}
|
||||
\cgalParamDescription{a property map containing the feature-or-not status of each vertex of `g`}
|
||||
\cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits<Graph>::%vertex_descriptor`
|
||||
as key type and `bool` as value type.}
|
||||
\cgalParamNEnd
|
||||
\cgalNamedParamsEnd
|
||||
|
||||
\returns `true` if writing was successful, `false` otherwise.
|
||||
*/
|
||||
template <typename Graph, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||
bool write_OM(const std::string& fname,
|
||||
const Graph& g,
|
||||
const CGAL_NP_CLASS& np = parameters::default_values())
|
||||
{
|
||||
using vertex_descriptor = typename boost::graph_traits<Graph>::vertex_descriptor;
|
||||
using edge_descriptor = typename boost::graph_traits<Graph>::edge_descriptor;
|
||||
|
||||
using CGAL::parameters::get_parameter;
|
||||
using CGAL::parameters::choose_parameter;
|
||||
auto vfpm = choose_parameter(get_parameter(np, internal_np::vertex_is_constrained),
|
||||
CGAL::Constant_property_map<vertex_descriptor, bool>(false));
|
||||
auto efpm = choose_parameter(get_parameter(np, internal_np::edge_is_constrained),
|
||||
CGAL::Constant_property_map<edge_descriptor, bool>(false));
|
||||
auto vpm = choose_parameter(get_parameter(np, internal_np::vertex_point),
|
||||
get_const_property_map(vertex_point, g));
|
||||
return internal::write_OM(fname, g, vpm, vfpm, efpm);
|
||||
}
|
||||
|
||||
|
||||
} // namespace IO
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_USE_OPENMESH || DOXYGEN_RUNNING
|
||||
#endif // CGAL_IO_OM
|
||||
|
|
@ -9,7 +9,6 @@
|
|||
//
|
||||
// Author(s) : Andreas Fabri, Philipp Moeller
|
||||
|
||||
// include this to avoid a VC15 warning
|
||||
#include <CGAL/Named_function_parameters.h>
|
||||
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
|
|
@ -21,7 +20,6 @@
|
|||
#include <CGAL/boost/graph/iterator.h>
|
||||
#include <CGAL/Iterator_range.h>
|
||||
#include <CGAL/boost/graph/helpers.h>
|
||||
#include <CGAL/boost/graph/io.h>
|
||||
#include <CGAL/assertions.h>
|
||||
#include <CGAL/hash_openmesh.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -11,11 +11,16 @@
|
|||
#ifndef CGAL_BOOST_GRAPH_GRAPH_TRAITS_POLYMESH_ARRAYKERNELT_H
|
||||
#define CGAL_BOOST_GRAPH_GRAPH_TRAITS_POLYMESH_ARRAYKERNELT_H
|
||||
|
||||
#ifdef OPEN_MESH_CLASS
|
||||
#error OPEN_MESH_CLASS is already defined
|
||||
#endif
|
||||
|
||||
// https://www.graphics.rwth-aachen.de/media/openmesh_static/Documentations/OpenMesh-Doc-Latest/a02182.html
|
||||
#include <OpenMesh/Core/IO/MeshIO.hh>
|
||||
#include <CGAL/boost/graph/properties_PolyMesh_ArrayKernelT.h>
|
||||
#include <OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>
|
||||
|
||||
|
||||
#define OPEN_MESH_CLASS OpenMesh::PolyMesh_ArrayKernelT<K>
|
||||
#include <CGAL/boost/graph/graph_traits_OpenMesh.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include <CGAL/boost/graph/IO/INP.h>
|
||||
#include <CGAL/boost/graph/IO/OBJ.h>
|
||||
#include <CGAL/boost/graph/IO/OFF.h>
|
||||
#include <CGAL/boost/graph/IO/OM.h>
|
||||
#include <CGAL/boost/graph/IO/PLY.h>
|
||||
#include <CGAL/boost/graph/IO/STL.h>
|
||||
#include <CGAL/boost/graph/IO/VTK.h>
|
||||
|
|
|
|||
|
|
@ -47,6 +47,16 @@ target_link_libraries(surf_io_plugin PRIVATE scene_surface_mesh_item)
|
|||
cgal_lab_plugin(lcc_io_plugin lcc_io_plugin KEYWORDS Viewer)
|
||||
target_link_libraries(lcc_io_plugin PRIVATE scene_lcc_item)
|
||||
|
||||
find_package(OpenMesh QUIET)
|
||||
if(OpenMesh_FOUND)
|
||||
include(CGAL_OpenMesh_support)
|
||||
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 scene_selection_item)
|
||||
target_link_libraries(om_plugin PRIVATE CGAL::OpenMesh_support)
|
||||
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
|
||||
|
|
|
|||
|
|
@ -0,0 +1,200 @@
|
|||
#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 "Scene_polyhedron_selection_item.h"
|
||||
|
||||
#include <CGAL/boost/graph/IO/OM.h>
|
||||
#include <CGAL/boost/graph/io.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_vfeature_map;
|
||||
auto sm_vfeature_pmap = boost::make_assoc_property_map(sm_vfeature_map);
|
||||
|
||||
std::map<edge_descriptor,bool> sm_efeature_map;
|
||||
auto sm_efeature_pmap = boost::make_assoc_property_map(sm_efeature_map);
|
||||
|
||||
// Try building a surface_mesh
|
||||
SMesh* sm = new SMesh();
|
||||
ok = CGAL::IO::read_OM((const char*)fileinfo.filePath().toUtf8(),
|
||||
*sm,
|
||||
CGAL::parameters::vertex_is_constrained_map(sm_vfeature_pmap)
|
||||
.edge_is_constrained_map(sm_efeature_pmap));
|
||||
|
||||
if(!ok || !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);
|
||||
|
||||
Scene_polyhedron_selection_item* selection_item = new Scene_polyhedron_selection_item(item, CGAL::Three::Three::mainWindow());
|
||||
for(auto v : vertices(*sm)){
|
||||
if(get(sm_vfeature_pmap, v)){
|
||||
selection_item->selected_vertices.insert(v);
|
||||
}
|
||||
}
|
||||
for(auto e : edges(*sm)){
|
||||
if(get(sm_efeature_pmap, e)){
|
||||
selection_item->selected_edges.insert(e);
|
||||
}
|
||||
}
|
||||
item->setName(fileinfo.completeBaseName());
|
||||
ok = true;
|
||||
if(add_to_scene)
|
||||
{
|
||||
CGAL::Three::Three::scene()->addItem(item);
|
||||
if(!selection_item->isEmpty())
|
||||
CGAL::Three::Three::scene()->addItem(selection_item);
|
||||
}
|
||||
|
||||
QList<Scene_item*> res;
|
||||
res << item;
|
||||
if(!selection_item->isEmpty())
|
||||
res << selection_item;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
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)
|
||||
|| qobject_cast<const Scene_polyhedron_selection_item*>(item);
|
||||
}
|
||||
|
||||
bool CGAL_Lab_om_plugin::
|
||||
save(QFileInfo fileinfo, QList<CGAL::Three::Scene_item*>& items)
|
||||
{
|
||||
Scene_surface_mesh_item* sm_item = nullptr;
|
||||
Scene_polyhedron_selection_item* selection_item = nullptr;
|
||||
|
||||
for (Scene_item* item : items)
|
||||
{
|
||||
if (sm_item == nullptr)
|
||||
{
|
||||
sm_item = qobject_cast<Scene_surface_mesh_item*>(item);
|
||||
if (sm_item != nullptr) //surface_mesh_item found
|
||||
continue;
|
||||
}
|
||||
if (selection_item == nullptr)
|
||||
{
|
||||
selection_item = qobject_cast<Scene_polyhedron_selection_item*>(item);
|
||||
}
|
||||
}
|
||||
|
||||
if (sm_item == nullptr && selection_item == nullptr)
|
||||
return false;
|
||||
|
||||
if (selection_item != nullptr)
|
||||
{
|
||||
if (sm_item == nullptr)
|
||||
sm_item = selection_item->polyhedron_item();
|
||||
|
||||
if (sm_item != selection_item->polyhedron_item())
|
||||
{
|
||||
std::cerr << "Warning! Selection is not associated to the surface_mesh. Ignoring selection." << std::endl;
|
||||
selection_item = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool res = false;
|
||||
if (selection_item != nullptr)
|
||||
{
|
||||
res = CGAL::IO::write_OM((const char*)fileinfo.filePath().toUtf8()
|
||||
, *sm_item->face_graph()
|
||||
, CGAL::parameters::vertex_is_constrained_map(selection_item->constrained_vertices_pmap())
|
||||
.edge_is_constrained_map(selection_item->constrained_edges_pmap()));
|
||||
}
|
||||
else
|
||||
{
|
||||
res = CGAL::IO::write_OM((const char*)fileinfo.filePath().toUtf8()
|
||||
, *sm_item->face_graph());
|
||||
}
|
||||
|
||||
if (res)
|
||||
{
|
||||
items.removeAll(sm_item);
|
||||
if (selection_item != nullptr)
|
||||
items.removeAll(selection_item);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#include "OM_io_plugin.moc"
|
||||
|
|
@ -9,6 +9,7 @@ each specific format.
|
|||
|
||||
- \ref IOStreamOFF
|
||||
- \ref IOStreamOBJ
|
||||
- \ref IOStreamOM
|
||||
- \ref IOStreamSTL
|
||||
- \ref IOStreamPLY
|
||||
- \ref IOStreamXYZ
|
||||
|
|
@ -141,6 +142,29 @@ If the data of a polygon mesh cannot be read in a `FaceGraph` due to bad orienta
|
|||
manifoldness issues, consider using \link PMP_IO_grp `CGAL::Polygon_mesh_processing::IO::read_polygon_mesh()` \endlink,
|
||||
which offers combinatorial repairing while reading bad inputs.
|
||||
|
||||
\section IOStreamOM OpenMesh (OM) File format
|
||||
The OpenMesh proprietary format, using the file extension `.om`, can be used to represent collections of planar polygons with possibly shared vertices.
|
||||
Additionally, it allows to store and restore custom properties along with the standard properties.
|
||||
|
||||
More information are provided <a href="https://www.graphics.rwth-aachen.de/media/openmesh_static/Documentations/OpenMesh-Doc-Latest/a06338.html">here</a>.
|
||||
|
||||
<table class="iotable">
|
||||
<tr>
|
||||
<th colspan="4">OpenMesh Format (OM)</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="75">Input</td>
|
||||
<td width="175">Polygon Mesh</td>
|
||||
<td width="250">Any model of `MutableFaceGraph`</td>
|
||||
<td width="500">\link PkgBGLIoFuncsOM CGAL::IO::read_OM(const std::string&, Graph&)\endlink</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Output</td>
|
||||
<td>Polygon Mesh</td>
|
||||
<td>Any model of `FaceGraph`</td>
|
||||
<td>\link PkgBGLIoFuncsOM CGAL::IO::write_OM(const std::string&, const Graph&)\endlink</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
\section IOStreamSTL STereoLithography (STL) File Format
|
||||
|
||||
|
|
|
|||
|
|
@ -421,6 +421,7 @@ The table above only lists the functions that work with any polygon mesh.
|
|||
<th colspan="1">\ref IOStreamOBJ "OBJ"</th>
|
||||
<th colspan="1">\ref IOStreamGocad "GOCAD"</th>
|
||||
<th colspan="1">\ref IOStreamWRL "WRL"</th>
|
||||
<th colspan="1">\ref IOStreamOM "OpenMesh (OM)"</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Input</td>
|
||||
|
|
@ -430,6 +431,7 @@ The table above only lists the functions that work with any polygon mesh.
|
|||
<td>`CGAL::IO::read_VTP()`</td>
|
||||
<td>`CGAL::IO::read_OBJ()`</td>
|
||||
<td>`CGAL::IO::read_GOCAD()`</td>
|
||||
<td>`CGAL::IO::read_OM()`</td>
|
||||
<td><center> - </center></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -441,6 +443,7 @@ The table above only lists the functions that work with any polygon mesh.
|
|||
<td>`CGAL::IO::write_OBJ()`</td>
|
||||
<td>`CGAL::IO::write_GOCAD()`</td>
|
||||
<td>`CGAL::IO::write_WRL()`</td>
|
||||
<td>`CGAL::IO::write_OM()`</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue