Merge pull request #2723 from MaelRL/PMP-Graph_partition-GF

BGL Small feature: Graph partitioning
This commit is contained in:
Laurent Rineau 2018-01-31 18:29:59 +01:00
commit 67f4ab82af
20 changed files with 8060 additions and 84 deletions

View File

@ -30,8 +30,8 @@ the ideas of \sc{Bgl} in a nutshell. Section \ref BGLHeader explains
where to find header files and the chosen naming conventions, as we blend two
different libraries. The four following sections give examples for
how the surface mesh, the polyhedron, the arrangement, and the 2D triangulation classes
are adapted to \sc{Bgl}. Finally, Section \ref BGLExtensions introduces
the `HalfedgeGraph` which is an extension to the graph concepts of the \sc{Bgl}.
are adapted to \sc{Bgl}. Starting with Section \ref BGLExtensions, we introduce
new concepts, classes, and functions that extend the functionalities of the \sc{Bgl}.
\section BGLA A Short Introduction to the Boost Graph Library
@ -379,24 +379,28 @@ accordingly:
\cgalExample{BGL_arrangement_2/arrangement_dual.cpp}
\section BGLExtensions Extensions of the BGL
The previous sections introduced partial specializations
and free functions so that several \cgal data structures are adapted as models of some
of the \sc{Bgl} graph concepts.
In this section we define a set of new concepts to extend the
functionality of \sc{Bgl} in order to match \ref PkgHDSSummary more
In this section, we introduce new concepts, iterators, and property maps inspired
by the functionalities of the BGL.
\subsection BGLExtensionsGraphConcepts Graph concepts
In this section, we define a set of new concepts to extend the
functionality of \sc{Bgl} in order to match \ref PkgHDSSummary more
closely and to enable writing generic algorithms, which operate on data structures that
have faces and halfedges.
`HalfedgeGraph` refines
<a href="http://www.boost.org/libs/graph/doc/BidirectionalGraph.html">`Bidirectional Graph`</a> with operations to accommodate halfedge data structures.
Given a halfedge, say `h`, the concept `HalfedgeGraph` requires the provision
of the halfedge opposite to `h`, the halfedge that succeeds `h`,
and the halfedge that precedes `h`.
`MutableHalfedgeGraph` adds the requirement for operations to
change the next/previous relation and to adjust the target of a halfedge.
@ -411,22 +415,53 @@ The halfedge extensions are used by the surface simplification algorithms,
which follow the design of \sc{Bgl} as sketched in Section \ref BGLA.
\subsection BGLIteratorsAndCirculators Iterators and Circulators
Starting at a halfedge `h` of a halfedge graph `g`, applying several times `next(h,g)` brings us back
to the halfedge where we started. All halfedges traversed on the way are incident to the same face.
By combining basic operations on graphs, we create various useful
\link devman_iterators_and_circulators iterators and circulators\endlink
to traverse specific types of elements. For example:
Using the composition of the `next(h,g)` and `opposite(h,g)` functions results
- Starting at a halfedge `h` of a halfedge graph `g`, applying several times `next(h,g)` brings us back
to the halfedge where we started. All halfedges traversed on the way are incident to the same face.
- Using the composition of the functions `next(h,g)` and `opposite(h,g)` results
in another cycle, namely the cycle of halfedges which are incident to
the same vertex.
For convenience, two iterator and circulator types enable the traversal of all halfedges
incident to a given face, and all halfedges having a given vertex as target.
These types are not part of the concept `HalfedgeGraph`, but they
These types are not part of the concept `HalfedgeGraph`, but they
are class templates that work for any model of this concept.
A complete list of these traversal tools can be found in \link PkgBGLIterators the reference manual\endlink.
\subsubsection BGLExampleIncidentVertices Example: Finding Incident Vertices in a HalfedgeGraph
The following example shows several functions that enable navigating in a `HalfedgeGraph`.
We have two implementations of the operation that finds the vertices adjacent to a vertex `v`.
Let us have a look at the first version. Given a vertex descriptor `vd`,
we first call `halfedge(vd,g)` to obtain the halfedge with `vd` as target.
Applying `source()` then gives us an adjacent vertex. We then get to the next halfedge
with `vd` as target, by first going to the next halfedge around the face, and then
going to the opposite halfedge.
The second version does the `%next()` and `%opposite()` jumping with an iterator.
Note that when calling `source()` we have to dereference `hi`, as the function
expects a halfedge descriptor and not a halfedge iterator.
Also note that `halfedges_around_target()` expects a halfedge, and not a vertex.
This provides the user with the ability to start the traversal at a specific
halfedge incident to the input vertex (and not the arbitrary incident halfedge
stored in the vertex record.)
\cgalExample{BGL_polyhedron_3/incident_vertices.cpp}
\subsubsection BGLExampleNormalHalfedgeGraph Example: Calculating Facet Normals using HalfedgeGraph
The following example program shows a simple algorithm for calculating
facet normals for a polyhedron using the \sc{Bgl} API. A
<a href="http://www.boost.org/libs/property_map/doc/vector_property_map.html">boost::vector_property_map</a>
is used to to store the calculated normals instead of changing the Polyhedron items class.
\cgalExample{BGL_polyhedron_3/normals.cpp}
\subsection BGLProperties Properties and Dynamic Properties
@ -440,7 +475,6 @@ The lifetime of a dynamic property is bound to the lifetime
of the property map: reference counting is used to delete the property
when no map refers to it.
Dynamic property tags such as `dynamic_vertex_property_t` are a generalization of
`boost::vertex_index_t`, as they have a template parameter for the
value type of the dynamic property map, and a default value.
@ -454,21 +488,32 @@ serves for retrieving a property map for a given graph and dynamic
property tag, as well as for retrieving a value for a given key and
property map.
The following example shows how to attach a `string` property to vertices and
a `double` value to the halfedges of a graph.
\cgalExample{Property_map/dynamic_properties.cpp}
\subsection BGLEulerOperations Euler Operations
\section BGLEulerOperations Euler Operations
There are two categories of mutating operations. The first category comprises
low level operations that change incidences such as the target vertex of a
halfedge.
A halfedge graph might turn invalid by the application of inconsistent
low lever operations. The second category of operations
low lever operations. The second category of operations
are called <em>%Euler Operations</em>. These are high level operations such
as adding a center vertex to a face, which means also adding halfedges
and faces, and updating incidence information. The %Euler operations
enable manipulating models of `MutableFaceGraph`.
The complete list of Euler operations provided by this package can be found in
\link PkgBGLEulerOperations the reference manual\endlink.
\section BGLGraphAdaptors Graph Adaptors
Graph adaptors are classes that build an interface over an existing graph to provide
new functionalities. By operating almost entirely on the input graph, adaptors
can avoid potentially expensive operations, both in term of time and memory.
\subsection BGLDual The Dual Graph
The <em>dual graph</em> of a `FaceGraph` `G` is a graph that has a vertex for each
@ -559,40 +604,29 @@ Vertices of the seam mesh that are linked by a green dashed segment correspond
to the same vertex in the underlying mesh.
\cgalFigureEnd
Seam meshes are for example used in Chapter \ref PkgSurfaceParameterizationSummary.
Seam meshes are for example used in Chapter \ref PkgSurfaceParameterizationSummary
to parameterize a topological sphere by first virtually cutting it into a topological
disk.
\subsection BGLExamples Examples
\section PMPPartitioning Graph Partitioning
\subsubsection BGLExampleIncidentVertices Example: Finding Incident Vertices in a HalfedgeGraph
For algorithms that operate locally, partitioning is often an easy way to parallelize
the algorithm at little cost.
The functions `CGAL::METIS::partition_graph()` and `CGAL::METIS::partition_dual_graph()`
provide wrappers to the graph partitioning library METIS \cgalCite{karypis1998fast},
allowing to split triangular meshes that are models of the concept `FaceListGraph`
into a given number of subdomains.
The following example shows several functions that enable navigating in a `HalfedgeGraph`.
We have two implementations of the operation that finds the vertices adjacent to a vertex `v`.
Let us have a look at the first version. Given a vertex descriptor `vd`,
we first call `halfedge(vd,g)` to obtain the halfedge with `vd` as target.
Applying `source()` then gives us an adjacent vertex. We then get to the next halfedge
with `vd` as target, by first going to the next halfedge around the face, and then
going to the opposite halfedge.
The second version does the `%next()` and `%opposite()` jumping with an iterator.
Note that when calling `source()` we have to dereference `hi`, as the function
expects a halfedge descriptor and not a halfedge iterator.
Also note that `halfedges_around_target()` expects a halfedge, and not a vertex.
This provides the user with the ability to start the traversal at a specific
halfedge incident to the input vertex (and not the arbitrary incident halfedge
stored in the vertex record.)
\cgalExample{BGL_polyhedron_3/incident_vertices.cpp}
\subsubsection BGLExampleNormalHalfedgeGraph Example: Calculating Facet Normals using HalfedgeGraph
The following example program shows a simple algorithm for calculating
facet normals for a polyhedron using the \sc{Bgl} API. A
<a href="http://www.boost.org/libs/property_map/doc/vector_property_map.html">boost::vector_property_map</a>
is used to to store the calculated normals instead of changing the Polyhedron items class.
\cgalExample{BGL_polyhedron_3/normals.cpp}
The following example shows how to read, partition, and write a mesh using
`partition_dual_graph()`. The class template `CGAL::Face_filtered_graph`
and the free function `copy_face_graph()` are used to create an independent mesh from one
of the subdomains of the partition. Note that the copy is optional as writing
can be done directly using `Face_filtered_graph`.
\cgalExample{BGL_surface_mesh/surface_mesh_partition.cpp}
Using \ref BGLNamedParameters some of the many options of METIS can be customized,
as shown in \ref BGL_polyhedron_3/polyhedron_partition.cpp "this example".
*/
} /* namespace CGAL */

View File

@ -12,7 +12,10 @@ INPUT += ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Euler_operations.h \
${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Dual.h \
${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/convert_nef_polyhedron_to_polygon_mesh.h \
${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Seam_mesh.h \
${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/io.h
${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/io.h \
${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/partition.h \
${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/METIS/partition_graph.h \
${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/METIS/partition_dual_graph.h
EXAMPLE_PATH = ${CGAL_Surface_mesh_skeletonization_EXAMPLE_DIR} \
${CGAL_Surface_mesh_segmentation_EXAMPLE_DIR} \

View File

@ -81,6 +81,39 @@ being marked or not.\n
<b>Default:</b> a default property map where no edge is constrained
\cgalNPEnd
\cgalNPBegin{METIS_options} \anchor BGL_METIS_options
is a parameter used in `partition_graph()` and `partition_dual_graph()`
to pass options to the METIS graph partitioner. The many options of METIS
are not described here. Instead, users should refer to METIS'
<a href="http://glaros.dtc.umn.edu/gkhome/fetch/sw/metis/manual.pdf">documentation</a>.\n
<b>Type:</b> an array of size `METIS_NOPTIONS` with value type `idx_t`
(an integer type defined by METIS). \n
<b>Default:</b> an array of size `METIS_NOPTIONS` with value type `idx_t`,
initialized using the function `METIS_SetDefaultOptions()`.
\cgalNPEnd
\cgalNPBegin{vertex_partition_id_map} \anchor BGL_vertex_partition_id_map
is the property map storing for each vertex of the mesh the id of the subpart
of the partition that has been assigned to this vertex.\n
<b>Type:</b> a class model of `ReadWritePropertyMap` with
`boost::graph_traits<PolygonMesh>::%vertex_descriptor` as key type and
`int` as value type. \n
<b>Default:</b> None: this property map is used to store the partition IDs of the vertices
as result of a partition algorithm; if it is not provided, this information is
simply inaccessible.
\cgalNPEnd
\cgalNPBegin{face_partition_id_map} \anchor BGL_face_partition_id_map
is the property map storing for each face of the mesh the id of the subpart
of the partition that has been assigned to this face.\n
<b>Type:</b> a class model of `ReadWritePropertyMap` with
`boost::graph_traits<PolygonMesh>::%face_descriptor` as key type and
`int` as value type. \n
<b>Default:</b> None: this property map is used to store the partition IDs of the faces
as result of a partition algorithm; if it is not provided, this information is
simply inaccessible.
\cgalNPEnd
\cgalNPTableEnd
*/

View File

@ -205,6 +205,8 @@ Valid Expression | returns | Description
/// \defgroup PkgBGLEulerOperations Euler Operations
/// \ingroup PkgBGL
/// \defgroup PkgBGLPartition Partitioning Operations
/// \ingroup PkgBGL
/*!
\addtogroup PkgBGLPropertiesDynamic
@ -268,6 +270,13 @@ both in term of time and memory.
*/
/*!
\addtogroup PkgBGLPartition
Methods to split a mesh into subdomains, using the library
<a href="http://glaros.dtc.umn.edu/gkhome/metis/metis/overview">METIS</a>.
*/
/*!
\addtogroup PkgBGL
\cgalPkgDescriptionBegin{CGAL and the Boost Graph Library,PkgBGLSummary}
@ -390,7 +399,6 @@ user might encounter.
- `CGAL::Face_around_face_circulator`
## Euler Operations ##
- `CGAL::Euler::add_center_vertex()`
- `CGAL::Euler::add_edge()`
- `CGAL::Euler::add_face()`
@ -425,7 +433,6 @@ user might encounter.
- `CGAL::convert_nef_polyhedron_to_polygon_mesh()`
- `CGAL::split_graph_into_polylines()`
## Graph Adaptors ##
- `CGAL::Dual`
- `CGAL::Face_filtered_graph`
@ -433,6 +440,10 @@ user might encounter.
- `CGAL::Graph_with_descriptor_with_graph_property_map`
- `CGAL::Seam_mesh`
## Partitioning Methods ##
- `CGAL::METIS::partition_graph()`
- `CGAL::METIS::partition_dual_graph()`
## I/O Functions ##
- `CGAL::read_off()`
- `CGAL::write_off()`

View File

@ -3,19 +3,28 @@
\example BGL_arrangement_2/arr_rational_nt.h
\example BGL_arrangement_2/arrangement_dual.cpp
\example BGL_arrangement_2/primal.cpp
\example BGL_polyhedron_3/copy_polyhedron.cpp
\example BGL_polyhedron_3/cube.off
\example BGL_polyhedron_3/distance.cpp
\example BGL_polyhedron_3/incident_vertices.cpp
\example BGL_polyhedron_3/kruskal.cpp
\example BGL_polyhedron_3/kruskal_with_stored_id.cpp
\example BGL_polyhedron_3/normals.cpp
\example BGL_polyhedron_3/incident_vertices.cpp
\example BGL_polyhedron_3/polyhedron_partition.cpp
\example BGL_polyhedron_3/range.cpp
\example BGL_polyhedron_3/transform_iterator.cpp
\example BGL_triangulation_2/dijkstra.cpp
\example BGL_triangulation_2/dijkstra_with_internal_properties.cpp
\example BGL_triangulation_2/emst.cpp
\example BGL_triangulation_2/emst_regular.cpp
\example BGL_triangulation_2/emst_cdt_plus_hierarchy.cpp
\example BGL_surface_mesh/prim.cpp
\example BGL_surface_mesh/gwdwg.cpp
\example BGL_surface_mesh/seam_mesh.cpp
\example BGL_surface_mesh/write_inp.cpp
\example BGL_surface_mesh/surface_mesh_dual.cpp
\example BGL_surface_mesh/connected_components.cpp
\example BGL_surface_mesh/surface_mesh_partition.cpp
\example Surface_mesh_skeletonization/simple_mcfskel_example.cpp
\example Surface_mesh_segmentation/extract_segmentation_into_mesh_example.cpp
\example Polygon_mesh_processing/face_filtered_graph_example.cpp

View File

@ -40,6 +40,14 @@ else()
message(STATUS "Examples that use OpenMesh will not be compiled.")
endif()
find_package( METIS )
if( METIS_FOUND )
include_directories(${METIS_INCLUDE_DIRS} )
else()
message( STATUS "Examples that use the METIS library will not be compiled." )
endif()
# include for local directory
# include for local package
@ -71,3 +79,8 @@ if(OpenMesh_FOUND)
target_link_libraries( copy_polyhedron PRIVATE ${OPENMESH_LIBRARIES} )
endif()
if( METIS_FOUND )
create_single_source_cgal_program( "polyhedron_partition.cpp" )
target_link_libraries( polyhedron_partition PRIVATE ${METIS_LIBRARIES} )
endif()

View File

@ -0,0 +1,951 @@
OFF
315 634 0
-0.142420 0.065177 0.260608
-0.181989 0.076540 0.271445
-0.123893 0.066093 0.329939
-0.122979 0.064590 0.188283
0.142420 0.065177 -0.260608
0.181989 0.076540 -0.271445
0.123893 0.066093 -0.329939
0.122979 0.064590 -0.188283
-0.072239 -0.014726 -0.341881
-0.017838 -0.014627 -0.366416
-0.039749 0.043670 -0.372418
-0.099600 -0.066092 -0.359901
-0.032912 -0.066020 -0.395573
-0.138410 -0.065466 -0.296287
-0.135170 -0.077707 -0.393831
-0.049677 -0.077763 -0.440679
0.068739 -0.068686 -0.390190
0.072239 -0.014726 0.341881
0.017838 -0.014627 0.366416
0.039749 0.043670 0.372418
0.099600 -0.066092 0.359901
0.032912 -0.066020 0.395573
0.138410 -0.065466 0.296287
0.135170 -0.077707 0.393831
0.049677 -0.077763 0.440679
-0.068739 -0.068686 0.390190
-0.045055 -0.055361 -0.476864
-0.037186 -0.014824 -0.499314
0.051296 -0.044322 -0.483565
-0.126475 -0.014757 -0.465447
0.150198 0.055570 -0.424934
0.060284 0.068494 -0.459204
0.135079 0.077725 -0.392823
0.045055 -0.055361 0.476864
0.037186 -0.014824 0.499314
-0.051296 -0.044322 0.483565
0.126475 -0.014757 0.465447
-0.150198 0.055570 0.424934
-0.060284 0.068494 0.459204
-0.135079 0.077725 0.392823
0.188724 0.013117 0.082286
0.233576 0.010949 0.199004
0.215392 -0.043248 0.185690
0.156431 0.043450 0.020495
0.171897 0.000092 0.002021
0.162866 0.035579 -0.035095
-0.188724 0.013117 -0.082286
-0.233576 0.010949 -0.199004
-0.215392 -0.043248 -0.185690
-0.156431 0.043450 -0.020495
-0.171897 0.000092 -0.002021
-0.162866 0.035579 0.035095
-0.067313 0.014873 0.490898
0.021715 0.044742 0.489868
-0.126516 0.014972 0.465443
-0.214720 0.015203 0.374161
-0.176897 0.015193 0.425242
-0.236797 0.015313 0.316273
-0.193127 0.066315 0.349240
-0.208420 0.067939 0.286047
-0.229263 0.043816 0.250443
-0.214658 0.043635 0.184550
-0.130377 0.078643 0.137373
0.067313 0.014873 -0.490898
-0.021715 0.044742 -0.489868
0.126516 0.014972 -0.465443
0.214720 0.015203 -0.374161
0.176897 0.015193 -0.425242
0.236797 0.015313 -0.316273
0.193127 0.066315 -0.349240
0.208420 0.067939 -0.286047
0.229263 0.043816 -0.250443
0.214658 0.043635 -0.184550
0.181744 -0.076895 -0.225204
0.141494 -0.076729 -0.390420
0.212561 -0.067863 -0.284234
0.199134 -0.043974 -0.379903
0.224567 -0.043744 -0.324583
0.233145 -0.014538 -0.201222
0.242955 -0.014647 -0.261574
0.156545 -0.043448 -0.017204
0.163391 -0.035324 0.038619
0.188528 0.001833 -0.078150
0.194436 -0.025458 -0.109043
-0.181744 -0.076895 0.225204
-0.141494 -0.076729 0.390420
-0.212561 -0.067863 0.284234
-0.199134 -0.043974 0.379903
-0.224567 -0.043744 0.324583
-0.233145 -0.014538 0.201222
-0.242955 -0.014647 0.261574
-0.156545 -0.043448 0.017204
-0.163391 -0.035324 -0.038619
-0.188528 0.001833 0.078150
-0.194436 -0.025458 0.109043
-0.006718 -0.041711 -0.133416
0.069747 -0.071193 -0.115051
-0.039011 -0.076564 -0.103399
0.192968 -0.066144 0.349289
0.149444 -0.055219 0.425539
0.068472 0.068833 0.390202
0.091510 0.028661 0.330536
0.106919 -0.017598 0.296052
0.122356 -0.042525 0.244251
0.109380 -0.041514 0.199886
0.148483 -0.069250 0.225265
0.111048 -0.071410 0.151511
0.198237 0.068094 0.337988
0.182439 0.044243 0.406197
0.236321 0.014962 0.322550
0.214756 -0.014995 0.374311
0.176985 -0.015124 0.425130
0.243695 0.014726 0.262496
0.227091 -0.043871 0.308431
0.229584 -0.043650 0.250875
0.177985 -0.075834 0.246262
0.201340 -0.070830 0.270330
-0.198237 0.068094 -0.337988
-0.182439 0.044243 -0.406197
-0.236321 0.014962 -0.322550
-0.243695 0.014726 -0.262496
-0.215975 0.054756 -0.201749
-0.216058 0.065555 -0.270604
-0.130747 0.073971 -0.079098
-0.154051 0.054750 -0.064135
-0.068472 0.068833 -0.390202
-0.091510 0.028661 -0.330536
-0.106919 -0.017598 -0.296052
-0.122356 -0.042525 -0.244251
-0.109380 -0.041514 -0.199886
-0.148483 -0.069250 -0.225265
-0.117365 0.029066 -0.274731
-0.112650 0.000764 -0.268704
-0.112501 0.029427 -0.214335
-0.104553 0.001720 -0.211251
-0.119854 0.054039 -0.314476
-0.139580 0.071459 -0.324689
-0.137664 0.077821 -0.381521
-0.134682 0.054062 -0.246484
-0.157216 0.071046 -0.245232
-0.072145 -0.052976 -0.145240
-0.067260 -0.026653 -0.159535
-0.016679 0.000263 -0.144728
-0.069480 0.001467 -0.166527
-0.078129 0.028679 -0.165774
-0.055533 0.043972 -0.142594
-0.114030 0.053191 -0.183583
-0.132300 0.070511 -0.172194
-0.066408 0.072769 -0.112665
-0.182880 0.077035 -0.246568
-0.198380 0.070615 -0.206609
-0.109991 0.043758 -0.462619
-0.086940 0.072150 -0.443723
-0.192968 -0.066144 -0.349289
-0.149444 -0.055219 -0.425539
-0.214756 -0.014995 -0.374311
-0.176985 -0.015124 -0.425130
-0.227091 -0.043871 -0.308431
-0.229584 -0.043650 -0.250875
-0.177985 -0.075834 -0.246262
-0.201340 -0.070830 -0.270330
0.215975 0.054756 0.201749
0.216058 0.065555 0.270604
0.130747 0.073971 0.079098
0.154051 0.054750 0.064135
0.117365 0.029066 0.274731
0.112650 0.000764 0.268704
0.112501 0.029427 0.214335
0.104553 0.001720 0.211251
0.119854 0.054039 0.314476
0.139580 0.071459 0.324689
0.137664 0.077821 0.381521
0.134682 0.054062 0.246484
0.157216 0.071046 0.245232
0.072145 -0.052976 0.145240
0.067260 -0.026653 0.159535
0.016679 0.000263 0.144728
0.069480 0.001467 0.166527
0.078129 0.028679 0.165774
0.055533 0.043972 0.142594
0.114030 0.053191 0.183583
0.132300 0.070511 0.172194
0.066408 0.072769 0.112665
0.182880 0.077035 0.246568
0.198380 0.070615 0.206609
0.109991 0.043758 0.462619
0.086940 0.072150 0.443723
-0.143990 0.064253 0.061311
-0.162481 0.072128 0.141000
-0.070836 0.053288 0.144711
-0.103935 0.027092 0.203309
-0.064337 0.027059 0.158590
-0.085285 0.072778 0.126957
0.130377 0.078643 -0.137373
0.143990 0.064253 -0.061311
0.162481 0.072128 -0.141000
0.033931 -0.102736 0.021128
-0.013620 -0.092970 0.067033
-0.017420 -0.103765 0.019514
0.144430 -0.063958 0.063078
0.164735 -0.071550 0.145631
0.039842 -0.043515 -0.372455
0.043745 0.000113 -0.358932
0.098774 0.028764 -0.320716
0.011679 0.044474 -0.377875
0.056461 0.043910 -0.365659
0.016926 0.077778 -0.437286
0.051474 0.071274 -0.403438
-0.144430 -0.063958 -0.063078
-0.164735 -0.071550 -0.145631
-0.039842 -0.043515 0.372455
-0.043745 0.000113 0.358932
-0.098774 0.028764 0.320716
-0.011679 0.044474 0.377875
-0.056461 0.043910 0.365659
-0.016926 0.077778 0.437286
-0.051474 0.071274 0.403438
0.089422 0.084836 0.087783
0.148983 0.077301 0.155338
-0.089422 0.084836 -0.087783
-0.148983 0.077301 -0.155338
0.155013 -0.054050 -0.062498
0.098521 -0.088093 0.058144
0.109518 -0.080499 -0.003782
0.135082 -0.071895 -0.082591
-0.040608 -0.001091 0.151679
-0.006474 0.027369 0.138989
-0.117240 0.027902 0.263865
-0.111172 -0.000862 0.238784
-0.108034 -0.015290 0.286318
-0.118081 -0.028990 0.243559
-0.096603 -0.029218 0.187188
-0.087620 -0.001514 0.185718
-0.049084 -0.028336 0.148599
0.006940 -0.053514 0.124233
0.009912 -0.027355 0.139023
-0.059559 -0.052588 0.136104
-0.069747 -0.071193 0.115051
0.010884 -0.076074 0.101284
0.064208 -0.075195 0.115066
0.131198 -0.078763 0.139298
0.078259 -0.088505 0.085363
-0.155013 -0.054050 0.062498
-0.056726 -0.095471 -0.060074
-0.131198 -0.078763 -0.139298
-0.111048 -0.071410 -0.151511
-0.098521 -0.088093 -0.058144
-0.109518 -0.080499 0.003782
-0.135082 -0.071895 0.082591
0.103906 0.085665 -0.069889
0.108709 0.081251 -0.005000
0.034442 0.102371 0.021265
0.075963 0.094600 0.013042
0.013471 0.103828 -0.022416
-0.027796 0.100485 0.037640
-0.103906 0.085665 0.069889
-0.108709 0.081251 0.005000
-0.034442 0.102371 -0.021265
-0.075963 0.094600 -0.013042
0.040608 -0.001091 -0.151679
0.006474 0.027369 -0.138989
0.064337 0.027059 -0.158590
0.117240 0.027902 -0.263865
0.103935 0.027092 -0.203309
0.111172 -0.000862 -0.238784
0.108034 -0.015290 -0.286318
0.118081 -0.028990 -0.243559
0.096603 -0.029218 -0.187188
0.087620 -0.001514 -0.185718
0.159791 -0.044092 -0.427265
0.110272 -0.043635 -0.462468
0.061774 -0.071645 -0.450800
0.078724 -0.077581 -0.420633
0.091129 0.000205 -0.322400
0.091584 -0.028435 -0.330507
0.139783 -0.071270 -0.324585
0.119941 -0.053753 -0.314439
0.134093 -0.053827 -0.246057
0.156632 -0.071069 -0.245245
0.059559 -0.052588 -0.136104
0.049084 -0.028336 -0.148599
0.112106 -0.053467 -0.182295
0.130580 -0.070469 -0.170441
0.214980 -0.054727 -0.199625
0.197084 -0.070768 -0.204512
0.013620 -0.092970 -0.067033
0.024285 -0.100338 -0.035804
0.107539 -0.079004 -0.102761
0.084682 -0.089243 -0.045045
-0.159791 -0.044092 0.427265
-0.110272 -0.043635 0.462468
-0.061774 -0.071645 0.450800
-0.078724 -0.077581 0.420633
-0.091129 0.000205 0.322400
-0.091584 -0.028435 0.330507
-0.139783 -0.071270 0.324585
-0.119941 -0.053753 0.314439
-0.134093 -0.053827 0.246057
-0.156632 -0.071069 0.245245
-0.112106 -0.053467 0.182295
-0.130580 -0.070469 0.170441
-0.214980 -0.054727 0.199625
-0.197084 -0.070768 0.204512
-0.107539 -0.079004 0.102761
-0.084682 -0.089243 0.045045
-0.006757 0.053977 0.123829
-0.020415 0.076271 0.101549
-0.080278 0.085841 0.090316
-0.000654 0.092672 0.070206
0.070836 0.053288 -0.144711
0.085285 0.072778 -0.126957
0.006757 0.053977 -0.123829
0.020415 0.076271 -0.101549
0.000654 0.092672 -0.070206
0.080278 0.085841 -0.090316
3 0 1 2
3 3 1 0
3 4 5 6
3 7 5 4
3 8 9 10
3 11 12 9
3 11 9 8
3 8 13 11
3 14 15 11
3 12 15 16
3 15 12 11
3 13 14 11
3 17 18 19
3 20 21 18
3 20 18 17
3 17 22 20
3 23 24 20
3 21 24 25
3 24 21 20
3 22 23 20
3 26 27 28
3 29 27 26
3 30 31 32
3 5 32 6
3 33 34 35
3 36 34 33
3 37 38 39
3 1 39 2
3 40 41 42
3 43 44 45
3 40 44 43
3 46 47 48
3 49 50 51
3 46 50 49
3 34 52 35
3 52 34 53
3 52 53 38
3 54 52 38
3 37 54 38
3 37 55 56
3 37 56 54
3 57 58 59
3 58 1 59
3 58 57 55
3 58 55 37
3 39 58 37
3 39 1 58
3 60 59 61
3 60 57 59
3 62 1 3
3 27 63 28
3 63 27 64
3 63 64 31
3 65 63 31
3 30 65 31
3 30 66 67
3 30 67 65
3 68 69 70
3 69 5 70
3 69 68 66
3 69 66 30
3 32 69 30
3 32 5 69
3 71 70 72
3 71 68 70
3 73 74 75
3 75 76 77
3 76 75 74
3 76 66 77
3 67 66 76
3 66 68 77
3 78 79 71
3 72 78 71
3 75 77 79
3 77 68 79
3 79 68 71
3 80 44 81
3 44 40 81
3 81 40 42
3 78 82 83
3 82 78 72
3 45 82 72
3 44 82 45
3 83 82 80
3 82 44 80
3 84 85 86
3 86 87 88
3 87 86 85
3 87 55 88
3 56 55 87
3 55 57 88
3 89 90 60
3 61 89 60
3 86 88 90
3 88 57 90
3 90 57 60
3 91 50 92
3 50 46 92
3 92 46 48
3 89 93 94
3 93 89 61
3 51 93 61
3 50 93 51
3 94 93 91
3 93 50 91
3 95 96 97
3 23 98 99
3 99 36 33
3 99 33 24
3 99 24 23
3 19 100 101
3 102 17 101
3 101 17 19
3 22 17 102
3 103 104 105
3 103 105 22
3 103 22 102
3 104 106 105
3 107 108 109
3 99 110 111
3 99 111 36
3 98 110 99
3 111 110 108
3 36 111 108
3 108 110 109
3 112 113 114
3 112 109 113
3 113 109 110
3 98 113 110
3 42 41 114
3 41 112 114
3 115 23 22
3 115 22 105
3 114 116 42
3 114 113 116
3 113 98 116
3 23 115 116
3 98 23 116
3 117 118 119
3 120 47 121
3 121 47 46
3 122 117 119
3 122 120 121
3 122 119 120
3 123 121 124
3 121 46 124
3 124 46 49
3 10 125 126
3 127 8 126
3 126 8 10
3 13 8 127
3 128 129 130
3 128 130 13
3 128 13 127
3 131 132 126
3 132 129 128
3 127 132 128
3 132 127 126
3 133 134 131
3 132 134 129
3 134 132 131
3 135 131 126
3 135 125 136
3 125 137 136
3 135 126 125
3 138 136 139
3 138 133 131
3 138 131 135
3 138 135 136
3 136 137 139
3 140 141 95
3 140 95 97
3 140 129 141
3 129 134 141
3 142 143 144
3 144 143 133
3 143 142 95
3 143 95 141
3 134 143 141
3 143 134 133
3 145 142 144
3 146 139 147
3 145 146 147
3 145 147 148
3 145 144 146
3 146 144 133
3 146 133 138
3 139 146 138
3 139 149 147
3 137 149 139
3 149 137 117
3 149 117 122
3 150 149 122
3 122 121 150
3 121 123 150
3 64 27 151
3 27 29 151
3 151 118 152
3 29 118 151
3 118 117 152
3 117 137 152
3 151 152 64
3 64 152 31
3 14 153 154
3 154 29 26
3 154 26 15
3 154 15 14
3 154 155 156
3 154 156 29
3 153 155 154
3 156 155 118
3 29 156 118
3 118 155 119
3 120 157 158
3 48 47 158
3 47 120 158
3 120 119 157
3 157 119 155
3 153 157 155
3 159 14 13
3 159 13 130
3 158 160 48
3 158 157 160
3 157 153 160
3 14 159 160
3 153 14 160
3 112 41 161
3 161 41 40
3 162 107 109
3 162 112 161
3 162 109 112
3 163 161 164
3 161 40 164
3 164 40 43
3 165 166 101
3 166 104 103
3 102 166 103
3 166 102 101
3 167 168 165
3 166 168 104
3 168 166 165
3 169 165 101
3 169 100 170
3 100 171 170
3 169 101 100
3 172 170 173
3 172 167 165
3 172 165 169
3 172 169 170
3 170 171 173
3 174 104 175
3 106 104 174
3 104 168 175
3 176 177 178
3 178 177 167
3 168 177 175
3 177 168 167
3 179 176 178
3 180 173 181
3 179 180 181
3 179 181 182
3 179 178 180
3 180 178 167
3 180 167 172
3 173 180 172
3 173 183 181
3 171 183 173
3 183 171 107
3 183 107 162
3 184 183 162
3 162 161 184
3 161 163 184
3 53 34 185
3 34 36 185
3 185 108 186
3 36 108 185
3 108 107 186
3 107 171 186
3 185 186 53
3 53 186 38
3 187 49 51
3 61 188 187
3 51 61 187
3 59 188 61
3 1 188 59
3 1 62 188
3 189 190 191
3 192 3 189
3 3 190 189
3 192 62 3
3 193 5 7
3 194 43 45
3 72 195 194
3 45 72 194
3 70 195 72
3 5 195 70
3 5 193 195
3 196 197 198
3 199 80 81
3 42 200 199
3 81 42 199
3 116 200 42
3 115 200 116
3 201 202 9
3 12 201 9
3 201 12 16
3 6 203 4
3 204 9 205
3 10 9 204
3 9 202 205
3 202 203 205
3 205 203 6
3 32 206 207
3 31 206 32
3 152 206 31
3 137 206 152
3 207 206 125
3 206 137 125
3 10 207 125
3 204 207 10
3 207 204 205
3 205 6 207
3 6 32 207
3 208 91 92
3 48 209 208
3 92 48 208
3 160 209 48
3 159 209 160
3 210 211 18
3 21 210 18
3 210 21 25
3 2 212 0
3 213 18 214
3 19 18 213
3 18 211 214
3 211 212 214
3 214 212 2
3 39 215 216
3 38 215 39
3 186 215 38
3 171 215 186
3 216 215 100
3 215 171 100
3 19 216 100
3 213 216 19
3 216 213 214
3 214 2 216
3 2 39 216
3 217 218 163
3 218 217 182
3 181 218 182
3 183 218 181
3 218 183 184
3 163 218 184
3 219 220 123
3 220 219 148
3 147 220 148
3 149 220 147
3 220 149 150
3 123 220 150
3 221 83 80
3 199 222 223
3 224 221 223
3 223 221 80
3 199 223 80
3 199 200 222
3 225 226 191
3 225 176 226
3 226 176 179
3 227 190 3
3 0 227 3
3 0 212 227
3 228 190 227
3 228 229 230
3 229 228 227
3 231 232 230
3 225 232 231
3 232 225 191
3 190 232 191
3 228 232 190
3 232 228 230
3 176 225 233
3 225 231 233
3 234 235 236
3 237 234 236
3 175 235 234
3 174 175 234
3 177 235 175
3 177 176 235
3 235 176 233
3 236 235 233
3 234 237 238
3 238 197 239
3 237 197 238
3 174 238 239
3 174 234 238
3 239 106 174
3 240 241 222
3 200 240 222
3 115 240 200
3 240 115 105
3 241 240 106
3 106 240 105
3 241 106 239
3 197 241 239
3 241 197 196
3 222 241 196
3 242 94 91
3 243 244 245
3 245 244 130
3 159 244 209
3 244 159 130
3 129 245 130
3 245 129 140
3 97 245 140
3 243 245 97
3 208 246 247
3 248 242 247
3 247 242 91
3 208 247 91
3 208 209 246
3 209 244 246
3 244 243 246
3 198 246 243
3 194 249 250
3 163 164 250
3 250 164 43
3 194 250 43
3 194 195 249
3 195 193 249
3 251 217 252
3 217 163 252
3 252 163 250
3 249 252 250
3 252 253 251
3 252 249 253
3 251 253 254
3 187 255 256
3 123 124 256
3 256 124 49
3 187 256 49
3 187 188 255
3 188 62 255
3 257 219 258
3 258 254 257
3 219 123 258
3 258 123 256
3 255 258 256
3 258 255 254
3 254 253 257
3 259 260 261
3 259 142 260
3 260 142 145
3 262 263 7
3 4 262 7
3 4 203 262
3 264 263 262
3 264 265 266
3 265 264 262
3 267 268 266
3 259 268 267
3 268 259 261
3 263 268 261
3 264 268 263
3 268 264 266
3 65 269 270
3 28 63 270
3 63 65 270
3 65 67 269
3 269 67 76
3 270 269 74
3 76 74 269
3 271 26 28
3 270 271 28
3 74 272 271
3 270 74 271
3 271 272 15
3 26 271 15
3 15 272 16
3 265 273 274
3 273 265 262
3 203 273 262
3 202 273 203
3 274 273 201
3 201 16 274
3 273 202 201
3 272 74 275
3 266 265 276
3 276 265 274
3 276 16 275
3 16 272 275
3 276 274 16
3 277 275 278
3 277 267 266
3 277 266 276
3 277 276 275
3 275 74 278
3 74 73 278
3 279 95 280
3 96 95 279
3 95 142 280
3 142 259 280
3 259 267 280
3 281 278 282
3 278 73 282
3 279 281 282
3 279 282 96
3 279 280 281
3 280 267 281
3 281 267 277
3 278 281 277
3 75 283 284
3 284 73 75
3 75 79 283
3 79 78 283
3 283 78 83
3 283 224 284
3 283 83 221
3 224 283 221
3 243 285 286
3 198 286 196
3 198 243 286
3 285 243 97
3 96 285 97
3 287 224 288
3 282 287 96
3 73 287 282
3 287 73 284
3 224 287 284
3 288 224 223
3 222 288 223
3 288 222 196
3 286 288 196
3 287 288 285
3 287 285 96
3 285 288 286
3 54 289 290
3 35 52 290
3 52 54 290
3 54 56 289
3 289 56 87
3 290 289 85
3 87 85 289
3 291 33 35
3 290 291 35
3 85 292 291
3 290 85 291
3 291 292 24
3 33 291 24
3 24 292 25
3 229 293 294
3 293 229 227
3 212 293 227
3 211 293 212
3 294 293 210
3 210 25 294
3 293 211 210
3 292 85 295
3 230 229 296
3 296 229 294
3 296 25 295
3 25 292 295
3 296 294 25
3 297 295 298
3 297 231 230
3 297 230 296
3 297 296 295
3 295 85 298
3 85 84 298
3 299 298 300
3 298 84 300
3 236 299 300
3 236 300 237
3 236 233 299
3 233 231 299
3 299 231 297
3 298 299 297
3 86 301 302
3 302 84 86
3 86 90 301
3 90 89 301
3 301 89 94
3 301 248 302
3 301 94 242
3 248 301 242
3 303 248 304
3 303 304 197
3 303 197 237
3 300 303 237
3 84 303 300
3 303 84 302
3 248 303 302
3 304 248 247
3 246 304 247
3 304 246 198
3 197 304 198
3 305 182 306
3 189 305 306
3 189 306 192
3 189 191 305
3 191 226 305
3 305 226 179
3 182 305 179
3 307 308 254
3 308 307 306
3 255 307 254
3 62 307 255
3 307 62 192
3 306 307 192
3 182 308 306
3 217 308 182
3 217 251 308
3 308 251 254
3 309 263 261
3 310 7 309
3 7 263 309
3 310 193 7
3 311 148 312
3 309 311 312
3 309 312 310
3 309 261 311
3 261 260 311
3 311 260 145
3 148 311 145
3 313 314 312
3 193 314 249
3 314 193 310
3 312 314 310
3 148 313 312
3 219 313 148
3 219 257 313
3 314 313 253
3 249 314 253
3 313 257 253

View File

@ -0,0 +1,57 @@
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/boost/graph/partition.h>
//
// TEST BGL NP
//
int main(int argc, char** argv)
{
typedef CGAL::Simple_cartesian<double> K;
std::ifstream in((argc>1) ? argv[1] : "data/eight.off");
int number_of_parts = (argc>2) ? atoi(argv[2]) : 8;
if(!in)
{
std::cerr << "Error: could not read input file" << std::endl;
return EXIT_FAILURE;
}
typedef CGAL::Polyhedron_3<K> PM;
PM pm;
in >> pm; // read the mesh
// The face <--> partition_id property map
typedef CGAL::dynamic_face_property_t<int> Face_property_tag;
typedef boost::property_map<PM, Face_property_tag>::type Face_id_map;
Face_id_map partition_id_map = get(Face_property_tag(), pm);
// Set some custom options for METIS
idx_t options[METIS_NOPTIONS];
// Set all options to default ahead of manually editing some values
METIS_SetDefaultOptions(options);
// See METIS documentation for details on the many options
options[METIS_OPTION_PTYPE] = METIS_PTYPE_KWAY;
options[METIS_OPTION_OBJTYPE] = METIS_OBJTYPE_VOL;
options[METIS_OPTION_CTYPE] = METIS_CTYPE_SHEM;
options[METIS_OPTION_NCUTS] = 3;
options[METIS_OPTION_NITER] = 10;
options[METIS_OPTION_SEED] = 12345;
options[METIS_OPTION_MINCONN] = 1;
options[METIS_OPTION_CONTIG] = 1;
options[METIS_OPTION_UFACTOR] = 25;
options[METIS_OPTION_DBGLVL] = METIS_DBG_INFO;
// Partition the mesh and output its parts
CGAL::METIS::partition_graph(pm, number_of_parts,
CGAL::parameters::vertex_index_map(get(boost::vertex_external_index, pm))
.face_partition_id_map(partition_id_map)
.METIS_options(&options));
return EXIT_SUCCESS;
}

View File

@ -1,26 +1,36 @@
project( BGL_surface_mesh_Examples )
cmake_minimum_required(VERSION 2.8.10)
cmake_minimum_required( VERSION 2.8.10 )
find_package(CGAL QUIET)
find_package( CGAL QUIET )
if ( CGAL_FOUND )
include( ${CGAL_USE_FILE} )
include( CGAL_CreateSingleSourceCGALProgram )
include_directories (BEFORE "../../include")
# create a target per cppfile
file(GLOB cppfiles RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
foreach(cppfile ${cppfiles})
create_single_source_cgal_program( "${cppfile}" )
endforeach()
else()
message(STATUS "This program requires the CGAL library, and will not be compiled.")
if ( NOT CGAL_FOUND )
message( STATUS "This project requires the CGAL library, and will not be compiled." )
return()
endif()
include( ${CGAL_USE_FILE} )
# include for local package
include_directories( BEFORE "../../include" )
include( CGAL_CreateSingleSourceCGALProgram )
create_single_source_cgal_program( "prim.cpp" )
create_single_source_cgal_program( "gwdwg.cpp" )
create_single_source_cgal_program( "seam_mesh.cpp" )
create_single_source_cgal_program( "write_inp.cpp" )
create_single_source_cgal_program( "surface_mesh_dual.cpp" )
create_single_source_cgal_program( "connected_components.cpp" )
find_package( METIS )
if( METIS_FOUND )
include_directories(${METIS_INCLUDE_DIRS} )
create_single_source_cgal_program( "surface_mesh_partition.cpp" )
target_link_libraries( surface_mesh_partition PRIVATE ${METIS_LIBRARIES} )
else()
message( STATUS "Examples that use the METIS library will not be compiled." )
endif()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,62 @@
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/boost/graph/Face_filtered_graph.h>
#include <CGAL/boost/graph/partition.h>
#include <fstream>
#include <iostream>
typedef CGAL::Simple_cartesian<double> K;
typedef CGAL::Surface_mesh<K::Point_3> SM;
int main(int argc, char** argv)
{
std::ifstream in((argc>1) ? argv[1] : "data/blobby.off");
int number_of_parts = (argc>2) ? atoi(argv[2]) : 8;
if(!in) {
std::cerr << "Error: could not read input file" << std::endl;
return EXIT_FAILURE;
}
SM sm;
CGAL::read_off(in, sm);
// The vertex <--> partition_id property map
typedef SM::Property_map<SM::Vertex_index, std::size_t> Vertex_id_map;
Vertex_id_map vertex_pid_map = sm.add_property_map<SM::Vertex_index, std::size_t>("v:pid").first;
// The face <--> partition_id property map
typedef SM::Property_map<SM::Face_index, std::size_t> Face_id_map;
Face_id_map face_pid_map = sm.add_property_map<SM::Face_index, std::size_t>("f:pid").first;
// Partition the mesh
CGAL::METIS::partition_dual_graph(sm, number_of_parts,
CGAL::parameters::vertex_partition_id_map(vertex_pid_map)
.face_partition_id_map(face_pid_map));
// Extract the part n°0 of the partition into a new, independent mesh
typedef CGAL::Face_filtered_graph<SM> Filtered_graph;
Filtered_graph filtered_sm(sm, 0 /*id of th part*/, face_pid_map);
CGAL_assertion(filtered_sm.is_selection_valid());
SM part_sm;
CGAL::copy_face_graph(filtered_sm, part_sm);
// Output the mesh extracted from subpart n°0
std::ofstream out("sm_part_0.off");
CGAL::write_off(out, part_sm);
// Output all the vertices that are in the part n°0
std::ofstream outxyz("out.xyz");
boost::graph_traits<SM>::vertex_iterator vit, ve;
boost::tie(vit, ve) = vertices(sm);
for(; vit!=ve; ++vit)
{
if(get(vertex_pid_map, *vit) == 0)
outxyz << sm.point(*vit) << std::endl;
}
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,188 @@
// Copyright (c) 2017 GeometryFactory (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0+
//
// Author(s) : Mael Rouxel-Labbé
#ifndef CGAL_BGL_PARTITION_DUAL_GRAPH_H
#define CGAL_BGL_PARTITION_DUAL_GRAPH_H
#include <CGAL/boost/graph/METIS/partition_graph.h>
#include <CGAL/boost/graph/copy_face_graph.h>
#include <CGAL/boost/graph/Face_filtered_graph.h>
#include <CGAL/boost/graph/helpers.h>
#include <CGAL/boost/graph/named_function_params.h>
#include <CGAL/boost/graph/named_params_helper.h>
#include <CGAL/assertions.h>
#include <metis.h>
#include <boost/graph/graph_traits.hpp>
#include <boost/tuple/tuple.hpp>
namespace CGAL {
namespace METIS {
template<typename TriangleMesh, typename METIS_options, typename NamedParameters>
void partition_dual_graph(const TriangleMesh& tm, int nparts,
METIS_options options, // options array
const NamedParameters& np)
{
CGAL_precondition(CGAL::is_triangle_mesh(tm));
CGAL_precondition_msg(nparts > 1, ("Partitioning requires a number of parts > 1"));
using boost::choose_param;
using boost::get_param;
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<TriangleMesh>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<TriangleMesh>::face_iterator face_iterator;
// vertex index map
typedef typename GetVertexIndexMap<TriangleMesh, NamedParameters>::type Indices;
Indices indices = choose_param(get_param(np, internal_np::vertex_index),
get_const_property_map(boost::vertex_index, tm));
idx_t nn = static_cast<idx_t>(num_vertices(tm));
idx_t ne = static_cast<idx_t>(num_faces(tm));
idx_t d = 3; // number of nodes per element
idx_t* eptr = new idx_t[ne + 1];
idx_t* eind = new idx_t[d * ne];
// fill the adjacency info
face_iterator fit, fe;
boost::tie(fit, fe) = faces(tm);
for(int i=0, j=0; fit!=fe; ++fit, ++i)
{
eptr[i] = j;
halfedge_descriptor h = halfedge(*fit, tm), done = h;
do
{
vertex_descriptor v = target(h, tm);
CGAL_assertion(j < d * ne);
eind[j++] = static_cast<idx_t>(get(indices, v));
h = next(h, tm);
} while (h != done);
CGAL_assertion(i < ne);
eptr[i + 1] = j;
}
// a dual edge between elements exists if they share 'nparts' vertices
idx_t ncommon = 2;
// either the edgecut or the total communication volume of the dual graphs partitioning
idx_t objval;
// partition info for the nodes
idx_t* npart = (idx_t*) calloc(nn, sizeof(idx_t));
CGAL_assertion(npart != NULL);
// partition info for the elements
idx_t* epart = (idx_t*) calloc(ne, sizeof(idx_t));
CGAL_assertion(epart != NULL);
// do not support Fortran-style arrays
CGAL_assertion((*options)[METIS_OPTION_NUMBERING] == -1 || // default initialization is '-1'
(*options)[METIS_OPTION_NUMBERING] == 0);
int ret = METIS_PartMeshDual(&ne, &nn, eptr, eind,
NULL /* elements weights*/, NULL /*elements sizes*/,
&ncommon, &nparts,
NULL /* partitions weights */,
*options,
&objval, epart, npart);
CGAL_assertion(ret == METIS_OK);
Output_vertex_partition_ids vo;
Output_face_partition_ids fo;
vo(tm, indices, npart, get_param(np, internal_np::vertex_partition_id));
fo(tm, epart, get_param(np, internal_np::face_partition_id));
}
template<typename TriangleMesh, typename NamedParameters>
void partition_dual_graph(const TriangleMesh& tm, int nparts,
const boost::param_not_found, // no METIS options were passed
const NamedParameters& np)
{
idx_t options[METIS_NOPTIONS];
METIS_SetDefaultOptions(options);
return partition_dual_graph(tm, nparts, &options, np);
}
/// \ingroup PkgBGLPartition
///
/// Computes a partition of the input triangular mesh into `nparts` parts,
/// based on the mesh's dual graph. The resulting partition is stored in the vertex and/or face
/// property maps that are passed as parameters using \ref bgl_namedparameters "Named Parameters".
///
/// Property map for `CGAL::vertex_index_t` should be either available
/// as an internal property map to `tm` or provided as \ref bgl_namedparameters "Named Parameters".
///
/// \param tm a triangle mesh
/// \param nparts the number of parts in the final partition
/// \param np optional \ref bgl_namedparameters "Named Parameters" described below
///
/// \tparam TriangleMesh is a model of the `FaceListGraph` concept.
/// \tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
///
/// \cgalNamedParamsBegin
/// \cgalParamBegin{vertex_index_map}
/// is a property map containing the index of each vertex of `tm` intialized from `0` to `num_vertices(tm)-1`.
/// \cgalParamEnd
/// \cgalParamBegin{METIS_options}
/// is a parameter used in to pass options to the METIS mesh
/// partitioner. The many options of METIS are not described here. Instead, users
/// should refer to the <a href="http://glaros.dtc.umn.edu/gkhome/fetch/sw/metis/manual.pdf">documentation</a>
/// of METIS directly.
/// \cgalParamEnd
/// \cgalParamBegin{vertex_partition_id_map}
/// is a property map that contains (after the function has been run)
/// the ID of the subpart for each vertex of `tm`.
/// \cgalParamEnd
/// \cgalParamBegin{face_partition_id_map}
/// is a property map that contains (after the function has been run)
/// the ID of the subpart for each face of `tm`.
/// \cgalParamEnd
/// \cgalNamedParamsEnd
///
/// \pre `tm` is a pure triangular surface mesh: there are no edges
/// without at least one incident face
template<typename TriangleMesh, typename NamedParameters>
void partition_dual_graph(const TriangleMesh& tm, int nparts, const NamedParameters& np)
{
using boost::get_param;
return partition_dual_graph(tm, nparts, get_param(np, internal_np::METIS_options), np);
}
template<typename TriangleMesh>
void partition_dual_graph(const TriangleMesh& tm, const int nparts)
{
return partition_dual_graph(tm, nparts, CGAL::parameters::all_default());
}
} // end namespace METIS
} // end namespace CGAL
#endif // CGAL_BGL_PARTITION_DUAL_GRAPH_H

View File

@ -0,0 +1,221 @@
// Copyright (c) 2017 GeometryFactory (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0+
//
// Author(s) : Mael Rouxel-Labbé
#ifndef CGAL_BGL_PARTITION_GRAPH_H
#define CGAL_BGL_PARTITION_GRAPH_H
#include <CGAL/boost/graph/copy_face_graph.h>
#include <CGAL/boost/graph/Face_filtered_graph.h>
#include <CGAL/boost/graph/helpers.h>
#include <CGAL/Polygon_mesh_processing/internal/named_function_params.h>
#include <CGAL/Polygon_mesh_processing/internal/named_params_helper.h>
#include <CGAL/assertions.h>
#include <metis.h>
#include <boost/graph/graph_traits.hpp>
#include <boost/tuple/tuple.hpp>
namespace CGAL {
namespace METIS {
struct Output_vertex_partition_ids
{
template<typename TriangleMesh, typename Indices>
void operator()(const TriangleMesh&, const Indices,
idx_t const * const, boost::param_not_found) { }
template<typename TriangleMesh,
typename Indices,
typename VertexPartitionIDPmap>
void operator()(const TriangleMesh& tm, const Indices indices,
idx_t const * const npart,
VertexPartitionIDPmap vertex_partition_id_map)
{
typename boost::graph_traits<TriangleMesh>::vertex_iterator vit, ve;
boost::tie(vit, ve) = vertices(tm);
for(; vit!=ve; ++vit)
put(vertex_partition_id_map, *vit, npart[get(indices, *vit)]);
}
};
struct Output_face_partition_ids
{
template<typename TriangleMesh>
void operator()(const TriangleMesh&,
idx_t const * const, boost::param_not_found) { }
template<typename TriangleMesh, typename FacePartitionIDPmap>
void operator()(const TriangleMesh& tm, idx_t const * const epart,
FacePartitionIDPmap face_partition_id_map)
{
typename boost::graph_traits<TriangleMesh>::face_iterator fit, fe;
boost::tie(fit, fe) = faces(tm);
for(int i=0; fit!=fe; ++fit, ++i)
put(face_partition_id_map, *fit, epart[i]);
}
};
template<typename TriangleMesh, typename METIS_options, typename NamedParameters>
void partition_graph(const TriangleMesh& tm, int nparts,
METIS_options options, // pointer to the options array
const NamedParameters& np)
{
CGAL_precondition(CGAL::is_triangle_mesh(tm));
CGAL_precondition_msg(nparts > 1, ("Partitioning requires a number of parts > 1"));
using boost::choose_param;
using boost::get_param;
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<TriangleMesh>::vertex_iterator vertex_iterator;
typedef typename boost::graph_traits<TriangleMesh>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<TriangleMesh>::face_iterator face_iterator;
//Vertex index map
typedef typename GetVertexIndexMap<TriangleMesh, NamedParameters>::type Indices;
Indices indices = choose_param(get_param(np, internal_np::vertex_index),
get_const_property_map(boost::vertex_index, tm));
idx_t nn = static_cast<idx_t>(num_vertices(tm));
idx_t ne = static_cast<idx_t>(num_faces(tm));
idx_t d = 3; // number of nodes per element
idx_t* eptr = new idx_t[ne + 1];
idx_t* eind = new idx_t[d * ne];
// fill the adjacency info
face_iterator fit, fe;
boost::tie(fit, fe) = faces(tm);
for(int i=0, j=0; fit!=fe; ++fit, ++i)
{
eptr[i] = j;
halfedge_descriptor h = halfedge(*fit, tm), done = h;
do
{
vertex_descriptor v = target(h, tm);
CGAL_assertion(j < d * ne);
eind[j++] = static_cast<idx_t>(get(indices, v));
h = next(h, tm);
} while (h != done);
CGAL_assertion(i < ne);
eptr[i + 1] = j;
}
// either the edgecut or the total communication volume of the dual graphs partitioning
idx_t objval;
// partition info for the nodes
idx_t* npart = (idx_t*) calloc(nn, sizeof(idx_t));
CGAL_assertion(npart != NULL);
// partition info for the elements
idx_t* epart = (idx_t*) calloc(ne, sizeof(idx_t));
CGAL_assertion(epart != NULL);
// do not support Fortran-style arrays
CGAL_assertion((*options)[METIS_OPTION_NUMBERING] == -1 || // default initialization is '-1'
(*options)[METIS_OPTION_NUMBERING] == 0);
int ret = METIS_PartMeshNodal(&ne, &nn, eptr, eind,
NULL /* nodes weights */, NULL /* nodes sizes */,
&nparts,
NULL /* partitions weights */,
*options,
&objval, epart, npart);
CGAL_assertion(ret == METIS_OK);
Output_vertex_partition_ids vo;
Output_face_partition_ids fo;
vo(tm, indices, npart, get_param(np, internal_np::vertex_partition_id));
fo(tm, epart, get_param(np, internal_np::face_partition_id));
}
template<typename TriangleMesh, typename NamedParameters>
void partition_graph(const TriangleMesh& tm, int nparts,
const boost::param_not_found, // no METIS options were passed
const NamedParameters& np)
{
idx_t options[METIS_NOPTIONS];
METIS_SetDefaultOptions(options);
return partition_graph(tm, nparts, &options, np);
}
/// \ingroup PkgBGLPartition
///
/// Computes a partition of the input triangular mesh into `nparts` parts, based on the
/// mesh's nodal graph. The resulting partition is stored in the vertex and/or face
/// property maps that are passed as parameters using \ref bgl_namedparameters "Named Parameters".
///
/// Property map for `CGAL::vertex_index_t` should be either available
/// as an internal property map to `tm` or provided as \ref bgl_namedparameters "Named Parameters".
///
/// \param tm a triangle mesh
/// \param nparts the number of parts in the final partition
/// \param np optional \ref bgl_namedparameters "Named Parameters" described below
///
/// \tparam TriangleMesh is a model of the `FaceListGraph` concept.
/// \tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
///
/// \cgalNamedParamsBegin
/// \cgalParamBegin{vertex_index_map}
/// is a property map containing the index of each vertex of `tm` intialized from `0` to `num_vertices(tm)-1`.
/// \cgalParamEnd
/// \cgalParamBegin{METIS_options}
/// is a parameter used in to pass options to the METIS mesh
/// partitioner. The many options of METIS are not described here. Instead, users
/// should refer to the <a href="http://glaros.dtc.umn.edu/gkhome/fetch/sw/metis/manual.pdf">documentation</a>
/// of METIS directly.
/// \cgalParamEnd
/// \cgalParamBegin{vertex_partition_id_map}
/// is a property map that contains (after the function has been run)
/// the ID of the subpart for each vertex of `tm`.
/// \cgalParamEnd
/// \cgalParamBegin{face_partition_id_map}
/// is a property map that contains (after the function has been run)
/// the ID of the subpart for each face of `tm`.
/// \cgalParamEnd
/// \cgalNamedParamsEnd
///
/// \pre `tm` is a pure triangular surface mesh: there are no edges
/// without at least one incident face
template<typename TriangleMesh, typename NamedParameters>
void partition_graph(const TriangleMesh& tm, int nparts, const NamedParameters& np)
{
using boost::get_param;
return partition_graph(tm, nparts, get_param(np, internal_np::METIS_options), np);
}
template<typename TriangleMesh>
void partition_graph(const TriangleMesh& tm, const int nparts)
{
return partition_graph(tm, nparts, CGAL::parameters::all_default());
}
} // end namespace METIS
} // end namespace CGAL
#endif // CGAL_BGL_PARTITION_GRAPH_H

View File

@ -28,6 +28,10 @@ CGAL_add_named_parameter(edge_is_constrained_t, edge_is_constrained, edge_is_con
CGAL_add_named_parameter(first_index_t, first_index, first_index)
CGAL_add_named_parameter(number_of_iterations_t, number_of_iterations, number_of_iterations)
CGAL_add_named_parameter(metis_options_t, METIS_options, METIS_options)
CGAL_add_named_parameter(vertex_partition_id_t, vertex_partition_id, vertex_partition_id_map)
CGAL_add_named_parameter(face_partition_id_t, face_partition_id, face_partition_id_map)
// List of named parameters that we use in the package 'Mesh_3'
CGAL_add_named_parameter(vertex_feature_degree_t, vertex_feature_degree, vertex_feature_degree_map)

View File

@ -0,0 +1,96 @@
// Copyright (c) 2017 GeometryFactory (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0+
//
// Author(s) : Mael Rouxel-Labbé
#ifndef CGAL_BGL_PARTITION_H
#define CGAL_BGL_PARTITION_H
/**
* \ingroup PkgBGL
* \file CGAL/boost/graph/partition.h
* Convenience header file including the headers for all the partitioning-related
* free functions of this package.
*/
#include <CGAL/boost/graph/METIS/partition_graph.h>
#include <CGAL/boost/graph/METIS/partition_dual_graph.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
namespace CGAL {
namespace internal {
// Note that to use the function below with Polyhedron_3, you need to enhance
// the Polyhedron_3 to use items, that is, use:
// typedef CGAL::Polyhedron_3<K, CGAL::Polyhedron_items_with_id_3> PM;
// \ingroup PkgBGLPartition
//
// Output each part of a partition as a single mesh.
//
// \param tm a triangle mesh
// \param nparts the number of parts
// \param fpmap the property map with the partition indices
// \param filename_base Partitions will be output in `.off` files named
// `{filename_base}_[0...nparts].off`
//
// \tparam TriangleMesh must be a model of a `FaceListGraph`, `HalfedgeListGraph`, and \bgllink{VertexListGraph}.
// \tparam FacePartitionIDPmap is a model of `ReadablePropertyMap`
// with `boost::graph_traits<TriangleMesh>::%face_descriptor`
// as key type and `boost::graph_traits<Graph>::%faces_size_type` as value type.
template<typename TriangleMesh, typename FacePartitionIDPmap>
void output_partition(const TriangleMesh& tm,
const idx_t nparts,
const FacePartitionIDPmap fpmap,
const std::string filename_base)
{
CGAL_precondition(CGAL::is_triangle_mesh(tm));
typedef CGAL::Face_filtered_graph<TriangleMesh> Filtered_graph;
for(int i=0; i<nparts; ++i)
{
std::ostringstream filename;
filename << filename_base << "_" << i << ".off" << std::ends;
std::ofstream out(filename.str().c_str());
Filtered_graph m_part(tm, i, fpmap);
if(!m_part.is_selection_valid())
{
std::cerr << "Warning: cannot extract subdomain #" << i << " because it is "
<< "not a manifold mesh" << std::endl;
continue;
}
TriangleMesh out_mesh;
CGAL::copy_face_graph(m_part, out_mesh);
out << out_mesh;
}
}
} // namespace internal
} // namespace CGAL
#endif // CGAL_BGL_PARTITION_H

View File

@ -40,6 +40,10 @@ void test(const NamedParameters& np)
assert(get_param(np, CGAL::internal_np::first_index).v == 7);
assert(get_param(np, CGAL::internal_np::number_of_iterations).v == 8);
assert(get_param(np, CGAL::internal_np::METIS_options).v == 800000001);
assert(get_param(np, CGAL::internal_np::vertex_partition_id).v == 800000002);
assert(get_param(np, CGAL::internal_np::face_partition_id).v == 800000003);
// Named parameters that we use in the package 'Mesh_3'
assert(get_param(np, CGAL::internal_np::vertex_feature_degree).v == 9);
@ -98,6 +102,10 @@ void test(const NamedParameters& np)
check_same_type<7>(get_param(np, CGAL::internal_np::first_index));
check_same_type<8>(get_param(np, CGAL::internal_np::number_of_iterations));
check_same_type<800000001>(get_param(np, CGAL::internal_np::METIS_options));
check_same_type<800000002>(get_param(np, CGAL::internal_np::vertex_partition_id));
check_same_type<800000003>(get_param(np, CGAL::internal_np::face_partition_id));
// Named parameters that we use in the package 'Mesh_3'
check_same_type<9>(get_param(np, CGAL::internal_np::vertex_feature_degree));
@ -151,6 +159,9 @@ int main()
.edge_is_constrained_map(A<6>(6))
.first_index(A<7>(7))
.number_of_iterations(A<8>(8))
.METIS_options(A<800000001>(800000001))
.vertex_partition_id_map(A<800000002>(800000002))
.face_partition_id_map(A<800000003>(800000003))
.vertex_feature_degree_map(A<9>(9))
.geom_traits(A<10>(10))
.vertex_incident_patches_map(A<11>(11))

View File

@ -24,7 +24,6 @@ major difference being the absence of a past-the-end position in a sequence.
Note that circulators are NOT part of the \stl, but of \cgal.
In \cgal, we also define the concept of \ref PkgHandlesAndCirculatorsSummary "handle",
which behaves roughly
like a pointer to an object without an increment or decrement operation.
More details about handles and their requirements can be found in
@ -128,7 +127,6 @@ might not be valid.
<B>Stream iterators</B>
\stl provides a special type of input iterator called `istream_iterator`,
which is designed to be bound to an object of the class `istream` and
provides a way to read a sequence of values from the input stream to which
it is bound. For example, the following code reads numbers of type
@ -146,7 +144,6 @@ cout << sum << endl;
\endcode
In a similar fashion, \stl provides the type `ostream_iterator`,
which is designed to be bound to an object of the class `ostream`
and used to output values to the output stream to which it is bound.
@ -211,9 +208,7 @@ member function and a provided location of the insertion.
For convenience, \stl provides the templated
functions (or adaptors)
`front_inserter`,
`back_inserter`
and `inserter` to get insert iterators, also called inserters,
from containers.
@ -327,10 +322,8 @@ if ( ! CGAL::is_empty_range( i, j) )
The following two macros are also defined as a generic means for iterating
over either a linear or circular sequence:
`CGAL_For_all( ic1, ic2)`
`CGAL_For_all_backwards( ic1, ic2)`
- `CGAL_For_all( ic1, ic2)`
- `CGAL_For_all_backwards( ic1, ic2)`.
See the chapter \ref PkgHandlesAndCirculatorsSummary "Handles and Circulators"
in the <I>Support Library</I> part of \cgal manual
@ -345,7 +338,6 @@ in \cgalCite{cgal:a-gps-98}. For the purposes of this discussion, the relevant
types are:
<TABLE><TR><TD ALIGN=LEFT VALIGN=TOP NOWRAP>
`iterator`
<TD ALIGN=LEFT VALIGN=TOP NOWRAP>
type of iterator
@ -353,7 +345,6 @@ types are:
`const_iterator`
<TD ALIGN=LEFT VALIGN=TOP NOWRAP>
iterator type for container with constant elements
</TABLE>
and the relevant functions are:
@ -378,7 +369,6 @@ elements in addition to (or, where appropriate, instead of) the iterators.
This means that the following types should be defined:
<TABLE><TR><TD ALIGN=LEFT VALIGN=TOP NOWRAP>
`circulator`
<TD ALIGN=LEFT VALIGN=TOP NOWRAP>
type of circulator
@ -386,7 +376,6 @@ This means that the following types should be defined:
`const_circulator`
<TD ALIGN=LEFT VALIGN=TOP NOWRAP>
circulator type for container with constant elements
</TABLE>
as well as two access functions, one for each of the two types, with names

View File

@ -2838,6 +2838,17 @@ pages = "207--221"
year={2015}
}
@article{karypis1998fast,
title={A fast and high quality multilevel scheme for partitioning irregular graphs},
author={Karypis, George and Kumar, Vipin},
journal={SIAM Journal on scientific Computing},
volume={20},
number={1},
pages={359--392},
year={1998},
publisher={SIAM}
}
% ----------------------------------------------------------------------------
% END OF BIBFILE
% ----------------------------------------------------------------------------

View File

@ -111,11 +111,16 @@ Release date: April 2018
### CGAL and the Boost Graph Library (BGL)
- Add helper function `CGAL::expand_face_selection_for_removal` that
- Added helper function `CGAL::expand_face_selection_for_removal` that
expands a face selection to avoid creating a non manifold mesh when
removing the selected faces.
- Add support for dynamic property maps
- Added support for dynamic property maps.
- Added an interface to the [METIS library](http://glaros.dtc.umn.edu/gkhome/metis/metis/overview),
which allows to partition any mesh that is a model of `FaceListGraph`.
Wrappers to the METIS functions `METIS_PartMeshNodal` and `METIS_PartMeshDual`
are offered.
### 2D Arrangements

View File

@ -0,0 +1,187 @@
# -*- mode: cmake -*-
#
# METIS Find Module for MSTK
# Shamelessly stolen from Amanzi open source code https://software.lanl.gov/ascem/trac
#
# Usage:
# Control the search through METIS_DIR or setting environment variable
# METIS_ROOT to the METIS installation prefix.
#
# This module does not search default paths!
#
# Following variables are set:
# METIS_FOUND (BOOL) Flag indicating if METIS was found
# METIS_INCLUDE_DIR (PATH) Path to the METIS include file
# METIS_INCLUDE_DIRS (LIST) List of all required include files
# METIS_LIBRARY_DIR (PATH) Path to the METIS library
# METIS_LIBRARY (FILE) METIS library
# METIS_LIBRARIES (LIST) List of all required METIS libraries
#
# #############################################################################
# Standard CMake modules see CMAKE_ROOT/Modules
include(FindPackageHandleStandardArgs)
if ( METIS_LIBRARIES AND METIS_INCLUDE_DIRS )
# Do nothing. Variables are set. No need to search again
else(METIS_LIBRARIES AND METIS_INCLUDE_DIRS)
# Cache variables
if(METIS_DIR)
set(METIS_DIR "${METIS_DIR}" CACHE PATH "Path to search for METIS include and library files")
endif()
if(METIS_INCLUDE_DIR)
set(METIS_INCLUDE_DIR "${METIS_INCLUDE_DIR}" CACHE PATH "Path to search for METIS include files")
endif()
if(METIS_LIBRARY_DIR)
set(METIS_LIBRARY_DIR "${METIS_LIBRARY_DIR}" CACHE PATH "Path to search for METIS library files")
endif()
# Search for include files
# Search order preference:
# (1) METIS_INCLUDE_DIR - check existence of path AND if the include files exist
# (2) METIS_DIR/<include>
# (3) Default CMake paths See cmake --html-help=out.html file for more information.
#
set(metis_inc_names "metis.h")
if (METIS_INCLUDE_DIR)
if (EXISTS "${METIS_INCLUDE_DIR}")
find_path(metis_test_include_path
NAMES ${metis_inc_names}
HINTS ${METIS_INCLUDE_DIR}
NO_DEFAULT_PATH)
if(NOT metis_test_include_path)
message("Can not locate ${metis_inc_names} in ${METIS_INCLUDE_DIR}")
endif()
set(METIS_INCLUDE_DIR "${metis_test_include_path}")
else()
message("METIS_INCLUDE_DIR=${METIS_INCLUDE_DIR} does not exist")
set(METIS_INCLUDE_DIR "METIS_INCLUDE_DIR-NOTFOUND")
endif()
else()
# Metis sometimes puts the include files in a subdir called Lib
set(metis_inc_suffixes "include" "Lib")
if(METIS_DIR)
if (EXISTS "${METIS_DIR}" )
find_path(METIS_INCLUDE_DIR
NAMES ${metis_inc_names}
HINTS ${METIS_DIR}
PATH_SUFFIXES ${metis_inc_suffixes}
NO_DEFAULT_PATH)
else()
message("METIS_DIR=${METIS_DIR} does not exist")
set(METIS_INCLUDE_DIR "METIS_INCLUDE_DIR-NOTFOUND")
endif()
else()
find_path(METIS_INCLUDE_DIR
NAMES ${metis_inc_names}
PATH_SUFFIXES ${metis_inc_suffixes})
endif()
endif()
if ( NOT METIS_INCLUDE_DIR )
message("Can not locate METIS include directory")
endif()
# Search for libraries
# Search order preference:
# (1) METIS_LIBRARY_DIR - check existence of path AND if the library file exists
# (2) METIS_DIR/<lib,Lib>
# (3) Default CMake paths See cmake --html-help=out.html file for more information.
#
set(metis_lib_names "metis")
if (METIS_LIBRARY_DIR)
if (EXISTS "${METIS_LIBRARY_DIR}")
find_library(METIS_LIBRARY
NAMES ${metis_lib_names}
HINTS ${METIS_LIBRARY_DIR}
NO_DEFAULT_PATH)
else()
message("METIS_LIBRARY_DIR=${METIS_LIBRARY_DIR} does not exist")
set(METIS_LIBRARY "METIS_LIBRARY-NOTFOUND")
endif()
else()
list(APPEND metis_lib_suffixes "lib" "Lib")
if(METIS_DIR)
if (EXISTS "${METIS_DIR}" )
find_library(METIS_LIBRARY
NAMES ${metis_lib_names}
HINTS ${METIS_DIR}
PATH_SUFFIXES ${metis_lib_suffixes}
NO_DEFAULT_PATH)
else()
message("METIS_DIR=${METIS_DIR} does not exist")
set(METISLIBRARY "METIS_LIBRARY-NOTFOUND")
endif()
else()
find_library(METIS_LIBRARY
NAMES ${metis_lib_names}
PATH_SUFFIXES ${metis_lib_suffixes})
endif()
endif()
if ( NOT METIS_LIBRARY )
message("Can not locate METIS library")
endif()
# Define prerequisite packages
set(METIS_INCLUDE_DIRS ${METIS_INCLUDE_DIR})
set(METIS_LIBRARIES ${METIS_LIBRARY})
endif(METIS_LIBRARIES AND METIS_INCLUDE_DIRS )
# Send useful message if everything is found
find_package_handle_standard_args(METIS DEFAULT_MSG
METIS_LIBRARIES
METIS_INCLUDE_DIRS)
# find_package_handle_standard_args should set METIS_FOUND but it does not!
if ( METIS_LIBRARIES AND METIS_INCLUDE_DIRS)
set(METIS_FOUND TRUE)
else()
set(METIS_FOUND FALSE)
endif()
# Define the version
mark_as_advanced(
METIS_INCLUDE_DIR
METIS_INCLUDE_DIRS
METIS_LIBRARY
METIS_LIBRARIES
METIS_LIBRARY_DIR
)