mirror of https://github.com/CGAL/cgal
Merge remote-tracking branch 'cgal/6.1.x-branch' into 'cgal/main'
This commit is contained in:
commit
f98d968ed0
|
|
@ -1563,10 +1563,10 @@ does_satisfy_link_condition(typename boost::graph_traits<Graph>::edge_descriptor
|
||||||
*
|
*
|
||||||
* After the collapse of edge `e` the following holds:
|
* After the collapse of edge `e` the following holds:
|
||||||
* - The edge `e` is no longer in `g`.
|
* - The edge `e` is no longer in `g`.
|
||||||
* - The faces incident to edge `e` are no longer in `g`.
|
* - The triangle faces incident to edge `e` are no longer in `g`.
|
||||||
* - `v0` is no longer in `g`.
|
* - `v0` is no longer in `g`.
|
||||||
* - If `h` is not a border halfedge, `p_h` is no longer in `g` and is replaced by `o_n_h`.
|
* - If `h` is part of a triangle face, `p_h` is no longer in `g` and is replaced by `o_n_h`.
|
||||||
* - If the opposite of `h` is not a border halfedge, `p_o_h` is no longer in `g` and is replaced by `o_n_o_h`.
|
* - If the opposite of `h` is part of a triangle face, `p_o_h` is no longer in `g` and is replaced by `o_n_o_h`.
|
||||||
* - The halfedges kept in `g` that had `v0` as target and source now have `v1` as target and source, respectively.
|
* - The halfedges kept in `g` that had `v0` as target and source now have `v1` as target and source, respectively.
|
||||||
* - No other incidence information is changed in `g`.
|
* - No other incidence information is changed in `g`.
|
||||||
*
|
*
|
||||||
|
|
@ -1595,9 +1595,8 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor e,
|
||||||
bool lBottomFaceExists = ! is_border(qp,g);
|
bool lBottomFaceExists = ! is_border(qp,g);
|
||||||
bool lTopLeftFaceExists = lTopFaceExists && ! is_border(pt,g);
|
bool lTopLeftFaceExists = lTopFaceExists && ! is_border(pt,g);
|
||||||
bool lBottomRightFaceExists = lBottomFaceExists && ! is_border(qb,g);
|
bool lBottomRightFaceExists = lBottomFaceExists && ! is_border(qb,g);
|
||||||
|
bool lBottomIsTriangle = lBottomFaceExists && is_triangle(qp,g);
|
||||||
CGAL_precondition( !lTopFaceExists || (lTopFaceExists && ( degree(target(pt, g), g) > 2 ) ) ) ;
|
bool lTopIsTriangle = lTopFaceExists && is_triangle(pq,g);
|
||||||
CGAL_precondition( !lBottomFaceExists || (lBottomFaceExists && ( degree(target(qb, g), g) > 2 ) ) ) ;
|
|
||||||
|
|
||||||
vertex_descriptor q = target(pq, g);
|
vertex_descriptor q = target(pq, g);
|
||||||
vertex_descriptor p = source(pq, g);
|
vertex_descriptor p = source(pq, g);
|
||||||
|
|
@ -1605,7 +1604,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor e,
|
||||||
|
|
||||||
bool lP_Erased = false;
|
bool lP_Erased = false;
|
||||||
|
|
||||||
if ( lTopFaceExists )
|
if ( lTopIsTriangle)
|
||||||
{
|
{
|
||||||
CGAL_precondition( ! is_border(opposite(pt, g),g) ) ; // p-q-t is a face of the mesh
|
CGAL_precondition( ! is_border(opposite(pt, g),g) ) ; // p-q-t is a face of the mesh
|
||||||
if ( lTopLeftFaceExists )
|
if ( lTopLeftFaceExists )
|
||||||
|
|
@ -1632,7 +1631,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor e,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( lBottomFaceExists )
|
if ( lBottomIsTriangle)
|
||||||
{
|
{
|
||||||
CGAL_precondition( ! is_border(opposite(qb, g),g) ) ; // p-q-b is a face of the mesh
|
CGAL_precondition( ! is_border(opposite(qb, g),g) ) ; // p-q-b is a face of the mesh
|
||||||
if ( lBottomRightFaceExists )
|
if ( lBottomRightFaceExists )
|
||||||
|
|
@ -1679,7 +1678,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor e,
|
||||||
* collapses an edge in a graph having non-collapsable edges.
|
* collapses an edge in a graph having non-collapsable edges.
|
||||||
*
|
*
|
||||||
* Let `h` be the halfedge of `e`, and let `v0` and `v1` be the source and target vertices of `h`.
|
* Let `h` be the halfedge of `e`, and let `v0` and `v1` be the source and target vertices of `h`.
|
||||||
* Collapses the edge `e` replacing it with `v1`, as described in the paragraph above
|
* Collapses the edge `e` replacing it with `v1`, as described in the other overload
|
||||||
* and guarantees that an edge `e2`, for which `get(edge_is_constrained_map, e2)==true`,
|
* and guarantees that an edge `e2`, for which `get(edge_is_constrained_map, e2)==true`,
|
||||||
* is not removed after the collapse.
|
* is not removed after the collapse.
|
||||||
*
|
*
|
||||||
|
|
@ -1689,14 +1688,14 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor e,
|
||||||
*
|
*
|
||||||
* \returns vertex `v1`.
|
* \returns vertex `v1`.
|
||||||
* \pre This function requires `g` to be an oriented 2-manifold with or without boundaries.
|
* \pre This function requires `g` to be an oriented 2-manifold with or without boundaries.
|
||||||
* Furthermore, the edge `v0v1` must satisfy the link condition, which guarantees that the surface mesh is also 2-manifold after the edge collapse.
|
* Furthermore, the edge `e` must satisfy the link condition, which guarantees that the surface mesh is also 2-manifold after the edge collapse.
|
||||||
* \pre `get(edge_is_constrained_map, v0v1) == false`.
|
* \pre `get(edge_is_constrained_map, e) == false`.
|
||||||
* \pre `v0` and `v1` are not both incident to a constrained edge.
|
* \pre `v0` and `v1` are not both incident to a constrained edge.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template<typename Graph, typename EdgeIsConstrainedMap>
|
template<typename Graph, typename EdgeIsConstrainedMap>
|
||||||
typename boost::graph_traits<Graph>::vertex_descriptor
|
typename boost::graph_traits<Graph>::vertex_descriptor
|
||||||
collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
|
collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor e,
|
||||||
Graph& g,
|
Graph& g,
|
||||||
EdgeIsConstrainedMap Edge_is_constrained_map)
|
EdgeIsConstrainedMap Edge_is_constrained_map)
|
||||||
{
|
{
|
||||||
|
|
@ -1704,11 +1703,11 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
|
||||||
typedef typename Traits::vertex_descriptor vertex_descriptor;
|
typedef typename Traits::vertex_descriptor vertex_descriptor;
|
||||||
typedef typename Traits::halfedge_descriptor halfedge_descriptor;
|
typedef typename Traits::halfedge_descriptor halfedge_descriptor;
|
||||||
|
|
||||||
CGAL_precondition(is_valid_edge_descriptor(v0v1, g));
|
CGAL_precondition(is_valid_edge_descriptor(e, g));
|
||||||
CGAL_precondition(does_satisfy_link_condition(v0v1,g));
|
CGAL_precondition(does_satisfy_link_condition(e,g));
|
||||||
CGAL_precondition(!get(Edge_is_constrained_map, v0v1));
|
CGAL_precondition(!get(Edge_is_constrained_map, e));
|
||||||
|
|
||||||
halfedge_descriptor pq = halfedge(v0v1,g);
|
halfedge_descriptor pq = halfedge(e,g);
|
||||||
|
|
||||||
halfedge_descriptor qp = opposite(pq,g);
|
halfedge_descriptor qp = opposite(pq,g);
|
||||||
halfedge_descriptor pt = opposite(prev(pq,g),g);
|
halfedge_descriptor pt = opposite(prev(pq,g),g);
|
||||||
|
|
@ -1718,6 +1717,8 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
|
||||||
|
|
||||||
bool lTopFaceExists = ! is_border(pq,g) ;
|
bool lTopFaceExists = ! is_border(pq,g) ;
|
||||||
bool lBottomFaceExists = ! is_border(qp,g) ;
|
bool lBottomFaceExists = ! is_border(qp,g) ;
|
||||||
|
bool lTopIsTriangle = lTopFaceExists && is_triangle(pq,g);
|
||||||
|
bool lBottomIsTriangle = lBottomFaceExists && is_triangle(qp,g);
|
||||||
|
|
||||||
vertex_descriptor q = target(pq,g);
|
vertex_descriptor q = target(pq,g);
|
||||||
vertex_descriptor p = source(pq,g);
|
vertex_descriptor p = source(pq,g);
|
||||||
|
|
@ -1728,7 +1729,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
|
||||||
|
|
||||||
// If the top facet exists, we need to choose one out of the two edges which one disappears:
|
// If the top facet exists, we need to choose one out of the two edges which one disappears:
|
||||||
// p-t if it is not constrained and t-q otherwise
|
// p-t if it is not constrained and t-q otherwise
|
||||||
if ( lTopFaceExists )
|
if ( lTopIsTriangle )
|
||||||
{
|
{
|
||||||
if ( !get(Edge_is_constrained_map,edge(pt,g)) )
|
if ( !get(Edge_is_constrained_map,edge(pt,g)) )
|
||||||
{
|
{
|
||||||
|
|
@ -1742,7 +1743,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
|
||||||
|
|
||||||
// If the bottom facet exists, we need to choose one out of the two edges which one disappears:
|
// If the bottom facet exists, we need to choose one out of the two edges which one disappears:
|
||||||
// q-b if it is not constrained and b-p otherwise
|
// q-b if it is not constrained and b-p otherwise
|
||||||
if ( lBottomFaceExists )
|
if ( lBottomIsTriangle )
|
||||||
{
|
{
|
||||||
if ( !get(Edge_is_constrained_map,edge(qb,g)) )
|
if ( !get(Edge_is_constrained_map,edge(qb,g)) )
|
||||||
{
|
{
|
||||||
|
|
@ -1753,7 +1754,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lTopFaceExists && lBottomFaceExists)
|
if (lTopIsTriangle && lBottomIsTriangle)
|
||||||
{
|
{
|
||||||
if ( face(edges_to_erase[0],g) == face(edges_to_erase[1],g)
|
if ( face(edges_to_erase[0],g) == face(edges_to_erase[1],g)
|
||||||
&& (! is_border(edges_to_erase[0],g)) )
|
&& (! is_border(edges_to_erase[0],g)) )
|
||||||
|
|
@ -1800,7 +1801,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (lTopFaceExists)
|
if (lTopIsTriangle)
|
||||||
{
|
{
|
||||||
if (!(is_border(edges_to_erase[0],g))){
|
if (!(is_border(edges_to_erase[0],g))){
|
||||||
join_face(edges_to_erase[0],g);
|
join_face(edges_to_erase[0],g);
|
||||||
|
|
@ -1815,11 +1816,15 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
|
||||||
remove_face(opposite(edges_to_erase[0],g),g);
|
remove_face(opposite(edges_to_erase[0],g),g);
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (lBottomIsTriangle)
|
||||||
|
{
|
||||||
if (! (is_border(edges_to_erase[0],g))){
|
if (! (is_border(edges_to_erase[0],g))){
|
||||||
// q will be removed, swap it with p
|
// q will be removed, swap it with p
|
||||||
internal::swap_vertices(p, q, g);
|
internal::swap_vertices(p, q, g);
|
||||||
join_face(edges_to_erase[0],g);
|
join_face(edges_to_erase[0],g);
|
||||||
|
CGAL_assertion(source(qp,g)==p);
|
||||||
join_vertex(qp,g);
|
join_vertex(qp,g);
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
|
@ -1831,6 +1836,13 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
|
||||||
remove_face(opposite(edges_to_erase[0],g),g);
|
remove_face(opposite(edges_to_erase[0],g),g);
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
join_vertex(pq,g);
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// performs an edge flip, rotating the edge pointed by
|
/// performs an edge flip, rotating the edge pointed by
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
OFF
|
||||||
|
25 13 0
|
||||||
|
|
||||||
|
0.39160239696502686 1.3864846229553223 4.8046874923102223e-08
|
||||||
|
0.053782559931278229 1.3864846229553223 4.8046874923102223e-08
|
||||||
|
-0.94644606113433838 1.6651756763458252 4.8046874923102223e-08
|
||||||
|
-1.3082554340362549 1.7385153770446777 4.8046874923102223e-08
|
||||||
|
-1.3033660650253296 1.1860226392745972 4.8046874923102223e-08
|
||||||
|
1.61628258228302 -0.17601536214351654 4.8046874923102223e-08
|
||||||
|
0.55834579467773438 -0.19216139614582062 4.8046874923102223e-08
|
||||||
|
0.053782559931278229 -0.17601536214351654 4.8046874923102223e-08
|
||||||
|
-0.24240998923778534 -0.22679123282432556 4.8046874923102223e-08
|
||||||
|
-0.58168435096740723 -0.25845989584922791 4.8046874923102223e-08
|
||||||
|
-1.2915089130401611 -0.17601536214351654 4.8046874923102223e-08
|
||||||
|
-1.50871741771698 -0.17601536214351654 4.8046874923102223e-08
|
||||||
|
1.61628258228302 -1.7385153770446777 4.8046874923102223e-08
|
||||||
|
1.1978726387023926 -1.7385153770446777 4.8046874923102223e-08
|
||||||
|
0.71942150592803955 -1.7385153770446777 4.8046874923102223e-08
|
||||||
|
0.053782559931278229 -1.7385153770446777 4.8046874923102223e-08
|
||||||
|
-0.73973840475082397 -1.7385153770446777 4.8046874923102223e-08
|
||||||
|
1.61628258228302 0.36264327168464661 4.8046874923102223e-08
|
||||||
|
-0.26156377792358398 0.45463424921035767 4.8046874923102223e-08
|
||||||
|
-0.028661971911787987 -0.78840988874435425 4.8046874923102223e-08
|
||||||
|
0.053782559931278229 -1.2213115692138672 4.8046874923102223e-08
|
||||||
|
-1.5918357372283936 1.5331641435623169 4.8046874923102223e-08
|
||||||
|
-1.6162823438644409 0.87338578701019287 4.8046874923102223e-08
|
||||||
|
-1.50871741771698 -0.0072435899637639523 4.8046874923102223e-08
|
||||||
|
-1.50871741771698 -1.3000825643539429 4.8046874923102223e-08
|
||||||
|
7 18 2 3 4 22 9 8
|
||||||
|
3 2 18 1
|
||||||
|
7 18 7 6 5 17 0 1
|
||||||
|
7 12 5 6 7 8 19 13
|
||||||
|
6 11 24 16 15 20 10
|
||||||
|
3 9 19 8
|
||||||
|
4 10 20 19 9
|
||||||
|
3 7 18 8
|
||||||
|
3 14 20 15
|
||||||
|
4 13 19 20 14
|
||||||
|
3 3 21 4
|
||||||
|
4 9 22 23 10
|
||||||
|
3 10 23 11
|
||||||
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
#include <CGAL/boost/graph/Euler_operations.h>
|
#include <CGAL/boost/graph/Euler_operations.h>
|
||||||
#include <CGAL/boost/graph/IO/OFF.h>
|
#include <CGAL/boost/graph/IO/OFF.h>
|
||||||
|
|
||||||
#include <boost/range/distance.hpp>
|
#include <boost/range/distance.hpp>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
@ -213,12 +212,30 @@ collapse_edge_test()
|
||||||
assert(found == 2);
|
assert(found == 2);
|
||||||
CGAL::clear(test_mesh);
|
CGAL::clear(test_mesh);
|
||||||
}
|
}
|
||||||
|
// Case 6 non pure triangle mesh
|
||||||
|
{
|
||||||
|
Mesh ref;
|
||||||
|
if(!CGAL::IO::read_OFF("data/polygon_mesh_to_collapse.off", ref))
|
||||||
|
{
|
||||||
|
std::cout << "Error reading file: data/polygon_mesh_to_collapse.off" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
std::size_t nbe=halfedges(ref).size();
|
||||||
|
for (std::size_t i=0; i< nbe; ++i)
|
||||||
|
{
|
||||||
|
Mesh m = ref;
|
||||||
|
auto h = *std::next(halfedges(m).begin(), i);
|
||||||
|
|
||||||
|
if (CGAL::Euler::does_satisfy_link_condition(edge(h,m),m))
|
||||||
|
CGAL::Euler::collapse_edge(edge(h,m), m);
|
||||||
|
assert(CGAL::is_valid_polygon_mesh(m));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
|
||||||
collapse_edge_test<Polyhedron>();
|
collapse_edge_test<Polyhedron>();
|
||||||
collapse_edge_test<SM>();
|
collapse_edge_test<SM>();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -117,14 +117,14 @@ Qt is a cross-platform application and UI framework.
|
||||||
The component `CGAL_Qt6` is essential to run the \cgal demos and basic viewers.
|
The component `CGAL_Qt6` is essential to run the \cgal demos and basic viewers.
|
||||||
It requires \qt6 installed on your system.
|
It requires \qt6 installed on your system.
|
||||||
In case \qt is not yet installed on your system, you can download
|
In case \qt is not yet installed on your system, you can download
|
||||||
it from <A HREF="https://www.qt-project.org/">`https://www.qt-project.org/`</A>.
|
it from <A HREF="https://contribute.qt-project.org/">`https://contribute.qt-project.org/`</A>.
|
||||||
|
|
||||||
The exhaustive list of \qt6 components used in demos is:
|
The exhaustive list of \qt6 components used in demos is:
|
||||||
`Core`, `Gui`, `Help`, `OpenGL`, `OpenGLWidgets`, `Qml`, `Svg`, `Widgets`,
|
`Core`, `Gui`, `Help`, `OpenGL`, `OpenGLWidgets`, `Qml`, `Svg`, `Widgets`,
|
||||||
`WebSockets`, `Network`, and `qcollectiongenerator` (with `sqlite` driver plugin).
|
`WebSockets`, `Network`, and `qcollectiongenerator` (with `sqlite` driver plugin).
|
||||||
|
|
||||||
\subsection thirdpartyEigen Eigen
|
\subsection thirdpartyEigen Eigen
|
||||||
<b>Version 3.3.7 or later</b>
|
<b>Version 3.3.7 or later (including Eigen3 5.0.0)</b>
|
||||||
|
|
||||||
\eigen is a `C++` template library for linear algebra. \eigen supports all
|
\eigen is a `C++` template library for linear algebra. \eigen supports all
|
||||||
matrix sizes, various matrix decomposition methods and sparse linear solvers.
|
matrix sizes, various matrix decomposition methods and sparse linear solvers.
|
||||||
|
|
@ -138,7 +138,7 @@ Overview</a> page. In order to use Eigen in \cgal programs, the
|
||||||
executables should be linked with the CMake imported target
|
executables should be linked with the CMake imported target
|
||||||
`CGAL::Eigen3_support` provided in `CGAL_Eigen3_support.cmake`.
|
`CGAL::Eigen3_support` provided in `CGAL_Eigen3_support.cmake`.
|
||||||
|
|
||||||
The \eigen web site is <A HREF="https://eigen.tuxfamily.org/index.php?title=Main_Page">`https://eigen.tuxfamily.org`</A>.
|
The \eigen web site is <A HREF="https://libeigen.gitlab.io/">`https://libeigen.gitlab.io/`</A>.
|
||||||
|
|
||||||
\subsection thirdpartyOpenGR OpenGR
|
\subsection thirdpartyOpenGR OpenGR
|
||||||
|
|
||||||
|
|
@ -167,17 +167,6 @@ Alternatively, version 1.3.1 of \libpointmatcher is supported with version 3.3.7
|
||||||
`https://github.com/ethz-asl/libpointmatcher/blob/master/doc/Compilation.md`:`NABO_INCLUDE_DIR` becomes `libnabo_INCLUDE_DIRS`
|
`https://github.com/ethz-asl/libpointmatcher/blob/master/doc/Compilation.md`:`NABO_INCLUDE_DIR` becomes `libnabo_INCLUDE_DIRS`
|
||||||
and `NABO_LIBRARY` becomes `libnabo_LIBRARIES` in the "Build libpointmatcher" section.
|
and `NABO_LIBRARY` becomes `libnabo_LIBRARIES` in the "Build libpointmatcher" section.
|
||||||
|
|
||||||
\subsection thirdpartyLeda LEDA
|
|
||||||
<b>Version 6.2 or later</b>
|
|
||||||
|
|
||||||
\leda is a library of efficient data structures and
|
|
||||||
algorithms. Like \core, \leda offers a real number data type.
|
|
||||||
|
|
||||||
In \cgal this library is optional, and its number types can
|
|
||||||
be used as an alternative to \gmp, \mpfr, and \core.
|
|
||||||
|
|
||||||
Free and commercial editions of \leda are available from <A HREF="https://www.algorithmic-solutions.com">`https://www.algorithmic-solutions.com`</A>.
|
|
||||||
|
|
||||||
\subsection thirdpartyMPFI Multiple Precision Floating-point Interval (MPFI)
|
\subsection thirdpartyMPFI Multiple Precision Floating-point Interval (MPFI)
|
||||||
<b>Version 1.4 or later</b>
|
<b>Version 1.4 or later</b>
|
||||||
|
|
||||||
|
|
@ -265,7 +254,7 @@ vcpkg install suitesparse
|
||||||
\subsection thirdpartyMETIS METIS
|
\subsection thirdpartyMETIS METIS
|
||||||
<b>Version 5.1 or later</b>
|
<b>Version 5.1 or later</b>
|
||||||
|
|
||||||
\metis is a library developed by the <A HREF="http://glaros.dtc.umn.edu/gkhome/">Karypis Lab</A>
|
\metis is a library developed by the <A HREF="https://github.com/KarypisLab/">Karypis Lab</A>
|
||||||
and designed to partition graphs and produce fill-reducing matrix orderings.
|
and designed to partition graphs and produce fill-reducing matrix orderings.
|
||||||
|
|
||||||
\cgal offers wrappers around some of the methods of the \metis library
|
\cgal offers wrappers around some of the methods of the \metis library
|
||||||
|
|
@ -274,7 +263,7 @@ to allow the partitioning of graphs that are models of the concepts of the
|
||||||
and, by extension, of surface meshes (see Section \ref BGLPartitioning of the package \ref PkgBGL).
|
and, by extension, of surface meshes (see Section \ref BGLPartitioning of the package \ref PkgBGL).
|
||||||
|
|
||||||
More information is available on the METIS library
|
More information is available on the METIS library
|
||||||
at <A HREF="http://glaros.dtc.umn.edu/gkhome/metis/metis/overview">`http://glaros.dtc.umn.edu/gkhome/metis/metis/overview`</A>.
|
at <A HREF="https://github.com/KarypisLab/METIS">`https://github.com/KarypisLab/METIS`</A>.
|
||||||
|
|
||||||
\subsection thirdpartyzlib zlib
|
\subsection thirdpartyzlib zlib
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -221,7 +221,10 @@ void
|
||||||
DemosMainWindow::popupAboutBox(QString title, QString html_resource_name)
|
DemosMainWindow::popupAboutBox(QString title, QString html_resource_name)
|
||||||
{
|
{
|
||||||
QFile about_CGAL(html_resource_name);
|
QFile about_CGAL(html_resource_name);
|
||||||
about_CGAL.open(QIODevice::ReadOnly);
|
if (!about_CGAL.open(QIODevice::ReadOnly)) {
|
||||||
|
QMessageBox::warning(this, tr("Error"), tr("Could not open resource file: %1").arg(html_resource_name));
|
||||||
|
return;
|
||||||
|
}
|
||||||
QString about_CGAL_txt = QTextStream(&about_CGAL).readAll();
|
QString about_CGAL_txt = QTextStream(&about_CGAL).readAll();
|
||||||
#ifdef CGAL_VERSION_STR
|
#ifdef CGAL_VERSION_STR
|
||||||
QString cgal_version(CGAL_VERSION_STR);
|
QString cgal_version(CGAL_VERSION_STR);
|
||||||
|
|
|
||||||
|
|
@ -23,12 +23,13 @@ int main()
|
||||||
std::vector<PointVectorPair> pv_pairs;
|
std::vector<PointVectorPair> pv_pairs;
|
||||||
const std::function<void(const PointVectorPair& p)> lambda =
|
const std::function<void(const PointVectorPair& p)> lambda =
|
||||||
[&](const PointVectorPair& p) {
|
[&](const PointVectorPair& p) {
|
||||||
FT len = p.second.squared_length();
|
const FT len = CGAL::sqrt(p.second.squared_length());
|
||||||
if (len > 0 || len != 1.0) {
|
if (len > 0) {
|
||||||
Vector_3 n = p.second * (1.0 / CGAL::sqrt(len));
|
Vector_3 n = p.second / len;
|
||||||
pv_pairs.push_back(std::make_pair(p.first, n));
|
pv_pairs.push_back(std::make_pair(p.first, n));
|
||||||
|
} else {
|
||||||
|
pv_pairs.push_back(p);
|
||||||
}
|
}
|
||||||
else pv_pairs.push_back(p);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pv_pairs.clear();
|
pv_pairs.clear();
|
||||||
|
|
|
||||||
|
|
@ -63,9 +63,6 @@ if(CGAL_Qt6_FOUND AND Qt6_FOUND)
|
||||||
include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake)
|
include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake)
|
||||||
cgal_add_compilation_test(T3_demo)
|
cgal_add_compilation_test(T3_demo)
|
||||||
|
|
||||||
include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake)
|
|
||||||
cgal_add_compilation_test(T3_demo)
|
|
||||||
|
|
||||||
else(CGAL_Qt6_FOUND AND Qt6_FOUND)
|
else(CGAL_Qt6_FOUND AND Qt6_FOUND)
|
||||||
|
|
||||||
set(TRIANGULATION_3_MISSING_DEPS "")
|
set(TRIANGULATION_3_MISSING_DEPS "")
|
||||||
|
|
|
||||||
|
|
@ -209,31 +209,3 @@ void MainWindow::on_actionClear_Scene_triggered()
|
||||||
// update viewer
|
// update viewer
|
||||||
Q_EMIT( sceneChanged() );
|
Q_EMIT( sceneChanged() );
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::popupAboutCGAL()
|
|
||||||
{
|
|
||||||
// read contents from .html file
|
|
||||||
QFile about_CGAL(":/documentation/documentation/about_CGAL.html");
|
|
||||||
about_CGAL.open(QIODevice::ReadOnly|QIODevice::Text);
|
|
||||||
QString about_CGAL_txt = QTextStream(&about_CGAL).readAll();
|
|
||||||
|
|
||||||
// popup a message box
|
|
||||||
QMessageBox mb(QMessageBox::NoIcon,
|
|
||||||
tr("About CGAL..."),
|
|
||||||
about_CGAL_txt,
|
|
||||||
QMessageBox::Ok,
|
|
||||||
this);
|
|
||||||
|
|
||||||
// set links to be accessible by mouse or keyboard
|
|
||||||
QLabel* mb_label = mb.findChild<QLabel*>("qt_msgbox_label");
|
|
||||||
if(mb_label) {
|
|
||||||
mb_label->setTextInteractionFlags(mb_label->textInteractionFlags() |
|
|
||||||
::Qt::LinksAccessibleByMouse |
|
|
||||||
::Qt::LinksAccessibleByKeyboard);
|
|
||||||
} else {
|
|
||||||
std::cerr << "Cannot find child \"qt_msgbox_label\" in QMessageBox\n"
|
|
||||||
<< " with Qt version " << QT_VERSION_STR << "!\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
mb.exec();
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -36,9 +36,6 @@ public Q_SLOTS:
|
||||||
// show menu
|
// show menu
|
||||||
void on_actionClear_Scene_triggered();
|
void on_actionClear_Scene_triggered();
|
||||||
|
|
||||||
// about menu
|
|
||||||
void popupAboutCGAL();
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void sceneChanged();
|
void sceneChanged();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,9 @@ int main(int argc, char** argv)
|
||||||
app.setOrganizationName("INRIA");
|
app.setOrganizationName("INRIA");
|
||||||
app.setApplicationName("3D Triangulation Demo");
|
app.setApplicationName("3D Triangulation Demo");
|
||||||
|
|
||||||
|
// Import resources from libCGALQt (Qt6).
|
||||||
|
CGAL_QT_INIT_RESOURCES;
|
||||||
|
|
||||||
MainWindow mw;
|
MainWindow mw;
|
||||||
mw.show();
|
mw.show();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -183,13 +183,13 @@ void Viewer::compile_shaders()
|
||||||
"} \n"
|
"} \n"
|
||||||
"\n"
|
"\n"
|
||||||
};
|
};
|
||||||
QOpenGLShader *vertex_shader = new QOpenGLShader(QOpenGLShader::Vertex);
|
QOpenGLShader *vertex_shader = new QOpenGLShader(QOpenGLShader::Vertex, this);
|
||||||
if(!vertex_shader->compileSourceCode(vertex_source))
|
if(!vertex_shader->compileSourceCode(vertex_source))
|
||||||
{
|
{
|
||||||
std::cerr<<"Compiling vertex source FAILED"<<std::endl;
|
std::cerr<<"Compiling vertex source FAILED"<<std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
QOpenGLShader *fragment_shader= new QOpenGLShader(QOpenGLShader::Fragment);
|
QOpenGLShader *fragment_shader= new QOpenGLShader(QOpenGLShader::Fragment, this);
|
||||||
if(!fragment_shader->compileSourceCode(fragment_source))
|
if(!fragment_shader->compileSourceCode(fragment_source))
|
||||||
{
|
{
|
||||||
std::cerr<<"Compiling fragmentsource FAILED"<<std::endl;
|
std::cerr<<"Compiling fragmentsource FAILED"<<std::endl;
|
||||||
|
|
@ -258,14 +258,14 @@ void Viewer::compile_shaders()
|
||||||
"} \n"
|
"} \n"
|
||||||
"\n"
|
"\n"
|
||||||
};
|
};
|
||||||
QOpenGLShader *vertex_shader_spheres = new QOpenGLShader(QOpenGLShader::Vertex);
|
QOpenGLShader *vertex_shader_spheres = new QOpenGLShader(QOpenGLShader::Vertex, this);
|
||||||
if(!vertex_shader_spheres->compileSourceCode(vertex_source_spheres))
|
if(!vertex_shader_spheres->compileSourceCode(vertex_source_spheres))
|
||||||
{
|
{
|
||||||
std::cerr<<"Compiling vertex source FAILED"<<std::endl;
|
std::cerr<<"Compiling vertex source FAILED"<<std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QOpenGLShader *fragment_shader_spheres= new QOpenGLShader(QOpenGLShader::Fragment);
|
QOpenGLShader *fragment_shader_spheres= new QOpenGLShader(QOpenGLShader::Fragment, this);
|
||||||
if(!fragment_shader_spheres->compileSourceCode(fragment_source_spheres))
|
if(!fragment_shader_spheres->compileSourceCode(fragment_source_spheres))
|
||||||
{
|
{
|
||||||
std::cerr<<"Compiling fragmentsource FAILED"<<std::endl;
|
std::cerr<<"Compiling fragmentsource FAILED"<<std::endl;
|
||||||
|
|
@ -312,7 +312,7 @@ void Viewer::compile_shaders()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
QOpenGLShader *vertex_shader_cylinders = new QOpenGLShader(QOpenGLShader::Vertex);
|
QOpenGLShader *vertex_shader_cylinders = new QOpenGLShader(QOpenGLShader::Vertex, this);
|
||||||
if(!vertex_shader_cylinders->compileSourceCode(vertex_source_cylinders))
|
if(!vertex_shader_cylinders->compileSourceCode(vertex_source_cylinders))
|
||||||
{
|
{
|
||||||
std::cerr<<"Compiling vertex source FAILED"<<std::endl;
|
std::cerr<<"Compiling vertex source FAILED"<<std::endl;
|
||||||
|
|
@ -1628,7 +1628,7 @@ void Viewer::draw()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewer::drawVertex(const Point_3& p, std::vector<float> *vertices)
|
void Viewer::drawVertex(const Point_3& p, Coords_ptr& vertices)
|
||||||
{
|
{
|
||||||
|
|
||||||
vertices->push_back(p.x()); vertices->push_back(p.y()); vertices->push_back(p.z());
|
vertices->push_back(p.x()); vertices->push_back(p.y()); vertices->push_back(p.z());
|
||||||
|
|
@ -1636,13 +1636,13 @@ void Viewer::drawVertex(const Point_3& p, std::vector<float> *vertices)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewer::drawEdge(const Point_3& from, const Point_3& to, std::vector<float> *vertices)
|
void Viewer::drawEdge(const Point_3& from, const Point_3& to, Coords_ptr& vertices)
|
||||||
{
|
{
|
||||||
vertices->push_back( from.x()); vertices->push_back(from.y()); vertices->push_back(from.z());
|
vertices->push_back( from.x()); vertices->push_back(from.y()); vertices->push_back(from.z());
|
||||||
vertices->push_back( to.x()); vertices->push_back(to.y()); vertices->push_back(to.z());
|
vertices->push_back( to.x()); vertices->push_back(to.y()); vertices->push_back(to.z());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewer::drawFacet(const Triangle_3& t, std::vector<float> *vertices)
|
void Viewer::drawFacet(const Triangle_3& t, Coords_ptr& vertices)
|
||||||
{
|
{
|
||||||
Point_3 p0 = t.vertex(0);
|
Point_3 p0 = t.vertex(0);
|
||||||
Point_3 p1 = t.vertex(1);
|
Point_3 p1 = t.vertex(1);
|
||||||
|
|
@ -2482,7 +2482,7 @@ void Viewer::incremental_insert() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Viewer::draw_cylinder(float R, int prec, std::vector<float> *vertices, std::vector<float> *normals)
|
void Viewer::draw_cylinder(float R, int prec, Coords_ptr& vertices, Coords_ptr& normals)
|
||||||
{
|
{
|
||||||
vertices->resize(0);
|
vertices->resize(0);
|
||||||
normals->resize(0);
|
normals->resize(0);
|
||||||
|
|
@ -2551,7 +2551,7 @@ void Viewer::draw_cylinder(float R, int prec, std::vector<float> *vertices, std:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewer::draw_sphere(float R, int prec, std::vector<float> *vertices, std::vector<float> *normals)
|
void Viewer::draw_sphere(float R, int prec, Coords_ptr& vertices, Coords_ptr& normals)
|
||||||
{
|
{
|
||||||
vertices->resize(0);
|
vertices->resize(0);
|
||||||
normals->resize(0);
|
normals->resize(0);
|
||||||
|
|
|
||||||
|
|
@ -42,42 +42,41 @@ public:
|
||||||
, m_hasEmptyS(false)
|
, m_hasEmptyS(false)
|
||||||
, m_showTrackball(true)
|
, m_showTrackball(true)
|
||||||
, m_pDlgPrefer(nullptr)
|
, m_pDlgPrefer(nullptr)
|
||||||
{
|
, pos_emptyFacet{new Coords}
|
||||||
pos_emptyFacet = new std::vector<float>();
|
, pos_emptySphere{new Coords}
|
||||||
pos_emptySphere= new std::vector<float>();
|
, points_emptySphere{new Coords}
|
||||||
points_emptySphere = new std::vector<float>();
|
, pos_points{new Coords}
|
||||||
pos_points = new std::vector<float>();
|
, pos_newPoint{new Coords}
|
||||||
pos_newPoint = new std::vector<float>();
|
, pos_selectedVertex{new Coords}
|
||||||
pos_selectedVertex = new std::vector<float>();
|
, pos_movingPoint{new Coords}
|
||||||
pos_movingPoint = new std::vector<float>();
|
, pos_queryPoint{new Coords}
|
||||||
pos_queryPoint = new std::vector<float>();
|
, pos_trackBall{ new Coords}
|
||||||
pos_trackBall = new std::vector<float>();
|
, pos_voronoi{new Coords}
|
||||||
pos_voronoi = new std::vector<float>();
|
, pos_delaunay{new Coords}
|
||||||
pos_delaunay = new std::vector<float>();
|
, pos_facets{new Coords}
|
||||||
pos_facets = new std::vector<float>();
|
, pos_newFacet{new Coords}
|
||||||
pos_newFacet = new std::vector<float>();
|
, pos_nearest_neighbor{new Coords}
|
||||||
pos_nearest_neighbor = new std::vector<float>();
|
, points_locationSphere{new Coords}
|
||||||
points_locationSphere = new std::vector<float>();
|
, points_cylinder{new Coords}
|
||||||
points_cylinder = new std::vector<float>();
|
, normals_cylinder{new Coords}
|
||||||
normals_cylinder = new std::vector<float>();
|
, points_sphere{new Coords}
|
||||||
points_sphere = new std::vector<float>();
|
, points_trackBall{new Coords}
|
||||||
points_trackBall = new std::vector<float>();
|
, normals_sphere{new Coords}
|
||||||
normals_sphere = new std::vector<float>();
|
, normals_emptySphere{new Coords}
|
||||||
normals_emptySphere = new std::vector<float>();
|
, normals_trackBall{new Coords}
|
||||||
normals_trackBall= new std::vector<float>();
|
, transfo1_voronoi{new Coords}
|
||||||
transfo1_voronoi = new std::vector<float>();
|
, transfo2_voronoi{new Coords}
|
||||||
transfo2_voronoi = new std::vector<float>();
|
, transfo3_voronoi{new Coords}
|
||||||
transfo3_voronoi = new std::vector<float>();
|
, transfo4_voronoi{new Coords}
|
||||||
transfo4_voronoi = new std::vector<float>();
|
, transfo1_delaunay{new Coords}
|
||||||
transfo1_delaunay = new std::vector<float>();
|
, transfo2_delaunay{new Coords}
|
||||||
transfo2_delaunay = new std::vector<float>();
|
, transfo3_delaunay{new Coords}
|
||||||
transfo3_delaunay = new std::vector<float>();
|
, transfo4_delaunay{new Coords}
|
||||||
transfo4_delaunay = new std::vector<float>();
|
, incremental_points{new Coords}
|
||||||
incremental_points = new std::vector<float>();
|
, incremental_next_point{new Coords}
|
||||||
incremental_next_point = new std::vector<float>();
|
, incremental_facet{new Coords}
|
||||||
incremental_facet = new std::vector<float>();
|
, incremental_conflict{new Coords}
|
||||||
incremental_conflict = new std::vector<float>();
|
{}
|
||||||
}
|
|
||||||
|
|
||||||
~Viewer()
|
~Viewer()
|
||||||
{
|
{
|
||||||
|
|
@ -269,12 +268,15 @@ protected:
|
||||||
QString helpString() const;
|
QString helpString() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
using Coords = std::vector<float>;
|
||||||
|
using Coords_ptr = std::unique_ptr<std::vector<float>>;
|
||||||
|
|
||||||
// draw a 3d effect vertex
|
// draw a 3d effect vertex
|
||||||
void drawVertex(const Point_3& p, std::vector<float> *vertices);
|
void drawVertex(const Point_3& p, Coords_ptr& vertices);
|
||||||
// draw a 3d effect edge
|
// draw a 3d effect edge
|
||||||
void drawEdge(const Point_3& from, const Point_3 &to, std::vector<float> *vertices);
|
void drawEdge(const Point_3& from, const Point_3 &to, Coords_ptr& vertices);
|
||||||
// draw a facet
|
// draw a facet
|
||||||
void drawFacet(const Triangle_3& t, std::vector<float> *vertices);
|
void drawFacet(const Triangle_3& t, Coords_ptr& vertices);
|
||||||
// test whether the give 3D point is on the sphere
|
// test whether the give 3D point is on the sphere
|
||||||
inline bool isOnSphere( const Point_3 & pt ) {
|
inline bool isOnSphere( const Point_3 & pt ) {
|
||||||
return ( (pt.x()*pt.x() + pt.y()*pt.y() + pt.z()*pt.z()) == (m_fRadius*m_fRadius) );
|
return ( (pt.x()*pt.x() + pt.y()*pt.y() + pt.z()*pt.z()) == (m_fRadius*m_fRadius) );
|
||||||
|
|
@ -362,42 +364,41 @@ private:
|
||||||
bool are_buffers_initialized;
|
bool are_buffers_initialized;
|
||||||
bool extension_is_found;
|
bool extension_is_found;
|
||||||
|
|
||||||
std::vector<float> *pos_emptyFacet;
|
Coords_ptr pos_emptyFacet;
|
||||||
std::vector<float> *pos_emptySphere;
|
Coords_ptr pos_emptySphere;
|
||||||
std::vector<float> *points_emptySphere;
|
Coords_ptr points_emptySphere;
|
||||||
std::vector<float> *pos_points;
|
Coords_ptr pos_points;
|
||||||
std::vector<float> *pos_newPoint;
|
Coords_ptr pos_newPoint;
|
||||||
std::vector<float> *pos_selectedVertex;
|
Coords_ptr pos_selectedVertex;
|
||||||
std::vector<float> *pos_movingPoint;
|
Coords_ptr pos_movingPoint;
|
||||||
std::vector<float> *pos_queryPoint;
|
Coords_ptr pos_queryPoint;
|
||||||
std::vector<float> *pos_trackBall;
|
Coords_ptr pos_trackBall;
|
||||||
std::vector<float> *points_trackBall;
|
Coords_ptr pos_voronoi;
|
||||||
std::vector<float> *pos_voronoi;
|
Coords_ptr pos_delaunay;
|
||||||
std::vector<float> *pos_delaunay;
|
Coords_ptr pos_facets;
|
||||||
std::vector<float> *pos_facets;
|
Coords_ptr pos_newFacet;
|
||||||
std::vector<float> *pos_newFacet;
|
Coords_ptr pos_nearest_neighbor;
|
||||||
std::vector<float> *pos_nearest_neighbor;
|
Coords_ptr points_locationSphere;
|
||||||
std::vector<float> *points_locationSphere;
|
Coords_ptr points_cylinder;
|
||||||
std::vector<float> *points_cylinder;
|
Coords_ptr normals_cylinder;
|
||||||
std::vector<float> *normals_cylinder;
|
Coords_ptr points_sphere;
|
||||||
std::vector<float> *points_sphere;
|
Coords_ptr points_trackBall;
|
||||||
std::vector<float> *normals_sphere;
|
Coords_ptr normals_sphere;
|
||||||
std::vector<float> *normals_emptySphere;
|
Coords_ptr normals_emptySphere;
|
||||||
std::vector<float> *normals_trackBall;
|
Coords_ptr normals_trackBall;
|
||||||
std::vector<float> *transfo1_voronoi;
|
Coords_ptr transfo1_voronoi;
|
||||||
std::vector<float> *transfo2_voronoi;
|
Coords_ptr transfo2_voronoi;
|
||||||
std::vector<float> *transfo3_voronoi;
|
Coords_ptr transfo3_voronoi;
|
||||||
std::vector<float> *transfo4_voronoi;
|
Coords_ptr transfo4_voronoi;
|
||||||
std::vector<float> *transfo1_delaunay;
|
Coords_ptr transfo1_delaunay;
|
||||||
std::vector<float> *transfo2_delaunay;
|
Coords_ptr transfo2_delaunay;
|
||||||
std::vector<float> *transfo3_delaunay;
|
Coords_ptr transfo3_delaunay;
|
||||||
std::vector<float> *transfo4_delaunay;
|
Coords_ptr transfo4_delaunay;
|
||||||
std::vector<float> *incremental_points;
|
Coords_ptr incremental_points;
|
||||||
std::vector<float> *incremental_next_point;
|
Coords_ptr incremental_next_point;
|
||||||
std::vector<float> *incremental_facet;
|
Coords_ptr incremental_facet;
|
||||||
std::vector<float> *incremental_conflict;
|
Coords_ptr incremental_conflict;
|
||||||
|
//pickin
|
||||||
//picking
|
|
||||||
QMap<float, int> picked_IDs;
|
QMap<float, int> picked_IDs;
|
||||||
QPoint picking_pos;
|
QPoint picking_pos;
|
||||||
|
|
||||||
|
|
@ -414,8 +415,8 @@ private:
|
||||||
void compute_elements();
|
void compute_elements();
|
||||||
void attrib_buffers(CGAL::QGLViewer*);
|
void attrib_buffers(CGAL::QGLViewer*);
|
||||||
void compile_shaders();
|
void compile_shaders();
|
||||||
void draw_cylinder(float R, int prec, std::vector<float> *vertices, std::vector<float> *normals);
|
void draw_cylinder(float R, int prec, Coords_ptr& vertices, Coords_ptr& normals);
|
||||||
void draw_sphere(float R, int prec, std::vector<float> *vertices, std::vector<float> *normals);
|
void draw_sphere(float R, int prec, Coords_ptr& vertices, Coords_ptr& normals);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue