mirror of https://github.com/CGAL/cgal
Merge remote-tracking branch 'upstream/master' into gsoc2022
This commit is contained in:
commit
2778d878ce
|
|
@ -56,7 +56,7 @@ jobs:
|
|||
set -x
|
||||
sudo apt-get update && sudo apt-get install -y graphviz ssh bibtex2html
|
||||
sudo pip install lxml
|
||||
sudo pip install 'pyquery==1.4.1' # it seems to be the last py2 compatible version
|
||||
sudo pip install pyquery
|
||||
wget --no-verbose -O doxygen_exe https://cgal.geometryfactory.com/~cgaltest/doxygen_1_8_13_patched/doxygen
|
||||
sudo mv doxygen_exe /usr/bin/doxygen
|
||||
sudo chmod +x /usr/bin/doxygen
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ jobs:
|
|||
set -x
|
||||
git config --global user.email "cgal@geometryfactory.com"
|
||||
git config --global user.name "cgaltest"
|
||||
git clone https://maxGimeno:${{ secrets.PUSH_TO_CGAL_GITHUB_IO_TOKEN }}@github.com/CGAL/cgal.github.io.git --depth=5
|
||||
git clone https://CGAL:${{ secrets.PUSH_TO_CGAL_GITHUB_IO_TOKEN }}@github.com/CGAL/cgal.github.io.git
|
||||
PR_NUMBER=$(python -c "import json; import os; y = json.load(open(os.environ['GITHUB_EVENT_PATH'])); print(y[\"number\"])")
|
||||
cd cgal.github.io/
|
||||
egrep -v " ${PR_NUMBER}\." index.html > tmp.html || true
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ public:
|
|||
operator()(const Ray_3& r, const Primitive& primitive)`.
|
||||
|
||||
A common algorithm to compute the intersection between a bounding box and a ray is <A
|
||||
HREF="http://www.siggraph.org/education/materials/HyperGraph/raytrace/rtinter3.htm">the
|
||||
HREF="https://education.siggraph.org/static/HyperGraph/raytrace/rtinter3.htm">the
|
||||
slab method</A>.
|
||||
*/
|
||||
typedef unspecified_type Intersection_distance;
|
||||
|
|
|
|||
|
|
@ -289,7 +289,7 @@ ArrangementPainterOstream<CGAL::Arr_linear_traits_2<Kernel_>>::operator<<(
|
|||
QRectF seg_bb = this->convert(seg.bbox());
|
||||
if (
|
||||
this->clippingRect.isValid() &&
|
||||
!this->clippingRect.intersects(seg_bb) &
|
||||
!this->clippingRect.intersects(seg_bb) &&
|
||||
(!seg.is_horizontal() && !seg.is_vertical()))
|
||||
{ return *this; }
|
||||
|
||||
|
|
|
|||
|
|
@ -631,7 +631,6 @@ namespace CartesianKernelFunctors {
|
|||
typedef typename K::Point_2 Point_2;
|
||||
typedef typename K::Line_2 Line_2;
|
||||
typedef typename K::Equal_2 Equal_2;
|
||||
typedef typename K::Less_signed_distance_to_line_2 Less_signed_distance_to_line_2;
|
||||
|
||||
public:
|
||||
typedef typename K::Comparison_result result_type;
|
||||
|
|
@ -642,6 +641,7 @@ namespace CartesianKernelFunctors {
|
|||
{
|
||||
CGAL_kernel_precondition_code(Equal_2 equal;)
|
||||
CGAL_kernel_precondition(! equal(a,b));
|
||||
|
||||
return cmp_signed_dist_to_lineC2( a.x(), a.y(),
|
||||
b.x(), b.y(),
|
||||
c.x(), c.y(),
|
||||
|
|
@ -651,10 +651,9 @@ namespace CartesianKernelFunctors {
|
|||
result_type
|
||||
operator()(const Line_2& l, const Point_2& p, const Point_2& q) const
|
||||
{
|
||||
Less_signed_distance_to_line_2 less = K().less_signed_distance_to_line_2_object();
|
||||
if (less(l, p, q)) return SMALLER;
|
||||
if (less(l, q, p)) return LARGER;
|
||||
return EQUAL;
|
||||
return cmp_signed_dist_to_directionC2(l.a(), l.b(),
|
||||
p.x(), p.y(),
|
||||
q.x(), q.y());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ The resulting sequence is placed starting at position
|
|||
`result`, and the past-the-end iterator for the resulting
|
||||
sequence is returned. It is not specified at which point the
|
||||
cyclic sequence of extreme points is cut into a linear sequence.
|
||||
|
||||
\pre The source range [`first`,`beyond`) does not contain `result`.
|
||||
The default traits class `Default_traits` is the kernel in which the
|
||||
value type of `ForwardIterator` is defined.
|
||||
|
|
@ -36,6 +37,8 @@ functions that return instances of these types:
|
|||
\sa `CGAL::ch_graham_andrew()`
|
||||
\sa `CGAL::ch_jarvis()`
|
||||
\sa `CGAL::ch_melkman()`
|
||||
\sa `CGAL::lower_hull_points_2()`
|
||||
\sa `CGAL::upper_hull_points_2()`
|
||||
\sa `CGAL::convex_hull_2()`
|
||||
|
||||
\cgalHeading{Implementation}
|
||||
|
|
@ -49,7 +52,7 @@ points.
|
|||
template <class ForwardIterator, class OutputIterator, class Traits>
|
||||
OutputIterator
|
||||
ch_akl_toussaint(ForwardIterator first, ForwardIterator beyond,
|
||||
OutputIterator result,
|
||||
const Traits& ch_traits = Default_traits());
|
||||
OutputIterator result,
|
||||
const Traits& ch_traits = Default_traits());
|
||||
|
||||
} /* namespace CGAL */
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ The resulting sequence is placed starting at position
|
|||
`result`, and the past-the-end iterator for the resulting
|
||||
sequence is returned. It is not specified at which point the
|
||||
cyclic sequence of extreme points is cut into a linear sequence.
|
||||
|
||||
\pre The source range [`first`,`beyond`) does not contain `result`.
|
||||
|
||||
The default traits class `Default_traits` is the kernel in which the
|
||||
|
|
@ -24,7 +25,7 @@ the concept `ConvexHullTraits_2` and their corresponding member
|
|||
functions that return instances of these types:
|
||||
<UL>
|
||||
<LI>`Traits::Point_2`,
|
||||
<LI>`Traits::Less_signed_distance_to_line_2`,
|
||||
<LI>`Traits::Compare_signed_distance_to_line_2`,
|
||||
<LI>`Traits::Left_turn_2`,
|
||||
<LI>`Traits::Less_xy_2`,
|
||||
<LI>`Traits::Equal_2`.
|
||||
|
|
@ -36,6 +37,8 @@ functions that return instances of these types:
|
|||
\sa `CGAL::ch_graham_andrew()`
|
||||
\sa `CGAL::ch_jarvis()`
|
||||
\sa `CGAL::ch_melkman()`
|
||||
\sa `CGAL::lower_hull_points_2()`
|
||||
\sa `CGAL::upper_hull_points_2()`
|
||||
\sa `CGAL::convex_hull_2()`
|
||||
|
||||
\cgalHeading{Implementation}
|
||||
|
|
@ -44,14 +47,11 @@ This function implements the non-recursive variation of
|
|||
Eddy's algorithm \cgalCite{e-nchap-77} described in \cgalCite{b-chfsp-78}.
|
||||
This algorithm requires \f$ O(n h)\f$ time
|
||||
in the worst case for \f$ n\f$ input points with \f$ h\f$ extreme points.
|
||||
|
||||
|
||||
*/
|
||||
template <class InputIterator, class OutputIterator, class Traits>
|
||||
OutputIterator
|
||||
ch_bykat( InputIterator first,
|
||||
InputIterator beyond,
|
||||
OutputIterator result,
|
||||
const Traits & ch_traits = Default_traits);
|
||||
ch_bykat(InputIterator first, InputIterator beyond,
|
||||
OutputIterator result,
|
||||
const Traits & ch_traits = Default_traits);
|
||||
|
||||
} /* namespace CGAL */
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ The resulting sequence is placed starting at position
|
|||
`result`, and the past-the-end iterator for the resulting
|
||||
sequence is returned. It is not specified at which point the
|
||||
cyclic sequence of extreme points is cut into a linear sequence.
|
||||
|
||||
\pre The source range [`first`,`beyond`) does not contain `result`.
|
||||
|
||||
The default traits class `Default_traits` is the kernel in which the
|
||||
|
|
@ -25,7 +26,7 @@ functions that return instances of these types:
|
|||
<UL>
|
||||
<LI>`Traits::Point_2`,
|
||||
<LI>`Traits::Equal_2`,
|
||||
<LI>`Traits::Less_signed_distance_to_line_2`,
|
||||
<LI>`Traits::Compare_signed_distance_to_line_2`,
|
||||
<LI>`Traits::Left_turn_2`,
|
||||
<LI>`Traits::Less_xy_2`.
|
||||
</UL>
|
||||
|
|
@ -36,6 +37,8 @@ functions that return instances of these types:
|
|||
\sa `CGAL::ch_graham_andrew()`
|
||||
\sa `CGAL::ch_jarvis()`
|
||||
\sa `CGAL::ch_melkman()`
|
||||
\sa `CGAL::lower_hull_points_2()`
|
||||
\sa `CGAL::upper_hull_points_2()`
|
||||
\sa `CGAL::convex_hull_2()`
|
||||
|
||||
\cgalHeading{Implementation}
|
||||
|
|
@ -50,9 +53,8 @@ in the worst case for \f$ n\f$ input points with \f$ h\f$ extreme points.
|
|||
*/
|
||||
template <class InputIterator, class OutputIterator, class Traits>
|
||||
OutputIterator
|
||||
ch_eddy( InputIterator first,
|
||||
InputIterator beyond,
|
||||
OutputIterator result,
|
||||
const Traits & ch_traits = Default_traits);
|
||||
ch_eddy(InputIterator first, InputIterator beyond,
|
||||
OutputIterator result,
|
||||
const Traits& ch_traits = Default_traits);
|
||||
|
||||
} /* namespace CGAL */
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ The resulting sequence is placed starting at position
|
|||
`result`, and the past-the-end iterator for the resulting
|
||||
sequence is returned. It is not specified at which point the
|
||||
cyclic sequence of extreme points is cut into a linear sequence.
|
||||
\pre The source range [`first`,`beyond`) does not contain `result`.
|
||||
|
||||
\pre The source range [`first`,`beyond`) does not contain `result`.
|
||||
|
||||
The default traits class `Default_traits` is the kernel in which the
|
||||
value type of `InputIteratore` is defined.
|
||||
|
|
@ -34,7 +34,6 @@ functions that return instances of these types:
|
|||
\sa `CGAL::ch_akl_toussaint()`
|
||||
\sa `CGAL::ch_bykat()`
|
||||
\sa `CGAL::ch_eddy()`
|
||||
\sa `CGAL::ch_graham_andrew_scan()`
|
||||
\sa `CGAL::ch_jarvis()`
|
||||
\sa `CGAL::ch_melkman()`
|
||||
\sa `CGAL::convex_hull_2()`
|
||||
|
|
@ -52,10 +51,9 @@ in the worst case for \f$ n\f$ input points.
|
|||
*/
|
||||
template <class InputIterator, class OutputIterator, class Traits>
|
||||
OutputIterator
|
||||
ch_graham_andrew( InputIterator first,
|
||||
InputIterator beyond,
|
||||
OutputIterator result,
|
||||
const Traits & ch_traits = Default_traits);
|
||||
ch_graham_andrew(InputIterator first, InputIterator beyond,
|
||||
OutputIterator result,
|
||||
const Traits& ch_traits = Default_traits);
|
||||
|
||||
} /* namespace CGAL */
|
||||
|
||||
|
|
@ -125,8 +123,8 @@ template <class BidirectionalIterator, class OutputIterator,
|
|||
class Traits>
|
||||
OutputIterator
|
||||
ch_graham_andrew_scan( BidirectionalIterator first,
|
||||
BidirectionalIterator beyond,
|
||||
OutputIterator result,
|
||||
const Traits& ch_traits = Default_traits);
|
||||
BidirectionalIterator beyond,
|
||||
OutputIterator result,
|
||||
const Traits& ch_traits = Default_traits);
|
||||
|
||||
} /* namespace CGAL */
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ The resulting sequence is placed starting at position
|
|||
`result`, and the past-the-end iterator for the resulting
|
||||
sequence is returned. It is not specified at which point the
|
||||
cyclic sequence of extreme points is cut into a linear sequence.
|
||||
|
||||
\pre The source range [`first`,`beyond`) does not contain `result`.
|
||||
|
||||
The default traits class `Default_traits` is the kernel in which the
|
||||
|
|
@ -36,6 +37,8 @@ functions that return instances of these types:
|
|||
\sa `CGAL::ch_graham_andrew()`
|
||||
\sa `CGAL::ch_jarvis_march()`
|
||||
\sa `CGAL::ch_melkman()`
|
||||
\sa `CGAL::lower_hull_points_2()`
|
||||
\sa `CGAL::upper_hull_points_2()`
|
||||
\sa `CGAL::convex_hull_2()`
|
||||
|
||||
\cgalHeading{Implementation}
|
||||
|
|
@ -44,14 +47,12 @@ This function uses the Jarvis march (gift-wrapping)
|
|||
algorithm \cgalCite{j-ichfs-73}. This algorithm requires \f$ O(n h)\f$ time
|
||||
in the worst case for \f$ n\f$ input points with \f$ h\f$ extreme points.
|
||||
|
||||
|
||||
*/
|
||||
template <class ForwardIterator, class OutputIterator, class Traits>
|
||||
OutputIterator
|
||||
ch_jarvis( ForwardIterator first,
|
||||
ForwardIterator beyond,
|
||||
OutputIterator result,
|
||||
const Traits & ch_traits = Default_traits);
|
||||
ch_jarvis(ForwardIterator first, ForwardIterator beyond,
|
||||
OutputIterator result,
|
||||
const Traits& ch_traits = Default_traits);
|
||||
|
||||
} /* namespace CGAL */
|
||||
|
||||
|
|
@ -106,9 +107,9 @@ is an element of range [`first`,`beyond`).
|
|||
template <class ForwardIterator, class OutputIterator, class Traits>
|
||||
OutputIterator
|
||||
ch_jarvis_march(ForwardIterator first, ForwardIterator beyond,
|
||||
const Traits::Point_2& start_p,
|
||||
const Traits::Point_2& stop_p,
|
||||
OutputIterator result,
|
||||
const Traits& ch_traits = Default_traits);
|
||||
const Traits::Point_2& start_p,
|
||||
const Traits::Point_2& stop_p,
|
||||
OutputIterator result,
|
||||
const Traits& ch_traits = Default_traits);
|
||||
|
||||
} /* namespace CGAL */
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ of the points in the range [`first`, `beyond`).
|
|||
The resulting sequence is placed starting at
|
||||
position `result`, and the past-the-end iterator for
|
||||
the resulting sequence is returned.
|
||||
|
||||
\pre The source range [`first`,`beyond`) corresponds to a simple polyline. [`first`,`beyond`) does not contain `result`.
|
||||
|
||||
The default traits class `Default_traits` is the kernel in which the
|
||||
|
|
@ -35,6 +36,8 @@ functions that return instances of these types:
|
|||
\sa `CGAL::ch_graham_andrew()`
|
||||
\sa `CGAL::ch_jarvis()`
|
||||
\sa `CGAL::ch_melkman()`
|
||||
\sa `CGAL::lower_hull_points_2()`
|
||||
\sa `CGAL::upper_hull_points_2()`
|
||||
\sa `CGAL::convex_hull_2()`
|
||||
|
||||
\cgalHeading{Implementation}
|
||||
|
|
@ -42,12 +45,11 @@ functions that return instances of these types:
|
|||
It uses an implementation of Melkman's algorithm \cgalCite{m-olcch-87}.
|
||||
Running time of this is linear.
|
||||
|
||||
|
||||
*/
|
||||
template <class InputIterator, class OutputIterator>
|
||||
OutputIterator
|
||||
ch_melkman( InputIterator first, InputIterator last,
|
||||
OutputIterator result,
|
||||
const Traits& ch_traits = Default_traits);
|
||||
ch_melkman(InputIterator first, InputIterator beyond,
|
||||
OutputIterator result,
|
||||
const Traits& ch_traits = Default_traits);
|
||||
|
||||
} /* namespace CGAL */
|
||||
|
|
|
|||
|
|
@ -13,10 +13,9 @@ The resulting sequence is placed starting at position
|
|||
`result`, and the past-the-end iterator for the resulting
|
||||
sequence is returned. It is not specified at which point the
|
||||
cyclic sequence of extreme points is cut into a linear sequence.
|
||||
|
||||
\pre The source range [`first`,`beyond`) does not contain `result`.
|
||||
|
||||
|
||||
|
||||
\cgalHeading{Requirements}
|
||||
|
||||
<OL>
|
||||
|
|
@ -27,7 +26,7 @@ the concept `ConvexHullTraits_2` and their corresponding member
|
|||
functions that return instances of these types:
|
||||
<UL>
|
||||
<LI>`Traits::Point_2`,
|
||||
<LI>`Traits::Less_signed_distance_to_line_2`,
|
||||
<LI>`Traits::Compare_signed_distance_to_line_2`,
|
||||
<LI>`Traits::Equal_2`,
|
||||
<LI>`Traits::Less_xy_2`,
|
||||
<LI>`Traits::Less_yx_2`,
|
||||
|
|
@ -136,8 +135,8 @@ of \f$ O(n \log n)\f$ for \f$ n\f$ input points.
|
|||
template <class InputIterator, class OutputIterator>
|
||||
OutputIterator
|
||||
lower_hull_points_2(InputIterator first, InputIterator beyond,
|
||||
OutputIterator result,
|
||||
const Traits & ch_traits = Default_traits );
|
||||
OutputIterator result,
|
||||
const Traits& ch_traits = Default_traits );
|
||||
|
||||
} /* namespace CGAL */
|
||||
|
||||
|
|
@ -195,12 +194,10 @@ This function uses Andrew's
|
|||
variant of Graham's scan algorithm \cgalCite{a-aeach-79}, \cgalCite{m-mdscg-84}. The algorithm
|
||||
has worst-case running time of \f$ O(n \log n)\f$ for \f$ n\f$ input points.
|
||||
|
||||
|
||||
*/
|
||||
template <class InputIterator, class OutputIterator>
|
||||
OutputIterator
|
||||
upper_hull_points_2(InputIterator first, InputIterator beyond,
|
||||
OutputIterator result,
|
||||
const Traits & ch_traits = Default_traits );
|
||||
|
||||
OutputIterator result,
|
||||
const Traits& ch_traits = Default_traits);
|
||||
} /* namespace CGAL */
|
||||
|
|
|
|||
|
|
@ -43,10 +43,10 @@ typedef R::Less_xy_2 Less_xy_2;
|
|||
typedef R::Less_yx_2 Less_yx_2;
|
||||
|
||||
/*!
|
||||
|
||||
This internal functor builds and cache the line on the first call to its `operator()`.
|
||||
*/
|
||||
typedef CGAL::r_Less_dist_to_line<R>
|
||||
Less_signed_distance_to_line_2;
|
||||
typedef unspecified_type
|
||||
Compare_signed_distance_to_line_2;
|
||||
|
||||
/*!
|
||||
|
||||
|
|
@ -91,8 +91,8 @@ Less_yx_2 less_yx_2_object();
|
|||
/*!
|
||||
|
||||
*/
|
||||
Less_signed_distance_to_line_2
|
||||
less_signed_distance_to_line_2_object();
|
||||
Compare_signed_distance_to_line_2
|
||||
compare_signed_distance_to_line_2_object();
|
||||
|
||||
/*!
|
||||
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ typedef R::Less_yx Less_yx_2;
|
|||
/*!
|
||||
|
||||
*/
|
||||
typedef R::Less_signed_distance_to_line_2
|
||||
Less_signed_distance_to_line_2;
|
||||
typedef R::Compare_signed_distance_to_line_2
|
||||
Compare_signed_distance_to_line_2;
|
||||
|
||||
/*!
|
||||
|
||||
|
|
@ -92,8 +92,8 @@ Less_yx_2 less_yx_2_object();
|
|||
/*!
|
||||
|
||||
*/
|
||||
Less_signed_distance_to_line_2
|
||||
less_signed_distance_to_line_2_object();
|
||||
Compare_signed_distance_to_line_2
|
||||
compare_signed_distance_to_line_2_object();
|
||||
|
||||
/*!
|
||||
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@ is specified with each function.
|
|||
\cgalHasModel `CGAL::Projection_traits_yz_3<K>`
|
||||
\cgalHasModel `CGAL::Projection_traits_xz_3<K>`
|
||||
|
||||
\sa `IsStronglyConvexTraits_3`
|
||||
|
||||
*/
|
||||
|
||||
class ConvexHullTraits_2 {
|
||||
|
|
@ -66,18 +64,12 @@ typedef unspecified_type Left_turn_2;
|
|||
|
||||
/*!
|
||||
Predicate object type that must provide
|
||||
`bool operator()(Point_2 p, Point_2 q,
|
||||
Point_2 r,Point_2 s)`, which returns `true` iff
|
||||
the signed distance from \f$ r\f$ to the line \f$ l_{pq}\f$ through \f$ p\f$ and \f$ q\f$
|
||||
is smaller than the distance from \f$ s\f$ to \f$ l_{pq}\f$. It is used to
|
||||
compute the point right of a line with maximum unsigned distance to
|
||||
the line. The predicate must provide a total order compatible
|
||||
with convexity, <I>i.e.</I>, for any line segment \f$ s\f$ one of the
|
||||
endpoints
|
||||
of \f$ s\f$ is the smallest point among the points on \f$ s\f$, with respect to
|
||||
the order given by `Less_signed_distance_to_line_2`.
|
||||
`bool operator()(Point_2 p, Point_2 q, Point_2 r,Point_2 s)`,
|
||||
which compares the signed distance of \f$ r\f$ and \f$ s\f$ to the directed line \f$ l_{pq}\f$
|
||||
through \f$ p\f$ and \f$ q\f$.
|
||||
It is used to compute the point right of a line with maximum unsigned distance to the line.
|
||||
*/
|
||||
typedef unspecified_type Less_signed_distance_to_line_2;
|
||||
typedef unspecified_type Compare_signed_distance_to_line_2;
|
||||
|
||||
/*!
|
||||
Predicate object type that must provide
|
||||
|
|
@ -135,7 +127,7 @@ Less_yx_2 less_yx_2_object();
|
|||
/*!
|
||||
|
||||
*/
|
||||
Less_signed_distance_to_line_2 less_signed_distance_to_line_2_object();
|
||||
Compare_signed_distance_to_line_2 compare_signed_distance_to_line_2_object();
|
||||
|
||||
/*!
|
||||
|
||||
|
|
|
|||
|
|
@ -3,4 +3,5 @@ Kernel_23
|
|||
STL_Extension
|
||||
Algebraic_foundations
|
||||
Circulator
|
||||
Convex_hull_3
|
||||
Stream_support
|
||||
|
|
|
|||
|
|
@ -12,8 +12,6 @@ OutputIterator
|
|||
ch_graham_anderson( InputIterator first, InputIterator beyond,
|
||||
OutputIterator result, const Traits& ch_traits)
|
||||
{
|
||||
using namespace boost;
|
||||
|
||||
typedef typename Traits::Point_2 Point_2;
|
||||
typedef typename Traits::Less_xy_2 Less_xy_2;
|
||||
typedef typename Traits::Less_rotate_ccw_2 Less_rotate_ccw_2;
|
||||
|
|
|
|||
|
|
@ -220,8 +220,6 @@ ch_akl_toussaint(ForwardIterator first, ForwardIterator last,
|
|||
OutputIterator result,
|
||||
const Traits& ch_traits)
|
||||
{
|
||||
using namespace boost;
|
||||
|
||||
typedef typename Traits::Point_2 Point_2;
|
||||
typedef typename Traits::Left_turn_2 Left_of_line;
|
||||
// added
|
||||
|
|
|
|||
|
|
@ -34,15 +34,16 @@ ch_bykat(InputIterator first, InputIterator last,
|
|||
OutputIterator result,
|
||||
const Traits& ch_traits)
|
||||
{
|
||||
using namespace boost;
|
||||
|
||||
typedef typename Traits::Point_2 Point_2;
|
||||
typedef typename Traits::Left_turn_2 Left_turn_2;
|
||||
typedef typename Traits::Less_signed_distance_to_line_2 Less_dist;
|
||||
typedef typename Traits::Equal_2 Equal_2;
|
||||
|
||||
Left_turn_2 left_turn = ch_traits.left_turn_2_object();
|
||||
typedef typename Traits::Compare_signed_distance_to_line_2 Compare_dist_2;
|
||||
typedef typename Traits::Equal_2 Equal_2;
|
||||
typedef typename Traits::Left_turn_2 Left_turn_2;
|
||||
typedef typename Traits::Less_xy_2 Less_xy_2;
|
||||
|
||||
Equal_2 equal_points = ch_traits.equal_2_object();
|
||||
Left_turn_2 left_turn = ch_traits.left_turn_2_object();
|
||||
Less_xy_2 less_xy = ch_traits.less_xy_2_object();
|
||||
|
||||
if (first == last) return result;
|
||||
|
||||
|
|
@ -80,11 +81,23 @@ ch_bykat(InputIterator first, InputIterator last,
|
|||
for (;;)
|
||||
{
|
||||
// This functor must be in the for loop so that the Convex_hull_constructive traits_2 works correctly
|
||||
Less_dist less_dist = ch_traits.less_signed_distance_to_line_2_object();
|
||||
Compare_dist_2 cmp_dist = ch_traits.compare_signed_distance_to_line_2_object();
|
||||
|
||||
if ( l != r)
|
||||
{
|
||||
Point_2 c = *std::min_element( l, r, [&less_dist,&a,&b](const Point_2&p1, const Point_2& p2)
|
||||
{ return less_dist(a, b, p1, p2); });
|
||||
// We need the farthest point, but since we are on the right side of the line,
|
||||
// signed distances are negative. Hence std::min_element.
|
||||
auto less_dist = [&a, &b, &cmp_dist, &less_xy](const Point_2&p1, const Point_2& p2) -> bool
|
||||
{
|
||||
CGAL::Comparison_result res = cmp_dist(a, b, p1, p2);
|
||||
if(res == CGAL::EQUAL)
|
||||
return less_xy(p1, p2);
|
||||
|
||||
return (res == CGAL::SMALLER);
|
||||
};
|
||||
|
||||
Point_2 c = *std::min_element( l, r, less_dist);
|
||||
|
||||
H.push_back( b );
|
||||
L.push_back( l );
|
||||
R.push_back( l = std::partition(l, r, [&left_turn,&c,&b](const Point_2&p)
|
||||
|
|
@ -126,17 +139,18 @@ ch_bykat_with_threshold(InputIterator first, InputIterator last,
|
|||
OutputIterator result,
|
||||
const Traits& ch_traits)
|
||||
{
|
||||
using namespace boost;
|
||||
|
||||
typedef typename Traits::Point_2 Point_2;
|
||||
typedef typename Traits::Left_turn_2 Left_turn_2;
|
||||
typedef typename Traits::Less_signed_distance_to_line_2
|
||||
Less_dist;
|
||||
typedef typename std::vector< Point_2 >::iterator
|
||||
PointIterator;
|
||||
|
||||
typedef typename Traits::Compare_signed_distance_to_line_2 Compare_dist_2;
|
||||
typedef typename Traits::Equal_2 Equal_2;
|
||||
typedef typename Traits::Left_turn_2 Left_turn_2;
|
||||
typedef typename Traits::Less_xy_2 Less_xy_2;
|
||||
|
||||
typedef typename std::vector< Point_2 >::iterator PointIterator;
|
||||
|
||||
Equal_2 equal_points = ch_traits.equal_2_object();
|
||||
Left_turn_2 left_turn = ch_traits.left_turn_2_object();
|
||||
Less_xy_2 less_xy = ch_traits.less_xy_2_object();
|
||||
|
||||
if (first == last) return result;
|
||||
|
||||
|
|
@ -172,21 +186,33 @@ ch_bykat_with_threshold(InputIterator first, InputIterator last,
|
|||
#endif // no postconditions ...
|
||||
H.push_back( a );
|
||||
L.push_back( Pbegin );
|
||||
Left_turn_2 left_turn = ch_traits.left_turn_2_object();
|
||||
R.push_back( l = std::partition( Pbegin, Pend, [&left_turn,&a,&b](const Point_2&p)
|
||||
{ return left_turn(a, b, p); }));
|
||||
r = std::partition( l, Pend, [&left_turn,&a,&b](const Point_2&p)
|
||||
{ return left_turn(b, a, p); });
|
||||
|
||||
Less_dist less_dist = ch_traits.less_signed_distance_to_line_2_object();
|
||||
for (;;)
|
||||
{
|
||||
// This functor must be in the for loop so that the Convex_hull_constructive traits_2 works correctly
|
||||
Compare_dist_2 cmp_dist = ch_traits.compare_signed_distance_to_line_2_object();
|
||||
|
||||
if ( l != r)
|
||||
{
|
||||
if ( r-l > CGAL_ch_THRESHOLD )
|
||||
{
|
||||
Point_2 c = *std::min_element( l, r, [&less_dist,&a,&b](const Point_2&p1, const Point_2& p2)
|
||||
{ return less_dist(a, b, p1, p2); });
|
||||
// We need the farthest point, but since we are on the right side of the line,
|
||||
// signed distances are negative. Hence std::min_element.
|
||||
auto less_dist = [&a, &b, &cmp_dist, &less_xy](const Point_2&p1, const Point_2& p2) -> bool
|
||||
{
|
||||
CGAL::Comparison_result res = cmp_dist(a, b, p1, p2);
|
||||
if(res == CGAL::EQUAL)
|
||||
return less_xy(p1, p2);
|
||||
|
||||
return (res == CGAL::SMALLER);
|
||||
};
|
||||
|
||||
Point_2 c = *std::min_element( l, r, less_dist);
|
||||
|
||||
H.push_back( b );
|
||||
L.push_back( l );
|
||||
R.push_back( l = std::partition(l, r, [&left_turn,&c,&b](const Point_2&p)
|
||||
|
|
@ -199,15 +225,14 @@ ch_bykat_with_threshold(InputIterator first, InputIterator last,
|
|||
{
|
||||
std::swap( a, *--l);
|
||||
std::swap( b, *++r);
|
||||
if ( ch_traits.less_xy_2_object()(*l,*r) )
|
||||
if ( less_xy(*l,*r) )
|
||||
{
|
||||
std::sort(std::next(l), r,
|
||||
ch_traits.less_xy_2_object() );
|
||||
std::sort(std::next(l), r, less_xy);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::sort(std::next(l), r, [&ch_traits](const Point_2&p1, const Point_2& p2)
|
||||
{ return ch_traits.less_xy_2_object()(p2, p1); });
|
||||
std::sort(std::next(l), r, [&less_xy](const Point_2&p1, const Point_2& p2)
|
||||
{ return less_xy(p2, p1); });
|
||||
}
|
||||
ch__ref_graham_andrew_scan(l, std::next(r), res, ch_traits);
|
||||
std::swap( a, *l);
|
||||
|
|
|
|||
|
|
@ -34,13 +34,15 @@ ch__recursive_eddy(List& L,
|
|||
ListIterator a_it, ListIterator b_it,
|
||||
const Traits& ch_traits)
|
||||
{
|
||||
using namespace boost;
|
||||
|
||||
typedef typename Traits::Point_2 Point_2;
|
||||
typedef typename Traits::Left_turn_2 Left_turn_2;
|
||||
typedef typename Traits::Less_signed_distance_to_line_2 Less_dist;
|
||||
|
||||
typedef typename Traits::Compare_signed_distance_to_line_2 Compare_dist_2;
|
||||
typedef typename Traits::Less_xy_2 Less_xy_2;
|
||||
typedef typename Traits::Left_turn_2 Left_turn_2;
|
||||
|
||||
Compare_dist_2 cmp_dist = ch_traits.compare_signed_distance_to_line_2_object();
|
||||
Left_turn_2 left_turn = ch_traits.left_turn_2_object();
|
||||
Less_xy_2 less_xy = ch_traits.less_xy_2_object();
|
||||
|
||||
CGAL_ch_precondition( \
|
||||
std::find_if(a_it, b_it, \
|
||||
|
|
@ -48,13 +50,23 @@ ch__recursive_eddy(List& L,
|
|||
{ return left_turn(*b_it, *a_it, p); }) \
|
||||
!= b_it );
|
||||
|
||||
const Point_2& a = *a_it;
|
||||
const Point_2& b = *b_it;
|
||||
|
||||
ListIterator f_it = std::next(a_it);
|
||||
Less_dist less_dist = ch_traits.less_signed_distance_to_line_2_object();
|
||||
ListIterator
|
||||
c_it = std::min_element( f_it, b_it, // max before
|
||||
[&less_dist, a_it, b_it](const Point_2& p1, const Point_2& p2)
|
||||
{ return less_dist(*a_it, *b_it, p1, p2); });
|
||||
|
||||
// We need the farthest point, but since we are on the right side of the line,
|
||||
// signed distances are negative. Hence std::min_element.
|
||||
auto less_dist = [&a, &b, &cmp_dist, &less_xy](const Point_2&p1, const Point_2& p2) -> bool
|
||||
{
|
||||
CGAL::Comparison_result res = cmp_dist(a, b, p1, p2);
|
||||
if(res == CGAL::EQUAL)
|
||||
return less_xy(p1, p2);
|
||||
|
||||
return (res == CGAL::SMALLER);
|
||||
};
|
||||
|
||||
ListIterator c_it = std::min_element( f_it, b_it, less_dist);
|
||||
Point_2 c = *c_it;
|
||||
|
||||
c_it = std::partition(f_it, b_it, [&left_turn, &c, a_it](const Point_2& p)
|
||||
|
|
@ -80,8 +92,6 @@ ch_eddy(InputIterator first, InputIterator last,
|
|||
OutputIterator result,
|
||||
const Traits& ch_traits)
|
||||
{
|
||||
using namespace boost;
|
||||
|
||||
typedef typename Traits::Point_2 Point_2;
|
||||
typedef typename Traits::Left_turn_2 Left_turn_2;
|
||||
typedef typename Traits::Equal_2 Equal_2;
|
||||
|
|
|
|||
|
|
@ -36,8 +36,6 @@ ch_jarvis_march(ForwardIterator first, ForwardIterator last,
|
|||
OutputIterator result,
|
||||
const Traits& ch_traits)
|
||||
{
|
||||
using namespace boost;
|
||||
|
||||
if (first == last) return result;
|
||||
typedef typename Traits::Less_rotate_ccw_2 Less_rotate_ccw;
|
||||
typedef typename Traits::Equal_2 Equal_2;
|
||||
|
|
|
|||
|
|
@ -15,14 +15,14 @@
|
|||
|
||||
#include <CGAL/license/Convex_hull_2.h>
|
||||
|
||||
|
||||
#ifndef CGAL_CH_NO_POSTCONDITIONS
|
||||
#include <CGAL/convexity_check_2.h>
|
||||
#endif // CGAL_CH_NO_POSTCONDITIONS
|
||||
|
||||
#include <CGAL/Convex_hull_2/ch_assertions.h>
|
||||
#include <queue>
|
||||
#include <iterator>
|
||||
|
||||
#include <algorithm>
|
||||
#include <deque>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
|
|
|
|||
|
|
@ -181,8 +181,6 @@ ch_brute_force_chain_check_2(ForwardIterator1 first1,
|
|||
ForwardIterator2 last2,
|
||||
const Traits& ch_traits )
|
||||
{
|
||||
using namespace boost;
|
||||
|
||||
typedef typename Traits::Left_turn_2 Left_turn_2;
|
||||
|
||||
ForwardIterator1 iter11;
|
||||
|
|
|
|||
|
|
@ -1,173 +0,0 @@
|
|||
// Copyright (c) 2001 Max-Planck-Institute Saarbruecken (Germany).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org).
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
// Author(s) : Susan Hert
|
||||
|
||||
#ifndef CGAL_CONVEX_HULL_PROJECTIVE_XY_TRAITS_2_H
|
||||
#define CGAL_CONVEX_HULL_PROJECTIVE_XY_TRAITS_2_H
|
||||
|
||||
#include <CGAL/license/Convex_hull_2.h>
|
||||
|
||||
|
||||
|
||||
#define CGAL_DEPRECATED_HEADER "<CGAL/Convex_hull_projective_xy_traits_2.h>"
|
||||
#define CGAL_REPLACEMENT_HEADER "<CGAL/Projection_traits_xy_3.h>"
|
||||
#include <CGAL/Installation/internal/deprecation_warning.h>
|
||||
|
||||
#include <CGAL/predicates/kernel_ftC2.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template <class Point_3>
|
||||
class Less_xy_plane_xy_2
|
||||
{
|
||||
public:
|
||||
typedef bool result_type;
|
||||
|
||||
bool
|
||||
operator()(const Point_3& p, const Point_3& q) const
|
||||
{
|
||||
return
|
||||
compare_lexicographically_xyC2(p.x(), p.y(), q.x(), q.y()) == SMALLER;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Point_3>
|
||||
class Equal_xy_plane_xy_2
|
||||
{
|
||||
public:
|
||||
typedef bool result_type;
|
||||
|
||||
bool
|
||||
operator()(const Point_3& p, const Point_3& q) const
|
||||
{
|
||||
return
|
||||
compare_lexicographically_xyC2(p.x(), p.y(), q.x(), q.y()) == EQUAL;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Point_3>
|
||||
class Less_yx_plane_xy_2
|
||||
{
|
||||
public:
|
||||
typedef bool result_type;
|
||||
|
||||
bool
|
||||
operator()(const Point_3& p, const Point_3& q) const
|
||||
{
|
||||
return
|
||||
compare_lexicographically_xyC2(p.y(), p.x(), q.y(), q.x()) == SMALLER;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Point_3>
|
||||
class Left_turn_plane_xy_2
|
||||
{
|
||||
public:
|
||||
typedef bool result_type;
|
||||
|
||||
bool
|
||||
operator()(const Point_3& p, const Point_3& q, const Point_3& r) const
|
||||
{
|
||||
return orientationC2(p.x(), p.y(), q.x(), q.y(), r.x(), r.y()) ==
|
||||
LEFT_TURN;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Point_3>
|
||||
class Less_dist_to_line_plane_xy_2
|
||||
{
|
||||
public:
|
||||
typedef bool result_type;
|
||||
|
||||
bool
|
||||
operator()(const Point_3& p, const Point_3& q,
|
||||
const Point_3& r, const Point_3& s) const
|
||||
{
|
||||
Comparison_result
|
||||
res = cmp_signed_dist_to_lineC2(p.x(), p.y(), q.x(), q.y(),
|
||||
r.x(), r.y(), s.x(), s.y());
|
||||
if ( res == LARGER )
|
||||
return false;
|
||||
else if ( res == SMALLER )
|
||||
return true;
|
||||
else
|
||||
return compare_lexicographically_xyC2(r.x(), r.y(), s.x(), s.y())
|
||||
== SMALLER;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Point_3>
|
||||
class Less_rotate_ccw_plane_xy_2
|
||||
{
|
||||
public:
|
||||
typedef bool result_type;
|
||||
|
||||
bool
|
||||
operator()(const Point_3& r, const Point_3& p, const Point_3& q) const
|
||||
{
|
||||
Orientation orient =
|
||||
orientationC2(r.x(), r.y(), p.x(), p.y(), q.x(), q.y());
|
||||
if ( orient == LEFT_TURN )
|
||||
return true;
|
||||
else if ( orient == RIGHT_TURN )
|
||||
return false;
|
||||
else
|
||||
{
|
||||
if (p.x() == r.x() && p.y() == r.y()) return false;
|
||||
if (q.x() == r.x() && q.y() == r.y()) return true;
|
||||
if (p.x() == q.x() && p.y() == q.y()) return false;
|
||||
return
|
||||
collinear_are_ordered_along_lineC2(r.x(), r.y(),
|
||||
q.x(), q.y(), p.x(), p.y());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <class Point_3>
|
||||
class Convex_hull_projective_xy_traits_2
|
||||
{
|
||||
public:
|
||||
typedef Point_3 Point_2;
|
||||
typedef Less_xy_plane_xy_2<Point_3> Less_xy_2;
|
||||
typedef Equal_xy_plane_xy_2<Point_3> Equal_2;
|
||||
typedef Less_yx_plane_xy_2<Point_3> Less_yx_2;
|
||||
typedef Left_turn_plane_xy_2<Point_3> Left_turn_2;
|
||||
typedef Less_rotate_ccw_plane_xy_2<Point_3> Less_rotate_ccw_2;
|
||||
typedef Less_dist_to_line_plane_xy_2<Point_3>
|
||||
Less_signed_distance_to_line_2;
|
||||
Less_xy_2
|
||||
less_xy_2_object() const
|
||||
{ return Less_xy_2(); }
|
||||
|
||||
Equal_2
|
||||
equal_2_object() const
|
||||
{ return Equal_2(); }
|
||||
|
||||
Less_yx_2
|
||||
less_yx_2_object() const
|
||||
{ return Less_yx_2(); }
|
||||
|
||||
Left_turn_2
|
||||
left_turn_2_object() const
|
||||
{ return Left_turn_2(); }
|
||||
|
||||
Less_rotate_ccw_2
|
||||
less_rotate_ccw_2_object() const
|
||||
{ return Less_rotate_ccw_2(); }
|
||||
|
||||
Less_signed_distance_to_line_2
|
||||
less_signed_distance_to_line_2_object() const
|
||||
{ return Less_signed_distance_to_line_2(); }
|
||||
};
|
||||
|
||||
}
|
||||
#endif // CGAL_CONVEX_HULL_PROJECTIVE_XY_TRAITS_2_H
|
||||
|
|
@ -1,181 +0,0 @@
|
|||
// Copyright (c) 2001 Max-Planck-Institute Saarbruecken (Germany).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org).
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
// Author(s) : Susan Hert
|
||||
|
||||
#ifndef CGAL_CONVEX_HULL_PROJECTIVE_XZ_TRAITS_2_H
|
||||
#define CGAL_CONVEX_HULL_PROJECTIVE_XZ_TRAITS_2_H
|
||||
|
||||
#include <CGAL/license/Convex_hull_2.h>
|
||||
|
||||
|
||||
#define CGAL_DEPRECATED_HEADER "<CGAL/Convex_hull_projective_xz_traits_2.h>"
|
||||
#define CGAL_REPLACEMENT_HEADER "<CGAL/Projection_traits_xz_3.h>"
|
||||
#include <CGAL/Installation/internal/deprecation_warning.h>
|
||||
|
||||
#include <CGAL/predicates/kernel_ftC2.h>
|
||||
#include <CGAL/predicates_on_points_2.h>
|
||||
#include <CGAL/function_objects.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template <class Point_3>
|
||||
class Less_xy_plane_xz_2
|
||||
{
|
||||
public:
|
||||
typedef bool result_type;
|
||||
|
||||
bool
|
||||
operator()(const Point_3& p, const Point_3& q) const
|
||||
{
|
||||
return
|
||||
compare_lexicographically_xyC2(p.x(), p.z(), q.x(), q.z()) == SMALLER;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Point_3>
|
||||
class Equal_xy_plane_xz_2
|
||||
{
|
||||
public:
|
||||
typedef bool result_type;
|
||||
|
||||
bool
|
||||
operator()(const Point_3& p, const Point_3& q) const
|
||||
{
|
||||
return
|
||||
compare_lexicographically_xyC2(p.x(), p.z(), q.x(), q.z()) == EQUAL;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Point_3>
|
||||
class Less_yx_plane_xz_2
|
||||
{
|
||||
public:
|
||||
typedef bool result_type;
|
||||
|
||||
bool
|
||||
operator()(const Point_3& p, const Point_3& q) const
|
||||
{
|
||||
return
|
||||
compare_lexicographically_xyC2(p.z(), p.x(), q.z(), q.x()) == SMALLER;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Point_3>
|
||||
class Left_turn_plane_xz_2
|
||||
{
|
||||
public:
|
||||
typedef bool result_type;
|
||||
|
||||
bool
|
||||
operator()(const Point_3& p, const Point_3& q, const Point_3& r) const
|
||||
{
|
||||
return orientationC2(p.x(), p.z(), q.x(), q.z(), r.x(), r.z())
|
||||
== LEFT_TURN;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <class Point_3>
|
||||
class Less_dist_to_line_plane_xz_2
|
||||
{
|
||||
public:
|
||||
typedef bool result_type;
|
||||
|
||||
bool
|
||||
operator()(const Point_3& p, const Point_3& q,
|
||||
const Point_3& r, const Point_3& s) const
|
||||
{
|
||||
Comparison_result
|
||||
res = cmp_signed_dist_to_lineC2(p.x(), p.z(), q.x(), q.z(),
|
||||
r.x(), r.z(), s.x(), s.z());
|
||||
if ( res == LARGER )
|
||||
return false;
|
||||
else if ( res == SMALLER )
|
||||
return true;
|
||||
else
|
||||
return compare_lexicographically_xyC2(r.x(), r.z(), s.x(), s.z())
|
||||
== SMALLER;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <class Point_3>
|
||||
class Less_rotate_ccw_plane_xz_2
|
||||
{
|
||||
public:
|
||||
|
||||
typedef bool result_type;
|
||||
|
||||
bool
|
||||
operator()(const Point_3& r, const Point_3& p, const Point_3& q) const
|
||||
{
|
||||
Orientation orient =
|
||||
orientationC2(r.x(), r.z(), p.x(), p.z(), q.x(), q.z());
|
||||
if ( orient == LEFT_TURN )
|
||||
return true;
|
||||
else if ( orient == RIGHT_TURN )
|
||||
return false;
|
||||
else
|
||||
{
|
||||
if (p.x() == r.x() && p.z() == r.z()) return false;
|
||||
if (q.x() == r.x() && q.z() == r.z()) return true;
|
||||
if (p.x() == q.x() && p.z() == q.z()) return false;
|
||||
return
|
||||
collinear_are_ordered_along_lineC2(r.x(), r.z(),
|
||||
q.x(), q.z(), p.x(), p.z());
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <class Point_3>
|
||||
class Convex_hull_projective_xz_traits_2
|
||||
{
|
||||
public:
|
||||
typedef Point_3 Point_2;
|
||||
typedef Less_xy_plane_xz_2<Point_3> Less_xy_2;
|
||||
typedef Equal_xy_plane_xz_2<Point_3> Equal_2;
|
||||
typedef Less_yx_plane_xz_2<Point_3> Less_yx_2;
|
||||
typedef Left_turn_plane_xz_2<Point_3> Left_turn_2;
|
||||
typedef Less_rotate_ccw_plane_xz_2<Point_3> Less_rotate_ccw_2;
|
||||
typedef Less_dist_to_line_plane_xz_2<Point_3>
|
||||
Less_signed_distance_to_line_2;
|
||||
Less_xy_2
|
||||
less_xy_2_object() const
|
||||
{ return Less_xy_2(); }
|
||||
|
||||
Equal_2
|
||||
equal_2_object() const
|
||||
{ return Equal_2(); }
|
||||
|
||||
Less_yx_2
|
||||
less_yx_2_object() const
|
||||
{ return Less_yx_2(); }
|
||||
|
||||
Left_turn_2
|
||||
left_turn_2_object() const
|
||||
{ return Left_turn_2(); }
|
||||
|
||||
Less_rotate_ccw_2
|
||||
less_rotate_ccw_2_object() const
|
||||
{ return Less_rotate_ccw_2(); }
|
||||
|
||||
Less_signed_distance_to_line_2
|
||||
less_signed_distance_to_line_2_object() const
|
||||
{ return Less_signed_distance_to_line_2(); }
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // CGAL_CONVEX_HULL_PROJECTIVE_XZ_TRAITS_2_H
|
||||
|
|
@ -1,194 +0,0 @@
|
|||
// Copyright (c) 2001 Max-Planck-Institute Saarbruecken (Germany).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org).
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
// Author(s) : Susan Hert
|
||||
|
||||
#ifndef CGAL_CONVEX_HULL_PROJECTIVE_YZ_TRAITS_2_H
|
||||
#define CGAL_CONVEX_HULL_PROJECTIVE_YZ_TRAITS_2_H
|
||||
|
||||
#include <CGAL/license/Convex_hull_2.h>
|
||||
|
||||
|
||||
#define CGAL_DEPRECATED_HEADER "<CGAL/Convex_hull_projective_yz_traits_2.h>"
|
||||
#define CGAL_REPLACEMENT_HEADER "<CGAL/Projection_traits_yz_3.h>"
|
||||
#include <CGAL/Installation/internal/deprecation_warning.h>
|
||||
|
||||
#include <CGAL/predicates/kernel_ftC2.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template <class Point_3>
|
||||
class Less_xy_plane_yz_2
|
||||
{
|
||||
public:
|
||||
typedef bool result_type;
|
||||
|
||||
bool
|
||||
operator()(const Point_3& p, const Point_3& q) const
|
||||
{
|
||||
return
|
||||
compare_lexicographically_xyC2(p.y(), p.z(), q.y(), q.z()) == SMALLER;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Point_3>
|
||||
class Equal_xy_plane_yz_2
|
||||
{
|
||||
public:
|
||||
typedef bool result_type;
|
||||
|
||||
bool
|
||||
operator()(const Point_3& p, const Point_3& q) const
|
||||
{
|
||||
return
|
||||
compare_lexicographically_xyC2(p.y(), p.z(), q.y(), q.z()) == EQUAL;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Point_3>
|
||||
class Less_yx_plane_yz_2
|
||||
{
|
||||
public:
|
||||
typedef bool result_type;
|
||||
|
||||
bool
|
||||
operator()(const Point_3& p, const Point_3& q) const
|
||||
{
|
||||
return
|
||||
compare_lexicographically_xyC2(p.z(), p.y(), q.z(), q.y()) == SMALLER;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Point_3>
|
||||
class Left_turn_plane_yz_2
|
||||
{
|
||||
public:
|
||||
typedef bool result_type;
|
||||
|
||||
bool
|
||||
operator()(const Point_3& p, const Point_3& q, const Point_3& r) const
|
||||
{
|
||||
return orientationC2(p.y(), p.z(), q.y(), q.z(), r.y(), r.z())
|
||||
== LEFT_TURN;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Point_3>
|
||||
class Left_of_line_plane_yz_2
|
||||
{
|
||||
public:
|
||||
Left_of_line_plane_yz_2(const Point_3& a, const Point_3& b):
|
||||
p_a(a), p_b(b)
|
||||
{ }
|
||||
|
||||
bool
|
||||
operator()(const Point_3& c) const
|
||||
{
|
||||
return orientationC2(p_a.y(), p_a.z(), p_b.y(), p_b.z(), c.y(), c.z()) ==
|
||||
LEFT_TURN;
|
||||
}
|
||||
private:
|
||||
Point_3 p_a;
|
||||
Point_3 p_b;
|
||||
};
|
||||
|
||||
template <class Point_3>
|
||||
class Less_dist_to_line_plane_yz_2
|
||||
{
|
||||
public:
|
||||
typedef bool result_type;
|
||||
|
||||
bool
|
||||
operator()(const Point_3& p, const Point_3& q,
|
||||
const Point_3& r, const Point_3& s) const
|
||||
{
|
||||
Comparison_result
|
||||
res = cmp_signed_dist_to_lineC2(p.y(), p.z(), q.y(), q.z(),
|
||||
r.y(), r.z(), s.y(), s.z());
|
||||
if ( res == LARGER )
|
||||
return false;
|
||||
else if ( res == SMALLER )
|
||||
return true;
|
||||
else
|
||||
return compare_lexicographically_xyC2(r.y(), r.z(), s.y(), s.z())
|
||||
== SMALLER;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Point_3>
|
||||
class Less_rotate_ccw_plane_yz_2
|
||||
{
|
||||
public:
|
||||
typedef bool result_type;
|
||||
|
||||
bool
|
||||
operator()(const Point_3& r, const Point_3& p, const Point_3& q) const
|
||||
{
|
||||
Orientation orient =
|
||||
orientationC2(r.y(), r.z(), p.y(), p.z(), q.y(), q.z());
|
||||
if ( orient == LEFT_TURN )
|
||||
return true;
|
||||
else if ( orient == RIGHT_TURN )
|
||||
return false;
|
||||
else
|
||||
{
|
||||
if (p.y() == r.y() && p.z() == r.z()) return false;
|
||||
if (q.y() == r.y() && q.z() == r.z()) return true;
|
||||
if (p.y() == q.y() && p.z() == q.z()) return false;
|
||||
return
|
||||
collinear_are_ordered_along_lineC2(r.y(), r.z(),
|
||||
q.y(), q.z(), p.y(), p.z());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <class Point_3>
|
||||
class Convex_hull_projective_yz_traits_2
|
||||
{
|
||||
public:
|
||||
typedef Point_3 Point_2;
|
||||
typedef Less_xy_plane_yz_2<Point_3> Less_xy_2;
|
||||
typedef Equal_xy_plane_yz_2<Point_3> Equal_2;
|
||||
typedef Less_yx_plane_yz_2<Point_3> Less_yx_2;
|
||||
typedef Left_turn_plane_yz_2<Point_3> Left_turn_2;
|
||||
typedef Less_dist_to_line_plane_yz_2<Point_3>
|
||||
Less_signed_distance_to_line_2;
|
||||
typedef Less_rotate_ccw_plane_yz_2<Point_3> Less_rotate_ccw_plane_2;
|
||||
|
||||
Less_xy_2
|
||||
less_xy_2_object() const
|
||||
{ return Less_xy_2(); }
|
||||
|
||||
Equal_2
|
||||
equal_2_object() const
|
||||
{ return Equal_2(); }
|
||||
|
||||
Less_yx_2
|
||||
less_yx_2_object() const
|
||||
{ return Less_yx_2(); }
|
||||
|
||||
Left_turn_2
|
||||
left_turn_2_object() const
|
||||
{ return Left_turn_2(); }
|
||||
|
||||
Less_signed_distance_to_line_2
|
||||
less_signed_distance_to_line_2_object() const
|
||||
{ return Less_signed_distance_to_line_2(); }
|
||||
|
||||
Less_rotate_ccw_plane_2
|
||||
less_rotate_ccw_plane_2_object() const
|
||||
{ return Less_rotate_ccw_plane_2(); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // CGAL_CONVEX_HULL_PROJECTIVE_YZ_TRAITS_2_H
|
||||
|
|
@ -13,16 +13,12 @@
|
|||
#ifndef CGAL_CONVEX_HULL_TRAITS_ADAPTER_2_H
|
||||
#define CGAL_CONVEX_HULL_TRAITS_ADAPTER_2_H
|
||||
|
||||
#include <CGAL/disable_warnings.h>
|
||||
|
||||
#include <boost/call_traits.hpp>
|
||||
|
||||
#include <CGAL/property_map.h>
|
||||
|
||||
|
||||
namespace CGAL{
|
||||
|
||||
|
||||
template<class Base_traits,class PointPropertyMap>
|
||||
class Convex_hull_traits_adapter_2:public Base_traits{
|
||||
PointPropertyMap ppmap_;
|
||||
|
|
@ -90,12 +86,12 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
struct Less_signed_distance_to_line_2 : public Base_traits::Less_signed_distance_to_line_2{
|
||||
Less_signed_distance_to_line_2(const PointPropertyMap& ppmap,const typename Base_traits::Less_signed_distance_to_line_2& base):
|
||||
Base_traits::Less_signed_distance_to_line_2(base),ppmap_(ppmap){}
|
||||
struct Compare_signed_distance_to_line_2 : public Base_traits::Compare_signed_distance_to_line_2{
|
||||
Compare_signed_distance_to_line_2(const PointPropertyMap& ppmap,const typename Base_traits::Compare_signed_distance_to_line_2& base):
|
||||
Base_traits::Compare_signed_distance_to_line_2(base),ppmap_(ppmap){}
|
||||
const PointPropertyMap& ppmap_;
|
||||
bool operator()(Arg_type p,Arg_type q, Arg_type r, Arg_type s) const {
|
||||
return static_cast<const typename Base_traits::Less_signed_distance_to_line_2*>(this)->operator()(get(ppmap_,p),get(ppmap_,q),get(ppmap_,r),get(ppmap_,s));
|
||||
return static_cast<const typename Base_traits::Compare_signed_distance_to_line_2*>(this)->operator()(get(ppmap_,p),get(ppmap_,q),get(ppmap_,r),get(ppmap_,s));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -103,7 +99,7 @@ public:
|
|||
Left_turn_2 left_turn_2_object () const {return Left_turn_2(ppmap_,static_cast<const Gt*>(this)->left_turn_2_object() );}
|
||||
Orientation_2 orientation_2_object () const {return Orientation_2(ppmap_,static_cast<const Gt*>(this)->orientation_2_object() );}
|
||||
Less_rotate_ccw_2 less_rotate_ccw_2_object () const {return Less_rotate_ccw_2(ppmap_,static_cast<const Gt*>(this)->less_rotate_ccw_2_object() );}
|
||||
Less_signed_distance_to_line_2 less_signed_distance_to_line_2_object () const {return Less_signed_distance_to_line_2(ppmap_,static_cast<const Gt*>(this)->less_signed_distance_to_line_2_object() );}
|
||||
Compare_signed_distance_to_line_2 compare_signed_distance_to_line_2_object () const {return Compare_signed_distance_to_line_2(ppmap_,static_cast<const Gt*>(this)->compare_signed_distance_to_line_2_object() );}
|
||||
Less_xy_2 less_xy_2_object () const {return Less_xy_2(ppmap_,static_cast<const Gt*>(this)->less_xy_2_object() );}
|
||||
Less_yx_2 less_yx_2_object () const {return Less_yx_2(ppmap_,static_cast<const Gt*>(this)->less_yx_2_object() );}
|
||||
|
||||
|
|
@ -113,6 +109,4 @@ public:
|
|||
|
||||
} //namespace CGAL
|
||||
|
||||
#include <CGAL/enable_warnings.h>
|
||||
|
||||
#endif //CGAL_CONVEX_HULL_TRAITS_ADAPTER_2_H
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
namespace CGAL {
|
||||
|
||||
// same as |convex_hull_2(first,last,result)|. {\sc traits}:
|
||||
// uses |Traits::Point_2|, |Traits::Less_signed_distance_to_line_2|,
|
||||
// uses |Traits::Point_2|, |Traits::Compare_signed_distance_to_line_2|,
|
||||
// |Traits::Left_turn_2|,, |Traits::Equal_2| and |Traits::Less_xy_2|.
|
||||
template <class InputIterator, class OutputIterator, class Traits>
|
||||
OutputIterator
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
namespace CGAL {
|
||||
|
||||
// same as |convex_hull_2(first,last,result)|. {\sc traits}: uses
|
||||
// |Traits::Point_2|, |Traits::Less_signed_distance_to_line_2|,
|
||||
// |Traits::Point_2|, |Traits::Compare_signed_distance_to_line_2|,
|
||||
// |Traits::Left_turn_2|, |Traits::Equal_2| and |Traits::Less_xy_2|.
|
||||
template <class InputIterator, class OutputIterator, class Traits>
|
||||
OutputIterator
|
||||
|
|
|
|||
|
|
@ -1,69 +0,0 @@
|
|||
// Copyright (c) 2002 Max-Planck-Institute Saarbruecken (Germany).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org).
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
// Author(s) : Susan Hert
|
||||
|
||||
#ifndef CGAL_CH_FUNCTION_OBJECTS_2_H
|
||||
#define CGAL_CH_FUNCTION_OBJECTS_2_H
|
||||
|
||||
#include <CGAL/license/Convex_hull_2.h>
|
||||
|
||||
|
||||
#include <CGAL/enum.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
namespace internal {
|
||||
|
||||
template <class R>
|
||||
class r_Less_dist_to_line
|
||||
{
|
||||
public:
|
||||
typedef bool result_type;
|
||||
|
||||
typedef typename R::Point_2 Point;
|
||||
typedef typename R::Line_2 Line;
|
||||
|
||||
r_Less_dist_to_line() : line_constructed( false )
|
||||
{ }
|
||||
|
||||
bool operator()(const Point& a, const Point& b,
|
||||
const Point& c, const Point& d) const
|
||||
{
|
||||
if (!line_constructed)
|
||||
{
|
||||
line_constructed = true;
|
||||
l_ab = Line(a,b);
|
||||
}
|
||||
Comparison_result res = compare_signed_distance_to_line(l_ab, c, d);
|
||||
if ( res == SMALLER )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if ( res == EQUAL )
|
||||
{
|
||||
return lexicographically_xy_smaller( c, d );
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
mutable bool line_constructed;
|
||||
mutable Line l_ab;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#endif // CGAL_CH_FUNCTION_OBJECTS_2_H
|
||||
|
|
@ -19,19 +19,62 @@
|
|||
|
||||
#include <CGAL/license/Convex_hull_2.h>
|
||||
|
||||
|
||||
#include <CGAL/ch_function_objects_2.h>
|
||||
#include <CGAL/enum.h>
|
||||
|
||||
namespace CGAL {
|
||||
namespace Convex_hulls_2 {
|
||||
namespace internal {
|
||||
|
||||
template <class R>
|
||||
class Compare_signed_distance_to_cached_line_2
|
||||
: public R::Compare_signed_distance_to_line_2
|
||||
{
|
||||
typedef typename R::Compare_signed_distance_to_line_2 Base;
|
||||
|
||||
public:
|
||||
typedef CGAL::Comparison_result result_type;
|
||||
|
||||
typedef typename R::Point_2 Point;
|
||||
typedef typename R::Line_2 Line;
|
||||
|
||||
Compare_signed_distance_to_cached_line_2(const Base& base_f)
|
||||
: Base(base_f),
|
||||
line_constructed(false)
|
||||
{ }
|
||||
|
||||
using Base::operator();
|
||||
|
||||
result_type operator()(const Point& a, const Point& b,
|
||||
const Point& c, const Point& d) const
|
||||
{
|
||||
if(!line_constructed)
|
||||
{
|
||||
line_constructed = true;
|
||||
l_ab = Line(a,b);
|
||||
}
|
||||
|
||||
return operator()(l_ab, c, d);
|
||||
}
|
||||
|
||||
private:
|
||||
mutable bool line_constructed;
|
||||
mutable Line l_ab;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace Convex_hulls_2
|
||||
|
||||
template <class K_>
|
||||
class Convex_hull_constructive_traits_2 : public K_
|
||||
class Convex_hull_constructive_traits_2
|
||||
: public K_
|
||||
{
|
||||
public:
|
||||
typedef K_ K;
|
||||
typedef typename K::Point_2 Point_2;
|
||||
typedef typename K::Less_xy_2 Less_xy_2;
|
||||
typedef typename K::Less_yx_2 Less_yx_2;
|
||||
typedef internal::r_Less_dist_to_line<K> Less_signed_distance_to_line_2;
|
||||
typedef Convex_hulls_2::internal::Compare_signed_distance_to_cached_line_2<K>
|
||||
Compare_signed_distance_to_line_2;
|
||||
typedef typename K::Less_rotate_ccw_2 Less_rotate_ccw_2;
|
||||
typedef typename K::Left_turn_2 Left_turn_2;
|
||||
typedef typename K::Equal_2 Equal_2;
|
||||
|
|
@ -45,9 +88,12 @@ public:
|
|||
less_yx_2_object() const
|
||||
{ return Less_yx_2(); }
|
||||
|
||||
Less_signed_distance_to_line_2
|
||||
less_signed_distance_to_line_2_object() const
|
||||
{ return Less_signed_distance_to_line_2(); }
|
||||
Compare_signed_distance_to_line_2
|
||||
compare_signed_distance_to_line_2_object() const
|
||||
{
|
||||
return Compare_signed_distance_to_line_2(
|
||||
this->K_::compare_signed_distance_to_line_2_object());
|
||||
}
|
||||
|
||||
Less_rotate_ccw_2
|
||||
less_rotate_ccw_2_object() const
|
||||
|
|
@ -62,15 +108,12 @@ public:
|
|||
{ return Equal_2(); }
|
||||
};
|
||||
|
||||
|
||||
// for backward compatability
|
||||
|
||||
template <class K>
|
||||
class convex_hull_constructive_traits_2 :
|
||||
public Convex_hull_constructive_traits_2<K>
|
||||
{
|
||||
};
|
||||
class convex_hull_constructive_traits_2
|
||||
: public Convex_hull_constructive_traits_2<K>
|
||||
{ };
|
||||
|
||||
} //namespace CGAL
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_CONVEX_HULL_CONSTRUCTIVE_TRAITS_2_H
|
||||
|
|
|
|||
|
|
@ -1,14 +1,17 @@
|
|||
#include <iostream>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <CGAL/convex_hull_2.h>
|
||||
#include <CGAL/convex_hull_traits_2.h>
|
||||
|
||||
#include <CGAL/boost/iterator/counting_iterator.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
typedef K::Point_2 Point_2;
|
||||
|
||||
|
||||
template <class F, class Point>
|
||||
struct Forward_bool_functor
|
||||
: public F
|
||||
|
|
@ -51,7 +54,7 @@ struct CH_traits_for_point_ids
|
|||
typedef CGAL::Convex_hull_traits_2<K> Base;
|
||||
typedef Forward_bool_functor<typename Base::Less_xy_2, typename K::Point_2> Less_xy_2;
|
||||
typedef Forward_bool_functor<typename Base::Less_yx_2, typename K::Point_2> Less_yx_2;
|
||||
typedef Forward_bool_functor<typename Base::Less_signed_distance_to_line_2, typename K::Point_2> Less_signed_distance_to_line_2;
|
||||
typedef Forward_bool_functor<typename Base::Compare_signed_distance_to_line_2, typename K::Point_2> Compare_signed_distance_to_line_2;
|
||||
typedef Forward_bool_functor<typename Base::Less_rotate_ccw_2, typename K::Point_2> Less_rotate_ccw_2;
|
||||
typedef Forward_bool_functor<typename Base::Left_turn_2, typename K::Point_2> Left_turn_2;
|
||||
typedef Forward_bool_functor<typename Base::Equal_2, typename K::Point_2> Equal_2;
|
||||
|
|
@ -86,9 +89,9 @@ struct CH_traits_for_point_ids
|
|||
return Less_yx_2(points);
|
||||
}
|
||||
|
||||
Less_signed_distance_to_line_2 less_signed_distance_to_line_2_object () const
|
||||
Compare_signed_distance_to_line_2 compare_signed_distance_to_line_2_object () const
|
||||
{
|
||||
return Less_signed_distance_to_line_2(points);
|
||||
return Compare_signed_distance_to_line_2(points);
|
||||
}
|
||||
|
||||
Less_rotate_ccw_2 less_rotate_ccw_2_object () const
|
||||
|
|
@ -128,5 +131,5 @@ int main()
|
|||
|
||||
assert( result.size() == 3 );
|
||||
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <CGAL/convex_hull_2.h>
|
||||
#include <CGAL/Projection_traits_xy_3.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
|
|
@ -8,18 +10,20 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
|||
typedef CGAL::Projection_traits_xy_3<Kernel> Traits;
|
||||
typedef Traits::Point_2 Point_2;
|
||||
|
||||
int main(){
|
||||
int main()
|
||||
{
|
||||
std::vector<Point_2> points;
|
||||
std::ifstream input("data/CD500");
|
||||
|
||||
double x,y;
|
||||
while (input >> x >> y){
|
||||
while(input >> x >> y)
|
||||
{
|
||||
points.push_back(Point_2(x,y,3.));
|
||||
}
|
||||
|
||||
std::vector<Point_2> ch2;
|
||||
|
||||
CGAL::convex_hull_2(points.begin(),points.end(),std::back_inserter(ch2),Traits());
|
||||
|
||||
std::cout << ch2.size() << std::endl;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,33 +1,9 @@
|
|||
// ============================================================================
|
||||
//
|
||||
// Copyright (c) 1999 The CGAL Consortium
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// release :
|
||||
// release_date :
|
||||
//
|
||||
// file : ch_test_CH.C
|
||||
// revision : $Id$
|
||||
// revision_date : $Date$
|
||||
// author(s) : Stefan Schirra
|
||||
//
|
||||
// coordinator : MPI, Saarbruecken
|
||||
// ============================================================================
|
||||
#include <CGAL/_test_fct_ch_I_2.h>
|
||||
|
||||
#include <CGAL/Homogeneous.h>
|
||||
#include <CGAL/Cartesian.h>
|
||||
#include <CGAL/convex_hull_traits_2.h>
|
||||
|
||||
#include <CGAL/convex_hull_constructive_traits_2.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
#ifdef CGAL_USE_LEDA
|
||||
#include <CGAL/leda_integer.h>
|
||||
#include <CGAL/leda_rational.h>
|
||||
|
|
@ -37,28 +13,23 @@
|
|||
#include <CGAL/Gmpz.h>
|
||||
#endif
|
||||
|
||||
#include <CGAL/_test_fct_ch_I_2.h>
|
||||
|
||||
int
|
||||
main()
|
||||
int main()
|
||||
{
|
||||
#ifdef CGAL_USE_LEDA
|
||||
CGAL::Convex_hull_constructive_traits_2< CGAL::Homogeneous<leda_integer> >
|
||||
cch_H_integer;
|
||||
std::cout << "Homogeneous<integer>: C ";
|
||||
CGAL::ch__batch_test( cch_H_integer );
|
||||
CGAL::Convex_hull_constructive_traits_2< CGAL::Homogeneous<leda_integer> > cch_H_integer;
|
||||
std::cout << "Homogeneous<integer>:" << std::endl;
|
||||
CGAL::ch__batch_test(cch_H_integer);
|
||||
#endif
|
||||
|
||||
#ifdef CGAL_USE_GMP
|
||||
CGAL::Convex_hull_constructive_traits_2< CGAL::Homogeneous<CGAL::Gmpz> >
|
||||
cch_H_gmp;
|
||||
std::cout << "Homogeneous<gmp>: C ";
|
||||
CGAL::ch__batch_test( cch_H_gmp );
|
||||
CGAL::Convex_hull_constructive_traits_2< CGAL::Homogeneous<CGAL::Gmpz> > cch_H_gmp;
|
||||
std::cout << "Homogeneous<gmp>:" << std::endl;
|
||||
CGAL::ch__batch_test(cch_H_gmp);
|
||||
#endif
|
||||
|
||||
CGAL::Convex_hull_constructive_traits_2< CGAL::Homogeneous<double> >
|
||||
cch_H_double;
|
||||
std::cout << "Homogeneous<double>: C ";
|
||||
CGAL::ch__batch_test( cch_H_double );
|
||||
return 0;
|
||||
CGAL::Convex_hull_constructive_traits_2< CGAL::Homogeneous<double> > cch_H_double;
|
||||
std::cout << "Homogeneous<double>:" << std::endl;
|
||||
CGAL::ch__batch_test(cch_H_double);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
#include <CGAL/_test_fct_ch_I_2.h>
|
||||
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <CGAL/convex_hull_constructive_traits_2.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
CGAL::Exact_predicates_inexact_constructions_kernel ch_EPICK;
|
||||
std::cout << "EPICK:" << std::endl;
|
||||
CGAL::ch__batch_test(ch_EPICK);
|
||||
|
||||
CGAL::Convex_hull_constructive_traits_2<CGAL::Exact_predicates_inexact_constructions_kernel> cch_EPICK;
|
||||
std::cout << "Constructive EPICK:" << std::endl;
|
||||
CGAL::ch__batch_test(cch_EPICK);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
@ -1,31 +1,6 @@
|
|||
// ============================================================================
|
||||
//
|
||||
// Copyright (c) 1999 The CGAL Consortium
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// release :
|
||||
// release_date :
|
||||
//
|
||||
// file : ch_test_SC.C
|
||||
// revision : $Id$
|
||||
// revision_date : $Date$
|
||||
// author(s) : Stefan Schirra
|
||||
//
|
||||
// coordinator : MPI, Saarbruecken
|
||||
// ============================================================================
|
||||
#include <CGAL/_test_fct_ch_I_2.h>
|
||||
|
||||
#include <CGAL/Cartesian.h>
|
||||
#include <CGAL/convex_hull_traits_2.h>
|
||||
#include <CGAL/convex_hull_constructive_traits_2.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
#ifdef CGAL_USE_LEDA
|
||||
#include <CGAL/leda_integer.h>
|
||||
|
|
@ -36,25 +11,23 @@
|
|||
#include <CGAL/Gmpz.h>
|
||||
#endif
|
||||
|
||||
#include <CGAL/_test_fct_ch_I_2.h>
|
||||
|
||||
int
|
||||
main()
|
||||
int main()
|
||||
{
|
||||
#ifdef CGAL_USE_LEDA
|
||||
CGAL::Cartesian<leda_rational> ch_C_rational;
|
||||
std::cout << "Cartesian<rational>: ";
|
||||
CGAL::ch__batch_test( ch_C_rational );
|
||||
std::cout << "Cartesian<rational>:" << std::endl;
|
||||
CGAL::ch__batch_test(ch_C_rational);
|
||||
#endif
|
||||
|
||||
#ifdef CGAL_USE_GMP
|
||||
CGAL::Cartesian<CGAL::Quotient<CGAL::Gmpz> > ch_C_Qgmp;
|
||||
std::cout << "Cartesian<Quotient<Gmpz> > >: ";
|
||||
CGAL::ch__batch_test( ch_C_Qgmp );
|
||||
std::cout << "Cartesian<Quotient<Gmpz> > >:" << std::endl;
|
||||
CGAL::ch__batch_test(ch_C_Qgmp);
|
||||
#endif
|
||||
|
||||
CGAL::Cartesian<double> ch_C_double;
|
||||
std::cout << "Cartesian<double>: ";
|
||||
CGAL::ch__batch_test( ch_C_double );
|
||||
return 0;
|
||||
std::cout << "Cartesian<double>:" << std::endl;
|
||||
CGAL::ch__batch_test(ch_C_double);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,31 +1,6 @@
|
|||
// ============================================================================
|
||||
//
|
||||
// Copyright (c) 1999 The CGAL Consortium
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// release :
|
||||
// release_date :
|
||||
//
|
||||
// file : ch_test_SH.C
|
||||
// revision : $Id$
|
||||
// revision_date : $Date$
|
||||
// author(s) : Stefan Schirra
|
||||
//
|
||||
// coordinator : MPI, Saarbruecken
|
||||
// ============================================================================
|
||||
#include <CGAL/_test_fct_ch_I_2.h>
|
||||
|
||||
#include <CGAL/Homogeneous.h>
|
||||
#include <CGAL/convex_hull_traits_2.h>
|
||||
#include <CGAL/convex_hull_constructive_traits_2.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
#ifdef CGAL_USE_LEDA
|
||||
#include <CGAL/leda_integer.h>
|
||||
|
|
@ -35,25 +10,24 @@
|
|||
#ifdef CGAL_USE_GMP
|
||||
#include <CGAL/Gmpz.h>
|
||||
#endif
|
||||
#include <CGAL/_test_fct_ch_I_2.h>
|
||||
|
||||
int
|
||||
main()
|
||||
int main()
|
||||
{
|
||||
#ifdef CGAL_USE_LEDA
|
||||
CGAL::Homogeneous<leda_integer> ch_H_integer;
|
||||
std::cout << "Homogeneous<integer>: ";
|
||||
std::cout << "Homogeneous<integer>:" << std::endl;
|
||||
CGAL::ch__batch_test( ch_H_integer );
|
||||
#endif
|
||||
|
||||
#ifdef CGAL_USE_GMP
|
||||
CGAL::Homogeneous<CGAL::Gmpz> ch_H_gmp;
|
||||
std::cout << "Homogeneous<gmp>: ";
|
||||
std::cout << "Homogeneous<gmp>:" << std::endl;
|
||||
CGAL::ch__batch_test( ch_H_gmp );
|
||||
#endif
|
||||
|
||||
CGAL::Homogeneous<double> ch_H_double;
|
||||
std::cout << "Homogeneous<double>: ";
|
||||
std::cout << "Homogeneous<double>:" << std::endl;
|
||||
CGAL::ch__batch_test( ch_H_double );
|
||||
return 0;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,32 +1,6 @@
|
|||
// ============================================================================
|
||||
//
|
||||
// Copyright (c) 1999 The CGAL Consortium
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// release :
|
||||
// release_date :
|
||||
//
|
||||
// file : ch_test_SS.C
|
||||
// revision : $Id$
|
||||
// revision_date : $Date$
|
||||
// author(s) : Stefan Schirra
|
||||
//
|
||||
// coordinator : MPI, Saarbruecken
|
||||
// ============================================================================
|
||||
|
||||
#include <CGAL/_test_fct_ch_I_2.h>
|
||||
|
||||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/convex_hull_traits_2.h>
|
||||
#include <CGAL/convex_hull_constructive_traits_2.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
#ifdef CGAL_USE_LEDA
|
||||
#include <CGAL/leda_integer.h>
|
||||
|
|
@ -36,25 +10,24 @@
|
|||
#ifdef CGAL_USE_GMP
|
||||
#include <CGAL/Gmpz.h>
|
||||
#endif
|
||||
#include <CGAL/_test_fct_ch_I_2.h>
|
||||
|
||||
int
|
||||
main()
|
||||
int main()
|
||||
{
|
||||
#ifdef CGAL_USE_LEDA
|
||||
CGAL::Simple_cartesian<leda_rational> ch_S_rational;
|
||||
std::cout << "SimpleCartesian<rational>: ";
|
||||
std::cout << "SimpleCartesian<rational>:" << std::endl;
|
||||
CGAL::ch__batch_test( ch_S_rational );
|
||||
#endif
|
||||
|
||||
#ifdef CGAL_USE_GMP
|
||||
CGAL::Simple_cartesian<CGAL::Quotient<CGAL::Gmpz> > ch_S_Qgmp;
|
||||
std::cout << "SimpleCartesian<Quotient<Gmpz> > >: ";
|
||||
std::cout << "SimpleCartesian<Quotient<Gmpz> > >:" << std::endl;
|
||||
CGAL::ch__batch_test( ch_S_Qgmp );
|
||||
#endif
|
||||
|
||||
CGAL::Simple_cartesian<double> ch_S_double;
|
||||
std::cout << "SimpleCartesian<double>: ";
|
||||
std::cout << "SimpleCartesian<double>:" << std::endl;
|
||||
CGAL::ch__batch_test( ch_S_double );
|
||||
return 0;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,21 +18,243 @@
|
|||
// coordinator : MPI, Saarbruecken
|
||||
// ============================================================================
|
||||
|
||||
|
||||
#ifndef _TEST_FCT_CH_I_2_H
|
||||
#define _TEST_FCT_CH_I_2_H
|
||||
|
||||
#include <cassert>
|
||||
#include <CGAL/ch__test.h>
|
||||
|
||||
#include <CGAL/Random.h>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template <class Traits>
|
||||
bool
|
||||
ch__batch_test( const Traits& chI );
|
||||
void ch__batch_test_simple(const Traits& chI)
|
||||
{
|
||||
using Point_2 = typename Traits::Point_2;
|
||||
|
||||
} //namespace CGAL
|
||||
std::cout << std::endl << " == Test Simple ==" << std::endl;
|
||||
|
||||
#include <CGAL/_test_fct_ch_I_2_impl.h>
|
||||
std::vector<Point_2> points;
|
||||
points.push_back(Point_2( -10, 0, 1));
|
||||
points.push_back(Point_2( -15, -1, 1));
|
||||
points.push_back(Point_2( -7, -10, 1));
|
||||
points.push_back(Point_2( -9, -20, 1));
|
||||
points.push_back(Point_2( -3, -20, 1));
|
||||
points.push_back(Point_2( 74, 0, 1));
|
||||
points.push_back(Point_2( 1, 1, 1));
|
||||
points.push_back(Point_2( 0, 100, 1));
|
||||
|
||||
assert(ch__test(points.begin(), points.end(), chI));
|
||||
}
|
||||
|
||||
template <class Traits>
|
||||
void ch__batch_test_cocircular(const Traits& chI)
|
||||
{
|
||||
using Point_2 = typename Traits::Point_2;
|
||||
|
||||
std::cout << std::endl << " == Test Cocircular ==" << std::endl;
|
||||
|
||||
std::vector<Point_2> cocircular_points;
|
||||
cocircular_points.push_back(Point_2( 39, 80, 89));
|
||||
cocircular_points.push_back(Point_2( 180, 299, 349));
|
||||
cocircular_points.push_back(Point_2( -3, -4, 5));
|
||||
cocircular_points.push_back(Point_2(-651, 260, 701));
|
||||
cocircular_points.push_back(Point_2( 180, -19, 181));
|
||||
cocircular_points.push_back(Point_2(-153, 104, 185));
|
||||
cocircular_points.push_back(Point_2(-247, -96, 265));
|
||||
cocircular_points.push_back(Point_2( -32, 255, 257));
|
||||
cocircular_points.push_back(Point_2( 45, -28, 53));
|
||||
cocircular_points.push_back(Point_2( -12, -35, 37));
|
||||
|
||||
assert(!ch_brute_force_check_2(cocircular_points.begin(), cocircular_points.end(),
|
||||
cocircular_points.begin(), cocircular_points.end(), chI));
|
||||
assert(ch_brute_force_check_2(cocircular_points.begin(), cocircular_points.begin(),
|
||||
cocircular_points.begin(), cocircular_points.end(), chI));
|
||||
assert(ch__test(cocircular_points.begin(), cocircular_points.end(), chI, ch_ALL, ch_CHECK_CONVEXITY));
|
||||
|
||||
std::vector<Point_2> extreme_points;
|
||||
convex_hull_2(cocircular_points.begin(), cocircular_points.end(),
|
||||
std::back_inserter(extreme_points), chI);
|
||||
|
||||
assert(is_ccw_strongly_convex_2(extreme_points.begin(), extreme_points.begin(), chI));
|
||||
assert(is_cw_strongly_convex_2(extreme_points.rend(), extreme_points.rend(), chI));
|
||||
assert(is_ccw_strongly_convex_2(extreme_points.begin(), extreme_points.begin() + 1, chI));
|
||||
assert(is_cw_strongly_convex_2(extreme_points.begin(), extreme_points.begin() + 1, chI));
|
||||
assert(is_ccw_strongly_convex_2(extreme_points.begin(), extreme_points.end(), chI));
|
||||
assert(is_cw_strongly_convex_2(extreme_points.rbegin(), extreme_points.rend(), chI));
|
||||
}
|
||||
|
||||
template <class Traits>
|
||||
void ch__batch_test_cocircular_ordered(const Traits& chI)
|
||||
{
|
||||
using Point_2 = typename Traits::Point_2;
|
||||
|
||||
std::cout << std::endl << " == Test Cocircular (ordered) ==" << std::endl;
|
||||
|
||||
std::vector<Point_2> cocircular_points;
|
||||
cocircular_points.push_back(Point_2( 180, -19, 181));
|
||||
cocircular_points.push_back(Point_2( 45, -28, 53));
|
||||
cocircular_points.push_back(Point_2( -12, -35, 37));
|
||||
cocircular_points.push_back(Point_2( -3, -4, 5));
|
||||
cocircular_points.push_back(Point_2(-247, -96, 265));
|
||||
cocircular_points.push_back(Point_2(-651, 260, 701));
|
||||
cocircular_points.push_back(Point_2(-153, 104, 185));
|
||||
cocircular_points.push_back(Point_2( -32, 255, 257));
|
||||
cocircular_points.push_back(Point_2( 39, 80, 89));
|
||||
cocircular_points.push_back(Point_2( 180, 299, 349));
|
||||
|
||||
assert(!ch_brute_force_check_2(cocircular_points.begin(), cocircular_points.end(),
|
||||
cocircular_points.begin(), cocircular_points.end(), chI));
|
||||
assert(ch_brute_force_check_2(cocircular_points.begin(), cocircular_points.begin(),
|
||||
cocircular_points.begin(), cocircular_points.end(), chI));
|
||||
assert(ch__test(cocircular_points.begin(), cocircular_points.end(), chI, ch_ALL, ch_CHECK_CONVEXITY));
|
||||
|
||||
std::vector<Point_2> extreme_points;
|
||||
convex_hull_2(cocircular_points.begin(), cocircular_points.end(),
|
||||
std::back_inserter(extreme_points), chI);
|
||||
|
||||
assert(is_ccw_strongly_convex_2(extreme_points.begin(), extreme_points.begin(), chI));
|
||||
assert(is_cw_strongly_convex_2(extreme_points.rend(), extreme_points.rend(), chI));
|
||||
assert(is_ccw_strongly_convex_2(extreme_points.begin(), extreme_points.begin() + 1, chI));
|
||||
assert(is_cw_strongly_convex_2(extreme_points.begin(), extreme_points.begin() + 1, chI));
|
||||
assert(is_ccw_strongly_convex_2(extreme_points.begin(), extreme_points.end(), chI));
|
||||
assert(is_cw_strongly_convex_2(extreme_points.rbegin(), extreme_points.rend(), chI));
|
||||
}
|
||||
|
||||
template <class Traits>
|
||||
void ch__batch_test_collinear(const Traits& chI)
|
||||
{
|
||||
using Point_2 = typename Traits::Point_2;
|
||||
|
||||
std::cout << std::endl << " == Test Collinear ==" << std::endl;
|
||||
|
||||
std::vector<Point_2> collinear_points;
|
||||
collinear_points.push_back(Point_2( 16, 20, 1));
|
||||
collinear_points.push_back(Point_2( 46, 40, 1));
|
||||
collinear_points.push_back(Point_2( 76, 60, 1));
|
||||
collinear_points.push_back(Point_2(106, 80, 1));
|
||||
collinear_points.push_back(Point_2(-14, 0, 1));
|
||||
collinear_points.push_back(Point_2(136, 100, 1));
|
||||
|
||||
assert(ch__test(collinear_points.begin(), collinear_points.end(), chI));
|
||||
}
|
||||
|
||||
template <class Traits>
|
||||
void ch__batch_test_multiple(const Traits& chI)
|
||||
{
|
||||
using Point_2 = typename Traits::Point_2;
|
||||
|
||||
std::cout << std::endl << " == Test Multiple ==" << std::endl;
|
||||
|
||||
std::vector<Point_2> multiple_points;
|
||||
multiple_points.push_back(Point_2(17, 80, 1));
|
||||
multiple_points.push_back(Point_2(17, 80, 1));
|
||||
multiple_points.push_back(Point_2(17, 80, 1));
|
||||
multiple_points.push_back(Point_2(17, 80, 1));
|
||||
|
||||
assert(ch_brute_force_check_2(multiple_points.begin(), multiple_points.end(),
|
||||
multiple_points.begin(), multiple_points.begin() + 1, chI));
|
||||
assert(is_ccw_strongly_convex_2(multiple_points.begin(), multiple_points.begin(), chI));
|
||||
|
||||
assert(ch__test(multiple_points.begin(), multiple_points.end(), chI));
|
||||
assert(ch__test(multiple_points.begin() + 2, multiple_points.begin() + 3, chI));
|
||||
}
|
||||
|
||||
template <class Traits>
|
||||
void ch__batch_test_iso_rectangle(const Traits& chI)
|
||||
{
|
||||
using Point_2 = typename Traits::Point_2;
|
||||
|
||||
std::cout << std::endl << " == Test Iso Rectangle ==" << std::endl;
|
||||
|
||||
std::vector<Point_2> iso_rectangle_points;
|
||||
iso_rectangle_points.push_back(Point_2( 15, 0, 1));
|
||||
iso_rectangle_points.push_back(Point_2( 45, 0, 1));
|
||||
iso_rectangle_points.push_back(Point_2( 70, 0, 10));
|
||||
iso_rectangle_points.push_back(Point_2( 12, 0, 1));
|
||||
iso_rectangle_points.push_back(Point_2( 56, 118, 1));
|
||||
iso_rectangle_points.push_back(Point_2( 27, 118, 1));
|
||||
iso_rectangle_points.push_back(Point_2( 56, 118, 1));
|
||||
iso_rectangle_points.push_back(Point_2(112, 118, 1));
|
||||
iso_rectangle_points.push_back(Point_2( 0, 9, 1));
|
||||
iso_rectangle_points.push_back(Point_2( 0, 78, 1));
|
||||
iso_rectangle_points.push_back(Point_2( 0, 16, 1));
|
||||
iso_rectangle_points.push_back(Point_2( 0, 77, 1));
|
||||
iso_rectangle_points.push_back(Point_2(150, 56, 1));
|
||||
iso_rectangle_points.push_back(Point_2(150, 57, 1));
|
||||
iso_rectangle_points.push_back(Point_2(150, 58, 1));
|
||||
iso_rectangle_points.push_back(Point_2(150, 58, 1));
|
||||
|
||||
assert(ch__test(iso_rectangle_points.begin(), iso_rectangle_points.end(), chI));
|
||||
assert(ch__test(iso_rectangle_points.begin(), iso_rectangle_points.begin()+3, chI));
|
||||
assert(ch__test(iso_rectangle_points.begin()+4, iso_rectangle_points.begin()+7, chI));
|
||||
assert(ch__test(iso_rectangle_points.begin()+5, iso_rectangle_points.begin()+5, chI));
|
||||
}
|
||||
|
||||
// https://github.com/CGAL/cgal/issues/6723
|
||||
template <class Traits>
|
||||
void ch__batch_test_issue_6723(const Traits& chI)
|
||||
{
|
||||
using Point_2 = typename Traits::Point_2;
|
||||
|
||||
std::cout << std::endl << " == Test issue_6723 ==" << std::endl;
|
||||
|
||||
std::vector<Point_2> points = { Point_2( 4, 2, 1),
|
||||
Point_2( 0, 0, 1),
|
||||
Point_2(10, 0, 1),
|
||||
Point_2( 3, 1, 1),
|
||||
Point_2( 3,-1, 1),
|
||||
Point_2( 2, 2, 1),
|
||||
Point_2( 5, 2, 1),
|
||||
Point_2( 9, 2, 1),
|
||||
Point_2( 3, 2, 1) };
|
||||
|
||||
assert(ch__test(points.begin(), points.end(), chI));
|
||||
}
|
||||
|
||||
template <class Traits>
|
||||
void ch__batch_test_random(const Traits& chI)
|
||||
{
|
||||
using Point_2 = typename Traits::Point_2;
|
||||
|
||||
std::cout << std::endl << " == Test Random ==" << std::endl;
|
||||
|
||||
CGAL::Random rnd;
|
||||
std::cout << "Random seed = " << rnd.get_seed() << std::endl;
|
||||
|
||||
std::vector<Point_2> points;
|
||||
|
||||
const int h = rnd.get_int(1, 100);
|
||||
for(int i=0; i<10; ++i)
|
||||
{
|
||||
const int x = rnd.get_int(-100, 100);
|
||||
const int y = rnd.get_int(-100, 100);
|
||||
points.emplace_back(x, y, h);
|
||||
}
|
||||
|
||||
assert(ch__test(points.begin(), points.end(), chI));
|
||||
}
|
||||
|
||||
template <class Traits>
|
||||
bool ch__batch_test(const Traits& chI)
|
||||
{
|
||||
std::cout << "Testing Convex Hulls" << std::endl;;
|
||||
|
||||
ch__batch_test_simple(chI);
|
||||
ch__batch_test_cocircular(chI);
|
||||
ch__batch_test_cocircular_ordered(chI); // so melkman gets called
|
||||
ch__batch_test_collinear(chI);
|
||||
ch__batch_test_multiple(chI);
|
||||
ch__batch_test_iso_rectangle(chI);
|
||||
ch__batch_test_issue_6723(chI);
|
||||
ch__batch_test_random(chI);
|
||||
|
||||
std::cout << "done" << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // _TEST_FCT_CH_I_2_H
|
||||
|
|
|
|||
|
|
@ -1,137 +0,0 @@
|
|||
// ============================================================================
|
||||
//
|
||||
// Copyright (c) 1999 The CGAL Consortium
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// release :
|
||||
// release_date :
|
||||
//
|
||||
// file : _test_fct_ch_I_2.C
|
||||
// revision : $Id$
|
||||
// revision_date : $Date$
|
||||
// author(s) : Stefan Schirra
|
||||
//
|
||||
// coordinator : MPI, Saarbruecken
|
||||
// ============================================================================
|
||||
|
||||
|
||||
#ifndef _TEST_FCT_CH_I_2_IMPL_H
|
||||
#define _TEST_FCT_CH_I_2_IMPL_H
|
||||
|
||||
#include <CGAL/_test_fct_ch_I_2.h>
|
||||
#include <cassert>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template <class Traits>
|
||||
bool
|
||||
ch__batch_test( const Traits& chI )
|
||||
{
|
||||
typedef typename Traits::Point_2 Point_2;
|
||||
|
||||
std::cout << "Testing ch";
|
||||
std::vector< Point_2 > Cocircular_points;
|
||||
Cocircular_points.push_back( Point_2( 39, 80, 89 ));
|
||||
Cocircular_points.push_back( Point_2( 180, 299, 349 ));
|
||||
Cocircular_points.push_back( Point_2( -3, -4, 5 ));
|
||||
Cocircular_points.push_back( Point_2( -651, 260, 701 ));
|
||||
Cocircular_points.push_back( Point_2( 180, -19, 181 ));
|
||||
Cocircular_points.push_back( Point_2( -153, 104, 185 ));
|
||||
Cocircular_points.push_back( Point_2( -247, -96, 265 ));
|
||||
Cocircular_points.push_back( Point_2( -32, 255, 257 ));
|
||||
Cocircular_points.push_back( Point_2( 45, -28, 53 ));
|
||||
Cocircular_points.push_back( Point_2( -12, -35, 37 ));
|
||||
assert( ! ch_brute_force_check_2( \
|
||||
Cocircular_points.begin(), Cocircular_points.end(), \
|
||||
Cocircular_points.begin(), Cocircular_points.end(), chI ));
|
||||
assert( ch_brute_force_check_2( \
|
||||
Cocircular_points.begin(), Cocircular_points.begin(), \
|
||||
Cocircular_points.begin(), Cocircular_points.end(), chI ));
|
||||
assert( ch__test( Cocircular_points.begin(), \
|
||||
Cocircular_points.end(), \
|
||||
chI, ch_ALL, ch_CHECK_CONVEXITY ));
|
||||
std::vector< Point_2 > extreme_points;
|
||||
convex_hull_2(Cocircular_points.begin(), Cocircular_points.end(),
|
||||
std::back_inserter(extreme_points), chI );
|
||||
assert( is_ccw_strongly_convex_2( extreme_points.begin(), \
|
||||
extreme_points.begin(), \
|
||||
chI ));
|
||||
assert( is_cw_strongly_convex_2( extreme_points.rend(),
|
||||
extreme_points.rend(), \
|
||||
chI ));
|
||||
assert( is_ccw_strongly_convex_2( extreme_points.begin(), \
|
||||
extreme_points.begin() + 1, chI ));
|
||||
assert( is_cw_strongly_convex_2( extreme_points.begin(), \
|
||||
extreme_points.begin() + 1, chI ));
|
||||
assert( is_ccw_strongly_convex_2( extreme_points.begin(), \
|
||||
extreme_points.end(), \
|
||||
chI ));
|
||||
assert( is_cw_strongly_convex_2( extreme_points.rbegin(),
|
||||
extreme_points.rend(), \
|
||||
chI ));
|
||||
|
||||
std::cout << '.';
|
||||
std::vector< Point_2 > Collinear_points;
|
||||
Collinear_points.push_back( Point_2( 16, 20, 1 ));
|
||||
Collinear_points.push_back( Point_2( 46, 40, 1 ));
|
||||
Collinear_points.push_back( Point_2( 76, 60, 1 ));
|
||||
Collinear_points.push_back( Point_2( 106, 80, 1 ));
|
||||
Collinear_points.push_back( Point_2( -14, 0 , 1));
|
||||
Collinear_points.push_back( Point_2( 136, 100, 1 ));
|
||||
assert( ch__test( Collinear_points.begin(), \
|
||||
Collinear_points.end(), chI ));
|
||||
|
||||
std::cout << '.';
|
||||
std::vector< Point_2 > Multiple_points;
|
||||
Multiple_points.push_back( Point_2( 17, 80, 1 ));
|
||||
Multiple_points.push_back( Point_2( 17, 80, 1 ));
|
||||
Multiple_points.push_back( Point_2( 17, 80, 1 ));
|
||||
Multiple_points.push_back( Point_2( 17, 80, 1 ));
|
||||
assert( ch_brute_force_check_2( \
|
||||
Multiple_points.begin(), Multiple_points.end(),\
|
||||
Multiple_points.begin(), Multiple_points.begin() + 1, chI ));
|
||||
assert( is_ccw_strongly_convex_2(Multiple_points.begin(), \
|
||||
Multiple_points.begin(), chI ));
|
||||
assert( ch__test( Multiple_points.begin(), \
|
||||
Multiple_points.end(), chI ));
|
||||
assert( ch__test( Multiple_points.begin() + 2, \
|
||||
Multiple_points.begin() + 3, chI ));
|
||||
|
||||
std::cout << '.';
|
||||
std::vector< Point_2 > Iso_rectangle_points;
|
||||
Iso_rectangle_points.push_back( Point_2( 15, 0, 1 ));
|
||||
Iso_rectangle_points.push_back( Point_2( 45, 0, 1 ));
|
||||
Iso_rectangle_points.push_back( Point_2( 70, 0, 10 ));
|
||||
Iso_rectangle_points.push_back( Point_2( 12, 0, 1 ));
|
||||
Iso_rectangle_points.push_back( Point_2( 56, 118, 1 ));
|
||||
Iso_rectangle_points.push_back( Point_2( 27, 118, 1 ));
|
||||
Iso_rectangle_points.push_back( Point_2( 56, 118, 1 ));
|
||||
Iso_rectangle_points.push_back( Point_2( 112, 118, 1));
|
||||
Iso_rectangle_points.push_back( Point_2( 0, 9, 1));
|
||||
Iso_rectangle_points.push_back( Point_2( 0, 78, 1));
|
||||
Iso_rectangle_points.push_back( Point_2( 0, 16, 1));
|
||||
Iso_rectangle_points.push_back( Point_2( 0, 77, 1));
|
||||
Iso_rectangle_points.push_back( Point_2( 150, 56, 1));
|
||||
Iso_rectangle_points.push_back( Point_2( 150, 57, 1));
|
||||
Iso_rectangle_points.push_back( Point_2( 150, 58, 1));
|
||||
Iso_rectangle_points.push_back( Point_2( 150, 58, 1));
|
||||
assert( ch__test( Iso_rectangle_points.begin(), \
|
||||
Iso_rectangle_points.end(), chI ));
|
||||
assert( ch__test( Iso_rectangle_points.begin(), \
|
||||
Iso_rectangle_points.begin()+3, chI ));
|
||||
assert( ch__test( Iso_rectangle_points.begin()+4, \
|
||||
Iso_rectangle_points.begin()+7, chI ));
|
||||
assert( ch__test( Iso_rectangle_points.begin()+5, \
|
||||
Iso_rectangle_points.begin()+5, chI ));
|
||||
|
||||
std::cout << "done" << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#endif // _TEST_FCT_CH_I_2_IMPL_H
|
||||
|
|
@ -29,46 +29,206 @@
|
|||
#include <CGAL/ch_eddy.h>
|
||||
#include <CGAL/ch_bykat.h>
|
||||
#include <CGAL/ch_jarvis.h>
|
||||
#include <CGAL/ch_melkman.h>
|
||||
|
||||
#include <CGAL/Polygon_2_algorithms.h>
|
||||
|
||||
#include <array>
|
||||
#include <iterator>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
enum ch_Algorithm{ ch_JARVIS,
|
||||
ch_GRAHAM_ANDREW,
|
||||
ch_EDDY,
|
||||
enum ch_Algorithm
|
||||
{
|
||||
ch_AKL_TOUSSAINT = 0,
|
||||
ch_BYKAT,
|
||||
ch_BYKAT_WITH_THRESHOLD,
|
||||
ch_EDDY,
|
||||
ch_JARVIS,
|
||||
ch_GRAHAM_ANDREW,
|
||||
ch_LOWER_UPPER,
|
||||
ch_AKL_TOUSSAINT,
|
||||
ch_MELKMAN,
|
||||
ch_ALL,
|
||||
ch_DEFAULT };
|
||||
ch_DEFAULT
|
||||
};
|
||||
|
||||
enum ch_Check_status{ ch_CHECK_ALL,
|
||||
static std::array<std::string, 10> algorithm_names = {{ "AKL TOUSSAINT",
|
||||
"BYKAT",
|
||||
"BYKAT WITH THRESHOLD",
|
||||
"EDDY",
|
||||
"JARVIS",
|
||||
"GRAHAM ANDREW",
|
||||
"LOWER UPPER",
|
||||
"MELKMAN",
|
||||
"ALL",
|
||||
"DEFAULT"
|
||||
}};
|
||||
|
||||
enum ch_Check_status
|
||||
{
|
||||
ch_CHECK_ALL,
|
||||
ch_CHECK_CONVEXITY,
|
||||
ch_CHECK_CONTAINEMENT,
|
||||
ch_NO_CHECK };
|
||||
ch_NO_CHECK
|
||||
};
|
||||
|
||||
template <class InputIterator, class Traits>
|
||||
bool
|
||||
ch__test(InputIterator first, InputIterator last,
|
||||
// Also compare the results
|
||||
template <typename InputIterator, typename Traits>
|
||||
bool test_all_and_compare(InputIterator first, InputIterator beyond,
|
||||
const Traits& ch_traits,
|
||||
ch_Algorithm alg,
|
||||
ch_Check_status check_level);
|
||||
ch_Check_status check_level = ch_CHECK_ALL)
|
||||
{
|
||||
using Point_2 = typename Traits::Point_2;
|
||||
|
||||
bool call_melkman = is_simple_2(first, beyond, ch_traits);
|
||||
|
||||
std::cout << "Input:";
|
||||
InputIterator first_o = first;
|
||||
for(; first_o!=beyond;++first_o)
|
||||
std::cout << " " << first_o->x() << " " << first_o->y() << " 0";
|
||||
std::cout << std::endl;
|
||||
|
||||
if(!ch__test(first, beyond, ch_traits, ch_AKL_TOUSSAINT, check_level))
|
||||
return false;
|
||||
if(!ch__test(first, beyond, ch_traits, ch_BYKAT, check_level))
|
||||
return false;
|
||||
if(!ch__test(first, beyond, ch_traits, ch_BYKAT_WITH_THRESHOLD, check_level))
|
||||
return false;
|
||||
if(!ch__test(first, beyond, ch_traits, ch_EDDY, check_level))
|
||||
return false;
|
||||
if(!ch__test(first, beyond, ch_traits, ch_JARVIS, check_level))
|
||||
return false;
|
||||
if(!ch__test(first, beyond, ch_traits, ch_GRAHAM_ANDREW, check_level))
|
||||
return false;
|
||||
if(!ch__test(first, beyond, ch_traits, ch_LOWER_UPPER, check_level))
|
||||
return false;
|
||||
if(call_melkman)
|
||||
{
|
||||
if(!ch__test(first, beyond, ch_traits, ch_MELKMAN, check_level))
|
||||
return false;
|
||||
}
|
||||
|
||||
std::set<Point_2> V0;
|
||||
ch_akl_toussaint(first, beyond, std::inserter(V0, V0.end()), ch_traits);
|
||||
|
||||
{
|
||||
std::set<Point_2> V0_other;
|
||||
ch_bykat(first, beyond, std::inserter(V0_other, V0_other.end()), ch_traits);
|
||||
assert(V0 == V0_other);
|
||||
}
|
||||
|
||||
{
|
||||
std::set<Point_2> V0_other;
|
||||
ch_bykat_with_threshold(first, beyond, std::inserter(V0_other, V0_other.end()), ch_traits);
|
||||
assert(V0 == V0_other);
|
||||
}
|
||||
|
||||
{
|
||||
std::set<Point_2> V0_other;
|
||||
ch_eddy(first, beyond, std::inserter(V0_other, V0_other.end()), ch_traits);
|
||||
assert(V0 == V0_other);
|
||||
}
|
||||
|
||||
{
|
||||
std::set<Point_2> V0_other;
|
||||
ch_jarvis(first, beyond, std::inserter(V0_other, V0_other.end()), ch_traits);
|
||||
assert(V0 == V0_other);
|
||||
}
|
||||
|
||||
{
|
||||
std::set<Point_2> V0_other;
|
||||
ch_graham_andrew(first, beyond, std::inserter(V0_other, V0_other.end()), ch_traits);
|
||||
assert(V0 == V0_other);
|
||||
}
|
||||
|
||||
{
|
||||
std::set<Point_2> V0_other;
|
||||
lower_hull_points_2(first, beyond, std::inserter(V0_other, V0_other.end()), ch_traits);
|
||||
upper_hull_points_2(first, beyond, std::inserter(V0_other, V0_other.end()), ch_traits);
|
||||
assert(V0 == V0_other);
|
||||
}
|
||||
|
||||
if(call_melkman)
|
||||
{
|
||||
std::cout << "Simple polyline, proceed with melkman check" << std::endl;
|
||||
std::set<Point_2> V0_other;
|
||||
ch_melkman(first, beyond, std::inserter(V0_other, V0_other.end()), ch_traits);
|
||||
|
||||
assert(V0 == V0_other);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Cannot call melkman on non-simple polyline" << std::endl;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class InputIterator, class Traits>
|
||||
bool
|
||||
ch__test(InputIterator first, InputIterator last,
|
||||
ch__test(InputIterator first, InputIterator beyond,
|
||||
const Traits& ch_traits,
|
||||
ch_Algorithm alg);
|
||||
ch_Algorithm alg = ch_ALL,
|
||||
ch_Check_status check_level = ch_CHECK_ALL)
|
||||
{
|
||||
using Point_2 = typename Traits::Point_2;
|
||||
std::vector<Point_2> VI(first, beyond);
|
||||
std::vector<Point_2> VO;
|
||||
|
||||
template <class InputIterator, class Traits>
|
||||
bool
|
||||
ch__test(InputIterator first, InputIterator last,
|
||||
const Traits& ch_traits);
|
||||
std::cout << "Algorithm: " << algorithm_names[std::size_t(alg)] << std::endl;
|
||||
switch(alg)
|
||||
{
|
||||
case ch_AKL_TOUSSAINT:
|
||||
ch_akl_toussaint(first, beyond, std::back_inserter(VO), ch_traits);
|
||||
break;
|
||||
case ch_BYKAT:
|
||||
ch_bykat(first, beyond, std::back_inserter(VO), ch_traits);
|
||||
break;
|
||||
case ch_BYKAT_WITH_THRESHOLD:
|
||||
ch_bykat_with_threshold(first, beyond, std::back_inserter(VO), ch_traits);
|
||||
break;
|
||||
case ch_EDDY:
|
||||
ch_eddy(first, beyond, std::back_inserter(VO), ch_traits);
|
||||
break;
|
||||
case ch_JARVIS:
|
||||
ch_jarvis(first, beyond, std::back_inserter(VO), ch_traits);
|
||||
break;
|
||||
case ch_GRAHAM_ANDREW:
|
||||
ch_graham_andrew(first, beyond, std::back_inserter(VO), ch_traits);
|
||||
break;
|
||||
case ch_LOWER_UPPER:
|
||||
lower_hull_points_2(first, beyond, std::back_inserter(VO), ch_traits);
|
||||
upper_hull_points_2(first, beyond, std::back_inserter(VO), ch_traits);
|
||||
break;
|
||||
case ch_MELKMAN:
|
||||
ch_melkman(first, beyond, std::back_inserter(VO), ch_traits);
|
||||
break;
|
||||
case ch_ALL:
|
||||
return test_all_and_compare(first, beyond, ch_traits, check_level);
|
||||
case ch_DEFAULT:
|
||||
default:
|
||||
convex_hull_2(first, beyond, std::back_inserter(VO), ch_traits);
|
||||
break;
|
||||
}
|
||||
|
||||
switch(check_level)
|
||||
{
|
||||
case ch_CHECK_CONVEXITY:
|
||||
return is_ccw_strongly_convex_2(VO.begin(), VO.end(), ch_traits);
|
||||
case ch_CHECK_CONTAINEMENT:
|
||||
return ch_brute_force_check_2(first, beyond, VO.begin(), VO.end(), ch_traits);
|
||||
case ch_NO_CHECK:
|
||||
return true;
|
||||
case ch_CHECK_ALL:
|
||||
default:
|
||||
return is_ccw_strongly_convex_2(VO.begin(), VO.end(), ch_traits) &&
|
||||
ch_brute_force_check_2(first, beyond, VO.begin(), VO.end(), ch_traits);
|
||||
}
|
||||
}
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#include <CGAL/ch__test_impl.h>
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_CH__TEST_H
|
||||
|
|
|
|||
|
|
@ -1,290 +0,0 @@
|
|||
// ============================================================================
|
||||
//
|
||||
// Copyright (c) 1999 The CGAL Consortium
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// release :
|
||||
// release_date :
|
||||
//
|
||||
// file : ch__test.C
|
||||
// revision : $Id$
|
||||
// revision_date : $Date$
|
||||
// author(s) : Stefan Schirra
|
||||
//
|
||||
// coordinator : MPI, Saarbruecken
|
||||
// ============================================================================
|
||||
|
||||
|
||||
#ifndef CGAL_CH__TEST_IMPL_H
|
||||
#define CGAL_CH__TEST_IMPL_H
|
||||
|
||||
#include <CGAL/ch__test.h>
|
||||
|
||||
namespace CGAL {
|
||||
template <class InputIterator, class Traits>
|
||||
bool
|
||||
ch__test(InputIterator first, InputIterator last, const Traits& ch_traits)
|
||||
{
|
||||
ch_Algorithm alg = ch_ALL;
|
||||
ch_Check_status check_level = ch_CHECK_ALL;
|
||||
typedef typename Traits::Point_2 Point_2;
|
||||
std::vector< Point_2 > VI (first, last);
|
||||
std::vector< Point_2 > VO;
|
||||
typedef typename std::vector< Point_2 >::iterator V_iter;
|
||||
V_iter VIfirst = VI.begin();
|
||||
V_iter VIlast = VI.end();
|
||||
switch (alg)
|
||||
{
|
||||
case ch_JARVIS:
|
||||
ch_jarvis(VIfirst, VIlast, std::back_inserter(VO), ch_traits);
|
||||
break;
|
||||
case ch_GRAHAM_ANDREW:
|
||||
ch_graham_andrew(VIfirst, VIlast, std::back_inserter(VO),
|
||||
ch_traits);
|
||||
break;
|
||||
case ch_EDDY:
|
||||
ch_eddy(VIfirst, VIlast, std::back_inserter(VO),
|
||||
ch_traits);
|
||||
break;
|
||||
case ch_AKL_TOUSSAINT:
|
||||
ch_akl_toussaint( VIfirst, VIlast, std::back_inserter(VO),
|
||||
ch_traits);
|
||||
break;
|
||||
case ch_BYKAT:
|
||||
ch_bykat(VIfirst, VIlast, std::back_inserter(VO),
|
||||
ch_traits);
|
||||
break;
|
||||
case ch_BYKAT_WITH_THRESHOLD:
|
||||
ch_bykat_with_threshold(VIfirst, VIlast, std::back_inserter(VO),
|
||||
ch_traits);
|
||||
break;
|
||||
case ch_LOWER_UPPER:
|
||||
lower_hull_points_2(VIfirst, VIlast, std::back_inserter(VO),
|
||||
ch_traits);
|
||||
upper_hull_points_2(VIfirst, VIlast, std::back_inserter(VO),
|
||||
ch_traits);
|
||||
break;
|
||||
case ch_ALL:
|
||||
return
|
||||
ch__test(VIfirst, VIlast, ch_traits,
|
||||
ch_JARVIS, check_level)
|
||||
&& ch__test(VIfirst, VIlast, ch_traits,
|
||||
ch_GRAHAM_ANDREW, check_level)
|
||||
&& ch__test(VIfirst, VIlast, ch_traits,
|
||||
ch_EDDY, check_level)
|
||||
&& ch__test(VIfirst, VIlast, ch_traits,
|
||||
ch_BYKAT, check_level)
|
||||
&& ch__test(VIfirst, VIlast, ch_traits,
|
||||
ch_BYKAT_WITH_THRESHOLD, check_level)
|
||||
&& ch__test(VIfirst, VIlast, ch_traits,
|
||||
ch_LOWER_UPPER, check_level)
|
||||
&& ch__test(VIfirst, VIlast, ch_traits,
|
||||
ch_AKL_TOUSSAINT, check_level);
|
||||
case ch_DEFAULT:
|
||||
default:
|
||||
convex_hull_2( VIfirst, VIlast, std::back_inserter(VO),
|
||||
ch_traits);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (check_level)
|
||||
{
|
||||
case ch_CHECK_CONVEXITY:
|
||||
return is_ccw_strongly_convex_2( VO.begin(), VO.end(),
|
||||
ch_traits);
|
||||
case ch_CHECK_CONTAINEMENT:
|
||||
return ch_brute_force_check_2( VIfirst, VIlast,
|
||||
VO.begin(), VO.end(),
|
||||
ch_traits);
|
||||
case ch_NO_CHECK:
|
||||
return true;
|
||||
case ch_CHECK_ALL:
|
||||
default:
|
||||
return is_ccw_strongly_convex_2( VO.begin(), VO.end(),
|
||||
ch_traits)
|
||||
&& ch_brute_force_check_2( VIfirst, VIlast,
|
||||
VO.begin(), VO.end(),
|
||||
ch_traits);
|
||||
}
|
||||
}
|
||||
|
||||
template <class InputIterator, class Traits>
|
||||
bool
|
||||
ch__test(InputIterator first, InputIterator last, const Traits& ch_traits,
|
||||
ch_Algorithm alg )
|
||||
{
|
||||
ch_Check_status check_level = ch_CHECK_ALL;
|
||||
typedef typename Traits::Point_2 Point_2;
|
||||
std::vector< Point_2 > VI (first, last);
|
||||
std::vector< Point_2 > VO;
|
||||
typedef typename std::vector< Point_2 >::iterator V_iter;
|
||||
V_iter VIfirst = VI.begin();
|
||||
V_iter VIlast = VI.end();
|
||||
switch (alg)
|
||||
{
|
||||
case ch_JARVIS:
|
||||
ch_jarvis(VIfirst, VIlast, std::back_inserter(VO), ch_traits);
|
||||
break;
|
||||
case ch_GRAHAM_ANDREW:
|
||||
ch_graham_andrew(VIfirst, VIlast, std::back_inserter(VO),
|
||||
ch_traits);
|
||||
break;
|
||||
case ch_EDDY:
|
||||
ch_eddy(VIfirst, VIlast, std::back_inserter(VO),
|
||||
ch_traits);
|
||||
break;
|
||||
case ch_AKL_TOUSSAINT:
|
||||
ch_akl_toussaint( VIfirst, VIlast, std::back_inserter(VO),
|
||||
ch_traits);
|
||||
break;
|
||||
case ch_BYKAT:
|
||||
ch_bykat(VIfirst, VIlast, std::back_inserter(VO),
|
||||
ch_traits);
|
||||
break;
|
||||
case ch_BYKAT_WITH_THRESHOLD:
|
||||
ch_bykat_with_threshold(VIfirst, VIlast, std::back_inserter(VO),
|
||||
ch_traits);
|
||||
break;
|
||||
case ch_LOWER_UPPER:
|
||||
lower_hull_points_2(VIfirst, VIlast, std::back_inserter(VO),
|
||||
ch_traits);
|
||||
upper_hull_points_2(VIfirst, VIlast, std::back_inserter(VO),
|
||||
ch_traits);
|
||||
break;
|
||||
case ch_ALL:
|
||||
return
|
||||
ch__test(VIfirst, VIlast, ch_traits,
|
||||
ch_JARVIS, check_level)
|
||||
&& ch__test(VIfirst, VIlast, ch_traits,
|
||||
ch_GRAHAM_ANDREW, check_level)
|
||||
&& ch__test(VIfirst, VIlast, ch_traits,
|
||||
ch_EDDY, check_level)
|
||||
&& ch__test(VIfirst, VIlast, ch_traits,
|
||||
ch_BYKAT, check_level)
|
||||
&& ch__test(VIfirst, VIlast, ch_traits,
|
||||
ch_BYKAT_WITH_THRESHOLD, check_level)
|
||||
&& ch__test(VIfirst, VIlast, ch_traits,
|
||||
ch_LOWER_UPPER, check_level)
|
||||
&& ch__test(VIfirst, VIlast, ch_traits,
|
||||
ch_AKL_TOUSSAINT, check_level);
|
||||
case ch_DEFAULT:
|
||||
default:
|
||||
( VIfirst, VIlast, std::back_inserter(VO),
|
||||
ch_traits);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (check_level)
|
||||
{
|
||||
case ch_CHECK_CONVEXITY:
|
||||
return is_ccw_strongly_convex_2( VO.begin(), VO.end(),
|
||||
ch_traits);
|
||||
case ch_CHECK_CONTAINEMENT:
|
||||
return ch_brute_force_check_2( VIfirst, VIlast,
|
||||
VO.begin(), VO.end(),
|
||||
ch_traits);
|
||||
case ch_NO_CHECK:
|
||||
return true;
|
||||
case ch_CHECK_ALL:
|
||||
default:
|
||||
return is_ccw_strongly_convex_2( VO.begin(), VO.end(),
|
||||
ch_traits)
|
||||
&& ch_brute_force_check_2( VIfirst, VIlast,
|
||||
VO.begin(), VO.end(),
|
||||
ch_traits);
|
||||
}
|
||||
}
|
||||
|
||||
template <class InputIterator, class Traits>
|
||||
bool
|
||||
ch__test(InputIterator first, InputIterator last, const Traits& ch_traits,
|
||||
ch_Algorithm alg, ch_Check_status check_level)
|
||||
{
|
||||
typedef typename Traits::Point_2 Point_2;
|
||||
std::vector< Point_2 > VI (first, last);
|
||||
std::vector< Point_2 > VO;
|
||||
typedef typename std::vector< Point_2 >::iterator V_iter;
|
||||
V_iter VIfirst = VI.begin();
|
||||
V_iter VIlast = VI.end();
|
||||
switch (alg)
|
||||
{
|
||||
case ch_JARVIS:
|
||||
ch_jarvis(VIfirst, VIlast, std::back_inserter(VO), ch_traits);
|
||||
break;
|
||||
case ch_GRAHAM_ANDREW:
|
||||
ch_graham_andrew(VIfirst, VIlast, std::back_inserter(VO),
|
||||
ch_traits);
|
||||
break;
|
||||
case ch_EDDY:
|
||||
ch_eddy(VIfirst, VIlast, std::back_inserter(VO),
|
||||
ch_traits);
|
||||
break;
|
||||
case ch_AKL_TOUSSAINT:
|
||||
ch_akl_toussaint( VIfirst, VIlast, std::back_inserter(VO),
|
||||
ch_traits);
|
||||
break;
|
||||
case ch_BYKAT:
|
||||
ch_bykat(VIfirst, VIlast, std::back_inserter(VO),
|
||||
ch_traits);
|
||||
break;
|
||||
case ch_BYKAT_WITH_THRESHOLD:
|
||||
ch_bykat_with_threshold(VIfirst, VIlast, std::back_inserter(VO),
|
||||
ch_traits);
|
||||
break;
|
||||
case ch_LOWER_UPPER:
|
||||
lower_hull_points_2(VIfirst, VIlast, std::back_inserter(VO),
|
||||
ch_traits);
|
||||
upper_hull_points_2(VIfirst, VIlast, std::back_inserter(VO),
|
||||
ch_traits);
|
||||
break;
|
||||
case ch_ALL:
|
||||
return
|
||||
ch__test(VIfirst, VIlast, ch_traits,
|
||||
ch_JARVIS, check_level)
|
||||
&& ch__test(VIfirst, VIlast, ch_traits,
|
||||
ch_GRAHAM_ANDREW, check_level)
|
||||
&& ch__test(VIfirst, VIlast, ch_traits,
|
||||
ch_EDDY, check_level)
|
||||
&& ch__test(VIfirst, VIlast, ch_traits,
|
||||
ch_BYKAT, check_level)
|
||||
&& ch__test(VIfirst, VIlast, ch_traits,
|
||||
ch_BYKAT_WITH_THRESHOLD, check_level)
|
||||
&& ch__test(VIfirst, VIlast, ch_traits,
|
||||
ch_LOWER_UPPER, check_level)
|
||||
&& ch__test(VIfirst, VIlast, ch_traits,
|
||||
ch_AKL_TOUSSAINT, check_level);
|
||||
case ch_DEFAULT:
|
||||
default:
|
||||
convex_hull_2( VIfirst, VIlast, std::back_inserter(VO),
|
||||
ch_traits);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (check_level)
|
||||
{
|
||||
case ch_CHECK_CONVEXITY:
|
||||
return is_ccw_strongly_convex_2( VO.begin(), VO.end(),
|
||||
ch_traits);
|
||||
case ch_CHECK_CONTAINEMENT:
|
||||
return ch_brute_force_check_2( VIfirst, VIlast,
|
||||
VO.begin(), VO.end(),
|
||||
ch_traits);
|
||||
case ch_NO_CHECK:
|
||||
return true;
|
||||
case ch_CHECK_ALL:
|
||||
default:
|
||||
return is_ccw_strongly_convex_2( VO.begin(), VO.end(),
|
||||
ch_traits)
|
||||
&& ch_brute_force_check_2( VIfirst, VIlast,
|
||||
VO.begin(), VO.end(),
|
||||
ch_traits);
|
||||
}
|
||||
}
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#endif // CGAL_CH__TEST_IMPL_H
|
||||
|
|
@ -114,7 +114,7 @@ namespace CGAL
|
|||
}
|
||||
};
|
||||
|
||||
struct Less_signed_distance_to_line_2 {
|
||||
struct Compare_signed_distance_to_line_2 {
|
||||
typedef typename R::RT RT;
|
||||
typedef bool result_type;
|
||||
|
||||
|
|
@ -181,8 +181,8 @@ namespace CGAL
|
|||
return Less_yx_2();
|
||||
}
|
||||
|
||||
Less_signed_distance_to_line_2 less_signed_distance_to_line_2_object () const {
|
||||
return Less_signed_distance_to_line_2();
|
||||
Compare_signed_distance_to_line_2 compare_signed_distance_to_line_2_object () const {
|
||||
return Compare_signed_distance_to_line_2();
|
||||
}
|
||||
|
||||
Orientation_2 orientation_2_object () const {
|
||||
|
|
@ -276,7 +276,7 @@ namespace CGAL
|
|||
}
|
||||
};
|
||||
|
||||
struct Less_signed_distance_to_line_2 {
|
||||
struct Compare_signed_distance_to_line_2 {
|
||||
typedef typename R::RT RT;
|
||||
typedef bool result_type;
|
||||
|
||||
|
|
@ -343,8 +343,8 @@ namespace CGAL
|
|||
return Less_yx_2();
|
||||
}
|
||||
|
||||
Less_signed_distance_to_line_2 less_signed_distance_to_line_2_object () const {
|
||||
return Less_signed_distance_to_line_2();
|
||||
Compare_signed_distance_to_line_2 compare_signed_distance_to_line_2_object () const {
|
||||
return Compare_signed_distance_to_line_2();
|
||||
}
|
||||
|
||||
Orientation_2 orientation_2_object () const {
|
||||
|
|
@ -438,7 +438,7 @@ namespace CGAL
|
|||
}
|
||||
};
|
||||
|
||||
struct Less_signed_distance_to_line_2 {
|
||||
struct Compare_signed_distance_to_line_2 {
|
||||
typedef typename R::RT RT;
|
||||
typedef bool result_type;
|
||||
|
||||
|
|
@ -504,8 +504,8 @@ namespace CGAL
|
|||
return Less_yx_2();
|
||||
}
|
||||
|
||||
Less_signed_distance_to_line_2 less_signed_distance_to_line_2_object () const {
|
||||
return Less_signed_distance_to_line_2();
|
||||
Compare_signed_distance_to_line_2 compare_signed_distance_to_line_2_object () const {
|
||||
return Compare_signed_distance_to_line_2();
|
||||
}
|
||||
|
||||
Orientation_2 orientation_2_object () const {
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ public:
|
|||
typedef Convex_hull_3::internal::Forward_functor<
|
||||
typename Btt::Less_yx_2, PointPropertyMap> Less_yx_2;
|
||||
typedef Convex_hull_3::internal::Forward_functor<
|
||||
typename Btt::Less_signed_distance_to_line_2, PointPropertyMap> Less_signed_distance_to_line_2;
|
||||
typename Btt::Compare_signed_distance_to_line_2, PointPropertyMap> Compare_signed_distance_to_line_2;
|
||||
typedef Convex_hull_3::internal::Forward_functor<
|
||||
typename Btt::Left_turn_2, PointPropertyMap> Left_turn_2;
|
||||
|
||||
|
|
@ -219,8 +219,8 @@ public:
|
|||
{ return Less_xy_2(vpm_, static_cast<const Btt*>(this)->less_xy_2_object()); }
|
||||
Less_yx_2 less_yx_2_object() const
|
||||
{ return Less_yx_2(vpm_, static_cast<const Btt*>(this)->less_yx_2_object()); }
|
||||
Less_signed_distance_to_line_2 less_signed_distance_to_line_2_object() const
|
||||
{ return Less_signed_distance_to_line_2(vpm_, static_cast<const Btt*>(this)->Less_signed_distance_to_line_2()); }
|
||||
Compare_signed_distance_to_line_2 compare_signed_distance_to_line_2_object() const
|
||||
{ return Compare_signed_distance_to_line_2(vpm_, static_cast<const Btt*>(this)->Compare_signed_distance_to_line_2()); }
|
||||
Less_rotate_ccw_2 less_rotate_ccw_2_object() const
|
||||
{ return Less_rotate_ccw_2(vpm_, static_cast<const Btt*>(this)->less_rotate_ccw_2_object()); }
|
||||
Left_turn_2 left_turn_2_object() const
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
\cgalAutoToc
|
||||
|
||||
\cgal \cgalReleaseNumber is supported for the following \ms Visual `C++` compilers:
|
||||
14.0, 15.9, 16.0 (\visualstudio 2015, 2017, and 2019).
|
||||
14.0, 15.9, 16.0, 17.0 (\visualstudio 2015, 2017, 2019, and 2022).
|
||||
|
||||
\cgal is a library that has mandatory dependencies that must be first installed:
|
||||
\ref thirdpartyBoost and \ref thirdpartyMPFR.
|
||||
|
|
|
|||
|
|
@ -63,25 +63,28 @@ num_edges(const HalfedgeDS_default<T,I,A>& p)
|
|||
template<class T, class I, class A>
|
||||
typename boost::graph_traits< HalfedgeDS_default<T,I,A> const>::degree_size_type
|
||||
degree(typename boost::graph_traits< HalfedgeDS_default<T,I,A> const>::vertex_descriptor v
|
||||
, const HalfedgeDS_default<T,I,A>&)
|
||||
, const HalfedgeDS_default<T,I,A>& hds)
|
||||
{
|
||||
return v->vertex_degree();
|
||||
if(halfedge(v,hds) == boost::graph_traits<HalfedgeDS_default<T,I,A> const>::null_halfedge()){
|
||||
return 0;
|
||||
}
|
||||
return halfedges_around_target(v,hds).size();
|
||||
}
|
||||
|
||||
template<class T, class I, class A>
|
||||
typename boost::graph_traits< HalfedgeDS_default<T,I,A> const>::degree_size_type
|
||||
out_degree(typename boost::graph_traits< HalfedgeDS_default<T,I,A> const>::vertex_descriptor v
|
||||
, const HalfedgeDS_default<T,I,A>&)
|
||||
, const HalfedgeDS_default<T,I,A>& hds)
|
||||
{
|
||||
return v->vertex_degree();
|
||||
return degree(v, hds);
|
||||
}
|
||||
|
||||
template<class T, class I, class A>
|
||||
typename boost::graph_traits< HalfedgeDS_default<T,I,A> const>::degree_size_type
|
||||
in_degree(typename boost::graph_traits< HalfedgeDS_default<T,I,A> const>::vertex_descriptor v
|
||||
, const HalfedgeDS_default<T,I,A>&)
|
||||
, const HalfedgeDS_default<T,I,A>& hds)
|
||||
{
|
||||
return v->vertex_degree();
|
||||
return degree(v,hds);
|
||||
}
|
||||
|
||||
template<class T, class I, class A>
|
||||
|
|
@ -448,29 +451,6 @@ num_faces(const HalfedgeDS_default<T,I,A>& p)
|
|||
return p.size_of_faces();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct HDS_property_map;
|
||||
|
||||
template <>
|
||||
struct HDS_property_map<vertex_point_t>
|
||||
{
|
||||
template<class T, class I, class A>
|
||||
struct bind_
|
||||
{
|
||||
typedef internal::Point_accessor<
|
||||
typename boost::graph_traits<
|
||||
HalfedgeDS_default<T, I, A>
|
||||
>::vertex_descriptor,
|
||||
typename T::Point_3, typename T::Point_3&> type;
|
||||
|
||||
typedef internal::Point_accessor<
|
||||
typename boost::graph_traits<
|
||||
HalfedgeDS_default<T, I, A>
|
||||
>::vertex_descriptor,
|
||||
typename T::Point_3, const typename T::Point_3&> const_type;
|
||||
};
|
||||
};
|
||||
|
||||
template<class T, class I, class A>
|
||||
void reserve(HalfedgeDS_default<T,I,A>& p,
|
||||
typename boost::graph_traits< HalfedgeDS_default<T,I,A> const>::vertices_size_type nv,
|
||||
|
|
@ -481,37 +461,7 @@ void reserve(HalfedgeDS_default<T,I,A>& p,
|
|||
}
|
||||
|
||||
}// namespace CGAL
|
||||
namespace boost {
|
||||
|
||||
#define CGAL_PM_SPECIALIZATION(TAG) \
|
||||
template<class T, class I, class A> \
|
||||
struct property_map<CGAL::HalfedgeDS_default<T,I,A>, TAG> \
|
||||
{\
|
||||
typedef typename CGAL::HDS_property_map<TAG>:: \
|
||||
template bind_<T,I,A> map_gen; \
|
||||
typedef typename map_gen::type type; \
|
||||
typedef typename map_gen::const_type const_type; \
|
||||
};
|
||||
#include <CGAL/boost/graph/properties_HalfedgeDS_default.h>
|
||||
|
||||
CGAL_PM_SPECIALIZATION(vertex_point_t)
|
||||
|
||||
#undef CGAL_PM_SPECIALIZATION
|
||||
|
||||
} // namespace boost
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
// generalized 2-ary get functions
|
||||
template<class Gt, class I, class A, class PropertyTag>
|
||||
typename boost::property_map< CGAL::HalfedgeDS_default<Gt,I,A>, PropertyTag >::const_type
|
||||
get(PropertyTag, CGAL::HalfedgeDS_default<Gt,I,A> const&)
|
||||
{ return typename boost::property_map< CGAL::HalfedgeDS_default<Gt,I,A>, PropertyTag >::const_type(); }
|
||||
|
||||
template<class Gt, class I, class A, class PropertyTag>
|
||||
typename boost::property_map< CGAL::HalfedgeDS_default<Gt,I,A>, PropertyTag >::type
|
||||
get(PropertyTag, CGAL::HalfedgeDS_default<Gt,I,A>&)
|
||||
{ return typename boost::property_map< CGAL::HalfedgeDS_default<Gt,I,A>, PropertyTag >::type(); }
|
||||
|
||||
|
||||
} // namespace CGAL
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,494 @@
|
|||
// Copyright (c) 2007 GeometryFactory (France). All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org)
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
// Author(s) : Andreas Fabri, Fernando Cacciola
|
||||
|
||||
// note only the properties below are protected by the macro,
|
||||
// the rest of the file is the shared implementation of properties for
|
||||
// Polyhedron and HalfedgeDS_default
|
||||
#ifndef CGAL_BOOST_GRAPH_PROPERTIES_HALFEDGEDS_BASE_H
|
||||
#define CGAL_BOOST_GRAPH_PROPERTIES_HALFEDGEDS_BASE_H
|
||||
|
||||
#include <CGAL/boost/graph/properties.h>
|
||||
#include <CGAL/Unique_hash_map.h>
|
||||
#include <CGAL/number_utils.h>
|
||||
#include <memory>
|
||||
#include <CGAL/boost/graph/internal/Has_member_id.h>
|
||||
#include <CGAL/Distance_3/Point_3_Point_3.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<class Handle>
|
||||
class HDS_index_map_external
|
||||
: public boost::put_get_helper<std::size_t&, HDS_index_map_external<Handle> >
|
||||
{
|
||||
public:
|
||||
typedef boost::lvalue_property_map_tag category;
|
||||
typedef std::size_t value_type;
|
||||
typedef std::size_t& reference;
|
||||
typedef Handle key_type;
|
||||
|
||||
private:
|
||||
typedef CGAL::Unique_hash_map<key_type,std::size_t> Map;
|
||||
|
||||
public:
|
||||
template <typename InputIterator>
|
||||
HDS_index_map_external(InputIterator begin, InputIterator end, std::size_t max)
|
||||
: map_(new Map(begin, end, 0, std::size_t(-1), max)) {}
|
||||
|
||||
reference operator[](const key_type& k) const { return (*map_)[k]; }
|
||||
private:
|
||||
std::shared_ptr<Map> map_;
|
||||
};
|
||||
|
||||
// Special case for edges.
|
||||
template<class Polyhedron>
|
||||
class HDS_edge_index_map_external
|
||||
: public boost::put_get_helper<std::size_t&, HDS_edge_index_map_external<Polyhedron> >
|
||||
{
|
||||
public:
|
||||
typedef boost::lvalue_property_map_tag category;
|
||||
typedef std::size_t value_type;
|
||||
typedef std::size_t& reference;
|
||||
typedef typename boost::graph_traits<Polyhedron>::edge_descriptor key_type;
|
||||
|
||||
private:
|
||||
typedef CGAL::Unique_hash_map<key_type,std::size_t> Map;
|
||||
|
||||
public:
|
||||
HDS_edge_index_map_external(Polyhedron& p)
|
||||
: map_(new Map(std::size_t(-1), num_halfedges(p)))
|
||||
{
|
||||
unsigned int data = 0;
|
||||
typename boost::graph_traits<Polyhedron>::edge_iterator it, end;
|
||||
for(boost::tie(it, end) = edges(p); it != end; ++it, ++data)
|
||||
(*map_)[*it] = data;
|
||||
}
|
||||
|
||||
reference operator[](const key_type& k) const { return (*map_)[k]; }
|
||||
private:
|
||||
std::shared_ptr<Map> map_;
|
||||
};
|
||||
|
||||
template<typename Handle, typename FT>
|
||||
struct HDS_wrap_squared
|
||||
{
|
||||
typedef FT value_type;
|
||||
typedef FT reference;
|
||||
typedef Handle key_type;
|
||||
typedef boost::readable_property_map_tag category;
|
||||
|
||||
template<typename E>
|
||||
FT operator[](const E& e) const {
|
||||
return approximate_sqrt(CGAL::squared_distance(e.halfedge()->vertex()->point(),
|
||||
e.halfedge()->opposite()->vertex()->point()));
|
||||
}
|
||||
|
||||
friend inline
|
||||
value_type get(const HDS_wrap_squared& m, const key_type k)
|
||||
{
|
||||
return m[k];
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// the tag we dispatch on from property_map<G, Property>
|
||||
template <class HDS, class Tag>
|
||||
struct HDS_property_map {};
|
||||
|
||||
} // end of CGAL::internal namespace
|
||||
|
||||
#endif // CGAL_BOOST_GRAPH_PROPERTIES_HALFEDGEDS_BASE_H
|
||||
|
||||
#if !defined(CGAL_HDS_TMPLT) || ! defined(CGAL_HDS_CLASS)
|
||||
#error CGAL_HDS_TMPLT or CGAL_HDS_CLASS is not defined
|
||||
#endif
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
// generalized 2-ary get functions
|
||||
template<class CGAL_HDS_TMPLT, class PropertyTag>
|
||||
typename boost::property_map<CGAL_HDS_CLASS, PropertyTag >::const_type
|
||||
get(PropertyTag,CGAL_HDS_CLASS const&)
|
||||
{ return typename boost::property_map<CGAL_HDS_CLASS, PropertyTag >::const_type(); }
|
||||
|
||||
template<class CGAL_HDS_TMPLT, class PropertyTag>
|
||||
typename boost::property_map<CGAL_HDS_CLASS, PropertyTag >::type
|
||||
get(PropertyTag,CGAL_HDS_CLASS&)
|
||||
{ return typename boost::property_map<CGAL_HDS_CLASS, PropertyTag >::type(); }
|
||||
|
||||
// generalized 3-ary get functions
|
||||
template<class CGAL_HDS_TMPLT, class PropertyTag, class Key>
|
||||
typename boost::property_traits< typename boost::property_map<CGAL_HDS_CLASS, PropertyTag >::type >::reference
|
||||
get(PropertyTag p,CGAL_HDS_CLASS& g, const Key& key)
|
||||
{ return get(get(p, g), key); }
|
||||
|
||||
template<class CGAL_HDS_TMPLT, class PropertyTag, class Key>
|
||||
typename boost::property_traits< typename boost::property_map<CGAL_HDS_CLASS, PropertyTag >::const_type >::reference
|
||||
get(PropertyTag p,CGAL_HDS_CLASS const& g, const Key& key)
|
||||
{ return get(get(p, g), key); }
|
||||
|
||||
|
||||
|
||||
#define DECLARE_HDS_DYNAMIC_PM(TAG, DESCRIPTOR) \
|
||||
template <typename CGAL_HDS_TMPLT, class T> \
|
||||
typename boost::property_map<CGAL_HDS_CLASS, TAG >::const_type \
|
||||
get(const TAG&, const CGAL_HDS_CLASS&) \
|
||||
{ \
|
||||
typedef typename boost::graph_traits< CGAL_HDS_CLASS >::DESCRIPTOR descriptor; \
|
||||
return internal::Dynamic_property_map<descriptor,T>(); \
|
||||
}
|
||||
|
||||
DECLARE_HDS_DYNAMIC_PM(dynamic_vertex_property_t<T>, vertex_descriptor)
|
||||
DECLARE_HDS_DYNAMIC_PM(dynamic_halfedge_property_t<T>, halfedge_descriptor)
|
||||
DECLARE_HDS_DYNAMIC_PM(dynamic_edge_property_t<T>, edge_descriptor)
|
||||
DECLARE_HDS_DYNAMIC_PM(dynamic_face_property_t<T>, face_descriptor)
|
||||
|
||||
#undef DECLARE_HDS_DYNAMIC_PM
|
||||
|
||||
// generalized put
|
||||
template<class CGAL_HDS_TMPLT, class PropertyTag, class Key,class Value>
|
||||
void put(PropertyTag p,CGAL_HDS_CLASS& g, const Key& key, const Value& value)
|
||||
{
|
||||
typedef typename boost::property_map<CGAL_HDS_CLASS, PropertyTag>::type Map;
|
||||
Map pmap = get(p, g);
|
||||
put(pmap, key, value);
|
||||
}
|
||||
|
||||
// specialization needs to be repeated for halfedge, vertex, face
|
||||
#define DECLARE_HDS_INDEX_PM(ENTITY, TAG, ACCESSOR) \
|
||||
template<class CGAL_HDS_TMPLT> \
|
||||
struct HDS_property_map<CGAL_HDS_CLASS, \
|
||||
boost::ENTITY##TAG> { \
|
||||
struct bind_ { \
|
||||
typedef internal::ACCESSOR##_accessor< \
|
||||
CGAL_HDS_CLASS, \
|
||||
typename boost::graph_traits< CGAL_HDS_CLASS \
|
||||
>::ENTITY##_descriptor > type;\
|
||||
typedef type const_type; \
|
||||
}; \
|
||||
};
|
||||
|
||||
DECLARE_HDS_INDEX_PM(halfedge, _index_t, Index)
|
||||
DECLARE_HDS_INDEX_PM(vertex, _index_t, Index)
|
||||
DECLARE_HDS_INDEX_PM(face, _index_t, Index)
|
||||
|
||||
} // end of CGAL namespace
|
||||
|
||||
#undef DECLARE_HDS_INDEX_PM
|
||||
|
||||
namespace CGAL {
|
||||
// not done with macros, because HDS_edge::id does not return a
|
||||
// reference
|
||||
template<class CGAL_HDS_TMPLT>
|
||||
struct HDS_property_map<CGAL_HDS_CLASS, boost::edge_index_t>
|
||||
{
|
||||
struct bind_
|
||||
{
|
||||
typedef internal::Edge_index_accessor<
|
||||
typename boost::graph_traits<
|
||||
CGAL_HDS_CLASS
|
||||
>::edge_descriptor > type;
|
||||
typedef type const_type;
|
||||
};
|
||||
};
|
||||
|
||||
template<class CGAL_HDS_TMPLT>
|
||||
struct HDS_property_map<CGAL_HDS_CLASS, boost::edge_weight_t>
|
||||
{
|
||||
struct bind_
|
||||
{
|
||||
typedef typename CGAL_HDS_CLASS::Traits::FT FT;
|
||||
typedef typename boost::graph_traits<CGAL_HDS_CLASS >::edge_descriptor edge_descriptor;
|
||||
typedef internal::HDS_wrap_squared<edge_descriptor,FT> type;
|
||||
typedef type const_type;
|
||||
};
|
||||
};
|
||||
|
||||
template<class CGAL_HDS_TMPLT>
|
||||
struct HDS_property_map<CGAL_HDS_CLASS,vertex_point_t>
|
||||
{
|
||||
struct bind_
|
||||
{
|
||||
typedef internal::Point_accessor<
|
||||
typename boost::graph_traits<
|
||||
CGAL_HDS_CLASS
|
||||
>::vertex_descriptor,
|
||||
typename Gt::Point_3, typename Gt::Point_3&> type;
|
||||
|
||||
typedef internal::Point_accessor<
|
||||
typename boost::graph_traits<
|
||||
CGAL_HDS_CLASS
|
||||
>::vertex_descriptor,
|
||||
typename Gt::Point_3, const typename Gt::Point_3&> const_type;
|
||||
};
|
||||
};
|
||||
|
||||
//
|
||||
// external indices
|
||||
//
|
||||
|
||||
template<class CGAL_HDS_TMPLT>
|
||||
struct HDS_property_map<CGAL_HDS_CLASS, edge_external_index_t>
|
||||
{
|
||||
struct bind_
|
||||
{
|
||||
typedef internal::HDS_edge_index_map_external<
|
||||
CGAL_HDS_CLASS
|
||||
> type;
|
||||
typedef type const_type;
|
||||
};
|
||||
};
|
||||
|
||||
template<class CGAL_HDS_TMPLT>
|
||||
struct HDS_property_map<CGAL_HDS_CLASS, halfedge_external_index_t>
|
||||
{
|
||||
struct bind_
|
||||
{
|
||||
typedef internal::HDS_index_map_external<
|
||||
typename boost::graph_traits<
|
||||
CGAL_HDS_CLASS
|
||||
>::halfedge_descriptor > type;
|
||||
typedef type const_type;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
template<class CGAL_HDS_TMPLT>
|
||||
struct HDS_property_map<CGAL_HDS_CLASS, vertex_external_index_t>
|
||||
{
|
||||
struct bind_
|
||||
{
|
||||
typedef internal::HDS_index_map_external<
|
||||
typename boost::graph_traits<
|
||||
CGAL_HDS_CLASS
|
||||
>::vertex_descriptor > type;
|
||||
typedef type const_type;
|
||||
};
|
||||
};
|
||||
|
||||
template<class CGAL_HDS_TMPLT>
|
||||
struct HDS_property_map<CGAL_HDS_CLASS, face_external_index_t>
|
||||
{
|
||||
struct bind_
|
||||
{
|
||||
typedef internal::HDS_index_map_external<
|
||||
typename boost::graph_traits<
|
||||
CGAL_HDS_CLASS
|
||||
>::face_descriptor > type;
|
||||
typedef type const_type;
|
||||
};
|
||||
};
|
||||
|
||||
template<class CGAL_HDS_TMPLT>
|
||||
typename boost::property_map<CGAL_HDS_CLASS, boost::edge_external_index_t >::const_type
|
||||
get(boost::edge_external_index_t,CGAL_HDS_CLASS const& p)
|
||||
{
|
||||
return typename boost::property_map<CGAL_HDS_CLASS, boost::edge_external_index_t >::const_type(
|
||||
const_cast<CGAL_HDS_CLASS& >(p));
|
||||
}
|
||||
|
||||
template<class CGAL_HDS_TMPLT>
|
||||
typename boost::property_map<CGAL_HDS_CLASS, boost::halfedge_external_index_t >::const_type
|
||||
get(boost::halfedge_external_index_t,CGAL_HDS_CLASS const& p)
|
||||
{
|
||||
CGAL_HDS_CLASS& ncp = const_cast<CGAL_HDS_CLASS&>(p);
|
||||
|
||||
return typename boost::property_map<CGAL_HDS_CLASS, boost::halfedge_external_index_t >::const_type(
|
||||
ncp.halfedges_begin(), ncp.halfedges_end(), ncp.size_of_halfedges());
|
||||
}
|
||||
|
||||
template<class CGAL_HDS_TMPLT>
|
||||
typename boost::property_map<CGAL_HDS_CLASS, boost::vertex_external_index_t >::const_type
|
||||
get(boost::vertex_external_index_t,CGAL_HDS_CLASS const& p)
|
||||
{
|
||||
CGAL_HDS_CLASS& ncp = const_cast<CGAL_HDS_CLASS&>(p);
|
||||
|
||||
return typename boost::property_map<CGAL_HDS_CLASS, boost::vertex_external_index_t >::const_type(
|
||||
ncp.vertices_begin(), ncp.vertices_end(), ncp.size_of_vertices());
|
||||
}
|
||||
|
||||
template<class CGAL_HDS_TMPLT>
|
||||
typename boost::property_map<CGAL_HDS_CLASS, boost::face_external_index_t >::const_type
|
||||
get(boost::face_external_index_t,CGAL_HDS_CLASS const& p)
|
||||
{
|
||||
CGAL_HDS_CLASS& ncp = const_cast<CGAL_HDS_CLASS&>(p);
|
||||
|
||||
return typename boost::property_map<CGAL_HDS_CLASS, boost::face_external_index_t >::const_type(
|
||||
ncp.facets_begin(), ncp.facets_end(), ncp.size_of_facets());
|
||||
}
|
||||
|
||||
// the same blurb for non-const
|
||||
|
||||
template<class CGAL_HDS_TMPLT>
|
||||
typename boost::property_map<CGAL_HDS_CLASS, boost::edge_external_index_t >::type
|
||||
get(boost::edge_external_index_t,CGAL_HDS_CLASS& p)
|
||||
{
|
||||
return typename boost::property_map<CGAL_HDS_CLASS, boost::edge_external_index_t >::type(
|
||||
p);
|
||||
}
|
||||
|
||||
template<class CGAL_HDS_TMPLT>
|
||||
typename boost::property_map<CGAL_HDS_CLASS, boost::halfedge_external_index_t >::type
|
||||
get(boost::halfedge_external_index_t,CGAL_HDS_CLASS & ncp)
|
||||
{
|
||||
return typename boost::property_map<CGAL_HDS_CLASS, boost::halfedge_external_index_t >::type(
|
||||
ncp.halfedges_begin(), ncp.halfedges_end(), ncp.size_of_halfedges());
|
||||
}
|
||||
|
||||
template<class CGAL_HDS_TMPLT>
|
||||
typename boost::property_map<CGAL_HDS_CLASS, boost::vertex_external_index_t >::type
|
||||
get(boost::vertex_external_index_t,CGAL_HDS_CLASS & ncp)
|
||||
{
|
||||
return typename boost::property_map<CGAL_HDS_CLASS, boost::vertex_external_index_t >::type(
|
||||
ncp.vertices_begin(), ncp.vertices_end(), ncp.size_of_vertices());
|
||||
}
|
||||
|
||||
|
||||
template<class CGAL_HDS_TMPLT>
|
||||
typename boost::property_map<CGAL_HDS_CLASS, boost::face_external_index_t >::type
|
||||
get(boost::face_external_index_t,CGAL_HDS_CLASS & ncp)
|
||||
{
|
||||
return typename boost::property_map<CGAL_HDS_CLASS, boost::face_external_index_t >::type(
|
||||
ncp.facets_begin(), ncp.facets_end(), ncp.size_of_facets());
|
||||
}
|
||||
|
||||
} // end of CGAL namespace
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
// property_map dispatcher into Polyhedron
|
||||
template<class CGAL_HDS_TMPLT, class Tag>
|
||||
struct property_map<CGAL_HDS_CLASS, Tag>
|
||||
{
|
||||
typedef typename CGAL::HDS_property_map<CGAL_HDS_CLASS, Tag>::
|
||||
bind_ map_gen;
|
||||
typedef typename map_gen::type type;
|
||||
typedef typename map_gen::const_type const_type;
|
||||
};
|
||||
|
||||
// property_map dispatcher into const Polyhedron
|
||||
template<class CGAL_HDS_TMPLT, class Tag>
|
||||
struct property_map<const CGAL_HDS_CLASS, Tag>
|
||||
{
|
||||
typedef typename CGAL::HDS_property_map<CGAL_HDS_CLASS, Tag>::
|
||||
bind_ map_gen;
|
||||
typedef typename map_gen::type type;
|
||||
typedef typename map_gen::const_type const_type;
|
||||
};
|
||||
|
||||
template<class CGAL_HDS_TMPLT, class T>
|
||||
struct property_map<CGAL_HDS_CLASS, CGAL::dynamic_vertex_property_t<T> >
|
||||
{
|
||||
typedef CGAL_HDS_CLASS G;
|
||||
typedef typename boost::graph_traits<G>::vertex_descriptor vertex_descriptor;
|
||||
typedef CGAL::internal::Dynamic_property_map<vertex_descriptor,T> type;
|
||||
typedef type const_type;
|
||||
};
|
||||
|
||||
template<class CGAL_HDS_TMPLT, class T>
|
||||
struct property_map<CGAL_HDS_CLASS, CGAL::dynamic_halfedge_property_t<T> >
|
||||
{
|
||||
typedef CGAL_HDS_CLASS G;
|
||||
typedef typename boost::graph_traits<G>::halfedge_descriptor halfedge_descriptor;
|
||||
typedef CGAL::internal::Dynamic_property_map<halfedge_descriptor,T> type;
|
||||
typedef type const_type;
|
||||
};
|
||||
|
||||
template<class CGAL_HDS_TMPLT, class T>
|
||||
struct property_map<CGAL_HDS_CLASS, CGAL::dynamic_edge_property_t<T> >
|
||||
{
|
||||
typedef CGAL_HDS_CLASS G;
|
||||
typedef typename boost::graph_traits<G>::edge_descriptor edge_descriptor;
|
||||
typedef CGAL::internal::Dynamic_property_map<edge_descriptor,T> type;
|
||||
typedef type const_type;
|
||||
};
|
||||
|
||||
template<class CGAL_HDS_TMPLT, class T>
|
||||
struct property_map<CGAL_HDS_CLASS, CGAL::dynamic_face_property_t<T> >
|
||||
{
|
||||
typedef CGAL_HDS_CLASS G;
|
||||
typedef typename boost::graph_traits<G>::face_descriptor face_descriptor;
|
||||
typedef CGAL::internal::Dynamic_property_map<face_descriptor,T> type;
|
||||
typedef type const_type;
|
||||
};
|
||||
|
||||
// What are those needed for ???
|
||||
template<class CGAL_HDS_TMPLT>
|
||||
struct edge_property_type<CGAL_HDS_CLASS >
|
||||
{
|
||||
typedef edge_weight_t type;
|
||||
};
|
||||
|
||||
template<class CGAL_HDS_TMPLT>
|
||||
struct vertex_property_type<CGAL_HDS_CLASS >
|
||||
{
|
||||
typedef CGAL::vertex_point_t type;
|
||||
};
|
||||
|
||||
template<class CGAL_HDS_TMPLT>
|
||||
struct vertex_property_type<const CGAL_HDS_CLASS >
|
||||
{
|
||||
typedef CGAL::vertex_point_t type;
|
||||
};
|
||||
|
||||
} // end of boost namespace
|
||||
|
||||
namespace CGAL{
|
||||
template<class CGAL_HDS_TMPLT>
|
||||
struct graph_has_property<CGAL_HDS_CLASS, boost::vertex_point_t>
|
||||
: CGAL::Tag_true {};
|
||||
|
||||
template<class CGAL_HDS_TMPLT>
|
||||
struct graph_has_property<CGAL_HDS_CLASS, boost::edge_weight_t>
|
||||
: CGAL::Tag_true {};
|
||||
|
||||
template<class CGAL_HDS_TMPLT>
|
||||
struct graph_has_property<CGAL_HDS_CLASS, boost::edge_index_t>
|
||||
: CGAL::Boolean_tag<
|
||||
CGAL::internal::Has_member_id<
|
||||
typename boost::graph_traits<CGAL_HDS_CLASS >::edge_descriptor
|
||||
>::value
|
||||
>
|
||||
{};
|
||||
|
||||
template<class CGAL_HDS_TMPLT>
|
||||
struct graph_has_property<CGAL_HDS_CLASS, boost::face_index_t>
|
||||
: CGAL::Boolean_tag<
|
||||
CGAL::internal::Has_member_id<
|
||||
typename CGAL_HDS_CLASS::Facet
|
||||
>::value
|
||||
>
|
||||
{};
|
||||
|
||||
template<class CGAL_HDS_TMPLT>
|
||||
struct graph_has_property<CGAL_HDS_CLASS, boost::halfedge_index_t>
|
||||
: CGAL::Boolean_tag<
|
||||
CGAL::internal::Has_member_id<
|
||||
typename CGAL_HDS_CLASS::Halfedge
|
||||
>::value
|
||||
>
|
||||
{};
|
||||
|
||||
template<class CGAL_HDS_TMPLT>
|
||||
struct graph_has_property<CGAL_HDS_CLASS, boost::vertex_index_t>
|
||||
: CGAL::Boolean_tag<
|
||||
CGAL::internal::Has_member_id<
|
||||
typename CGAL_HDS_CLASS::Vertex
|
||||
>::value
|
||||
>
|
||||
{};
|
||||
}// end of CGAL namespace
|
||||
|
||||
#undef CGAL_HDS_TMPLT
|
||||
#undef CGAL_HDS_CLASS
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright (c) 2007 GeometryFactory (France). All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org)
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
// Author(s) : Andreas Fabri, Fernando Cacciola
|
||||
|
||||
#ifndef CGAL_BOOST_GRAPH_PROPERTIES_HALFEDGEDS_DEFAULT_H
|
||||
#define CGAL_BOOST_GRAPH_PROPERTIES_HALFEDGEDS_DEFAULT_H
|
||||
|
||||
#define CGAL_HDS_TMPLT Gt, class I, class A
|
||||
#define CGAL_HDS_CLASS CGAL::HalfedgeDS_default<Gt,I,A>
|
||||
|
||||
#include <CGAL/boost/graph/properties_HalfedgeDS_base.h>
|
||||
|
||||
#endif // CGAL_BOOST_GRAPH_PROPERTIES_HALFEDGEDS_DEFAULT_H
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
Algebraic_foundations
|
||||
BGL
|
||||
Circulator
|
||||
Distance_3
|
||||
HalfedgeDS
|
||||
Hash_map
|
||||
Installation
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@
|
|||
|
||||
#include <CGAL/boost/graph/graph_traits_Surface_mesh.h>
|
||||
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
|
||||
#include <CGAL/boost/graph/properties_Polyhedron_3.h>
|
||||
#include <CGAL/boost/graph/helpers.h>
|
||||
#include <CGAL/Timer.h>
|
||||
#include<boost/range/iterator_range.hpp>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ Release History
|
|||
[Release 5.6](https://github.com/CGAL/cgal/releases/tag/v5.6)
|
||||
-----------
|
||||
|
||||
Release date: Dec 2022
|
||||
Release date: December 2022
|
||||
|
||||
### [Polygon Mesh Processing](https://doc.cgal.org/5.6/Manual/packages.html#PkgPolygonMeshProcessing)
|
||||
|
||||
|
|
@ -15,7 +15,13 @@ CGAL tetrahedral Delaunay refinement algorithm.
|
|||
|
||||
- This new package wraps all the existing code that deals with a `MeshComplex_3InTriangulation_3` to describe 3D simplicial meshess, and makes the data structure independent from the tetrahedral mesh generation package.
|
||||
|
||||
### [2D Convex Hulls](https://doc.cgal.org/5.6/Manual/packages.html#PkgConvexHull2)
|
||||
|
||||
- **Breaking change**: The concept `ConvexHullTraits_2` no longer requires the functor
|
||||
`Less_signed_distance_to_line_2`, but requires the functor `Compare_signed_distance_to_line_2` instead.
|
||||
- The long-deprecated classes `Convex_hull_projective_xy_traits_2`, `Convex_hull_projective_xz_traits_2`,
|
||||
and `Convex_hull_projective_yz_traits_2` have been removed. Users should use `Projection_traits_xy_3`,
|
||||
`Projection_traits_xz_3`, and `Projection_traits_yz_3` instead.
|
||||
|
||||
[Release 5.5](https://github.com/CGAL/cgal/releases/tag/v5.5)
|
||||
-----------
|
||||
|
|
@ -36,6 +42,11 @@ Release date: June 2022
|
|||
|
||||
See also the [announcement page](https://www.cgal.org/2022/05/18/alpha_wrap/).
|
||||
|
||||
### [2D Straight Skeleton and Polygon Offsetting (breaking change)](https://doc.cgal.org/5.5/Manual/packages.html#PkgStraightSkeleton2)
|
||||
- Fix the output of the function [CGAL::create_exterior_skeleton_and_offset_polygons_with_holes_2()](https://doc.cgal.org/5.5/Straight_skeleton_2/group__PkgStraightSkeleton2OffsetFunctions.html#gaa159f093e5d6d7fdb62c1660a44f95fe)
|
||||
to not take into account the offset of the outer frame.
|
||||
- Fix the computation of the exterior offset of a polygon with holes that was not computing the offset of the holes
|
||||
|
||||
### [3D Convex Hulls](https://doc.cgal.org/5.5/Manual/packages.html#PkgConvexHull3)
|
||||
|
||||
- Added an [overload of the function `CGAL::convex_hull_3()`](https://doc.cgal.org/5.5/Convex_hull_3/group__PkgConvexHull3Functions.html#ga52fca4745c2ef0351063fbe66b035fd1), which writes the result in an indexed triangle set.
|
||||
|
|
|
|||
|
|
@ -250,6 +250,32 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
template <class R, int dim>
|
||||
class Compare_signed_distance_to_line_projected_3
|
||||
{
|
||||
public:
|
||||
typedef typename R::Point_3 Point_3;
|
||||
typedef typename R::Point_2 Point_2;
|
||||
typedef typename R::FT RT;
|
||||
typename R::FT x(const Point_3 &p) const { return Projector<R,dim>::x(p); }
|
||||
typename R::FT y(const Point_3 &p) const { return Projector<R,dim>::y(p); }
|
||||
typedef typename R::Comparison_result result_type;
|
||||
|
||||
Point_2 project(const Point_3& p) const
|
||||
{
|
||||
return Point_2(x(p),y(p));
|
||||
}
|
||||
|
||||
result_type operator()(const Point_3& p,
|
||||
const Point_3& q,
|
||||
const Point_3& r,
|
||||
const Point_3& s) const
|
||||
{
|
||||
return typename R::Compare_signed_distance_to_line_2()
|
||||
( project(p), project(q), project(r), project(s) );
|
||||
}
|
||||
};
|
||||
|
||||
template <class R, int dim>
|
||||
class Less_signed_distance_to_line_projected_3
|
||||
{
|
||||
|
|
@ -259,7 +285,7 @@ public:
|
|||
typedef typename R::FT RT;
|
||||
typename R::FT x(const Point_3 &p) const { return Projector<R,dim>::x(p); }
|
||||
typename R::FT y(const Point_3 &p) const { return Projector<R,dim>::y(p); }
|
||||
typedef bool result_type;
|
||||
typedef typename R::Boolean result_type;
|
||||
|
||||
Point_2 project(const Point_3& p) const
|
||||
{
|
||||
|
|
@ -276,7 +302,6 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
template <class R,int dim>
|
||||
class Squared_distance_projected_3
|
||||
{
|
||||
|
|
@ -910,6 +935,7 @@ public:
|
|||
typedef Oriented_side_projected_3<Rp,dim> Oriented_side_2;
|
||||
typedef Angle_projected_3<Rp,dim> Angle_2;
|
||||
typedef Side_of_oriented_circle_projected_3<Rp,dim> Side_of_oriented_circle_2;
|
||||
typedef Compare_signed_distance_to_line_projected_3<Rp,dim> Compare_signed_distance_to_line_2;
|
||||
typedef Less_signed_distance_to_line_projected_3<Rp,dim> Less_signed_distance_to_line_2;
|
||||
typedef Side_of_bounded_circle_projected_3<Rp,dim> Side_of_bounded_circle_2;
|
||||
typedef Compare_distance_projected_3<Rp,dim> Compare_distance_2;
|
||||
|
|
@ -946,7 +972,7 @@ public:
|
|||
|
||||
|
||||
struct Less_xy_2 {
|
||||
typedef bool result_type;
|
||||
typedef typename R::Boolean result_type;
|
||||
bool operator()(const Point_2& p, const Point_2& q) const
|
||||
{
|
||||
Compare_x_2 cx;
|
||||
|
|
@ -960,7 +986,7 @@ public:
|
|||
|
||||
|
||||
struct Less_yx_2 {
|
||||
typedef bool result_type;
|
||||
typedef typename R::Boolean result_type;
|
||||
bool operator()(const Point_2& p, const Point_2& q) const
|
||||
{
|
||||
Compare_y_2 cy;
|
||||
|
|
@ -973,18 +999,18 @@ public:
|
|||
};
|
||||
|
||||
struct Equal_2 {
|
||||
typedef bool result_type;
|
||||
typedef typename R::Boolean result_type;
|
||||
bool operator()(const Point_2& p, const Point_2& q) const
|
||||
{
|
||||
|
||||
Equal_x_2 eqx;
|
||||
Equal_y_2 eqy;
|
||||
return eqx(p,q) & eqy(p,q);
|
||||
return eqx(p,q) && eqy(p,q);
|
||||
}
|
||||
};
|
||||
|
||||
struct Left_turn_2 {
|
||||
typedef bool result_type;
|
||||
typedef typename R::Boolean result_type;
|
||||
bool operator()(const Point_2& p, const Point_2& q, const Point_2& r) const
|
||||
{
|
||||
|
||||
|
|
@ -994,7 +1020,7 @@ public:
|
|||
};
|
||||
|
||||
struct Collinear_2 {
|
||||
typedef bool result_type;
|
||||
typedef typename R::Boolean result_type;
|
||||
bool operator()(const Point_2& p, const Point_2& q, const Point_2& r) const
|
||||
{
|
||||
Orientation_2 ori;
|
||||
|
|
@ -1046,6 +1072,10 @@ public:
|
|||
less_yx_2_object() const
|
||||
{ return Less_yx_2();}
|
||||
|
||||
Compare_signed_distance_to_line_2
|
||||
compare_signed_distance_to_line_2_object() const
|
||||
{return Compare_signed_distance_to_line_2();}
|
||||
|
||||
Less_signed_distance_to_line_2
|
||||
less_signed_distance_to_line_2_object() const
|
||||
{return Less_signed_distance_to_line_2();}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,11 @@ Besides fixes and general enhancement to existing packages, the following has ch
|
|||
|
||||
See also the [announcement page](https://www.cgal.org/2022/05/18/alpha_wrap/).
|
||||
|
||||
### [2D Straight Skeleton and Polygon Offsetting (breaking change)](https://doc.cgal.org/5.5/Manual/packages.html#PkgStraightSkeleton2)
|
||||
- Fix the output of the function [CGAL::create_exterior_skeleton_and_offset_polygons_with_holes_2()](https://doc.cgal.org/5.5/Straight_skeleton_2/group__PkgStraightSkeleton2OffsetFunctions.html#gaa159f093e5d6d7fdb62c1660a44f95fe)
|
||||
to not take into account the offset of the outer frame.
|
||||
- Fix the computation of the exterior offset of a polygon with holes that was not computing the offset of the holes
|
||||
|
||||
### [3D Convex Hulls](https://doc.cgal.org/5.5/Manual/packages.html#PkgConvexHull3)
|
||||
|
||||
- Added an [overload of the function `CGAL::convex_hull_3()`](https://doc.cgal.org/5.5/Convex_hull_3/group__PkgConvexHull3Functions.html#ga52fca4745c2ef0351063fbe66b035fd1), which writes the result in an indexed triangle set.
|
||||
|
|
@ -56,5 +61,3 @@ Besides fixes and general enhancement to existing packages, the following has ch
|
|||
### [CGAL and the Boost Graph Library (BGL)](https://doc.cgal.org/5.5/Manual/packages.html#PkgBGL)
|
||||
|
||||
- Added the function [`invert_selection()`](https://doc.cgal.org/5.5/BGL/structCGAL_1_1Face__filtered__graph.html#aa428541ebbdd35f9a6e9a3ffd60178df) in the class [`Face_filtered_graph`](https://doc.cgal.org/5.5/BGL/structCGAL_1_1Face__filtered__graph.html), which toggles the selected status of a graph: selected faces are deselected, and unselected faces are selected.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,9 @@
|
|||
Subject: CGAL 5.5 Released, Computational Geometry Algorithms Library
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Body:
|
||||
|
||||
The CGAL Open Source Project is pleased to announce the release 5.5
|
||||
of CGAL, the Computational Geometry Algorithms Library.
|
||||
The CGAL Open Source Project is pleased to announce the release 5.5 of
|
||||
CGAL, the Computational Geometry Algorithms Library.
|
||||
|
||||
|
||||
Besides fixes and general enhancement to existing packages, the following
|
||||
has changed since CGAL 5.4:
|
||||
|
||||
Besides fixes and general enhancement to existing packages, the
|
||||
following has changed since CGAL 5.4:
|
||||
|
||||
3D Alpha Wrapping (new package)
|
||||
|
||||
|
|
@ -25,6 +20,14 @@ has changed since CGAL 5.4:
|
|||
|
||||
See also https://www.cgal.org/2022/05/18/alpha_wrap/.
|
||||
|
||||
2D Straight Skeleton and Polygon Offsetting (breaking change)
|
||||
|
||||
- Fix the output of the function
|
||||
CGAL::create_exterior_skeleton_and_offset_polygons_with_holes_2() to
|
||||
not take into account the offset of the outer frame.
|
||||
- Fix the computation of the exterior offset of a polygon with holes
|
||||
that was not computing the offset of the holes
|
||||
|
||||
3D Convex Hulls
|
||||
|
||||
- Added an overload of the function CGAL::convex_hull_3(), which
|
||||
|
|
@ -112,10 +115,14 @@ CGAL and the Boost Graph Library (BGL)
|
|||
selected faces are deselected, and unselected faces are selected.
|
||||
|
||||
|
||||
See https://www.cgal.org/2022/07/04/cgal55/ for a
|
||||
See https://www.cgal.org/2022/07/15/cgal55/ for a
|
||||
complete list of changes.
|
||||
|
||||
|
||||
The same day, we also published CGAL-5.4.2 is the second bug-fix release for
|
||||
CGAL-5.4. See https://www.cgal.org/2022/07/15/cgal5.4.2/.
|
||||
|
||||
|
||||
The CGAL project is a collaborative effort to develop a robust,
|
||||
easy-to-use, and efficient C++ software library of geometric data
|
||||
structures and algorithms, like
|
||||
|
|
|
|||
|
|
@ -73,8 +73,7 @@ search_for_connected_components_in_labeled_image(const CGAL::Image_3& image,
|
|||
for(uint i=0; i<nx; i++)
|
||||
{
|
||||
using CGAL::IMAGEIO::static_evaluate;
|
||||
|
||||
if(visited[voxel_index] | second_pass[voxel_index]) {
|
||||
if(visited[voxel_index] || second_pass[voxel_index]) {
|
||||
++voxel_index;
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@
|
|||
#include <CGAL/Polyhedron_incremental_builder_3.h>
|
||||
#include <CGAL/Polyhedron_3.h>
|
||||
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
|
||||
#include <CGAL/boost/graph/properties_Polyhedron_3.h>
|
||||
#include <CGAL/Nef_3/SNC_point_locator.h>
|
||||
#include <CGAL/assertions.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ public:
|
|||
return;
|
||||
}
|
||||
const int p = std::numeric_limits<double>::digits;
|
||||
CGAL_assertion(CGAL_NTS is_finite(d) & is_valid(d));
|
||||
CGAL_assertion(CGAL_NTS is_finite(d) && is_valid(d));
|
||||
int exp;
|
||||
double x = std::frexp(d, &exp); // x in [1/2, 1], x*2^exp = d
|
||||
mpz_init_set_d (man(), // to the following integer:
|
||||
|
|
|
|||
|
|
@ -762,7 +762,7 @@ namespace INTERN_MP_FLOAT {
|
|||
while (true) {
|
||||
x = x % y;
|
||||
if (x == 0) {
|
||||
CGAL_postcondition(internal::divides(y, a) & internal::divides(y, b));
|
||||
CGAL_postcondition(internal::divides(y, a) && internal::divides(y, b));
|
||||
y.gcd_normalize();
|
||||
return y;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include <CGAL/Named_function_parameters.h>
|
||||
#include <CGAL/Polygon_mesh_processing/internal/named_params_helper.h>
|
||||
|
||||
#include <CGAL/Container_helper.h>
|
||||
#include <CGAL/iterator.h>
|
||||
#include <CGAL/Kernel_traits.h>
|
||||
|
||||
|
|
@ -604,22 +605,31 @@ Polygon construct_canonical_polygon_with_markers(const Polygon& polygon,
|
|||
const bool reversed)
|
||||
{
|
||||
const std::size_t polygon_size = polygon.size();
|
||||
|
||||
Polygon canonical_polygon;
|
||||
CGAL::internal::resize(canonical_polygon, polygon_size);
|
||||
|
||||
if(reversed)
|
||||
{
|
||||
std::size_t rfirst = polygon_size - 1 - first;
|
||||
canonical_polygon.insert(canonical_polygon.end(), polygon.rbegin() + rfirst, polygon.rend());
|
||||
canonical_polygon.insert(canonical_polygon.end(), polygon.rbegin(), polygon.rbegin() + rfirst);
|
||||
std::size_t rfirst = first + 1;
|
||||
std::size_t pos = 0;
|
||||
for(std::size_t i=rfirst; i --> 0 ;) // first to 0
|
||||
canonical_polygon[pos++] = polygon[i];
|
||||
for(std::size_t i=polygon_size; i --> rfirst ;) // polygon_size-1 to first+1
|
||||
canonical_polygon[pos++] = polygon[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
canonical_polygon.insert(canonical_polygon.end(), polygon.begin() + first, polygon.end());
|
||||
canonical_polygon.insert(canonical_polygon.end(), polygon.begin(), polygon.begin() + first);
|
||||
std::size_t pos = 0;
|
||||
for(std::size_t i=first; i<polygon_size; ++i)
|
||||
canonical_polygon[pos++] = polygon[i];
|
||||
for(std::size_t i=0; i<first; ++i)
|
||||
canonical_polygon[pos++] = polygon[i];
|
||||
}
|
||||
|
||||
CGAL_postcondition(canonical_polygon[0] == polygon[first]);
|
||||
CGAL_postcondition(canonical_polygon.size() == polygon_size);
|
||||
|
||||
return canonical_polygon;
|
||||
}
|
||||
|
||||
|
|
@ -981,6 +991,62 @@ std::size_t merge_duplicate_polygons_in_polygon_soup(const PointRange& points,
|
|||
return removed_polygons_n;
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
template <typename PointRange, typename PolygonRange,
|
||||
typename Polygon = typename Polygon_types<PointRange, PolygonRange>::Polygon_3>
|
||||
struct Polygon_soup_fixer
|
||||
{
|
||||
template <typename NamedParameters>
|
||||
void operator()(PointRange& points,
|
||||
PolygonRange& polygons,
|
||||
const NamedParameters& np) const
|
||||
{
|
||||
using parameters::get_parameter;
|
||||
using parameters::choose_parameter;
|
||||
|
||||
typedef typename GetPolygonGeomTraits<PointRange, PolygonRange, NamedParameters>::type Traits;
|
||||
Traits traits = choose_parameter<Traits>(get_parameter(np, internal_np::geom_traits));
|
||||
|
||||
#ifdef CGAL_PMP_REPAIR_POLYGON_SOUP_VERBOSE
|
||||
std::cout << "Repairing soup with " << points.size() << " points and " << polygons.size() << " polygons" << std::endl;
|
||||
#endif
|
||||
|
||||
merge_duplicate_points_in_polygon_soup(points, polygons, np);
|
||||
simplify_polygons_in_polygon_soup(points, polygons, traits);
|
||||
split_pinched_polygons_in_polygon_soup(points, polygons, traits);
|
||||
remove_invalid_polygons_in_polygon_soup(points, polygons);
|
||||
merge_duplicate_polygons_in_polygon_soup(points, polygons, np);
|
||||
remove_isolated_points_in_polygon_soup(points, polygons);
|
||||
}
|
||||
};
|
||||
|
||||
// Specialization if the polygon soup is an array
|
||||
// Disable repair functions that are meaningless for arrays
|
||||
template <typename PointRange, typename PolygonRange, typename PID, std::size_t N>
|
||||
struct Polygon_soup_fixer<PointRange, PolygonRange, std::array<PID, N> >
|
||||
{
|
||||
template <typename NamedParameters>
|
||||
void operator()(PointRange& points,
|
||||
PolygonRange& polygons,
|
||||
const NamedParameters& np) const
|
||||
{
|
||||
#ifdef CGAL_PMP_REPAIR_POLYGON_SOUP_VERBOSE
|
||||
std::cout << "Repairing soup with " << points.size() << " points and " << polygons.size() << " arrays" << std::endl;
|
||||
#endif
|
||||
|
||||
merge_duplicate_points_in_polygon_soup(points, polygons, np);
|
||||
// skipped steps:
|
||||
// simplify_polygons_in_polygon_soup(points, polygons, traits);
|
||||
// split_pinched_polygons_in_polygon_soup(points, polygons, traits);
|
||||
remove_invalid_polygons_in_polygon_soup(points, polygons);
|
||||
merge_duplicate_polygons_in_polygon_soup(points, polygons, np);
|
||||
remove_isolated_points_in_polygon_soup(points, polygons);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
/// \ingroup PMP_repairing_grp
|
||||
///
|
||||
/// \brief cleans a given polygon soup through various repairing operations.
|
||||
|
|
@ -1044,22 +1110,8 @@ void repair_polygon_soup(PointRange& points,
|
|||
PolygonRange& polygons,
|
||||
const NamedParameters& np = parameters::default_values())
|
||||
{
|
||||
using parameters::get_parameter;
|
||||
using parameters::choose_parameter;
|
||||
|
||||
typedef typename internal::GetPolygonGeomTraits<PointRange, PolygonRange, NamedParameters>::type Traits;
|
||||
Traits traits = choose_parameter<Traits>(get_parameter(np, internal_np::geom_traits));
|
||||
|
||||
#ifdef CGAL_PMP_REPAIR_POLYGON_SOUP_VERBOSE
|
||||
std::cout << "Repairing soup with " << points.size() << " points and " << polygons.size() << " polygons" << std::endl;
|
||||
#endif
|
||||
|
||||
merge_duplicate_points_in_polygon_soup(points, polygons, np);
|
||||
internal::simplify_polygons_in_polygon_soup(points, polygons, traits);
|
||||
internal::split_pinched_polygons_in_polygon_soup(points, polygons, traits);
|
||||
internal::remove_invalid_polygons_in_polygon_soup(points, polygons);
|
||||
merge_duplicate_polygons_in_polygon_soup(points, polygons, np);
|
||||
remove_isolated_points_in_polygon_soup(points, polygons);
|
||||
internal::Polygon_soup_fixer<PointRange, PolygonRange> fixer;
|
||||
fixer(points, polygons, np);
|
||||
}
|
||||
|
||||
} // end namespace Polygon_mesh_processing
|
||||
|
|
|
|||
|
|
@ -58,29 +58,46 @@ namespace internal {
|
|||
////// Helper structs
|
||||
|
||||
// Used to compare halfedges based on their geometry
|
||||
template <typename PolygonMesh, typename VertexPointMap>
|
||||
template <typename PolygonMesh, typename VertexPointMap, typename GeomTraits>
|
||||
struct Less_for_halfedge
|
||||
{
|
||||
typedef typename boost::graph_traits<PolygonMesh>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<PolygonMesh>::halfedge_descriptor halfedge_descriptor;
|
||||
typedef typename boost::property_traits<VertexPointMap>::reference Point;
|
||||
|
||||
Less_for_halfedge(const PolygonMesh& pmesh_, const VertexPointMap& vpm_)
|
||||
: pmesh(pmesh_), vpm(vpm_)
|
||||
Less_for_halfedge(const PolygonMesh& pmesh_, const VertexPointMap vpm_, const GeomTraits& gt_)
|
||||
: pmesh(pmesh_), vpm(vpm_), gt(gt_)
|
||||
{}
|
||||
|
||||
bool operator()(const halfedge_descriptor h1, const halfedge_descriptor h2) const
|
||||
{
|
||||
Point s1 = get(vpm,target(opposite(h1, pmesh), pmesh));
|
||||
Point t1 = get(vpm,target(h1, pmesh));
|
||||
Point s2 = get(vpm,target(opposite(h2, pmesh), pmesh));
|
||||
Point t2 = get(vpm,target(h2, pmesh));
|
||||
typename GeomTraits::Equal_3 equal = gt.equal_3_object();
|
||||
typename GeomTraits::Less_xyz_3 less = gt.less_xyz_3_object();
|
||||
|
||||
return (s1 < t1 ? std::make_pair(s1,t1) : std::make_pair(t1, s1))
|
||||
< (s2 < t2 ? std::make_pair(s2,t2) : std::make_pair(t2, s2));
|
||||
vertex_descriptor vm1 = source(h1, pmesh);
|
||||
vertex_descriptor vM1 = target(h1, pmesh);
|
||||
vertex_descriptor vm2 = source(h2, pmesh);
|
||||
vertex_descriptor vM2 = target(h2, pmesh);
|
||||
|
||||
if(less(get(vpm, vM1), get(vpm, vm1)))
|
||||
std::swap(vM1, vm1);
|
||||
if(less(get(vpm, vM2), get(vpm, vm2)))
|
||||
std::swap(vM2, vm2);
|
||||
|
||||
Point pm1 = get(vpm, vm1);
|
||||
Point pM1 = get(vpm, vM1);
|
||||
Point pm2 = get(vpm, vm2);
|
||||
Point pM2 = get(vpm, vM2);
|
||||
|
||||
if(equal(pm1, pm2))
|
||||
return less(pM1, pM2);
|
||||
|
||||
return less(pm1, pm2);
|
||||
}
|
||||
|
||||
const PolygonMesh& pmesh;
|
||||
const VertexPointMap& vpm;
|
||||
const VertexPointMap vpm;
|
||||
const GeomTraits& gt;
|
||||
};
|
||||
|
||||
// The following structs determine which of the two halfedges is kept when a pair is merged
|
||||
|
|
@ -316,15 +333,19 @@ template<typename Halfedge,
|
|||
typename Border_halfedge_map,
|
||||
typename Halfedge_pair,
|
||||
typename Manifold_halfedge_pair,
|
||||
typename Mesh,
|
||||
typename VPM,
|
||||
typename Mesh>
|
||||
typename GT>
|
||||
void fill_pairs(const Halfedge& he,
|
||||
Border_halfedge_map& border_halfedge_map,
|
||||
Halfedge_pair& halfedge_pairs,
|
||||
Manifold_halfedge_pair& manifold_halfedge_pairs,
|
||||
const Mesh& pmesh,
|
||||
VPM vpm,
|
||||
const Mesh& pmesh)
|
||||
const GT& gt)
|
||||
{
|
||||
typename GT::Equal_3 equal = gt.equal_3_object();
|
||||
|
||||
typename Border_halfedge_map::iterator set_it;
|
||||
bool insertion_ok;
|
||||
std::tie(set_it, insertion_ok) = border_halfedge_map.emplace(he, std::make_pair(1,0));
|
||||
|
|
@ -337,8 +358,8 @@ void fill_pairs(const Halfedge& he,
|
|||
const Halfedge other_he = set_it->first;
|
||||
set_it->second.second = halfedge_pairs.size(); // set the id of the pair in the vector
|
||||
halfedge_pairs.emplace_back(other_he, he);
|
||||
if(get(vpm, source(he,pmesh)) == get(vpm, target(other_he, pmesh)) &&
|
||||
get(vpm, target(he,pmesh)) == get(vpm, source(other_he, pmesh)))
|
||||
if(equal(get(vpm, source(he,pmesh)), get(vpm, target(other_he, pmesh))) &&
|
||||
equal(get(vpm, target(he,pmesh)), get(vpm, source(other_he, pmesh))))
|
||||
{
|
||||
// Even if the halfedges are compatible, refuse to stitch if that would break the graph
|
||||
if(face(opposite(he, pmesh), pmesh) == face(opposite(other_he, pmesh), pmesh))
|
||||
|
|
@ -379,6 +400,9 @@ OutputIterator collect_duplicated_stitchable_boundary_edges(const HalfedgeRange&
|
|||
VPM vpm = choose_parameter(get_parameter(np, internal_np::vertex_point),
|
||||
get_const_property_map(vertex_point, pmesh));
|
||||
|
||||
typedef typename GetGeomTraits<PolygonMesh, CGAL_NP_CLASS>::type GT;
|
||||
GT gt = choose_parameter<GT>(get_parameter(np, internal_np::geom_traits));
|
||||
|
||||
typedef CGAL::dynamic_face_property_t<int> Face_property_tag;
|
||||
typedef typename boost::property_map<PolygonMesh, Face_property_tag>::type Face_cc_map;
|
||||
|
||||
|
|
@ -386,10 +410,10 @@ OutputIterator collect_duplicated_stitchable_boundary_edges(const HalfedgeRange&
|
|||
std::size_t num_cc = 0;
|
||||
std::vector<std::vector<halfedge_descriptor> > border_edges_per_cc;
|
||||
|
||||
typedef Less_for_halfedge<PolygonMesh, VPM> Less_hedge;
|
||||
typedef Less_for_halfedge<PolygonMesh, VPM, GT> Less_hedge;
|
||||
typedef std::map<halfedge_descriptor, std::pair<int, std::size_t>, Less_hedge> Border_halfedge_map;
|
||||
|
||||
Less_hedge less_hedge(pmesh, vpm);
|
||||
Less_hedge less_hedge(pmesh, vpm, gt);
|
||||
Border_halfedge_map border_halfedge_map(less_hedge);
|
||||
|
||||
std::vector<std::pair<halfedge_descriptor, halfedge_descriptor> > halfedge_pairs;
|
||||
|
|
@ -420,7 +444,7 @@ OutputIterator collect_duplicated_stitchable_boundary_edges(const HalfedgeRange&
|
|||
if(per_cc)
|
||||
border_edges_per_cc[get(cc, face(opposite(he, pmesh), pmesh))].push_back(he);
|
||||
else
|
||||
fill_pairs(he, border_halfedge_map, halfedge_pairs, manifold_halfedge_pairs, vpm, pmesh);
|
||||
fill_pairs(he, border_halfedge_map, halfedge_pairs, manifold_halfedge_pairs, pmesh, vpm, gt);
|
||||
}
|
||||
|
||||
if(per_cc)
|
||||
|
|
@ -435,7 +459,7 @@ OutputIterator collect_duplicated_stitchable_boundary_edges(const HalfedgeRange&
|
|||
{
|
||||
halfedge_descriptor he = border_edges_per_cc[i][j];
|
||||
fill_pairs(he, border_halfedge_map_in_cc, halfedge_pairs,
|
||||
manifold_halfedge_pairs, vpm, pmesh);
|
||||
manifold_halfedge_pairs, pmesh, vpm, gt);
|
||||
}
|
||||
|
||||
// put in `out` only manifold edges from the set of edges to stitch.
|
||||
|
|
@ -863,17 +887,21 @@ std::size_t stitch_halfedge_range_dispatcher(const HalfedgePairRange& to_stitch_
|
|||
// However, even if non-manifoldness exists within a loop, it is safe choice to stitch consecutive
|
||||
// stitchable halfedges
|
||||
template <typename HalfedgeRange,
|
||||
typename HalfedgeKeeper,
|
||||
typename PolygonMesh,
|
||||
typename VPM,
|
||||
typename HalfedgeKeeper>
|
||||
typename GT>
|
||||
std::size_t zip_boundary_cycle(typename boost::graph_traits<PolygonMesh>::halfedge_descriptor& bh,
|
||||
const HalfedgeRange& cycle_halfedges,
|
||||
const HalfedgeKeeper& hd_kpr,
|
||||
PolygonMesh& pmesh,
|
||||
const VPM vpm,
|
||||
const HalfedgeKeeper& hd_kpr)
|
||||
const GT& gt)
|
||||
{
|
||||
typedef typename boost::graph_traits<PolygonMesh>::halfedge_descriptor halfedge_descriptor;
|
||||
|
||||
typename GT::Equal_3 equal = gt.equal_3_object();
|
||||
|
||||
std::size_t stitched_boundary_cycles_n = 0;
|
||||
|
||||
// Zipping cannot change the topology of the hole so the maintenance is trivial
|
||||
|
|
@ -909,10 +937,11 @@ std::size_t zip_boundary_cycle(typename boost::graph_traits<PolygonMesh>::halfed
|
|||
do
|
||||
{
|
||||
halfedge_descriptor hnn = next(hn, pmesh);
|
||||
CGAL_assertion(get(vpm, target(hn, pmesh)) == get(vpm, source(hnn, pmesh)));
|
||||
CGAL_assertion(equal(get(vpm, target(hn, pmesh)), get(vpm, source(hnn, pmesh))));
|
||||
|
||||
if(get(vpm, source(hn, pmesh)) == get(vpm, target(hnn, pmesh)) &&
|
||||
!is_degenerate_edge(edge(hn, pmesh), pmesh, parameters::vertex_point_map(vpm)))
|
||||
if(equal(get(vpm, source(hn, pmesh)), get(vpm, target(hnn, pmesh))) &&
|
||||
!is_degenerate_edge(edge(hn, pmesh), pmesh,
|
||||
parameters::vertex_point_map(vpm).geom_traits(gt)))
|
||||
{
|
||||
if(unstitchable_halfedges.count(hn) == 0)
|
||||
{
|
||||
|
|
@ -978,8 +1007,9 @@ std::size_t zip_boundary_cycle(typename boost::graph_traits<PolygonMesh>::halfed
|
|||
curr_hn = next(curr_hn, pmesh);
|
||||
|
||||
// check if the next two halfedges are not geometrically compatible
|
||||
if(get(vpm, source(curr_h, pmesh)) != get(vpm, target(curr_hn, pmesh)) ||
|
||||
is_degenerate_edge(edge(curr_hn, pmesh), pmesh, parameters::vertex_point_map(vpm)))
|
||||
if(!equal(get(vpm, source(curr_h, pmesh)), get(vpm, target(curr_hn, pmesh))) ||
|
||||
is_degenerate_edge(edge(curr_hn, pmesh), pmesh,
|
||||
parameters::vertex_point_map(vpm).geom_traits(gt)))
|
||||
{
|
||||
bh = curr_hn;
|
||||
break;
|
||||
|
|
@ -1044,6 +1074,9 @@ std::size_t stitch_boundary_cycle(const typename boost::graph_traits<PolygonMesh
|
|||
VPM vpm = choose_parameter(get_parameter(np, internal_np::vertex_point),
|
||||
get_const_property_map(vertex_point, pmesh));
|
||||
|
||||
typedef typename GetGeomTraits<PolygonMesh, CGAL_NP_CLASS>::type GT;
|
||||
GT gt = choose_parameter<GT>(get_parameter(np, internal_np::geom_traits));
|
||||
|
||||
typedef typename internal_np::Lookup_named_param_def<internal_np::halfedges_keeper_t,
|
||||
CGAL_NP_CLASS,
|
||||
Default_halfedges_keeper<PolygonMesh> >::type Halfedge_keeper;
|
||||
|
|
@ -1056,7 +1089,7 @@ std::size_t stitch_boundary_cycle(const typename boost::graph_traits<PolygonMesh
|
|||
for(halfedge_descriptor h : halfedges_around_face(bh, pmesh))
|
||||
cycle_halfedges.push_back(h);
|
||||
|
||||
std::size_t res = internal::zip_boundary_cycle(bh, cycle_halfedges, pmesh, vpm, hd_kpr);
|
||||
std::size_t res = internal::zip_boundary_cycle(bh, cycle_halfedges, hd_kpr, pmesh, vpm, gt);
|
||||
if(bh == boost::graph_traits<PolygonMesh>::null_halfedge()) // stitched everything
|
||||
{
|
||||
cycle_reps_maintainer.remove_representative(bh);
|
||||
|
|
@ -1111,6 +1144,17 @@ std::size_t stitch_boundary_cycle(const typename boost::graph_traits<PolygonMesh
|
|||
/// \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t`
|
||||
/// must be available in `PolygonMesh`.}
|
||||
/// \cgalParamNEnd
|
||||
///
|
||||
/// \cgalParamNBegin{geom_traits}
|
||||
/// \cgalParamDescription{an instance of a geometric traits class}
|
||||
/// \cgalParamType{The traits class must provide the nested type `Point_3`,
|
||||
/// and the nested functors:
|
||||
/// - `Less_xyz_3` to compare lexicographically two points
|
||||
/// - `Equal_3` to check whether two points are identical.
|
||||
/// For each functor `Foo`, a function `Foo foo_object()` must be provided.}
|
||||
/// \cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
||||
/// \cgalParamExtra{The geometric traits class must be compatible with the vertex point type.}
|
||||
/// \cgalParamNEnd
|
||||
/// \cgalNamedParamsEnd
|
||||
///
|
||||
/// \returns the number of pairs of halfedges that were stitched.
|
||||
|
|
@ -1172,6 +1216,17 @@ std::size_t stitch_boundary_cycles(const BorderHalfedgeRange& boundary_cycle_rep
|
|||
/// \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t`
|
||||
/// must be available in `PolygonMesh`.}
|
||||
/// \cgalParamNEnd
|
||||
///
|
||||
/// \cgalParamNBegin{geom_traits}
|
||||
/// \cgalParamDescription{an instance of a geometric traits class}
|
||||
/// \cgalParamType{The traits class must provide the nested type `Point_3`,
|
||||
/// and the nested functors:
|
||||
/// - `Less_xyz_3` to compare lexicographically two points
|
||||
/// - `Equal_3` to check whether two points are identical.
|
||||
/// For each functor `Foo`, a function `Foo foo_object()` must be provided.}
|
||||
/// \cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
||||
/// \cgalParamExtra{The geometric traits class must be compatible with the vertex point type.}
|
||||
/// \cgalParamNEnd
|
||||
/// \cgalNamedParamsEnd
|
||||
///
|
||||
/// \returns the number of pairs of halfedges that were stitched.
|
||||
|
|
@ -1412,15 +1467,6 @@ std::size_t stitch_borders(PolygonMesh& pmesh,
|
|||
/// \param np optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
|
||||
///
|
||||
/// \cgalNamedParamsBegin
|
||||
/// \cgalParamNBegin{vertex_point_map}
|
||||
/// \cgalParamDescription{a property map associating points to the vertices of `pmesh`}
|
||||
/// \cgalParamType{a class model of `ReadWritePropertyMap` with `boost::graph_traits<PolygonMesh>::%vertex_descriptor`
|
||||
/// as key type and `%Point_3` as value type}
|
||||
/// \cgalParamDefault{`boost::get(CGAL::vertex_point, pmesh)`}
|
||||
/// \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t`
|
||||
/// must be available in `PolygonMesh`.}
|
||||
/// \cgalParamNEnd
|
||||
///
|
||||
/// \cgalParamNBegin{apply_per_connected_component}
|
||||
/// \cgalParamDescription{specifies if the borders should only be stitched only within their own connected component.}
|
||||
/// \cgalParamType{Boolean}
|
||||
|
|
@ -1433,6 +1479,26 @@ std::size_t stitch_borders(PolygonMesh& pmesh,
|
|||
/// as key type and `std::size_t` as value type}
|
||||
/// \cgalParamDefault{an automatically indexed internal map}
|
||||
/// \cgalParamNEnd
|
||||
///
|
||||
/// \cgalParamNBegin{vertex_point_map}
|
||||
/// \cgalParamDescription{a property map associating points to the vertices of `pmesh`}
|
||||
/// \cgalParamType{a class model of `ReadWritePropertyMap` with `boost::graph_traits<PolygonMesh>::%vertex_descriptor`
|
||||
/// as key type and `%Point_3` as value type}
|
||||
/// \cgalParamDefault{`boost::get(CGAL::vertex_point, pmesh)`}
|
||||
/// \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t`
|
||||
/// must be available in `PolygonMesh`.}
|
||||
/// \cgalParamNEnd
|
||||
///
|
||||
/// \cgalParamNBegin{geom_traits}
|
||||
/// \cgalParamDescription{an instance of a geometric traits class}
|
||||
/// \cgalParamType{The traits class must provide the nested type `Point_3`,
|
||||
/// and the nested functors:
|
||||
/// - `Less_xyz_3` to compare lexicographically two points
|
||||
/// - `Equal_3` to check whether two points are identical.
|
||||
/// For each functor `Foo`, a function `Foo foo_object()` must be provided.}
|
||||
/// \cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
|
||||
/// \cgalParamExtra{The geometric traits class must be compatible with the vertex point type.}
|
||||
/// \cgalParamNEnd
|
||||
/// \cgalNamedParamsEnd
|
||||
///
|
||||
/// \return the number of pairs of halfedges that were stitched.
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include <CGAL/Polyhedron_3.h>
|
||||
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
|
||||
#include <CGAL/boost/graph/properties_Polyhedron_3.h>
|
||||
|
||||
#include <CGAL/boost/graph/helpers.h>
|
||||
#include <CGAL/boost/graph/property_maps.h>
|
||||
|
|
|
|||
|
|
@ -564,6 +564,21 @@ void test_slit_pinched_polygons(const bool /*verbose*/ = false)
|
|||
|
||||
int main()
|
||||
{
|
||||
// test compilation with different polygon soup types
|
||||
std::vector<Point_3> vpoints;
|
||||
std::vector<std::vector<std::size_t> > vpolygons;
|
||||
PMP::repair_polygon_soup(vpoints, vpolygons);
|
||||
|
||||
std::vector<std::deque<std::size_t> > dpolygons;
|
||||
PMP::repair_polygon_soup(vpoints, dpolygons);
|
||||
|
||||
std::deque<std::vector<std::size_t> > dvpolygons;
|
||||
PMP::repair_polygon_soup(vpoints, dvpolygons);
|
||||
|
||||
std::deque<std::array<std::size_t, 3> > apolygons;
|
||||
PMP::repair_polygon_soup(vpoints, apolygons);
|
||||
|
||||
// test functions
|
||||
test_polygon_canonicalization(true);
|
||||
test_merge_duplicate_points(false);
|
||||
test_merge_duplicate_polygons(false);
|
||||
|
|
|
|||
|
|
@ -14,8 +14,6 @@
|
|||
|
||||
#include <CGAL/iterator.h>
|
||||
#include <CGAL/Polygon_mesh_processing/remesh.h>
|
||||
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
|
||||
#include <CGAL/boost/graph/properties_Polyhedron_3.h>
|
||||
#include <CGAL/Polygon_mesh_processing/triangulate_faces.h>
|
||||
#include <CGAL/utility.h>
|
||||
#include <CGAL/property_map.h>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
#include <CGAL/boost/graph/copy_face_graph.h>
|
||||
|
||||
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
|
||||
#include <CGAL/property_map.h>
|
||||
|
||||
#include <boost/iterator/function_output_iterator.hpp>
|
||||
|
|
|
|||
|
|
@ -38,13 +38,6 @@
|
|||
namespace PMP = CGAL::Polygon_mesh_processing;
|
||||
|
||||
typedef Scene_surface_mesh_item Scene_face_graph_item;
|
||||
namespace CGAL {
|
||||
|
||||
template<>
|
||||
void set_halfedgeds_items_id (Scene_face_graph_item::Face_graph&)
|
||||
{}
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
typedef Scene_face_graph_item::Face_graph Face_graph;
|
||||
|
||||
|
|
@ -363,8 +356,6 @@ void Polyhedron_demo_mean_curvature_flow_skeleton_plugin::on_actionSegment()
|
|||
QElapsedTimer time;
|
||||
time.start();
|
||||
|
||||
// init the polyhedron simplex indices
|
||||
CGAL::set_halfedgeds_items_id(*item->input_triangle_mesh);
|
||||
boost::property_map<Face_graph, boost::vertex_index_t>::type
|
||||
vimap = get(boost::vertex_index, *item->input_triangle_mesh);
|
||||
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@
|
|||
#include "Scene_polyhedron_selection_item.h"
|
||||
|
||||
#include <CGAL/iterator.h>
|
||||
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
|
||||
#include <CGAL/boost/graph/properties_Polyhedron_3.h>
|
||||
#include <CGAL/utility.h>
|
||||
|
||||
#include <CGAL/Polygon_mesh_processing/random_perturbation.h>
|
||||
|
|
|
|||
|
|
@ -11,8 +11,6 @@
|
|||
#include "Plugins/PMP/Scene_facegraph_item_k_ring_selection.h"
|
||||
#include "Travel_isolated_components.h"
|
||||
|
||||
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
|
||||
#include <CGAL/boost/graph/properties_Polyhedron_3.h>
|
||||
#include <CGAL/boost/graph/iterator.h>
|
||||
|
||||
#include <iostream>
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
#include <boost/property_map/vector_property_map.hpp>
|
||||
|
||||
#include <CGAL/boost/graph/selection.h>
|
||||
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
|
||||
#include <CGAL/boost/graph/Euler_operations.h>
|
||||
|
||||
#include <CGAL/Qt/manipulatedFrame.h>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
#include "Scene_textured_polyhedron_item.h"
|
||||
#include <CGAL/IO/Polyhedron_iostream.h>
|
||||
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
|
||||
#include <CGAL/Polygon_mesh_processing/compute_normal.h>
|
||||
#include <QApplication>
|
||||
#include "Textured_polyhedron_type.h"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
#include "Scene_textured_surface_mesh_item.h"
|
||||
#include <CGAL/IO/Polyhedron_iostream.h>
|
||||
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
|
||||
#include <CGAL/Polygon_mesh_processing/compute_normal.h>
|
||||
#include <CGAL/Three/Triangle_container.h>
|
||||
#include <CGAL/Three/Edge_container.h>
|
||||
|
|
|
|||
|
|
@ -491,8 +491,9 @@ namespace boost {
|
|||
|
||||
#endif //CGAL_NO_DEPRECATED_CODE
|
||||
|
||||
#include <CGAL/boost/graph/properties_Polyhedron_3.h>
|
||||
#include <CGAL/boost/graph/properties_Polyhedron_3_time_stamp.h>
|
||||
#include <CGAL/boost/graph/properties_Polyhedron_3_features.h>
|
||||
#undef CGAL_HDS_PARAM_
|
||||
|
||||
#include <CGAL/boost/graph/properties_Polyhedron_3.h>
|
||||
|
||||
#endif // CGAL_BOOST_GRAPH_GRAPH_TRAITS_POLYHEDRON_3_H
|
||||
|
|
|
|||
|
|
@ -12,499 +12,9 @@
|
|||
#ifndef CGAL_BOOST_GRAPH_PROPERTIES_POLYHEDRON_3_H
|
||||
#define CGAL_BOOST_GRAPH_PROPERTIES_POLYHEDRON_3_H
|
||||
|
||||
#include <CGAL/boost/graph/properties.h>
|
||||
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
|
||||
#include <CGAL/Unique_hash_map.h>
|
||||
#include <CGAL/number_utils.h>
|
||||
#include <memory>
|
||||
#include <CGAL/boost/graph/internal/Has_member_id.h>
|
||||
#include <CGAL/Distance_3/Point_3_Point_3.h>
|
||||
#define CGAL_HDS_TMPLT Gt, class I, CGAL_HDS_PARAM_, class A
|
||||
#define CGAL_HDS_CLASS CGAL::Polyhedron_3<Gt,I,HDS,A>
|
||||
|
||||
#define CGAL_HDS_PARAM_ template < class Traits, class Items, class Alloc> class HDS
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<class Handle>
|
||||
class Polyhedron_index_map_external
|
||||
: public boost::put_get_helper<std::size_t&, Polyhedron_index_map_external<Handle> >
|
||||
{
|
||||
public:
|
||||
typedef boost::lvalue_property_map_tag category;
|
||||
typedef std::size_t value_type;
|
||||
typedef std::size_t& reference;
|
||||
typedef Handle key_type;
|
||||
|
||||
private:
|
||||
typedef CGAL::Unique_hash_map<key_type,std::size_t> Map;
|
||||
|
||||
public:
|
||||
template <typename InputIterator>
|
||||
Polyhedron_index_map_external(InputIterator begin, InputIterator end, std::size_t max)
|
||||
: map_(new Map(begin, end, 0, std::size_t(-1), max)) {}
|
||||
|
||||
reference operator[](const key_type& k) const { return (*map_)[k]; }
|
||||
private:
|
||||
std::shared_ptr<Map> map_;
|
||||
};
|
||||
|
||||
// Special case for edges.
|
||||
template<class Polyhedron>
|
||||
class Polyhedron_edge_index_map_external
|
||||
: public boost::put_get_helper<std::size_t&, Polyhedron_edge_index_map_external<Polyhedron> >
|
||||
{
|
||||
public:
|
||||
typedef boost::lvalue_property_map_tag category;
|
||||
typedef std::size_t value_type;
|
||||
typedef std::size_t& reference;
|
||||
typedef typename boost::graph_traits<Polyhedron>::edge_descriptor key_type;
|
||||
|
||||
private:
|
||||
typedef CGAL::Unique_hash_map<key_type,std::size_t> Map;
|
||||
|
||||
public:
|
||||
Polyhedron_edge_index_map_external(Polyhedron& p)
|
||||
: map_(new Map(std::size_t(-1), num_halfedges(p)))
|
||||
{
|
||||
unsigned int data = 0;
|
||||
typename boost::graph_traits<Polyhedron>::edge_iterator it, end;
|
||||
for(boost::tie(it, end) = edges(p); it != end; ++it, ++data)
|
||||
(*map_)[*it] = data;
|
||||
}
|
||||
|
||||
reference operator[](const key_type& k) const { return (*map_)[k]; }
|
||||
private:
|
||||
std::shared_ptr<Map> map_;
|
||||
};
|
||||
|
||||
template<typename Handle, typename FT>
|
||||
struct Wrap_squared
|
||||
{
|
||||
typedef FT value_type;
|
||||
typedef FT reference;
|
||||
typedef Handle key_type;
|
||||
typedef boost::readable_property_map_tag category;
|
||||
|
||||
template<typename E>
|
||||
FT operator[](const E& e) const {
|
||||
return approximate_sqrt(CGAL::squared_distance(e.halfedge()->vertex()->point(),
|
||||
e.halfedge()->opposite()->vertex()->point()));
|
||||
}
|
||||
|
||||
friend inline
|
||||
value_type get(const Wrap_squared& m, const key_type k)
|
||||
{
|
||||
return m[k];
|
||||
}
|
||||
};
|
||||
|
||||
} // internal
|
||||
|
||||
// the tag we dispatch on from property_map<G, Property>
|
||||
template <class Tag>
|
||||
struct Polyhedron_property_map {};
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
// generalized 2-ary get functions
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A, class PropertyTag>
|
||||
typename boost::property_map< CGAL::Polyhedron_3<Gt,I,HDS,A>, PropertyTag >::const_type
|
||||
get(PropertyTag, CGAL::Polyhedron_3<Gt,I,HDS,A> const&)
|
||||
{ return typename boost::property_map< CGAL::Polyhedron_3<Gt,I,HDS,A>, PropertyTag >::const_type(); }
|
||||
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A, class PropertyTag>
|
||||
typename boost::property_map< CGAL::Polyhedron_3<Gt,I,HDS,A>, PropertyTag >::type
|
||||
get(PropertyTag, CGAL::Polyhedron_3<Gt,I,HDS,A>&)
|
||||
{ return typename boost::property_map< CGAL::Polyhedron_3<Gt,I,HDS,A>, PropertyTag >::type(); }
|
||||
|
||||
// generalized 3-ary get functions
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A, class PropertyTag, class Key>
|
||||
typename boost::property_traits< typename boost::property_map< CGAL::Polyhedron_3<Gt,I,HDS,A>, PropertyTag >::type >::reference
|
||||
get(PropertyTag p, CGAL::Polyhedron_3<Gt,I,HDS,A>& g, const Key& key)
|
||||
{ return get(get(p, g), key); }
|
||||
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A, class PropertyTag, class Key>
|
||||
typename boost::property_traits< typename boost::property_map<CGAL::Polyhedron_3<Gt,I,HDS,A>, PropertyTag >::const_type >::reference
|
||||
get(PropertyTag p, CGAL::Polyhedron_3<Gt,I,HDS,A> const& g, const Key& key)
|
||||
{ return get(get(p, g), key); }
|
||||
|
||||
|
||||
|
||||
#define CGAL_POLYHEDRON_DYNAMIC_PM(TAG, DESCRIPTOR) \
|
||||
template <typename T, typename Gt, typename I, CGAL_HDS_PARAM_, typename A> \
|
||||
typename boost::property_map<Polyhedron_3<Gt,I,HDS,A>, TAG >::const_type \
|
||||
get(const TAG&, const Polyhedron_3<Gt,I,HDS,A>&) \
|
||||
{ \
|
||||
typedef typename boost::graph_traits< Polyhedron_3<Gt,I,HDS,A> >::DESCRIPTOR descriptor; \
|
||||
return internal::Dynamic_property_map<descriptor,T>(); \
|
||||
}
|
||||
|
||||
CGAL_POLYHEDRON_DYNAMIC_PM(dynamic_vertex_property_t<T>, vertex_descriptor)
|
||||
CGAL_POLYHEDRON_DYNAMIC_PM(dynamic_halfedge_property_t<T>, halfedge_descriptor)
|
||||
CGAL_POLYHEDRON_DYNAMIC_PM(dynamic_edge_property_t<T>, edge_descriptor)
|
||||
CGAL_POLYHEDRON_DYNAMIC_PM(dynamic_face_property_t<T>, face_descriptor)
|
||||
|
||||
|
||||
#undef CGAL_POLYHEDRON_DYNAMIC_PM
|
||||
|
||||
|
||||
// generalized put
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A, class PropertyTag, class Key,class Value>
|
||||
void put(PropertyTag p, CGAL::Polyhedron_3<Gt,I,HDS,A>& g, const Key& key, const Value& value)
|
||||
{
|
||||
typedef typename boost::property_map<CGAL::Polyhedron_3<Gt,I,HDS,A>, PropertyTag>::type Map;
|
||||
Map pmap = get(p, g);
|
||||
put(pmap, key, value);
|
||||
}
|
||||
|
||||
} // CGAL
|
||||
|
||||
// specialization needs to be repeated for halfedge, vertex, face
|
||||
#define CGAL_POLYHEDRON_INDEX_PM(ENTITY, TAG, ACCESSOR) \
|
||||
namespace CGAL { \
|
||||
template<> struct Polyhedron_property_map<boost::ENTITY##TAG> { \
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A> \
|
||||
struct bind_ { \
|
||||
typedef internal::ACCESSOR##_accessor< \
|
||||
CGAL::Polyhedron_3<Gt, I, HDS, A>, \
|
||||
typename boost::graph_traits< CGAL::Polyhedron_3<Gt, I, HDS, A> \
|
||||
>::ENTITY##_descriptor > type; \
|
||||
typedef type const_type; \
|
||||
}; \
|
||||
}; \
|
||||
} //CGAL
|
||||
|
||||
CGAL_POLYHEDRON_INDEX_PM(halfedge, _index_t, Index)
|
||||
CGAL_POLYHEDRON_INDEX_PM(vertex, _index_t, Index)
|
||||
CGAL_POLYHEDRON_INDEX_PM(face, _index_t, Index)
|
||||
|
||||
#undef CGAL_POLYHEDRON_INDEX_PM
|
||||
|
||||
namespace CGAL {
|
||||
// not done with macros, because HDS_edge::id does not return a
|
||||
// reference
|
||||
template <>
|
||||
struct Polyhedron_property_map<boost::edge_index_t>
|
||||
{
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct bind_
|
||||
{
|
||||
typedef internal::Edge_index_accessor<
|
||||
typename boost::graph_traits<
|
||||
CGAL::Polyhedron_3<Gt, I, HDS, A>
|
||||
>::edge_descriptor > type;
|
||||
typedef type const_type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Polyhedron_property_map<boost::edge_weight_t>
|
||||
{
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct bind_
|
||||
{
|
||||
typedef typename CGAL::Polyhedron_3<Gt, I, HDS, A>::Traits::FT FT;
|
||||
typedef typename boost::graph_traits<CGAL::Polyhedron_3<Gt, I, HDS, A> >::edge_descriptor edge_descriptor;
|
||||
typedef internal::Wrap_squared<edge_descriptor,FT> type;
|
||||
typedef type const_type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Polyhedron_property_map<vertex_point_t>
|
||||
{
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct bind_
|
||||
{
|
||||
typedef internal::Point_accessor<
|
||||
typename boost::graph_traits<
|
||||
CGAL::Polyhedron_3<Gt, I, HDS, A>
|
||||
>::vertex_descriptor,
|
||||
typename Gt::Point_3, typename Gt::Point_3&> type;
|
||||
|
||||
typedef internal::Point_accessor<
|
||||
typename boost::graph_traits<
|
||||
CGAL::Polyhedron_3<Gt, I, HDS, A>
|
||||
>::vertex_descriptor,
|
||||
typename Gt::Point_3, const typename Gt::Point_3&> const_type;
|
||||
};
|
||||
};
|
||||
|
||||
//
|
||||
// external indices
|
||||
//
|
||||
|
||||
template <>
|
||||
struct Polyhedron_property_map<edge_external_index_t>
|
||||
{
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct bind_
|
||||
{
|
||||
typedef internal::Polyhedron_edge_index_map_external<
|
||||
CGAL::Polyhedron_3<Gt, I, HDS, A>
|
||||
> type;
|
||||
typedef type const_type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Polyhedron_property_map<halfedge_external_index_t>
|
||||
{
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct bind_
|
||||
{
|
||||
typedef internal::Polyhedron_index_map_external<
|
||||
typename boost::graph_traits<
|
||||
CGAL::Polyhedron_3<Gt, I, HDS, A>
|
||||
>::halfedge_descriptor > type;
|
||||
typedef type const_type;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
template <>
|
||||
struct Polyhedron_property_map<vertex_external_index_t>
|
||||
{
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct bind_
|
||||
{
|
||||
typedef internal::Polyhedron_index_map_external<
|
||||
typename boost::graph_traits<
|
||||
CGAL::Polyhedron_3<Gt, I, HDS, A>
|
||||
>::vertex_descriptor > type;
|
||||
typedef type const_type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Polyhedron_property_map<face_external_index_t>
|
||||
{
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct bind_
|
||||
{
|
||||
typedef internal::Polyhedron_index_map_external<
|
||||
typename boost::graph_traits<
|
||||
CGAL::Polyhedron_3<Gt, I, HDS, A>
|
||||
>::face_descriptor > type;
|
||||
typedef type const_type;
|
||||
};
|
||||
};
|
||||
|
||||
} // CGAL
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
typename boost::property_map< CGAL::Polyhedron_3<Gt,I,HDS,A>, boost::edge_external_index_t >::const_type
|
||||
get(boost::edge_external_index_t, CGAL::Polyhedron_3<Gt,I,HDS,A> const& p)
|
||||
{
|
||||
return typename boost::property_map< CGAL::Polyhedron_3<Gt,I,HDS,A>, boost::edge_external_index_t >::const_type(
|
||||
const_cast<CGAL::Polyhedron_3<Gt,I,HDS,A>& >(p));
|
||||
}
|
||||
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
typename boost::property_map< CGAL::Polyhedron_3<Gt,I,HDS,A>, boost::halfedge_external_index_t >::const_type
|
||||
get(boost::halfedge_external_index_t, CGAL::Polyhedron_3<Gt,I,HDS,A> const& p)
|
||||
{
|
||||
CGAL::Polyhedron_3<Gt,I,HDS,A>& ncp = const_cast<CGAL::Polyhedron_3<Gt,I,HDS,A>&>(p);
|
||||
|
||||
return typename boost::property_map< CGAL::Polyhedron_3<Gt,I,HDS,A>, boost::halfedge_external_index_t >::const_type(
|
||||
ncp.halfedges_begin(), ncp.halfedges_end(), ncp.size_of_halfedges());
|
||||
}
|
||||
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
typename boost::property_map< CGAL::Polyhedron_3<Gt,I,HDS,A>, boost::vertex_external_index_t >::const_type
|
||||
get(boost::vertex_external_index_t, CGAL::Polyhedron_3<Gt,I,HDS,A> const& p)
|
||||
{
|
||||
CGAL::Polyhedron_3<Gt,I,HDS,A>& ncp = const_cast<CGAL::Polyhedron_3<Gt,I,HDS,A>&>(p);
|
||||
|
||||
return typename boost::property_map< CGAL::Polyhedron_3<Gt,I,HDS,A>, boost::vertex_external_index_t >::const_type(
|
||||
ncp.vertices_begin(), ncp.vertices_end(), ncp.size_of_vertices());
|
||||
}
|
||||
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
typename boost::property_map< CGAL::Polyhedron_3<Gt,I,HDS,A>, boost::face_external_index_t >::const_type
|
||||
get(boost::face_external_index_t, CGAL::Polyhedron_3<Gt,I,HDS,A> const& p)
|
||||
{
|
||||
CGAL::Polyhedron_3<Gt,I,HDS,A>& ncp = const_cast<CGAL::Polyhedron_3<Gt,I,HDS,A>&>(p);
|
||||
|
||||
return typename boost::property_map< CGAL::Polyhedron_3<Gt,I,HDS,A>, boost::face_external_index_t >::const_type(
|
||||
ncp.facets_begin(), ncp.facets_end(), ncp.size_of_facets());
|
||||
}
|
||||
|
||||
// the same blurb for non-const
|
||||
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
typename boost::property_map< CGAL::Polyhedron_3<Gt,I,HDS,A>, boost::edge_external_index_t >::type
|
||||
get(boost::edge_external_index_t, CGAL::Polyhedron_3<Gt,I,HDS,A>& p)
|
||||
{
|
||||
return typename boost::property_map< CGAL::Polyhedron_3<Gt,I,HDS,A>, boost::edge_external_index_t >::type(
|
||||
p);
|
||||
}
|
||||
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
typename boost::property_map< CGAL::Polyhedron_3<Gt,I,HDS,A>, boost::halfedge_external_index_t >::type
|
||||
get(boost::halfedge_external_index_t, CGAL::Polyhedron_3<Gt,I,HDS,A> & ncp)
|
||||
{
|
||||
return typename boost::property_map< CGAL::Polyhedron_3<Gt,I,HDS,A>, boost::halfedge_external_index_t >::type(
|
||||
ncp.halfedges_begin(), ncp.halfedges_end(), ncp.size_of_halfedges());
|
||||
}
|
||||
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
typename boost::property_map< CGAL::Polyhedron_3<Gt,I,HDS,A>, boost::vertex_external_index_t >::type
|
||||
get(boost::vertex_external_index_t, CGAL::Polyhedron_3<Gt,I,HDS,A> & ncp)
|
||||
{
|
||||
return typename boost::property_map< CGAL::Polyhedron_3<Gt,I,HDS,A>, boost::vertex_external_index_t >::type(
|
||||
ncp.vertices_begin(), ncp.vertices_end(), ncp.size_of_vertices());
|
||||
}
|
||||
|
||||
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
typename boost::property_map< CGAL::Polyhedron_3<Gt,I,HDS,A>, boost::face_external_index_t >::type
|
||||
get(boost::face_external_index_t, CGAL::Polyhedron_3<Gt,I,HDS,A> & ncp)
|
||||
{
|
||||
return typename boost::property_map< CGAL::Polyhedron_3<Gt,I,HDS,A>, boost::face_external_index_t >::type(
|
||||
ncp.facets_begin(), ncp.facets_end(), ncp.size_of_facets());
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
// property_map dispatcher into Polyhedron
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A, class Tag>
|
||||
struct property_map<CGAL::Polyhedron_3<Gt,I,HDS,A>, Tag>
|
||||
{
|
||||
typedef typename CGAL::Polyhedron_property_map<Tag>::
|
||||
template bind_<Gt,I,HDS,A> map_gen;
|
||||
typedef typename map_gen::type type;
|
||||
typedef typename map_gen::const_type const_type;
|
||||
};
|
||||
|
||||
// property_map dispatcher into const Polyhedron
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A, class Tag>
|
||||
struct property_map<const CGAL::Polyhedron_3<Gt,I,HDS,A>, Tag>
|
||||
{
|
||||
typedef typename CGAL::Polyhedron_property_map<Tag>::
|
||||
template bind_<Gt,I,HDS,A> map_gen;
|
||||
typedef typename map_gen::type type;
|
||||
typedef typename map_gen::const_type const_type;
|
||||
};
|
||||
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A, class T>
|
||||
struct property_map<CGAL::Polyhedron_3<Gt,I,HDS,A>, CGAL::dynamic_vertex_property_t<T> >
|
||||
{
|
||||
typedef CGAL::Polyhedron_3<Gt,I,HDS,A> G;
|
||||
typedef typename boost::graph_traits<G>::vertex_descriptor vertex_descriptor;
|
||||
typedef CGAL::internal::Dynamic_property_map<vertex_descriptor,T> type;
|
||||
typedef type const_type;
|
||||
};
|
||||
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A, class T>
|
||||
struct property_map<CGAL::Polyhedron_3<Gt,I,HDS,A>, CGAL::dynamic_halfedge_property_t<T> >
|
||||
{
|
||||
typedef CGAL::Polyhedron_3<Gt,I,HDS,A> G;
|
||||
typedef typename boost::graph_traits<G>::halfedge_descriptor halfedge_descriptor;
|
||||
typedef CGAL::internal::Dynamic_property_map<halfedge_descriptor,T> type;
|
||||
typedef type const_type;
|
||||
};
|
||||
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A, class T>
|
||||
struct property_map<CGAL::Polyhedron_3<Gt,I,HDS,A>, CGAL::dynamic_edge_property_t<T> >
|
||||
{
|
||||
typedef CGAL::Polyhedron_3<Gt,I,HDS,A> G;
|
||||
typedef typename boost::graph_traits<G>::edge_descriptor edge_descriptor;
|
||||
typedef CGAL::internal::Dynamic_property_map<edge_descriptor,T> type;
|
||||
typedef type const_type;
|
||||
};
|
||||
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A, class T>
|
||||
struct property_map<CGAL::Polyhedron_3<Gt,I,HDS,A>, CGAL::dynamic_face_property_t<T> >
|
||||
{
|
||||
typedef CGAL::Polyhedron_3<Gt,I,HDS,A> G;
|
||||
typedef typename boost::graph_traits<G>::face_descriptor face_descriptor;
|
||||
typedef CGAL::internal::Dynamic_property_map<face_descriptor,T> type;
|
||||
typedef type const_type;
|
||||
};
|
||||
|
||||
// What are those needed for ???
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct edge_property_type<CGAL::Polyhedron_3<Gt,I,HDS,A> >
|
||||
{
|
||||
typedef edge_weight_t type;
|
||||
};
|
||||
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct vertex_property_type<CGAL::Polyhedron_3<Gt,I,HDS,A> >
|
||||
{
|
||||
typedef CGAL::vertex_point_t type;
|
||||
};
|
||||
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct vertex_property_type<const CGAL::Polyhedron_3<Gt,I,HDS,A> >
|
||||
{
|
||||
typedef CGAL::vertex_point_t type;
|
||||
};
|
||||
|
||||
|
||||
} // namespace boost
|
||||
|
||||
namespace CGAL{
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct graph_has_property<CGAL::Polyhedron_3<Gt, I, HDS, A>, boost::vertex_point_t>
|
||||
: CGAL::Tag_true {};
|
||||
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct graph_has_property<CGAL::Polyhedron_3<Gt, I, HDS, A>, boost::edge_weight_t>
|
||||
: CGAL::Tag_true {};
|
||||
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct graph_has_property<CGAL::Polyhedron_3<Gt, I, HDS, A>, boost::edge_index_t>
|
||||
: CGAL::Boolean_tag<
|
||||
CGAL::internal::Has_member_id<
|
||||
typename boost::graph_traits<CGAL::Polyhedron_3<Gt, I, HDS, A> >::edge_descriptor
|
||||
>::value
|
||||
>
|
||||
{};
|
||||
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct graph_has_property<CGAL::Polyhedron_3<Gt, I, HDS, A>, boost::face_index_t>
|
||||
: CGAL::Boolean_tag<
|
||||
CGAL::internal::Has_member_id<
|
||||
typename CGAL::Polyhedron_3<Gt, I, HDS, A>::Facet
|
||||
>::value
|
||||
>
|
||||
{};
|
||||
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct graph_has_property<CGAL::Polyhedron_3<Gt, I, HDS, A>, boost::halfedge_index_t>
|
||||
: CGAL::Boolean_tag<
|
||||
CGAL::internal::Has_member_id<
|
||||
typename CGAL::Polyhedron_3<Gt, I, HDS, A>::Halfedge
|
||||
>::value
|
||||
>
|
||||
{};
|
||||
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct graph_has_property<CGAL::Polyhedron_3<Gt, I, HDS, A>, boost::vertex_index_t>
|
||||
: CGAL::Boolean_tag<
|
||||
CGAL::internal::Has_member_id<
|
||||
typename CGAL::Polyhedron_3<Gt, I, HDS, A>::Vertex
|
||||
>::value
|
||||
>
|
||||
{};
|
||||
}// end CGAL
|
||||
#undef CGAL_HDS_PARAM_
|
||||
|
||||
|
||||
|
||||
#include <CGAL/boost/graph/properties_Polyhedron_3_time_stamp.h>
|
||||
#include <CGAL/boost/graph/properties_Polyhedron_3_features.h>
|
||||
#include <CGAL/boost/graph/properties_HalfedgeDS_base.h>
|
||||
|
||||
#endif // CGAL_BOOST_GRAPH_PROPERTIES_POLYHEDRON_3_H
|
||||
|
|
|
|||
|
|
@ -55,10 +55,9 @@ void put(Polyhedron_face_patch_id_pmap<Patch_id>, Handle_type h, Patch_id pid)
|
|||
h->set_patch_id(pid);
|
||||
}
|
||||
|
||||
template <typename Patch_id>
|
||||
struct Polyhedron_property_map<CGAL::face_patch_id_t<Patch_id> >
|
||||
template <class Gt, class I, CGAL_HDS_PARAM_, class A, typename Patch_id>
|
||||
struct HDS_property_map<CGAL::Polyhedron_3<Gt, I, HDS, A>, CGAL::face_patch_id_t<Patch_id> >
|
||||
{
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct bind_
|
||||
{
|
||||
typedef Polyhedron_face_patch_id_pmap<Patch_id> type;
|
||||
|
|
@ -79,10 +78,9 @@ get(CGAL::face_patch_id_t<void>, const Polyhedron_3<Gt,I,HDS,A>&)
|
|||
return Pmap( std::pair<int,int>(0,1) );
|
||||
}
|
||||
|
||||
template <>
|
||||
struct Polyhedron_property_map<CGAL::face_patch_id_t<void> >
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct HDS_property_map<CGAL::Polyhedron_3<Gt, I, HDS, A>, CGAL::face_patch_id_t<void> >
|
||||
{
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct bind_
|
||||
{
|
||||
typedef typename internal::Get_static_property_map<Gt,I,HDS,A>::type type;
|
||||
|
|
@ -93,10 +91,9 @@ struct Polyhedron_property_map<CGAL::face_patch_id_t<void> >
|
|||
// Compatibility: when the `Patch_id` template argument of
|
||||
// `Polyhedron_mesh_domain` is `Tag_true` (because that argument was named
|
||||
// `UsePatchId` in previous versions of CGAL.
|
||||
template <>
|
||||
struct Polyhedron_property_map<CGAL::face_patch_id_t<CGAL::Tag_true> >
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct HDS_property_map<CGAL::Polyhedron_3<Gt, I, HDS, A>, CGAL::face_patch_id_t<CGAL::Tag_true> >
|
||||
{
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct bind_
|
||||
{
|
||||
typedef Polyhedron_3<Gt,I,HDS,A> Polyhedron;
|
||||
|
|
@ -108,9 +105,9 @@ struct Polyhedron_property_map<CGAL::face_patch_id_t<CGAL::Tag_true> >
|
|||
// Compatibility: when the `Patch_id` template argument of
|
||||
// `Polyhedron_mesh_domain` is `Tag_false` (because that argument was named
|
||||
// `UsePatchId` in previous versions of CGAL.
|
||||
template <>
|
||||
struct Polyhedron_property_map<CGAL::face_patch_id_t<CGAL::Tag_false> >
|
||||
: public Polyhedron_property_map<CGAL::face_patch_id_t<void> >
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct HDS_property_map<CGAL::Polyhedron_3<Gt, I, HDS, A>, CGAL::face_patch_id_t<CGAL::Tag_false> >
|
||||
: public HDS_property_map<CGAL::Polyhedron_3<Gt, I, HDS, A>, CGAL::face_patch_id_t<void> >
|
||||
{
|
||||
};
|
||||
|
||||
|
|
@ -144,10 +141,9 @@ void put(Polyhedron_num_feature_edges_pmap, Handle_type h, int n)
|
|||
}
|
||||
|
||||
|
||||
template <>
|
||||
struct Polyhedron_property_map<CGAL::vertex_feature_degree_t>
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct HDS_property_map<CGAL::Polyhedron_3<Gt, I, HDS, A>, CGAL::vertex_feature_degree_t>
|
||||
{
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct bind_
|
||||
{
|
||||
typedef Polyhedron_num_feature_edges_pmap type;
|
||||
|
|
@ -177,10 +173,9 @@ void put(Polyhedron_is_feature_edge_pmap, Handle_type e, bool b)
|
|||
e.halfedge()->opposite()->set_feature_edge(b);
|
||||
}
|
||||
|
||||
template <>
|
||||
struct Polyhedron_property_map<CGAL::edge_is_feature_t>
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct HDS_property_map<CGAL::Polyhedron_3<Gt, I, HDS, A>, CGAL::edge_is_feature_t>
|
||||
{
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct bind_
|
||||
{
|
||||
typedef Polyhedron_is_feature_edge_pmap type;
|
||||
|
|
@ -220,10 +215,9 @@ void put(Polyhedron_incident_patches_pmap<Patch_id>,
|
|||
h->add_incident_patch(n);
|
||||
}
|
||||
|
||||
template <typename Patch_id>
|
||||
struct Polyhedron_property_map<CGAL::vertex_incident_patches_t<Patch_id> >
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A, class Patch_id>
|
||||
struct HDS_property_map<CGAL::Polyhedron_3<Gt, I, HDS, A>, CGAL::vertex_incident_patches_t<Patch_id> >
|
||||
{
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct bind_
|
||||
{
|
||||
typedef Polyhedron_incident_patches_pmap<Patch_id> type;
|
||||
|
|
|
|||
|
|
@ -38,10 +38,9 @@ void put(Polyhedron_face_time_stamp_pmap, Handle_type h, std::size_t ts)
|
|||
h->set_time_stamp(ts);
|
||||
}
|
||||
|
||||
template <>
|
||||
struct Polyhedron_property_map<CGAL::vertex_time_stamp_t>
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct HDS_property_map<CGAL::Polyhedron_3<Gt, I, HDS, A>, CGAL::vertex_time_stamp_t>
|
||||
{
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct bind_
|
||||
{
|
||||
typedef Polyhedron_face_time_stamp_pmap type;
|
||||
|
|
@ -49,14 +48,14 @@ struct Polyhedron_property_map<CGAL::vertex_time_stamp_t>
|
|||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Polyhedron_property_map<CGAL::halfedge_time_stamp_t>
|
||||
: public Polyhedron_property_map<CGAL::vertex_time_stamp_t>
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct HDS_property_map<CGAL::Polyhedron_3<Gt, I, HDS, A>, CGAL::halfedge_time_stamp_t>
|
||||
: public HDS_property_map<CGAL::Polyhedron_3<Gt, I, HDS, A>, CGAL::vertex_time_stamp_t>
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct Polyhedron_property_map<CGAL::face_time_stamp_t>
|
||||
: public Polyhedron_property_map<CGAL::vertex_time_stamp_t>
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
struct HDS_property_map<CGAL::Polyhedron_3<Gt, I, HDS, A>, CGAL::face_time_stamp_t>
|
||||
: public HDS_property_map<CGAL::Polyhedron_3<Gt, I, HDS, A>, CGAL::vertex_time_stamp_t>
|
||||
{};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ of the `graph_traits` header files provided by \cgal.
|
|||
They can be disables by defining the macro `CGAL_DISABLE_HASH_OPENMESH`.
|
||||
|
||||
\sa `CGAL::Unique_hash_map<Key,Mapped,Hash>`
|
||||
\sa <A HREF="http://www.cplusplus.com/reference/unordered_set/unordered_set/">`std::unordered_set`</a>
|
||||
\sa <A HREF="http://www.cplusplus.com/reference/unordered_set/unordered_map/">`std::unordered_map`</a>
|
||||
\sa <A HREF="https://en.cppreference.com/w/cpp/container/unordered_set">`std::unordered_set`</a>
|
||||
\sa <A HREF="https://en.cppreference.com/w/cpp/container/unordered_map">`std::unordered_map`</a>
|
||||
\sa <A HREF="https://www.boost.org/libs/unordered/doc/html/unordered.html#unordered_set">`boost::unordered_set`</a>
|
||||
\sa <A HREF="https://www.boost.org/libs/unordered/doc/html/unordered.html#unordered_map">`boost::unordered_map`</a>
|
||||
|
||||
|
|
|
|||
|
|
@ -289,6 +289,11 @@ Uncertain<bool> operator!(Uncertain<bool> a)
|
|||
return Uncertain<bool>(!a.sup(), !a.inf());
|
||||
}
|
||||
|
||||
#ifdef __clang__
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wunknown-warning-option"
|
||||
# pragma GCC diagnostic ignored "-Wbitwise-instead-of-logical"
|
||||
#endif
|
||||
inline
|
||||
Uncertain<bool> operator|(Uncertain<bool> a, Uncertain<bool> b)
|
||||
{
|
||||
|
|
@ -324,7 +329,9 @@ Uncertain<bool> operator&(Uncertain<bool> a, bool b)
|
|||
{
|
||||
return Uncertain<bool>(a.inf() & b, a.sup() & b);
|
||||
}
|
||||
|
||||
#ifdef __clang__
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
// Equality operators
|
||||
|
||||
|
|
|
|||
|
|
@ -623,7 +623,7 @@ if [ -f '${LIST_TEST_PACKAGES}' ]; then
|
|||
# copy it, else prepare for the special "skipped" case in the table.
|
||||
for PACKAGE in \$(ls "${CGAL_TEST_DIR}"); do
|
||||
if [ -d "${CGAL_TEST_DIR}/\$PACKAGE" ]; then
|
||||
if source '${LIST_TEST_PACKAGES}' '${CGAL_ROOT}' | egrep -q \$PACKAGE; then
|
||||
if source '${LIST_TEST_PACKAGES}' '${CGAL_ROOT}' | grep -E -q \$PACKAGE; then
|
||||
mkdir "${CGAL_BINARY_DIR}/test/\${PACKAGE}"
|
||||
cp -r "${CGAL_TEST_DIR}/\${PACKAGE}" '${CGAL_BINARY_DIR}/test'
|
||||
elif [ "\$PACKAGE" = "resources" ]; then
|
||||
|
|
|
|||
|
|
@ -2,4 +2,4 @@
|
|||
|
||||
setopt extendedglob
|
||||
|
||||
file ^build*/(demo|test|examples|include|doc|src)/**/*.(h|hpp|H|C|c|cpp)| egrep -v ':[[:space:]]+(C(\+\+)? source, |LaTeX document, |HTML document, )?(ASCII|UTF-8 Unicode) text(, with very long lines)?$'
|
||||
file ^build*/(demo|test|examples|include|doc|src)/**/*.(h|hpp|H|C|c|cpp)| grep -E -v ':[[:space:]]+(C(\+\+)? source, |LaTeX document, |HTML document, )?(ASCII|UTF-8 Unicode) text(, with very long lines)?$'
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ git fetch $USER_REPO
|
|||
git checkout $BRANCH_NAME
|
||||
git reset --hard $USER_REPO/$BRANCH_NAME
|
||||
#setup the list_test_packages
|
||||
TMP_LIST=$(git diff --name-only cgal/$BASE_NAME...HEAD |egrep -v /doc |egrep "\.h"\|"\.cpp" |cut -s -d/ -f1 |sort -u | xargs -I {} ls -d {}/package_info 2>/dev/null |cut -d/ -f1 |egrep -v Installation||true)
|
||||
TMP_LIST=$(git diff --name-only cgal/$BASE_NAME...HEAD |grep -E -v /doc |grep -E "\.h"\|"\.cpp" |cut -s -d/ -f1 |sort -u | xargs -I {} ls -d {}/package_info 2>/dev/null |cut -d/ -f1 |grep -E -v Installation||true)
|
||||
|
||||
LIST_OF_PKGS=""
|
||||
for PKG in $(ls) ; do
|
||||
|
|
|
|||
|
|
@ -95,9 +95,9 @@ done
|
|||
|
||||
# check project in cmake scripts is correct
|
||||
echo '.. Checking if all CMakeLists.txt project names are correct...'
|
||||
project_name_tests=$(for i in ^build*/test/*/CMakeLists.txt; do pkg=$(echo $i | awk -F "/" '{print $3}'); egrep "${pkg}_Tests\s*\)" -L $i; done)
|
||||
project_name_examples=$(for i in ^build*/examples/*/CMakeLists.txt; do pkg=$(echo $i | awk -F "/" '{print $3}'); egrep "${pkg}_Examples\s*\)" -L $i; done)
|
||||
project_name_demo=$(for i in ^build*/demo/*/CMakeLists.txt; do pkg=$(echo $i | awk -F "/" '{print $3}'); egrep "${pkg}_Demo\s*\)" -L $i; done)
|
||||
project_name_tests=$(for i in ^build*/test/*/CMakeLists.txt; do pkg=$(echo $i | awk -F "/" '{print $3}'); grep -E "${pkg}_Tests\s*\)" -L $i; done)
|
||||
project_name_examples=$(for i in ^build*/examples/*/CMakeLists.txt; do pkg=$(echo $i | awk -F "/" '{print $3}'); grep -E "${pkg}_Examples\s*\)" -L $i; done)
|
||||
project_name_demo=$(for i in ^build*/demo/*/CMakeLists.txt; do pkg=$(echo $i | awk -F "/" '{print $3}'); grep -E "${pkg}_Demo\s*\)" -L $i; done)
|
||||
|
||||
if [ -n "${project_name_tests}" ]; then
|
||||
echo "CMakeLists with incorrect project name"
|
||||
|
|
@ -146,7 +146,7 @@ fi
|
|||
|
||||
#check GPL header files without license include directive
|
||||
echo '.. Checking include directives in GPL header files...'
|
||||
file_without_license_include=$(for pkg in `find */package_info -name 'license.txt' | awk -F "/" '{print $1}'`; do if [ -e ${pkg}/include ]; then find ${pkg}/include -type f -name '*.h' | xargs -r egrep -l "^#\s*define\s+CGAL_.*_H\s*$" | xargs -r egrep -l "SPDX-License-Identifier.*[ (]GPL" | xargs -r grep -L "#include <CGAL/license"; fi; done)
|
||||
file_without_license_include=$(for pkg in `find */package_info -name 'license.txt' | awk -F "/" '{print $1}'`; do if [ -e ${pkg}/include ]; then find ${pkg}/include -type f -name '*.h' | xargs -r grep -E -l "^#\s*define\s+CGAL_.*_H\s*$" | xargs -r grep -E -l "SPDX-License-Identifier.*[ (]GPL" | xargs -r grep -L "#include <CGAL/license"; fi; done)
|
||||
if [ -n "${file_without_license_include}" ]; then
|
||||
echo "The following files do not have an include directive of the package license header:"
|
||||
echo ${file_without_license_include}
|
||||
|
|
@ -155,7 +155,7 @@ fi
|
|||
|
||||
#check no file contains non-utf8 characters
|
||||
echo '.. Checking if non utf-8 characters are used...'
|
||||
txt_not_utf8=$(git ls-files -z --stage | awk -F"\t" 'BEGIN { RS="\0" }; { printf "%s\n", $2; }' | xargs file -N | grep "text" | egrep -v "UTF-8|ASCII|CSV|XML|EPS|FIG|assembler source|Perl script|from flex")
|
||||
txt_not_utf8=$(git ls-files -z --stage | awk -F"\t" 'BEGIN { RS="\0" }; { printf "%s\n", $2; }' | xargs file -N | grep "text" | grep -E -v "UTF-8|ASCII|CSV|XML|EPS|FIG|assembler source|Perl script|from flex")
|
||||
if [ -n "${txt_not_utf8}" ]; then
|
||||
echo "The following files have non utf-8 characters:"
|
||||
echo ${txt_not_utf8}
|
||||
|
|
@ -164,7 +164,7 @@ fi
|
|||
|
||||
#check no file contains tab characters
|
||||
echo '.. Checking if tab character is used...'
|
||||
file_with_tabs=$(git ls-files --stage | egrep '\.txt|\.h$|\.cpp|\.hpp' | awk '{print $4}' | xargs grep -P -l '\t')
|
||||
file_with_tabs=$(git ls-files --stage | grep -E '\.txt|\.h$|\.cpp|\.hpp' | awk '{print $4}' | xargs grep -P -l '\t')
|
||||
if [ -n "${file_with_tabs}" ]; then
|
||||
echo "The following files have tabs:"
|
||||
echo ${file_with_tabs}
|
||||
|
|
@ -173,7 +173,7 @@ fi
|
|||
|
||||
#check no file contains trailing whitespaces characters
|
||||
echo '.. Look for trailing whitespaces...'
|
||||
files_with_trailingws=$(git ls-files --stage | egrep '\.txt|\.h$|\.cpp|\.hpp' | awk '{print $4}' | xargs grep -P -l '\s+$')
|
||||
files_with_trailingws=$(git ls-files --stage | grep -E '\.txt|\.h$|\.cpp|\.hpp' | awk '{print $4}' | xargs grep -P -l '\s+$')
|
||||
if [ -n "${files_with_trailingws}" ]; then
|
||||
echo "The following files have trailing whitespaces:"
|
||||
echo ${files_with_trailingws}
|
||||
|
|
@ -191,7 +191,7 @@ fi
|
|||
|
||||
#check documented function named parameters exists
|
||||
echo '.. Checking documented function named parameters'
|
||||
nps=$(git ls-files --stage | egrep '\.h' | awk '{print $4}' | xargs egrep "cgalParamNBegin\{.+\}" | perl -lne 'print for /cgalParamNBegin{(.+)}/' | sort -u )
|
||||
nps=$(git ls-files --stage | grep -E '\.h' | awk '{print $4}' | xargs grep -E "cgalParamNBegin\{.+\}" | perl -lne 'print for /cgalParamNBegin{(.+)}/' | sort -u )
|
||||
git_dir=`pwd`
|
||||
tmp_dir=`mktemp -d`
|
||||
cd $tmp_dir
|
||||
|
|
|
|||
|
|
@ -282,7 +282,7 @@ EOF
|
|||
BASE=`basename $BASE .CPP`
|
||||
BASE=`basename $BASE .c++`
|
||||
BASE=`basename $BASE .C`
|
||||
egrep '\bmain[ \t]*\(' $file >/dev/null 2>&1
|
||||
grep -E '\bmain[ \t]*\(' $file >/dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "create_single_source_cgal_program( \"$file\" )"
|
||||
if [ -n "$ENABLE_CTEST" ]; then
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ EOF
|
|||
BASE=`basename $BASE .CPP`
|
||||
BASE=`basename $BASE .c++`
|
||||
BASE=`basename $BASE .C`
|
||||
egrep '\bmain[ \t]*\(' $file >/dev/null 2>&1
|
||||
grep -E '\bmain[ \t]*\(' $file >/dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "create_single_source_cgal_program( \"$file\" )"
|
||||
echo "Adding a target ${BASE}..." >&3
|
||||
|
|
|
|||
|
|
@ -330,7 +330,7 @@ public:
|
|||
dim_ = static_cast<int>(std::distance(ccci(p), ccci(p,0)));
|
||||
|
||||
data.reserve(pts.size());
|
||||
for(unsigned int i = 0; i < pts.size(); i++){
|
||||
for(std::size_t i = 0; i < pts.size(); i++){
|
||||
data.push_back(&pts[i]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,9 +38,13 @@ create_interior_skeleton_and_offset_polygons_with_holes_2(FT offset,
|
|||
\ingroup PkgStraightSkeleton2OffsetFunctions
|
||||
|
||||
returns a container with all the outer offset polygons <I>with holes</I>
|
||||
at distance `offset` of the 2D polygon `poly_with_holes`.
|
||||
at distance `offset` of the 2D polygon `poly_with_holes`. Note that the
|
||||
offset of the outer frame is ignored.
|
||||
|
||||
This is equivalent to `arrange_offset_polygons_2(create_exterior_skeleton_and_offset_polygons_2(offset, poly_with_holes, ofk, ssk))`.
|
||||
This is equivalent to a call to `CGAL::arrange_offset_polygons_2()` on the
|
||||
output of \link CGAL::create_exterior_skeleton_and_offset_polygons_2() `create_exterior_skeleton_and_offset_polygons_2(offset, poly_with_holes, ofk, ssk))` \endlink
|
||||
after having filtered out the polygon corresponding to the offset of the outer frame and
|
||||
having reversed the orientation of all other polygons.
|
||||
|
||||
\tparam OfK must be a model of `Kernel`. It is used to instantiate
|
||||
`Polygon_offset_builder_traits_2<OfK>` for constructing the offset polygons.
|
||||
|
|
|
|||
|
|
@ -422,11 +422,15 @@ This \cgal packages provides a helper function to compute the required separatio
|
|||
|
||||
If you use this function to place the outer frame you are guaranteed to obtain an offset contour corresponding exclusively to the frame, which you can always identify as the one with the largest area and which you can simple remove from the result (to keep just the relevant outer contours).
|
||||
|
||||
|
||||
\cgalFigureBegin{Exterior,exterior_skeleton.png,exterior_offset.png}
|
||||
Exterior skeleton obtained using a frame (left) and 2 sample exterior offset contours (right)
|
||||
\cgalFigureEnd
|
||||
|
||||
For convenience, the following functions are provided:
|
||||
|
||||
- `CGAL::create_exterior_skeleton_and_offset_polygons_2()` adds the outer frame to the input polygon (with or without holes) and provides output offset polygons (`CGAL::Polygon_2<K>`), including the offset of the outer frame.
|
||||
- `CGAL::create_exterior_skeleton_and_offset_polygons_with_holes_2()` adds the outer frame to the input polygon (with or without holes) and provides as output offset polygons with holes (`CGAL::Polygon_with_holes_2`), exclusing the offset of the outer frame.
|
||||
|
||||
\section Straight_skeleton_2Straight Straight Skeletons, Medial Axis and Voronoi Diagrams
|
||||
|
||||
The straight skeleton of a polygon is similar to the medial
|
||||
|
|
@ -441,7 +445,7 @@ On the other hand, only reflex vertices (whose internal angle \f$ > \pi\f$)
|
|||
are the source of deviations of the bisectors from its center
|
||||
location. Therefore, for convex polygons, the straight skeleton, the
|
||||
medial axis and the Voronoi diagram are exactly equivalent,
|
||||
and, if a non-convex polygon contains only vertices of lowfor f in *.txt ; do echo $f ; aspell list < $f | sort | uniq -c ; done
|
||||
and, if a non-convex polygon contains only vertices of low
|
||||
reflexivity, the straight skeleton bisectors will be placed nearly
|
||||
equidistant to their defining edges, producing a straight skeleton
|
||||
pretty much alike a proper medial axis.
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ endforeach()
|
|||
|
||||
if(CGAL_Qt5_FOUND)
|
||||
target_link_libraries(draw_straight_skeleton_2 PUBLIC CGAL::CGAL_Basic_viewer)
|
||||
target_link_libraries(exterior_offset_of_multiple_polygons_with_holes PUBLIC CGAL::CGAL_Basic_viewer)
|
||||
else()
|
||||
message(STATUS "NOTICE: The example draw_straight_skeleton_2 requires Qt and will not be compiled.")
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,131 @@
|
|||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <CGAL/Polygon_with_holes_2.h>
|
||||
#include <CGAL/create_offset_polygons_from_polygon_with_holes_2.h>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include <CGAL/draw_polygon_with_holes_2.h>
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K ;
|
||||
|
||||
typedef K::Point_2 Point ;
|
||||
typedef CGAL::Polygon_2<K> Polygon_2 ;
|
||||
typedef CGAL::Polygon_with_holes_2<K> PolygonWithHoles ;
|
||||
|
||||
typedef boost::shared_ptr<PolygonWithHoles> PolygonWithHolesPtr ;
|
||||
typedef boost::shared_ptr<Polygon_2> PolygonPtr ;
|
||||
|
||||
typedef std::vector<PolygonWithHolesPtr> PolygonWithHolesPtrVector;
|
||||
typedef std::vector<PolygonPtr> PolygonPtrVector;
|
||||
|
||||
PolygonWithHolesPtrVector
|
||||
exterior_offset_of_disjoint_polygons_with_holes(double lOffset, const std::vector<PolygonWithHoles>& pwhs)
|
||||
{
|
||||
std::vector<Point> outer_vertices;
|
||||
for (const PolygonWithHoles& pwh : pwhs)
|
||||
outer_vertices.insert(outer_vertices.end(),
|
||||
pwh.outer_boundary().container().begin(),
|
||||
pwh.outer_boundary().container().end());
|
||||
boost::optional<double> margin = compute_outer_frame_margin(outer_vertices.begin(),
|
||||
outer_vertices.end(),
|
||||
lOffset);
|
||||
|
||||
if ( margin )
|
||||
{
|
||||
double lm = CGAL::to_double(*margin);
|
||||
CGAL::Bbox_2 bbox = bbox_2(outer_vertices.begin(), outer_vertices.end());
|
||||
|
||||
double fxmin = bbox.xmin() - lm ;
|
||||
double fxmax = bbox.xmax() + lm ;
|
||||
double fymin = bbox.ymin() - lm ;
|
||||
double fymax = bbox.ymax() + lm ;
|
||||
|
||||
Polygon_2 frame ;
|
||||
frame.push_back( Point(fxmin,fymin) );
|
||||
frame.push_back( Point(fxmax,fymin) );
|
||||
frame.push_back( Point(fxmax,fymax) );
|
||||
frame.push_back( Point(fxmin,fymax) );
|
||||
|
||||
std::vector<Polygon_2> outer_as_holes;
|
||||
outer_as_holes.reserve(pwhs.size());
|
||||
for (const PolygonWithHoles& pwh : pwhs)
|
||||
outer_as_holes.emplace_back(pwh.outer_boundary().container().rbegin(),
|
||||
pwh.outer_boundary().container().rend());
|
||||
|
||||
PolygonWithHoles pwh(frame, outer_as_holes.begin(), outer_as_holes.end());
|
||||
PolygonPtrVector off_polys = CGAL::create_interior_skeleton_and_offset_polygons_2(lOffset,pwh);
|
||||
|
||||
// filter outer frame
|
||||
Point xtrm_pt = *(off_polys[0]->begin());
|
||||
std::size_t outer_id=0;
|
||||
for(std::size_t i=0; i<off_polys.size(); ++i)
|
||||
if (off_polys[i]->orientation() == CGAL::COUNTERCLOCKWISE)
|
||||
{
|
||||
for (const Point& p : off_polys[i]->container())
|
||||
if (p < xtrm_pt)
|
||||
{
|
||||
xtrm_pt=p;
|
||||
outer_id=i;
|
||||
}
|
||||
}
|
||||
if (outer_id != (off_polys.size()-1))
|
||||
std::swap(off_polys[outer_id], off_polys.back());
|
||||
off_polys.pop_back();
|
||||
for (PolygonPtr ptr : off_polys)
|
||||
ptr->reverse_orientation();
|
||||
|
||||
// offset of holes
|
||||
for (const PolygonWithHoles& pwh : pwhs)
|
||||
{
|
||||
for (PolygonWithHoles::Hole_const_iterator hit=pwh.holes_begin();
|
||||
hit!=pwh.holes_end();
|
||||
++hit)
|
||||
{
|
||||
Polygon_2 h = *hit;
|
||||
h.reverse_orientation();
|
||||
PolygonPtrVector off_hole = CGAL::create_interior_skeleton_and_offset_polygons_2(lOffset,h);
|
||||
off_polys.insert(off_polys.end(), off_hole.begin(), off_hole.end());
|
||||
}
|
||||
}
|
||||
|
||||
return CGAL::arrange_offset_polygons_2<PolygonWithHoles>(off_polys);
|
||||
}
|
||||
|
||||
return PolygonWithHolesPtrVector();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
std::vector<PolygonWithHoles> pwhs;
|
||||
|
||||
for (int i=0; i<4; ++i)
|
||||
{
|
||||
Polygon_2 outer;
|
||||
outer.push_back( Point(i+0+i*10, 0) );
|
||||
outer.push_back( Point(i+0+(i+1)*10, 0) );
|
||||
outer.push_back( Point(i+0+(i+1)*10, 10) );
|
||||
outer.push_back( Point(i+0+i*10, 10) );
|
||||
pwhs.emplace_back(outer);
|
||||
|
||||
Polygon_2 hole;
|
||||
hole.push_back( Point(i+3+i*10,3) ) ;
|
||||
hole.push_back( Point(i+6+i*10,3) ) ;
|
||||
hole.push_back( Point(i+6+i*10,6) ) ;
|
||||
hole.push_back( Point(i+3+i*10,6) ) ;
|
||||
pwhs[i].add_hole( hole ) ;
|
||||
}
|
||||
|
||||
double lOffset = 1.1 ;
|
||||
|
||||
PolygonWithHolesPtrVector offset_poly_with_holes = exterior_offset_of_disjoint_polygons_with_holes(lOffset,pwhs);
|
||||
|
||||
for (PolygonWithHolesPtr ptr : offset_poly_with_holes)
|
||||
CGAL::draw(*ptr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -45,7 +45,7 @@ bool are_parallel_edges_equally_oriented( Segment_2_with_ID<K> const& e0, Segmen
|
|||
template<class K>
|
||||
bool are_edges_orderly_collinear( Segment_2_with_ID<K> const& e0, Segment_2_with_ID<K> const& e1 )
|
||||
{
|
||||
return are_edges_collinear(e0,e1) & are_parallel_edges_equally_oriented(e0,e1);
|
||||
return are_edges_collinear(e0,e1) && are_parallel_edges_equally_oriented(e0,e1);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -389,7 +389,7 @@ create_exterior_skeleton_and_offset_polygons_2(const FT& aOffset,
|
|||
ofk);
|
||||
}
|
||||
|
||||
// Overloads common to both polygons with and without holes, a simple polygon is returned in any case
|
||||
// Overloads common to both polygons with and without holes, a simple polygons are returned in any case
|
||||
template<class FT, class APolygon, class OfK,
|
||||
class OutPolygon = typename CGAL_SS_i::Default_return_polygon_type<APolygon, OfK>::type>
|
||||
std::vector< boost::shared_ptr<OutPolygon> >
|
||||
|
|
|
|||
|
|
@ -97,6 +97,44 @@ create_interior_skeleton_and_offset_polygons_with_holes_2(const FT& aOffset,
|
|||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// EXTERIOR
|
||||
|
||||
/*! create_exterior_skeleton_and_offset_polygons_with_holes_2 (orders the resulting polygons) */
|
||||
|
||||
// Polygon might be a Polygon with holes or not, but it returns a Polygon with holes
|
||||
template<class FT, class Polygon, class OfK, class SsK,
|
||||
class OutPolygonWithHoles = typename CGAL_SS_i::Default_return_polygon_with_holes_type<Polygon, OfK>::type>
|
||||
std::vector<boost::shared_ptr<OutPolygonWithHoles> >
|
||||
inline
|
||||
create_exterior_skeleton_and_offset_polygons_with_holes_2(const FT& aOffset,
|
||||
const Polygon& aPoly,
|
||||
const OfK& ofk,
|
||||
const SsK& ssk)
|
||||
{
|
||||
typedef typename CGAL_SS_i::Default_return_polygon_type<Polygon, OfK>::type Polygon_;
|
||||
std::vector<boost::shared_ptr<Polygon_> > raw_output =
|
||||
create_exterior_skeleton_and_offset_polygons_2(aOffset, aPoly, ofk, ssk);
|
||||
|
||||
// filter offset of the outer frame
|
||||
typename OfK::Point_2 xtrm_pt = *(raw_output[0]->begin());
|
||||
std::size_t outer_id=0;
|
||||
for(std::size_t i=0; i<raw_output.size(); ++i)
|
||||
if (raw_output[i]->orientation() == COUNTERCLOCKWISE)
|
||||
{
|
||||
for (const typename OfK::Point_2& p : raw_output[i]->container())
|
||||
if (p < xtrm_pt)
|
||||
{
|
||||
xtrm_pt=p;
|
||||
outer_id=i;
|
||||
}
|
||||
}
|
||||
if (outer_id != (raw_output.size()-1))
|
||||
std::swap(raw_output[outer_id], raw_output.back());
|
||||
raw_output.pop_back();
|
||||
for (boost::shared_ptr<Polygon_> ptr : raw_output)
|
||||
ptr->reverse_orientation();
|
||||
|
||||
return arrange_offset_polygons_2<OutPolygonWithHoles>(raw_output);
|
||||
}
|
||||
|
||||
/*! create_interior_skeleton_and_offset_polygons_2 with a polygon with holes */
|
||||
|
||||
// overload where PolygonWithHoles actually is a type of Polygon that supports holes
|
||||
|
|
@ -111,23 +149,21 @@ create_exterior_skeleton_and_offset_polygons_2(const FT& aOffset,
|
|||
typename std::enable_if<
|
||||
CGAL_SS_i::has_Hole_const_iterator<PolygonWithHoles>::value>::type* = nullptr)
|
||||
{
|
||||
return create_exterior_skeleton_and_offset_polygons_2(aOffset, aPoly.outer_boundary(), ofk, ssk);
|
||||
}
|
||||
std::vector<boost::shared_ptr<OutPolygon> > polygons =
|
||||
create_exterior_skeleton_and_offset_polygons_2(aOffset, aPoly.outer_boundary(), ofk, ssk);
|
||||
|
||||
/*! create_exterior_skeleton_and_offset_polygons_with_holes_2 (orders the resulting polygons) */
|
||||
for (typename PolygonWithHoles::Hole_const_iterator hit=aPoly.holes_begin(); hit!=aPoly.holes_end(); ++hit)
|
||||
{
|
||||
typename PolygonWithHoles::Polygon_2 hole = *hit;
|
||||
hole.reverse_orientation();
|
||||
std::vector<boost::shared_ptr<OutPolygon> > hole_polygons =
|
||||
create_interior_skeleton_and_offset_polygons_2(aOffset,
|
||||
hole,
|
||||
ofk,ssk);
|
||||
polygons.insert(polygons.end(), hole_polygons.begin(), hole_polygons.end());
|
||||
}
|
||||
|
||||
// Polygon might be a Polygon with holes or not, but it returns a Polygon with holes
|
||||
template<class FT, class Polygon, class OfK, class SsK,
|
||||
class OutPolygonWithHoles = typename CGAL_SS_i::Default_return_polygon_with_holes_type<Polygon, OfK>::type>
|
||||
std::vector<boost::shared_ptr<OutPolygonWithHoles> >
|
||||
inline
|
||||
create_exterior_skeleton_and_offset_polygons_with_holes_2(const FT& aOffset,
|
||||
const Polygon& aPoly,
|
||||
const OfK& ofk,
|
||||
const SsK& ssk)
|
||||
{
|
||||
return arrange_offset_polygons_2<OutPolygonWithHoles>(
|
||||
create_exterior_skeleton_and_offset_polygons_2(aOffset, aPoly, ofk, ssk));
|
||||
return polygons;
|
||||
}
|
||||
|
||||
template<class FT, class Polygon, class OfK,
|
||||
|
|
|
|||
|
|
@ -760,9 +760,8 @@ void test_offset_polygon_exterior()
|
|||
// print_polygon_with_holes(*offp);
|
||||
|
||||
assert(offset_poly_with_holes.size() == 1);
|
||||
assert(offset_poly_with_holes[0]->outer_boundary().size() == 4);
|
||||
assert(offset_poly_with_holes[0]->number_of_holes() == 1);
|
||||
assert(offset_poly_with_holes[0]->holes_begin()->size() == 12);
|
||||
assert(offset_poly_with_holes[0]->outer_boundary().size() == 12);
|
||||
assert(offset_poly_with_holes[0]->number_of_holes() == 0);
|
||||
|
||||
// -----------------------------------------------------------------------------------------------
|
||||
// Value such that it is clearly separated into two contours
|
||||
|
|
@ -770,20 +769,19 @@ void test_offset_polygon_exterior()
|
|||
offset_poly_with_holes =
|
||||
create_exterior_skeleton_and_offset_polygons_with_holes_2(FT(7), poly, K(), EPICK());
|
||||
|
||||
// for(const auto& offp : offset_poly_with_holes)
|
||||
// print_polygon_with_holes(*offp);
|
||||
// for(const auto& offp : offset_poly_with_holes)
|
||||
// print_polygon_with_holes(*offp);
|
||||
|
||||
assert(offset_poly_with_holes.size() == 2);
|
||||
assert(offset_poly_with_holes[0]->outer_boundary().size() == 4);
|
||||
assert(offset_poly_with_holes.size() == 1);
|
||||
assert(offset_poly_with_holes[0]->number_of_holes() == 1);
|
||||
|
||||
// Technically both polygons below should be rectangles, but the algorithm puts a 5th vertex collinear.
|
||||
// Tolerating it for now...
|
||||
|
||||
// assert(offset_poly_with_holes[0]->holes_begin()->size() == 4);
|
||||
// assert(offset_poly_with_holes[1]->outer_boundary().size() == 4);
|
||||
assert(offset_poly_with_holes[0]->holes_begin()->size() >= 4);
|
||||
assert(offset_poly_with_holes[0]->outer_boundary().size() >= 4);
|
||||
assert(offset_poly_with_holes[0]->holes_begin()->is_simple());
|
||||
assert(offset_poly_with_holes[1]->outer_boundary().is_simple());
|
||||
assert(offset_poly_with_holes[0]->outer_boundary().is_simple());
|
||||
|
||||
// -----------------------------------------------------------------------------------------------
|
||||
// Border value between a single contour and two contours
|
||||
|
|
@ -795,17 +793,54 @@ void test_offset_polygon_exterior()
|
|||
// for(const auto& offp : offset_poly_with_holes)
|
||||
// print_polygon_with_holes(*offp);
|
||||
|
||||
assert(offset_poly_with_holes.size() == 2);
|
||||
assert(offset_poly_with_holes[0]->outer_boundary().size() == 4);
|
||||
assert(offset_poly_with_holes.size() >= 1);
|
||||
assert(offset_poly_with_holes[0]->number_of_holes() == 1);
|
||||
|
||||
// Technically both polygons below should be rectangles, but the algorithm puts a 5th vertex collinear.
|
||||
// Tolerating it for now...
|
||||
|
||||
// assert(offset_poly_with_holes[0]->holes_begin()->size() == 4);
|
||||
// assert(offset_poly_with_holes[1]->outer_boundary().size() == 4);
|
||||
assert(offset_poly_with_holes[0]->holes_begin()->size() >= 4);
|
||||
assert(offset_poly_with_holes[0]->outer_boundary().size() >= 4);
|
||||
assert(offset_poly_with_holes[0]->holes_begin()->is_simple());
|
||||
assert(offset_poly_with_holes[1]->outer_boundary().is_simple());
|
||||
assert(offset_poly_with_holes[0]->outer_boundary().is_simple());
|
||||
}
|
||||
|
||||
template <typename K>
|
||||
void test_offset_polygon_with_holes_exterior()
|
||||
{
|
||||
std::cout << " --- Test Polygon exterior, kernel: " << typeid(K).name() << std::endl;
|
||||
|
||||
typedef typename K::Point_2 Point;
|
||||
|
||||
typedef CGAL::Polygon_2<K> Polygon_2;
|
||||
typedef CGAL::Polygon_with_holes_2<K> Polygon_with_holes_2;
|
||||
typedef boost::shared_ptr<Polygon_with_holes_2> Polygon_with_holes_2_ptr;
|
||||
typedef std::vector<Polygon_with_holes_2_ptr> Polygon_with_holes_2_ptr_container;
|
||||
|
||||
Polygon_2 outer ;
|
||||
outer.push_back( Point( 10.0, 10.0) ) ;
|
||||
outer.push_back( Point(-10.0, 10.0) ) ;
|
||||
outer.push_back( Point(-10.0, -10.0) ) ;
|
||||
outer.push_back( Point(10.0, -10.0) ) ;
|
||||
|
||||
Polygon_2 hole ;
|
||||
hole.push_back( Point(5.0,5.0) ) ;
|
||||
hole.push_back( Point(5.0,-5.0) ) ;
|
||||
hole.push_back( Point(-5.0,-5.0) ) ;
|
||||
hole.push_back( Point(-5.0,5.0) ) ;
|
||||
|
||||
Polygon_with_holes_2 pwh(outer) ;
|
||||
pwh.add_hole( hole ) ;
|
||||
|
||||
Polygon_with_holes_2_ptr_container offset_poly_with_holes_1 =
|
||||
CGAL::create_exterior_skeleton_and_offset_polygons_with_holes_2(1., pwh, K(), EPICK());
|
||||
assert(offset_poly_with_holes_1.size()==1);
|
||||
assert(offset_poly_with_holes_1[0]->number_of_holes()==1);
|
||||
|
||||
Polygon_with_holes_2_ptr_container offset_poly_with_holes_2 =
|
||||
CGAL::create_exterior_skeleton_and_offset_polygons_with_holes_2(5., pwh, K(), EPICK());
|
||||
assert(offset_poly_with_holes_2.size()==1);
|
||||
assert(offset_poly_with_holes_2[0]->number_of_holes()==0);
|
||||
}
|
||||
|
||||
template <typename K>
|
||||
|
|
@ -940,6 +975,7 @@ void test_kernel()
|
|||
test_offset_non_manifold<K>();
|
||||
test_offset_non_manifold_2<K>();
|
||||
test_offset_polygon_exterior<K>();
|
||||
test_offset_polygon_with_holes_exterior<K>();
|
||||
test_offset_multiple_CCs<K>();
|
||||
|
||||
// Real data
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
#include <CGAL/IO/Polyhedron_iostream.h>
|
||||
// HalfedgeGraph adapters for Polyhedron_3
|
||||
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
|
||||
#include <CGAL/boost/graph/properties_Polyhedron_3.h>
|
||||
// #define CGAL_DEFORM_MESH_USE_EXPERIMENTAL_SR_ARAP
|
||||
#include <CGAL/Surface_mesh_deformation.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -13,9 +13,11 @@
|
|||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
||||
typedef CGAL::Surface_mesh<Kernel::Point_3> Triangle_mesh;
|
||||
|
||||
typedef CGAL::Surface_mesh_shortest_path_traits<Kernel, Triangle_mesh> Traits;
|
||||
typedef CGAL::Surface_mesh_shortest_path<Traits> Surface_mesh_shortest_path;
|
||||
typedef Traits::Barycentric_coordinates Barycentric_coordinates;
|
||||
|
||||
typedef boost::graph_traits<Triangle_mesh> Graph_traits;
|
||||
typedef Graph_traits::vertex_iterator vertex_iterator;
|
||||
typedef Graph_traits::face_iterator face_iterator;
|
||||
|
|
@ -34,23 +36,24 @@ struct Sequence_collector
|
|||
|
||||
void operator()(halfedge_descriptor he, double alpha)
|
||||
{
|
||||
|
||||
sequence.push_back( std::make_pair(he, alpha) );
|
||||
sequence.push_back(std::make_pair(he, alpha));
|
||||
}
|
||||
|
||||
void operator()(vertex_descriptor v)
|
||||
{
|
||||
sequence.push_back( v );
|
||||
sequence.push_back(v);
|
||||
}
|
||||
|
||||
void operator()(face_descriptor f, Barycentric_coordinates alpha)
|
||||
{
|
||||
sequence.push_back( std::make_pair(f, alpha) );
|
||||
sequence.push_back(std::make_pair(f, alpha));
|
||||
}
|
||||
};
|
||||
|
||||
// A visitor to print what a variant contains using boost::apply_visitor
|
||||
struct Print_visitor : public boost::static_visitor<> {
|
||||
struct Print_visitor
|
||||
: public boost::static_visitor<>
|
||||
{
|
||||
int i;
|
||||
Triangle_mesh& g;
|
||||
|
||||
|
|
@ -58,22 +61,25 @@ struct Print_visitor : public boost::static_visitor<> {
|
|||
|
||||
void operator()(vertex_descriptor v)
|
||||
{
|
||||
std::cout << "#" << ++i << " : Vertex : " << get(boost::vertex_index, g)[v] << "\n";
|
||||
std::cout << "#" << ++i << " Vertex: " << get(boost::vertex_index, g)[v];
|
||||
std::cout << " Position: " << Surface_mesh_shortest_path::point(v, g) << "\n";
|
||||
}
|
||||
|
||||
void operator()(const std::pair<halfedge_descriptor,double>& h_a)
|
||||
{
|
||||
std::cout << "#" << ++i << " : Edge : " << get(CGAL::halfedge_index, g)[h_a.first] << " , ("
|
||||
std::cout << "#" << ++i << " Edge: " << get(CGAL::halfedge_index, g)[h_a.first] << " , ("
|
||||
<< 1.0 - h_a.second << " , "
|
||||
<< h_a.second << ")\n";
|
||||
<< h_a.second << ")";
|
||||
std::cout << " Position: " << Surface_mesh_shortest_path::point(h_a.first, h_a.second, g) << "\n";
|
||||
}
|
||||
|
||||
void operator()(const std::pair<face_descriptor, Barycentric_coordinates>& f_bc)
|
||||
{
|
||||
std::cout << "#" << ++i << " : Face : " << get(CGAL::face_index, g)[f_bc.first] << " , ("
|
||||
std::cout << "#" << ++i << " Face: " << get(CGAL::face_index, g)[f_bc.first] << " , ("
|
||||
<< f_bc.second[0] << " , "
|
||||
<< f_bc.second[1] << " , "
|
||||
<< f_bc.second[2] << ")\n";
|
||||
<< f_bc.second[2] << ")";
|
||||
std::cout << " Position: " << Surface_mesh_shortest_path::point(f_bc.first, f_bc.second, g) << "\n";
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -100,12 +106,16 @@ int main(int argc, char** argv)
|
|||
|
||||
// construct a shortest path query object and add a source point
|
||||
Surface_mesh_shortest_path shortest_paths(tmesh);
|
||||
|
||||
std::cout << "Add source: " << Surface_mesh_shortest_path::point(*face_it, face_location, tmesh) << std::endl;
|
||||
shortest_paths.add_source_point(*face_it, face_location);
|
||||
|
||||
// pick a random target point inside a face
|
||||
face_it = faces(tmesh).first;
|
||||
std::advance(face_it, rand.get_int(0, static_cast<int>(num_faces(tmesh))));
|
||||
|
||||
std::cout << "Target is: " << Surface_mesh_shortest_path::point(*face_it, face_location, tmesh) << std::endl;
|
||||
|
||||
// collect the sequence of simplicies crossed by the shortest path
|
||||
Sequence_collector sequence_collector;
|
||||
shortest_paths.shortest_path_sequence_to_source_points(*face_it, face_location, sequence_collector);
|
||||
|
|
|
|||
|
|
@ -14,36 +14,29 @@
|
|||
|
||||
#include <CGAL/license/Surface_mesh_shortest_path.h>
|
||||
|
||||
#include <CGAL/disable_warnings.h>
|
||||
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <queue>
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <list>
|
||||
|
||||
#include <boost/array.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <iterator>
|
||||
|
||||
#include <CGAL/assertions.h>
|
||||
#include <CGAL/AABB_tree.h>
|
||||
#include <CGAL/Default.h>
|
||||
#include <CGAL/enum.h>
|
||||
#include <CGAL/number_utils.h>
|
||||
|
||||
#include <CGAL/Surface_mesh_shortest_path/barycentric.h>
|
||||
#include <CGAL/Surface_mesh_shortest_path/internal/Cone_tree.h>
|
||||
#include <CGAL/Surface_mesh_shortest_path/internal/misc_functions.h>
|
||||
|
||||
#include <CGAL/assertions.h>
|
||||
#include <CGAL/AABB_tree.h>
|
||||
#include <CGAL/boost/graph/helpers.h>
|
||||
#include <CGAL/boost/graph/iterator.h>
|
||||
#include <CGAL/Default.h>
|
||||
#include <CGAL/enum.h>
|
||||
#include <CGAL/number_utils.h>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/variant/get.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <list>
|
||||
#include <queue>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
/*!
|
||||
|
|
@ -276,8 +269,6 @@ public:
|
|||
/// @}
|
||||
|
||||
private:
|
||||
typedef typename Graph_traits::vertex_iterator vertex_iterator;
|
||||
typedef typename Graph_traits::halfedge_iterator halfedge_iterator;
|
||||
typedef typename Graph_traits::face_iterator face_iterator;
|
||||
|
||||
typedef typename Traits::Triangle_3 Triangle_3;
|
||||
|
|
@ -354,13 +345,11 @@ private:
|
|||
Expansion_priqueue m_expansionPriqueue;
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
|
||||
std::size_t m_currentNodeCount;
|
||||
std::size_t m_peakNodeCount;
|
||||
std::size_t m_queueAtPeakNodes;
|
||||
std::size_t m_peakQueueSize;
|
||||
std::size_t m_nodesAtPeakQueue;
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
|
|
@ -420,7 +409,6 @@ public:
|
|||
|
||||
#endif
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/// \cond
|
||||
|
|
@ -533,7 +521,8 @@ private:
|
|||
}
|
||||
|
||||
/*
|
||||
Filtering algorithm described in Xin and Wang (2009) "Improving chen and han's algorithm on the discrete geodesic problem."
|
||||
Filtering algorithm described in Xin and Wang (2009)
|
||||
"Improving chen and han's algorithm on the discrete geodesic problem."
|
||||
https://dl.acm.org/citation.cfm?doid=1559755.1559761
|
||||
*/
|
||||
bool window_distance_filter(Cone_tree_node* cone,
|
||||
|
|
@ -659,7 +648,6 @@ private:
|
|||
}
|
||||
|
||||
CGAL_assertion(cone->m_pendingLeftSubtree != nullptr);
|
||||
|
||||
cone->m_pendingLeftSubtree = nullptr;
|
||||
|
||||
if (window_distance_filter(cone, windowSegment, false))
|
||||
|
|
@ -689,14 +677,13 @@ private:
|
|||
typename Traits::Construct_vertex_2 cv2(m_traits.construct_vertex_2_object());
|
||||
typename Traits::Construct_triangle_3_along_segment_2_flattening ft3as2(m_traits.construct_triangle_3_along_segment_2_flattening_object());
|
||||
|
||||
CGAL_assertion(cone->m_pendingRightSubtree != nullptr);
|
||||
cone->m_pendingRightSubtree = nullptr;
|
||||
|
||||
if (m_debugOutput)
|
||||
{
|
||||
std::cout << std::endl << " >>>>>>>>>>>>>>>>>>> Expanding RIGHT CHILD <<<<<<<<<<<<<<<<<<<" <<std::endl;
|
||||
}
|
||||
|
||||
CGAL_assertion(cone->m_pendingRightSubtree != nullptr);
|
||||
cone->m_pendingRightSubtree = nullptr;
|
||||
|
||||
if (window_distance_filter(cone, windowSegment, true))
|
||||
{
|
||||
|
|
@ -729,7 +716,7 @@ private:
|
|||
|
||||
std::size_t associatedEdge;
|
||||
CGAL::Surface_mesh_shortest_paths_3::Barycentric_coordinates_type type;
|
||||
boost::tie(type, associatedEdge) = classify_barycentric_coordinates(location);
|
||||
std::tie(type, associatedEdge) = classify_barycentric_coordinates(location);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
|
|
@ -777,11 +764,13 @@ private:
|
|||
|
||||
Cone_tree_node* faceRoot = new Cone_tree_node(m_traits, m_graph, m_rootNodes.size());
|
||||
node_created();
|
||||
m_rootNodes.push_back(std::make_pair(faceRoot, sourcePointIt));
|
||||
m_rootNodes.emplace_back(faceRoot, sourcePointIt);
|
||||
|
||||
if (m_debugOutput)
|
||||
{
|
||||
typename Traits::Construct_barycentric_coordinates_weight cbcw(m_traits.construct_barycentric_coordinates_weight_object());
|
||||
|
||||
std::cout << std::endl << " ~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
|
||||
std::cout << "\tFace Root Expansion: id = " << get(m_faceIndexMap, f)
|
||||
<< " , Location = " << cbcw(faceLocation, 0) << " " << cbcw(faceLocation, 1)
|
||||
<< " " << cbcw(faceLocation, 2) << " " << std::endl;
|
||||
|
|
@ -794,8 +783,12 @@ private:
|
|||
const Barycentric_coordinates rotatedFaceLocation(shifted_coordinates(faceLocation, currentVertex));
|
||||
const Point_2 sourcePoint(construct_barycenter_in_triangle_2(layoutFace, rotatedFaceLocation));
|
||||
|
||||
Cone_tree_node* child = new Cone_tree_node(m_traits, m_graph, current, layoutFace, sourcePoint,
|
||||
FT(0), cv2(layoutFace, 0), cv2(layoutFace, 2),
|
||||
Cone_tree_node* child = new Cone_tree_node(m_traits, m_graph,
|
||||
current /*entryEdge*/,
|
||||
layoutFace, sourcePoint,
|
||||
FT(0) /*pseudoSourceDistance*/,
|
||||
cv2(layoutFace, 0) /*windowLeft*/,
|
||||
cv2(layoutFace, 2) /*windowRight*/,
|
||||
Cone_tree_node::FACE_SOURCE);
|
||||
node_created();
|
||||
faceRoot->push_middle_child(child);
|
||||
|
|
@ -803,7 +796,8 @@ private:
|
|||
if (m_debugOutput)
|
||||
{
|
||||
std::cout << "\tExpanding face root #" << currentVertex << " : " << std::endl;;
|
||||
std::cout << "\t\tFace = " << layoutFace << std::endl;
|
||||
std::cout << "\t\t3D Face = " << face3d << std::endl;
|
||||
std::cout << "\t\t2D Face = " << layoutFace << std::endl;
|
||||
std::cout << "\t\tLocation = " << sourcePoint << std::endl;
|
||||
}
|
||||
|
||||
|
|
@ -820,53 +814,127 @@ private:
|
|||
const FT t0, const FT t1,
|
||||
Source_point_iterator sourcePointIt)
|
||||
{
|
||||
typename Traits::Construct_barycenter_2 cb2(m_traits.construct_barycenter_2_object());
|
||||
CGAL_precondition(!is_border(baseEdge, m_graph));
|
||||
CGAL_precondition(t0 + t1 == FT(1));
|
||||
|
||||
typename Traits::Construct_vertex_2 cv2(m_traits.construct_vertex_2_object());
|
||||
typename Traits::Construct_triangle_3_to_triangle_2_projection pt3t2(m_traits.construct_triangle_3_to_triangle_2_projection_object());
|
||||
|
||||
if (m_debugOutput)
|
||||
{
|
||||
std::cout << std::endl << " ~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
|
||||
std::cout << "\tEdge Root Expansion: faceA = " << get(m_faceIndexMap, face(baseEdge, m_graph))
|
||||
<< " , faceB = " << get(m_faceIndexMap, face(opposite(baseEdge, m_graph), m_graph))
|
||||
<< " , t0 = " << t0 << " , t1 = " << t1 << std::endl;
|
||||
std::cout << "\t\tBoundary: " << is_border_edge(baseEdge, m_graph) << std::endl;
|
||||
}
|
||||
|
||||
Cone_tree_node* edgeRoot = new Cone_tree_node(m_traits, m_graph, m_rootNodes.size());
|
||||
node_created();
|
||||
m_rootNodes.emplace_back(edgeRoot, sourcePointIt);
|
||||
|
||||
/* If v0v1 is not a border edge:
|
||||
*
|
||||
* v2
|
||||
* / \
|
||||
* / \
|
||||
* / \
|
||||
* v0 - S - v1
|
||||
* \ /
|
||||
* \ /
|
||||
* \ /
|
||||
* v3
|
||||
* The source S must reach all Vi, so for each side of the edge, there are two windwows being spawned:
|
||||
* - v0v1 targetting v2 propagating only on the left (v0v2)
|
||||
* - v2v0 targetting v1 propagating only on the left (v2v1)
|
||||
* - v1v0 targetting v3 propagating only on the left (v1v3)
|
||||
* - v3v1 targetting v0 propagating only on the left (v3v0)
|
||||
*
|
||||
* If v0v1 is a border edge, spawn 3 children in the face, and none on the other side
|
||||
*/
|
||||
|
||||
if(is_border_edge(baseEdge, m_graph))
|
||||
{
|
||||
const Face_location edgeSourceLocation = face_location(baseEdge, t0);
|
||||
return expand_face_root(face(baseEdge, m_graph), edgeSourceLocation.second, sourcePointIt);
|
||||
}
|
||||
|
||||
// From here on, it is not a border edge --> spawn 2 children on each side
|
||||
|
||||
halfedge_descriptor baseEdges[2];
|
||||
baseEdges[0] = baseEdge;
|
||||
baseEdges[1] = opposite(baseEdge, m_graph);
|
||||
|
||||
Triangle_3 faces3d[2];
|
||||
Triangle_2 layoutFaces[2];
|
||||
|
||||
for (std::size_t i = 0; i < 2; ++i)
|
||||
{
|
||||
faces3d[i] = triangle_from_halfedge(baseEdges[i]);
|
||||
layoutFaces[i] = pt3t2(faces3d[i]);
|
||||
}
|
||||
|
||||
Point_2 sourcePoints[2];
|
||||
sourcePoints[0] = cb2(cv2(layoutFaces[0], 0), t0, cv2(layoutFaces[0], 1), t1);
|
||||
sourcePoints[1] = cb2(cv2(layoutFaces[1], 0), t1, cv2(layoutFaces[1], 1), t0);
|
||||
|
||||
Cone_tree_node* edgeRoot = new Cone_tree_node(m_traits, m_graph, m_rootNodes.size());
|
||||
node_created();
|
||||
m_rootNodes.push_back(std::make_pair(edgeRoot, sourcePointIt));
|
||||
// shift is because the entry halfedge is not necessarily equal to halfedge(face(entry_h, g), g)
|
||||
Barycentric_coordinates edgeSourceLocations[2];
|
||||
edgeSourceLocations[0] = shifted_coordinates(face_location(baseEdges[0], t0).second,
|
||||
Surface_mesh_shortest_paths_3::internal::edge_index(baseEdges[0], m_graph));
|
||||
edgeSourceLocations[1] = shifted_coordinates(face_location(baseEdges[1], t1).second,
|
||||
Surface_mesh_shortest_paths_3::internal::edge_index(baseEdges[1], m_graph));
|
||||
|
||||
for (std::size_t side = 0; side < 2; ++side)
|
||||
{
|
||||
Triangle_3 face3d(triangle_from_halfedge(baseEdges[side]));
|
||||
Triangle_2 layoutFace(pt3t2(face3d));
|
||||
Point_2 sourcePoint(construct_barycenter_in_triangle_2(layoutFace, edgeSourceLocations[side]));
|
||||
|
||||
// v0v1 targetting v2
|
||||
if (m_debugOutput)
|
||||
{
|
||||
std::cout << "\tExpanding edge root #" << side << " : " << std::endl;;
|
||||
std::cout << "\t\tFace = " << layoutFaces[side] << std::endl;
|
||||
std::cout << "\t\tLocation = " << sourcePoints[side] << std::endl;
|
||||
std::cout << std::endl << " ~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
|
||||
std::cout << "\tExpanding edge root, side #" << side << ", targetting LOCAL 'v2'" << std::endl;
|
||||
std::cout << "\t\t3D Face = " << face3d << std::endl;
|
||||
std::cout << "\t\t2D Face = " << layoutFace << std::endl;
|
||||
std::cout << "\t\tBarycentric coordinates: " << edgeSourceLocations[side][0]
|
||||
<< " " << edgeSourceLocations[side][1]
|
||||
<< " " << edgeSourceLocations[side][2] << std::endl;
|
||||
std::cout << "\t\tLocation = " << sourcePoint << std::endl;
|
||||
}
|
||||
|
||||
Cone_tree_node* mainChild = new Cone_tree_node(m_traits, m_graph, baseEdges[side], layoutFaces[side],
|
||||
sourcePoints[side], FT(0), cv2(layoutFaces[side], 0),
|
||||
cv2(layoutFaces[side], 1), Cone_tree_node::EDGE_SOURCE);
|
||||
Cone_tree_node* v2_Child = new Cone_tree_node(m_traits, m_graph,
|
||||
baseEdges[side] /*entryEdge*/,
|
||||
layoutFace,
|
||||
sourcePoint /*sourceImage*/,
|
||||
FT(0) /*pseudoSourceDistance*/,
|
||||
cv2(layoutFace, 0) /*windowLeft*/,
|
||||
cv2(layoutFace, 2) /*windowRight*/,
|
||||
Cone_tree_node::EDGE_SOURCE);
|
||||
node_created();
|
||||
edgeRoot->push_middle_child(mainChild);
|
||||
process_node(mainChild);
|
||||
edgeRoot->push_middle_child(v2_Child);
|
||||
process_node(v2_Child);
|
||||
|
||||
// v2v0 targetting v1
|
||||
face3d = triangle_from_halfedge(prev(baseEdges[side], m_graph));
|
||||
layoutFace = pt3t2(face3d);
|
||||
|
||||
// shift the barycentric coordinates to correspond to the new layout
|
||||
std::swap(edgeSourceLocations[side][1], edgeSourceLocations[side][2]);
|
||||
std::swap(edgeSourceLocations[side][0], edgeSourceLocations[side][1]);
|
||||
sourcePoint = Point_2(construct_barycenter_in_triangle_2(layoutFace, edgeSourceLocations[side]));
|
||||
|
||||
if (m_debugOutput)
|
||||
{
|
||||
std::cout << std::endl << " ~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
|
||||
std::cout << "\tExpanding edge root, side #" << side << ", targetting LOCAL 'v1'" << std::endl;
|
||||
std::cout << "\t\t3D Face = " << face3d << std::endl;
|
||||
std::cout << "\t\t2D Face = " << layoutFace << std::endl;
|
||||
std::cout << "\t\tBarycentric coordinates: " << edgeSourceLocations[side][0]
|
||||
<< " " << edgeSourceLocations[side][1]
|
||||
<< " " << edgeSourceLocations[side][2] << std::endl;
|
||||
std::cout << "\t\tLocation = " << sourcePoint << std::endl;
|
||||
}
|
||||
|
||||
Cone_tree_node* v1_Child = new Cone_tree_node(m_traits, m_graph,
|
||||
prev(baseEdges[side], m_graph) /*entryEdge*/,
|
||||
layoutFace,
|
||||
sourcePoint /*sourceImage*/,
|
||||
FT(0) /*pseudoSourceDistance*/,
|
||||
cv2(layoutFace, 0) /*windowLeft*/,
|
||||
cv2(layoutFace, 2) /*windowRight*/,
|
||||
Cone_tree_node::EDGE_SOURCE);
|
||||
node_created();
|
||||
edgeRoot->push_middle_child(v1_Child);
|
||||
process_node(v1_Child);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -878,6 +946,7 @@ private:
|
|||
{
|
||||
if (m_debugOutput)
|
||||
{
|
||||
std::cout << std::endl << " ~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
|
||||
std::cout << "\tVertex Root Expansion: Vertex = " << get(m_vertexIndexMap, vertex) << std::endl;
|
||||
}
|
||||
|
||||
|
|
@ -885,7 +954,7 @@ private:
|
|||
prev(halfedge(vertex, m_graph), m_graph));
|
||||
|
||||
node_created();
|
||||
m_rootNodes.push_back(std::make_pair(vertexRoot, sourcePointIt));
|
||||
m_rootNodes.emplace_back(vertexRoot, sourcePointIt);
|
||||
|
||||
m_closestToVertices[get(m_vertexIndexMap, vertex)] = Node_distance_pair(vertexRoot, FT(0));
|
||||
|
||||
|
|
@ -894,6 +963,13 @@ private:
|
|||
|
||||
/*
|
||||
Create child nodes for each face surrounding the vertex occupied by `parent`, and push them to the queue
|
||||
|
||||
By convention, source windows are left & middle (no right) as to not create overlaps.
|
||||
A child is also created for the border halfedge (if any) as to propagate distance
|
||||
to the next vertex on the border (aka `target(next(border_h, g), g)`).
|
||||
This creates a nonsensical triangle made of `source(border_h, g)`, `target(border_h, g)`,
|
||||
and `target(next(border_h, g), g)` but propagation is only done to the vertex (vertex source:
|
||||
no propagation on the right by convention, and left is a border halfedge so no propagation either).
|
||||
*/
|
||||
void expand_pseudo_source(Cone_tree_node* parent)
|
||||
{
|
||||
|
|
@ -911,8 +987,8 @@ private:
|
|||
|
||||
if (m_debugOutput)
|
||||
{
|
||||
std::cout << "expansionVertex: " << get(m_vertexIndexMap, expansionVertex) << std::endl;
|
||||
std::cout << "Distance from target to root: " << distanceFromTargetToRoot << std::endl;
|
||||
std::cout << "Pseudo source: V" << get(m_vertexIndexMap, expansionVertex) << std::endl;
|
||||
std::cout << "Distance from pseudo source to root: " << distanceFromTargetToRoot << std::endl;
|
||||
}
|
||||
|
||||
// A potential optimization could be made by only expanding in the 'necessary' range (i.e. the range outside of geodesic visibility), but the
|
||||
|
|
@ -931,7 +1007,7 @@ private:
|
|||
<< get(m_vertexIndexMap, source(currentEdge, m_graph)) << " "
|
||||
<< get(m_vertexIndexMap, target(currentEdge, m_graph)) << std::endl;
|
||||
std::cout << "face id = ";
|
||||
if (face(currentEdge, m_graph) != Graph_traits::null_face())
|
||||
if (!is_border(currentEdge, m_graph))
|
||||
{
|
||||
std::cout << get(m_faceIndexMap, face(currentEdge, m_graph)) << std::endl;
|
||||
|
||||
|
|
@ -945,9 +1021,11 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
Cone_tree_node* child = new Cone_tree_node(m_traits, m_graph, currentEdge, layoutFace,
|
||||
cv2(layoutFace, 1), distanceFromTargetToRoot,
|
||||
cv2(layoutFace, 0), cv2(layoutFace, 2),
|
||||
Cone_tree_node* child = new Cone_tree_node(m_traits, m_graph, currentEdge /*entryEdge*/,
|
||||
layoutFace, cv2(layoutFace, 1) /*sourceImage*/,
|
||||
distanceFromTargetToRoot,
|
||||
cv2(layoutFace, 0) /*windowLeft*/,
|
||||
cv2(layoutFace, 2) /*windowRight*/,
|
||||
Cone_tree_node::VERTEX_SOURCE);
|
||||
|
||||
node_created();
|
||||
|
|
@ -1131,18 +1209,18 @@ private:
|
|||
std::cout << "\tParent node: " << node->parent() << std::endl;
|
||||
std::cout << "\tParent node type: " << node->parent()->node_type() << std::endl;
|
||||
std::cout << "\tFace = " << node->layout_face() << std::endl;
|
||||
std::cout << "\tVertices = ";
|
||||
std::cout << "\tVertices =";
|
||||
halfedge_descriptor current = node->entry_edge();
|
||||
for (std::size_t i = 0; i<3; ++i)
|
||||
{
|
||||
std::cout << get(m_vertexIndexMap, source(current, m_graph)) << " ";
|
||||
std::cout << " " << get(m_vertexIndexMap, source(current, m_graph));
|
||||
current = next(current, m_graph);
|
||||
}
|
||||
std::cout << std::endl;
|
||||
std::cout << "\tSource Image = " << node->source_image() << std::endl;
|
||||
std::cout << "\tEntry Halfedge = (" << get(m_vertexIndexMap, source(node->entry_edge(), m_graph)) << " "
|
||||
std::cout << "\tEntry Halfedge = (V" << get(m_vertexIndexMap, source(node->entry_edge(), m_graph)) << " V"
|
||||
<< get(m_vertexIndexMap, target(node->entry_edge(), m_graph)) << ")" << std::endl;
|
||||
std::cout << "\tTarget vertex = " << get(m_vertexIndexMap, node->target_vertex()) << std::endl;
|
||||
std::cout << "\tTarget vertex = V" << get(m_vertexIndexMap, node->target_vertex()) << std::endl;
|
||||
|
||||
std::cout << "\tWindow Left = " << node->window_left() << std::endl;
|
||||
std::cout << "\tWindow Right = " << node->window_right() << std::endl;
|
||||
|
|
@ -1156,19 +1234,11 @@ private:
|
|||
leftSide = node->has_left_side();
|
||||
rightSide = node->has_right_side();
|
||||
}
|
||||
else // node corresponds to a source
|
||||
{
|
||||
if (node->node_type() == Cone_tree_node::EDGE_SOURCE)
|
||||
{
|
||||
leftSide = true;
|
||||
rightSide = true;
|
||||
}
|
||||
else
|
||||
else // source nodes only have left sides
|
||||
{
|
||||
leftSide = true;
|
||||
rightSide = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_debugOutput)
|
||||
{
|
||||
|
|
@ -1189,7 +1259,7 @@ private:
|
|||
|
||||
std::size_t entryHalfEdgeIndex = get(m_halfedgeIndexMap, node->entry_edge());
|
||||
|
||||
Node_distance_pair currentOccupier = m_vertexOccupiers[entryHalfEdgeIndex];
|
||||
const Node_distance_pair& currentOccupier = m_vertexOccupiers[entryHalfEdgeIndex];
|
||||
FT currentNodeDistance = node->distance_from_target_to_root();
|
||||
|
||||
if (m_debugOutput)
|
||||
|
|
@ -1231,11 +1301,11 @@ private:
|
|||
|
||||
if (m_debugOutput)
|
||||
{
|
||||
std::cout << "\t Current occupier, EH ("
|
||||
<< get(m_vertexIndexMap, source(currentOccupier.first->entry_edge(), m_graph)) << " "
|
||||
std::cout << "\t Current occupier, EH (V"
|
||||
<< get(m_vertexIndexMap, source(currentOccupier.first->entry_edge(), m_graph)) << " V"
|
||||
<< get(m_vertexIndexMap, target(currentOccupier.first->entry_edge(), m_graph)) << ")" << std::endl;
|
||||
std::cout << "\t Current occupier, Source = " << currentOccupier.first->source_image() << std::endl;
|
||||
std::cout << "\t Current Occupier Distance = " << currentOccupier.second << std::endl;
|
||||
std::cout << "\t Current occupier Distance = " << currentOccupier.second << std::endl;
|
||||
std::cout << "\t smaller (-1)/equal (0)/larger (1) comparison? " << c << std::endl;
|
||||
}
|
||||
}
|
||||
|
|
@ -1271,7 +1341,7 @@ private:
|
|||
|
||||
// This is a consequence of using the same basic node type for source and interval nodes
|
||||
// If this is a source node, it is only pointing to one of the two opposite edges (the left one by convention)
|
||||
if (node->node_type() != Cone_tree_node::INTERVAL && node->node_type() != Cone_tree_node::EDGE_SOURCE)
|
||||
if (node->is_source_node())
|
||||
{
|
||||
propagateRight = false;
|
||||
|
||||
|
|
@ -1313,9 +1383,9 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
// Check if node is now the absolute closest node, and replace the current closest as appropriate
|
||||
// Check if `node` is now the absolute closest node, and replace the current closest as appropriate
|
||||
std::size_t targetVertexIndex = get(m_vertexIndexMap, node->target_vertex());
|
||||
Node_distance_pair currentClosest = m_closestToVertices[targetVertexIndex];
|
||||
const Node_distance_pair& currentClosest = m_closestToVertices[targetVertexIndex];
|
||||
|
||||
if (m_debugOutput && currentClosest.first != nullptr)
|
||||
{
|
||||
|
|
@ -1325,11 +1395,12 @@ private:
|
|||
// If equal times, give priority to vertex sources since it's cleaner and simpler to handle than interval windows
|
||||
if (currentClosest.first == nullptr ||
|
||||
currentClosest.second > currentNodeDistance ||
|
||||
(currentClosest.second == currentNodeDistance && node->node_type() == Cone_tree_node::VERTEX_SOURCE))
|
||||
(currentClosest.second == currentNodeDistance &&
|
||||
node->node_type() == Cone_tree_node::VERTEX_SOURCE))
|
||||
{
|
||||
if (m_debugOutput)
|
||||
{
|
||||
std::cout << "\t Current node is now the closest at target vertex "
|
||||
std::cout << "\t Current node is now the closest at target vertex V"
|
||||
<< get(m_vertexIndexMap, node->target_vertex()) << std::endl;
|
||||
}
|
||||
|
||||
|
|
@ -1338,7 +1409,7 @@ private:
|
|||
{
|
||||
if (m_debugOutput)
|
||||
{
|
||||
std::cout << "\t Vertex " << targetVertexIndex << " is a pseudo-source" << std::endl;
|
||||
std::cout << "\t Vertex V" << targetVertexIndex << " is a pseudo-source" << std::endl;
|
||||
}
|
||||
|
||||
if (currentClosest.first != nullptr)
|
||||
|
|
@ -1399,11 +1470,13 @@ private:
|
|||
{
|
||||
if (propagateLeft)
|
||||
{
|
||||
CGAL_assertion(!node->is_null_face());
|
||||
push_left_child(node);
|
||||
}
|
||||
|
||||
if (propagateRight && (!node->is_source_node() || node->node_type() == Cone_tree_node::EDGE_SOURCE))
|
||||
if (propagateRight)
|
||||
{
|
||||
CGAL_assertion(!node->is_source_node());
|
||||
push_right_child(node);
|
||||
}
|
||||
|
||||
|
|
@ -1421,9 +1494,17 @@ private:
|
|||
|
||||
void push_left_child(Cone_tree_node* parent)
|
||||
{
|
||||
if (m_debugOutput)
|
||||
{
|
||||
std::cout << "Tentative push of left child edge "
|
||||
<< " (V" << get(m_vertexIndexMap, source(parent->left_child_edge(), m_graph))
|
||||
<< " V" << get(m_vertexIndexMap, target(parent->left_child_edge(), m_graph)) << ")" << std::endl;
|
||||
std::cout << "Boundary? " << is_border(parent->left_child_edge(), m_graph) << std::endl;
|
||||
}
|
||||
|
||||
typename Traits::Compute_squared_distance_2 csd2(m_traits.compute_squared_distance_2_object());
|
||||
|
||||
if (face(parent->left_child_edge(), m_graph) != Graph_traits::null_face())
|
||||
if (!is_border(parent->left_child_edge(), m_graph))
|
||||
{
|
||||
Segment_2 leftWindow;
|
||||
|
||||
|
|
@ -1467,12 +1548,15 @@ private:
|
|||
{
|
||||
if (m_debugOutput)
|
||||
{
|
||||
std::cout << "Tentative push of right child..." << std::endl;
|
||||
std::cout << "Tentative push of right child edge"
|
||||
<< " (V" << get(m_vertexIndexMap, source(parent->right_child_edge(), m_graph))
|
||||
<< " V" << get(m_vertexIndexMap, target(parent->right_child_edge(), m_graph)) << ")" << std::endl;
|
||||
std::cout << "Boundary? " << is_border(parent->right_child_edge(), m_graph) << std::endl;
|
||||
}
|
||||
|
||||
typename Traits::Compute_squared_distance_2 csd2(m_traits.compute_squared_distance_2_object());
|
||||
|
||||
if (face(parent->right_child_edge(), m_graph) != Graph_traits::null_face())
|
||||
if (!is_border(parent->right_child_edge(), m_graph))
|
||||
{
|
||||
Segment_2 rightWindow;
|
||||
bool result = clip_to_bounds(parent->right_child_base_segment(), parent->left_boundary(),
|
||||
|
|
@ -1605,14 +1689,11 @@ private:
|
|||
|
||||
void set_vertex_types()
|
||||
{
|
||||
vertex_iterator current, end;
|
||||
|
||||
for (boost::tie(current, end) = vertices(m_graph); current != end; ++current)
|
||||
for(vertex_descriptor v : vertices(m_graph))
|
||||
{
|
||||
if (halfedge(*current, m_graph)==Graph_traits::null_halfedge())
|
||||
continue;
|
||||
std::size_t vertexIndex = get(m_vertexIndexMap, *current);
|
||||
m_vertexIsPseudoSource[vertexIndex] = (is_saddle_vertex(*current) || is_boundary_vertex(*current));
|
||||
std::size_t vertexIndex = get(m_vertexIndexMap, v);
|
||||
m_vertexIsPseudoSource[vertexIndex] = !internal::is_isolated(v, m_graph) &&
|
||||
(is_saddle_vertex(v) || is_boundary_vertex(v));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1623,21 +1704,7 @@ private:
|
|||
|
||||
bool is_boundary_vertex(const vertex_descriptor v) const
|
||||
{
|
||||
halfedge_descriptor h = halfedge(v, m_graph);
|
||||
halfedge_descriptor first = h;
|
||||
|
||||
do
|
||||
{
|
||||
if (face(h, m_graph) == Graph_traits::null_face() || face(opposite(h, m_graph), m_graph) == Graph_traits::null_face())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
h = opposite(next(h, m_graph), m_graph);
|
||||
}
|
||||
while(h != first);
|
||||
|
||||
return false;
|
||||
return bool(is_border(v, m_graph));
|
||||
}
|
||||
|
||||
void delete_all_nodes()
|
||||
|
|
@ -1650,11 +1717,8 @@ private:
|
|||
|
||||
void reset_algorithm(const bool clearFaceLocations = true)
|
||||
{
|
||||
Cone_tree_node* null_value=nullptr;
|
||||
m_closestToVertices.resize(num_vertices(m_graph));
|
||||
std::fill(m_closestToVertices.begin(), m_closestToVertices.end(), Node_distance_pair(null_value, FT(0)));
|
||||
m_vertexOccupiers.resize(num_halfedges(m_graph));
|
||||
std::fill(m_vertexOccupiers.begin(), m_vertexOccupiers.end(), Node_distance_pair(null_value, FT(0)));
|
||||
m_closestToVertices.assign(num_vertices(m_graph), Node_distance_pair(nullptr, FT(-1)));
|
||||
m_vertexOccupiers.assign(num_halfedges(m_graph), Node_distance_pair(nullptr, FT(-1)));
|
||||
|
||||
while (!m_expansionPriqueue.empty())
|
||||
{
|
||||
|
|
@ -1671,7 +1735,7 @@ private:
|
|||
|
||||
delete_all_nodes();
|
||||
m_rootNodes.clear();
|
||||
m_vertexIsPseudoSource.resize(num_vertices(m_graph));
|
||||
m_vertexIsPseudoSource.assign(num_vertices(m_graph), false);
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
m_currentNodeCount = 0;
|
||||
|
|
@ -1684,7 +1748,7 @@ private:
|
|||
}
|
||||
|
||||
template <class Visitor>
|
||||
void visit_shortest_path(Cone_tree_node* startNode,
|
||||
void visit_shortest_path(const Cone_tree_node* startNode,
|
||||
const Point_2& startLocation,
|
||||
Visitor& visitor)
|
||||
{
|
||||
|
|
@ -1695,7 +1759,7 @@ private:
|
|||
typename Traits::Construct_target_2 construct_target_2(m_traits.construct_target_2_object());
|
||||
typename Traits::Intersect_2 intersect_2(m_traits.intersect_2_object());
|
||||
|
||||
Cone_tree_node* current = startNode;
|
||||
const Cone_tree_node* current = startNode;
|
||||
Point_2 currentLocation(startLocation);
|
||||
|
||||
while (!current->is_root_node())
|
||||
|
|
@ -1703,21 +1767,22 @@ private:
|
|||
switch (current->node_type())
|
||||
{
|
||||
case Cone_tree_node::INTERVAL:
|
||||
case Cone_tree_node::EDGE_SOURCE:
|
||||
{
|
||||
Segment_2 entrySegment = current->entry_segment();
|
||||
const Segment_2& entrySegment = current->entry_segment();
|
||||
const Point_2& currentSourceImage = current->source_image();
|
||||
Ray_2 rayToLocation(construct_ray_2(currentSourceImage, currentLocation));
|
||||
|
||||
const auto cgalIntersection = intersect_2(construct_line_2(entrySegment), construct_line_2(rayToLocation));
|
||||
const auto cgalIntersection = intersect_2(construct_line_2(entrySegment),
|
||||
construct_line_2(rayToLocation));
|
||||
|
||||
CGAL_assertion(bool(cgalIntersection));
|
||||
|
||||
const Point_2* result = boost::get<Point_2>(&*cgalIntersection);
|
||||
if (!result)
|
||||
result = ¤tSourceImage;
|
||||
|
||||
if (!result) result = ¤tSourceImage;
|
||||
|
||||
FT t0 = parametric_distance_along_segment_2(construct_source_2(entrySegment), construct_target_2(entrySegment), *result);
|
||||
FT t0 = parametric_distance_along_segment_2(construct_source_2(entrySegment),
|
||||
construct_target_2(entrySegment), *result);
|
||||
|
||||
if (m_debugOutput)
|
||||
{
|
||||
|
|
@ -1740,8 +1805,8 @@ private:
|
|||
std::cout << "Current Right Window: " << current->window_right() << " , "
|
||||
<< m_traits.compute_parametric_distance_along_segment_2_object()(entrySegment.start(), entrySegment.end(), current->window_right()) << std::endl;
|
||||
std::cout << "Current Segment Intersection: " << *result << std::endl;
|
||||
std::cout << "Edge: (" << get(m_vertexIndexMap, source(current->entry_edge(), m_graph))
|
||||
<< "," << get(m_vertexIndexMap, target(current->entry_edge(), m_graph)) << ") : " << t0 << std::endl;
|
||||
std::cout << "Edge: (V" << get(m_vertexIndexMap, source(current->entry_edge(), m_graph))
|
||||
<< ", V" << get(m_vertexIndexMap, target(current->entry_edge(), m_graph)) << ") : " << t0 << std::endl;
|
||||
}
|
||||
|
||||
visitor(current->entry_edge(), t0);
|
||||
|
|
@ -1753,13 +1818,16 @@ private:
|
|||
}
|
||||
break;
|
||||
case Cone_tree_node::VERTEX_SOURCE:
|
||||
// This might be a pseudo source
|
||||
visitor(target(current->entry_edge(), m_graph));
|
||||
currentLocation = current->parent()->target_point();
|
||||
current = current->parent();
|
||||
break;
|
||||
case Cone_tree_node::EDGE_SOURCE:
|
||||
case Cone_tree_node::FACE_SOURCE:
|
||||
// This is guaranteed to be the final node in any sequence
|
||||
visitor(m_rootNodes[current->tree_id()].second->first, m_rootNodes[current->tree_id()].second->second);
|
||||
visitor(m_rootNodes[current->tree_id()].second->first,
|
||||
m_rootNodes[current->tree_id()].second->second);
|
||||
current = current->parent();
|
||||
break;
|
||||
default:
|
||||
|
|
@ -1866,7 +1934,7 @@ private:
|
|||
|
||||
std::size_t associatedEdge;
|
||||
CGAL::Surface_mesh_shortest_paths_3::Barycentric_coordinates_type type;
|
||||
boost::tie(type, associatedEdge) = classify_barycentric_coordinates(location);
|
||||
std::tie(type, associatedEdge) = classify_barycentric_coordinates(location);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
|
|
@ -1979,42 +2047,35 @@ private:
|
|||
reset_algorithm(false);
|
||||
set_vertex_types();
|
||||
|
||||
m_vertexOccupiers.resize(num_halfedges(m_graph));
|
||||
m_closestToVertices.resize(num_vertices(m_graph));
|
||||
m_vertexOccupiers.assign(num_halfedges(m_graph), Node_distance_pair(nullptr, FT(-1)));
|
||||
m_closestToVertices.assign(num_vertices(m_graph), Node_distance_pair(nullptr, FT(-1)));
|
||||
|
||||
if (m_debugOutput)
|
||||
{
|
||||
vertex_iterator current, end;
|
||||
|
||||
std::size_t numVertices = 0;
|
||||
|
||||
for (boost::tie(current,end) = vertices(m_graph); current != end; ++current)
|
||||
for (vertex_descriptor v : vertices(m_graph))
|
||||
{
|
||||
std::cout << "Vertex#" << numVertices
|
||||
<< ": p = " << get(m_vertexPointMap,*current)
|
||||
<< " , Saddle Vertex: " << (is_saddle_vertex(*current) ? "yes" : "no")
|
||||
<< " , Boundary Vertex: " << (is_boundary_vertex(*current) ? "yes" : "no") << std::endl;
|
||||
<< ": p = " << get(m_vertexPointMap, v)
|
||||
<< " , Saddle Vertex: " << (is_saddle_vertex(v) ? "yes" : "no")
|
||||
<< " , Boundary Vertex: " << (is_boundary_vertex(v) ? "yes" : "no") << std::endl;
|
||||
++numVertices;
|
||||
}
|
||||
}
|
||||
|
||||
face_iterator facesCurrent;
|
||||
face_iterator facesEnd;
|
||||
|
||||
if (m_debugOutput)
|
||||
{
|
||||
std::size_t numFaces = 0;
|
||||
|
||||
for (boost::tie(facesCurrent, facesEnd) = faces(m_graph); facesCurrent != facesEnd; ++facesCurrent)
|
||||
for (face_descriptor f : faces(m_graph))
|
||||
{
|
||||
std::cout << "Face#" << numFaces << ": Vertices = (";
|
||||
++numFaces;
|
||||
halfedge_descriptor faceEdgesStart = halfedge(*facesCurrent, m_graph);
|
||||
halfedge_descriptor faceEdgesStart = halfedge(f, m_graph);
|
||||
halfedge_descriptor faceEdgesCurrent = faceEdgesStart;
|
||||
|
||||
do
|
||||
{
|
||||
std::cout << get(m_vertexIndexMap, source(faceEdgesCurrent, m_graph));
|
||||
std::cout << "V" << get(m_vertexIndexMap, source(faceEdgesCurrent, m_graph));
|
||||
|
||||
faceEdgesCurrent = next(faceEdgesCurrent, m_graph);
|
||||
|
||||
|
|
@ -2031,15 +2092,15 @@ private:
|
|||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (typename Source_point_list::iterator it = m_faceLocations.begin(); it != m_faceLocations.end(); ++it)
|
||||
{
|
||||
if (m_debugOutput)
|
||||
{
|
||||
std::cout << "Root: " << get(m_faceIndexMap, it->first)
|
||||
<< " , " << it->second[0] << " " << it->second[1] << " " << it->second[2] << " " << std::endl;
|
||||
std::cout << "Root: F" << get(m_faceIndexMap, it->first)
|
||||
<< " , bar " << it->second[0] << " " << it->second[1] << " " << it->second[2] << " "
|
||||
<< ", pos " << point(it->first, it->second) << std::endl;
|
||||
}
|
||||
|
||||
expand_root(it->first, it->second, Source_point_iterator(it));
|
||||
|
|
@ -2054,7 +2115,7 @@ private:
|
|||
|
||||
}
|
||||
|
||||
while (m_expansionPriqueue.size() > 0)
|
||||
while (!m_expansionPriqueue.empty())
|
||||
{
|
||||
if (m_debugOutput)
|
||||
{
|
||||
|
|
@ -2077,10 +2138,10 @@ private:
|
|||
if (!event->m_cancelled)
|
||||
{
|
||||
std::cout << " ------ Parent (" << event->m_parent << ") INFO: ";
|
||||
std::cout << "EH = (" << get(m_vertexIndexMap, source(event->m_parent->entry_edge(), m_graph)) << " "
|
||||
std::cout << "EH = (V" << get(m_vertexIndexMap, source(event->m_parent->entry_edge(), m_graph)) << " V"
|
||||
<< get(m_vertexIndexMap, target(event->m_parent->entry_edge(), m_graph)) << ") ";
|
||||
std::cout << "S = (" << event->m_parent->source_image() << ") ";
|
||||
std::cout << "T = " << get(m_vertexIndexMap, target(next(event->m_parent->entry_edge(), m_graph), m_graph));
|
||||
std::cout << "Src = (" << event->m_parent->source_image() << ") ";
|
||||
std::cout << "Tar = V" << get(m_vertexIndexMap, target(next(event->m_parent->entry_edge(), m_graph), m_graph));
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
|
|
@ -2114,8 +2175,8 @@ private:
|
|||
if (m_debugOutput)
|
||||
{
|
||||
std::cout << "Left Expansion: Parent = " << parent
|
||||
<< " Edge = (" << get(m_vertexIndexMap, source(event->m_parent->left_child_edge(), m_graph))
|
||||
<< "," << get(m_vertexIndexMap, target(event->m_parent->left_child_edge(), m_graph))
|
||||
<< " Edge = (V" << get(m_vertexIndexMap, source(event->m_parent->left_child_edge(), m_graph))
|
||||
<< ", V" << get(m_vertexIndexMap, target(event->m_parent->left_child_edge(), m_graph))
|
||||
<< ") , Distance = " << event->m_distanceEstimate
|
||||
<< " , Level = " << event->m_parent->level() + 1 << std::endl;
|
||||
}
|
||||
|
|
@ -2126,8 +2187,8 @@ private:
|
|||
if (m_debugOutput)
|
||||
{
|
||||
std::cout << "Right Expansion: Parent = " << parent
|
||||
<< " , Edge = (" << get(m_vertexIndexMap, source(event->m_parent->right_child_edge(), m_graph))
|
||||
<< "," << get(m_vertexIndexMap, target(event->m_parent->right_child_edge(), m_graph))
|
||||
<< " , Edge = (V" << get(m_vertexIndexMap, source(event->m_parent->right_child_edge(), m_graph))
|
||||
<< ", V" << get(m_vertexIndexMap, target(event->m_parent->right_child_edge(), m_graph))
|
||||
<< ") , Distance = " << event->m_distanceEstimate
|
||||
<< " , Level = " << event->m_parent->level() + 1 << std::endl;
|
||||
}
|
||||
|
|
@ -2165,7 +2226,7 @@ private:
|
|||
for (std::size_t i = 0; i < m_closestToVertices.size(); ++i)
|
||||
{
|
||||
std::cout << "\tVertex = " << i << std::endl;
|
||||
std::cout << "\tDistance = " << m_closestToVertices[i].second << std::endl;
|
||||
std::cout << "\tDistance = " << m_closestToVertices[i].second << " to " << m_closestToVertices[i].first << std::endl;
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
|
|
@ -2280,6 +2341,13 @@ public:
|
|||
Source_point_iterator add_source_point(vertex_descriptor v)
|
||||
{
|
||||
Face_location location = face_location(v);
|
||||
|
||||
if (m_debugOutput)
|
||||
{
|
||||
std::cout << "Face location from V" << get(m_vertexIndexMap, v) << " is F" << get(m_faceIndexMap, location.first) << " "
|
||||
<< location.second[0] << " " << location.second[1] << " " << location.second[2] << std::endl;
|
||||
}
|
||||
|
||||
return add_source_point(location);
|
||||
}
|
||||
|
||||
|
|
@ -2306,6 +2374,11 @@ public:
|
|||
*/
|
||||
Source_point_iterator add_source_point(const Face_location& location)
|
||||
{
|
||||
if (m_debugOutput)
|
||||
{
|
||||
std::cout << "Add source point at position " << point(location.first, location.second) << std::endl;
|
||||
}
|
||||
|
||||
Source_point_underlying_iterator added = m_faceLocations.insert(m_faceLocations.end(), location);
|
||||
|
||||
if (m_firstNewSourcePoint == m_faceLocations.end())
|
||||
|
|
@ -2471,9 +2544,8 @@ public:
|
|||
{
|
||||
build_sequence_tree();
|
||||
|
||||
Node_distance_pair result = m_closestToVertices[get(m_vertexIndexMap, v)];
|
||||
|
||||
Cone_tree_node* current = result.first;
|
||||
const Node_distance_pair& result = m_closestToVertices[get(m_vertexIndexMap, v)];
|
||||
const Cone_tree_node* current = result.first;
|
||||
|
||||
if (current)
|
||||
{
|
||||
|
|
@ -2500,9 +2572,8 @@ public:
|
|||
{
|
||||
build_sequence_tree();
|
||||
|
||||
std::pair<Node_distance_pair, Barycentric_coordinates> result = nearest_to_location(f, location);
|
||||
|
||||
Cone_tree_node* current = result.first.first;
|
||||
const std::pair<Node_distance_pair, Barycentric_coordinates>& result = nearest_to_location(f, location);
|
||||
const Cone_tree_node* current = result.first.first;
|
||||
|
||||
if (current)
|
||||
{
|
||||
|
|
@ -2542,8 +2613,8 @@ public:
|
|||
{
|
||||
build_sequence_tree();
|
||||
|
||||
Node_distance_pair result = m_closestToVertices[get(m_vertexIndexMap, v)];
|
||||
Cone_tree_node* current = result.first;
|
||||
const Node_distance_pair& result = m_closestToVertices[get(m_vertexIndexMap, v)];
|
||||
const Cone_tree_node* current = result.first;
|
||||
|
||||
if (current)
|
||||
{
|
||||
|
|
@ -2737,13 +2808,23 @@ public:
|
|||
/*!
|
||||
\brief returns the 3-dimensional coordinates of the given vertex.
|
||||
|
||||
\param vertex A vertex of the input face graph
|
||||
\param v A vertex of the input face graph
|
||||
*/
|
||||
Point_3 point(const vertex_descriptor vertex) const
|
||||
decltype(auto) point(const vertex_descriptor v) const
|
||||
{
|
||||
return get(m_vertexPointMap, vertex);
|
||||
return get(m_vertexPointMap, v);
|
||||
}
|
||||
|
||||
/// \cond
|
||||
|
||||
static decltype(auto) point(const vertex_descriptor v,
|
||||
const Triangle_mesh& tm)
|
||||
{
|
||||
return get(CGAL::vertex_point, tm, v);
|
||||
}
|
||||
|
||||
/// \endcond
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name Surface Face Location Constructions
|
||||
|
|
@ -2770,7 +2851,7 @@ public:
|
|||
{
|
||||
typename Traits::Construct_barycentric_coordinates construct_barycentric_coordinates(traits.construct_barycentric_coordinates_object());
|
||||
halfedge_descriptor hinit=halfedge(vertex, tm);
|
||||
while (face(hinit, tm) == Graph_traits::null_face())
|
||||
while (is_border(hinit, tm))
|
||||
hinit = opposite(next(hinit, tm), tm);
|
||||
|
||||
halfedge_descriptor he = next(hinit, tm);
|
||||
|
|
@ -3043,7 +3124,7 @@ public:
|
|||
Vertex_point_map vertexPointMap)
|
||||
{
|
||||
face_iterator facesStart, facesEnd;
|
||||
boost::tie(facesStart, facesEnd) = faces(tm);
|
||||
std::tie(facesStart, facesEnd) = faces(tm);
|
||||
outTree.rebuild(facesStart, facesEnd, tm, vertexPointMap);
|
||||
outTree.build();
|
||||
}
|
||||
|
|
@ -3054,6 +3135,4 @@ public:
|
|||
|
||||
} // namespace CGAL
|
||||
|
||||
#include <CGAL/enable_warnings.h>
|
||||
|
||||
#endif // CGAL_SURFACE_MESH_SHORTEST_PATH_SURFACE_MESH_SHORTEST_PATH_H
|
||||
|
|
|
|||
|
|
@ -493,7 +493,7 @@ public:
|
|||
// In the case of multiple rays reaching the same target, we want to know their respective position
|
||||
// so that pruning of branches can be done according to the "one angle one split" idiom.
|
||||
// However, the orientation predicate is evaluated in the unfolded 2D plane, which is obtained
|
||||
// via square roots; inconsisnties will exist. We don't want to prune in case it might be wrong,
|
||||
// via square roots; inconsistencies will exist. We don't want to prune in case it might be wrong,
|
||||
// so we add a little bit of tolerance on the evaluation of the predicate. If it's almost collinear,
|
||||
// return 'collinear' (EQUAL).
|
||||
const FT eps = (FT(100) * std::numeric_limits<FT>::epsilon());
|
||||
|
|
|
|||
|
|
@ -95,15 +95,22 @@ private:
|
|||
public:
|
||||
Cone_tree_node(const Traits& traits,
|
||||
const Triangle_mesh& g,
|
||||
const std::size_t treeId)
|
||||
const halfedge_descriptor entryEdge,
|
||||
const Triangle_2& layoutFace,
|
||||
const Point_2& sourceImage,
|
||||
const FT& pseudoSourceDistance,
|
||||
const Point_2& windowLeft,
|
||||
const Point_2& windowRight,
|
||||
const Node_type nodeType = INTERVAL)
|
||||
: m_traits(traits)
|
||||
, m_graph(g)
|
||||
, m_sourceImage(Point_2(CGAL::ORIGIN))
|
||||
, m_layoutFace(Point_2(CGAL::ORIGIN),Point_2(CGAL::ORIGIN),Point_2(CGAL::ORIGIN))
|
||||
, m_pseudoSourceDistance(0.0)
|
||||
, m_level(0)
|
||||
, m_treeId(treeId)
|
||||
, m_nodeType(ROOT)
|
||||
, m_entryEdge(entryEdge)
|
||||
, m_sourceImage(sourceImage)
|
||||
, m_layoutFace(layoutFace)
|
||||
, m_pseudoSourceDistance(pseudoSourceDistance)
|
||||
, m_windowLeft(windowLeft)
|
||||
, m_windowRight(windowRight)
|
||||
, m_nodeType(nodeType)
|
||||
, m_leftChild(nullptr)
|
||||
, m_rightChild(nullptr)
|
||||
, m_pendingLeftSubtree(nullptr)
|
||||
|
|
@ -135,27 +142,8 @@ public:
|
|||
|
||||
Cone_tree_node(const Traits& traits,
|
||||
const Triangle_mesh& g,
|
||||
const halfedge_descriptor entryEdge,
|
||||
const Triangle_2& layoutFace,
|
||||
const Point_2& sourceImage,
|
||||
const FT& pseudoSourceDistance,
|
||||
const Point_2& windowLeft,
|
||||
const Point_2& windowRight,
|
||||
const Node_type nodeType = INTERVAL)
|
||||
: m_traits(traits)
|
||||
, m_graph(g)
|
||||
, m_entryEdge(entryEdge)
|
||||
, m_sourceImage(sourceImage)
|
||||
, m_layoutFace(layoutFace)
|
||||
, m_pseudoSourceDistance(pseudoSourceDistance)
|
||||
, m_windowLeft(windowLeft)
|
||||
, m_windowRight(windowRight)
|
||||
, m_nodeType(nodeType)
|
||||
, m_leftChild(nullptr)
|
||||
, m_rightChild(nullptr)
|
||||
, m_pendingLeftSubtree(nullptr)
|
||||
, m_pendingRightSubtree(nullptr)
|
||||
, m_pendingMiddleSubtree(nullptr)
|
||||
const std::size_t treeId)
|
||||
: Cone_tree_node(traits, g, treeId, Graph_traits::null_halfedge())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,36 +1,279 @@
|
|||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <stdlib.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <CGAL/Surface_mesh.h>
|
||||
#include <CGAL/Surface_mesh_shortest_path.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <CGAL/AABB_face_graph_triangle_primitive.h>
|
||||
#include <CGAL/AABB_traits.h>
|
||||
#include <CGAL/AABB_tree.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <limits>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
||||
|
||||
typedef CGAL::Surface_mesh<Kernel::Point_3> Triangle_mesh;
|
||||
|
||||
typedef CGAL::Surface_mesh_shortest_path_traits<Kernel, Triangle_mesh> Traits;
|
||||
typedef CGAL::Surface_mesh_shortest_path<Traits> Surface_mesh_shortest_path;
|
||||
typedef boost::graph_traits<Triangle_mesh> Graph_traits;
|
||||
typedef Graph_traits::vertex_iterator vertex_iterator;
|
||||
typedef Graph_traits::face_iterator face_iterator;
|
||||
|
||||
typedef boost::property_map<Triangle_mesh, CGAL::vertex_point_t>::const_type VPM;
|
||||
typedef CGAL::AABB_face_graph_triangle_primitive<Triangle_mesh, VPM> AABB_face_graph_primitive;
|
||||
typedef CGAL::AABB_traits<Kernel, AABB_face_graph_primitive> AABB_face_graph_traits;
|
||||
|
||||
int main()
|
||||
void test_all_pairs()
|
||||
{
|
||||
CGAL::Surface_mesh<Kernel::Point_3> mesh;
|
||||
std::ifstream input("data/test_mesh_6.off");
|
||||
input >> mesh;
|
||||
input.close();
|
||||
|
||||
std::cout << "Input mesh: " << num_vertices(mesh) << " nv" << std::endl;
|
||||
|
||||
for (Triangle_mesh::Vertex_index v1 : vertices(mesh))
|
||||
for (Triangle_mesh::Vertex_index v2 : vertices(mesh))
|
||||
{
|
||||
Surface_mesh_shortest_path shortest_paths(mesh);
|
||||
shortest_paths.add_source_point(v1);
|
||||
double dist = shortest_paths.shortest_distance_to_source_points(v2).first;
|
||||
assert (dist==0 || v1!=v2);
|
||||
CGAL_USE(dist);
|
||||
|
||||
for (Triangle_mesh::Vertex_index v2 : vertices(mesh))
|
||||
{
|
||||
const double sq_dist = CGAL::square(shortest_paths.shortest_distance_to_source_points(v2).first);
|
||||
const double lower_bound = CGAL::squared_distance(mesh.point(v1), mesh.point(v2));
|
||||
std::cout << "sq_dist(" << v1 << ", " << v2 << ") = " << sq_dist << std::endl;
|
||||
std::cout << "lower bound: " << lower_bound << std::endl;
|
||||
|
||||
if(v1 == v2)
|
||||
assert(sq_dist == 0.);
|
||||
else
|
||||
assert(sq_dist > (1. - 1e-7) * lower_bound); // numerical errors
|
||||
|
||||
CGAL_USE(sq_dist);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void test_flat_donut()
|
||||
{
|
||||
CGAL::Surface_mesh<Kernel::Point_3> mesh;
|
||||
std::ifstream input("data/flat_donut.off");
|
||||
input >> mesh;
|
||||
input.close();
|
||||
|
||||
std::cout << "Input mesh: " << num_vertices(mesh) << " nv" << std::endl;
|
||||
|
||||
{
|
||||
Triangle_mesh::Face_index f0(0), f16(16);
|
||||
auto h0 = halfedge(f0, mesh), h16 = halfedge(f16, mesh);
|
||||
|
||||
for(std::size_t i=0; i<3; ++i)
|
||||
{
|
||||
Triangle_mesh::Vertex_index v0(0);
|
||||
Surface_mesh_shortest_path shortest_paths(mesh);
|
||||
shortest_paths.add_source_point(v0);
|
||||
|
||||
double dist = shortest_paths.shortest_distance_to_source_points(Triangle_mesh::Vertex_index(3)).first;
|
||||
assert(dist == 3);
|
||||
|
||||
dist = shortest_paths.shortest_distance_to_source_points(Triangle_mesh::Vertex_index(12)).first;
|
||||
assert(dist == 3);
|
||||
|
||||
dist = shortest_paths.shortest_distance_to_source_points(Triangle_mesh::Vertex_index(1)).first;
|
||||
assert(dist == 1);
|
||||
|
||||
dist = shortest_paths.shortest_distance_to_source_points(Triangle_mesh::Vertex_index(4)).first;
|
||||
assert(dist == 1);
|
||||
|
||||
dist = shortest_paths.shortest_distance_to_source_points(Triangle_mesh::Vertex_index(5)).first;
|
||||
assert(CGAL::abs(dist - sqrt(2.)) < 1e-7);
|
||||
|
||||
// change the canonical halfedges to test barycentric coordinates
|
||||
h0 = next(h0, mesh);
|
||||
set_halfedge(f0, h0, mesh);
|
||||
h16 = next(h16, mesh);
|
||||
set_halfedge(f16, h16, mesh);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
{
|
||||
Triangle_mesh::Vertex_index v0(3);
|
||||
|
||||
Surface_mesh_shortest_path shortest_paths(mesh);
|
||||
shortest_paths.add_source_point(v0);
|
||||
|
||||
double dist = shortest_paths.shortest_distance_to_source_points(Triangle_mesh::Vertex_index(0)).first;
|
||||
assert(dist == 3);
|
||||
|
||||
dist = shortest_paths.shortest_distance_to_source_points(Triangle_mesh::Vertex_index(15)).first;
|
||||
assert(dist == 3);
|
||||
|
||||
dist = shortest_paths.shortest_distance_to_source_points(Triangle_mesh::Vertex_index(2)).first;
|
||||
assert(dist == 1);
|
||||
|
||||
dist = shortest_paths.shortest_distance_to_source_points(Triangle_mesh::Vertex_index(7)).first;
|
||||
assert(dist == 1);
|
||||
|
||||
dist = shortest_paths.shortest_distance_to_source_points(Triangle_mesh::Vertex_index(6)).first;
|
||||
assert(CGAL::abs(dist - sqrt(2.)) < 1e-7);
|
||||
}
|
||||
|
||||
{
|
||||
Surface_mesh_shortest_path shortest_paths(mesh);
|
||||
shortest_paths.add_source_point(Triangle_mesh::Vertex_index(0));
|
||||
shortest_paths.add_source_point(Triangle_mesh::Vertex_index(3));
|
||||
|
||||
double dist = shortest_paths.shortest_distance_to_source_points(Triangle_mesh::Vertex_index(0)).first;
|
||||
assert(dist == 0);
|
||||
|
||||
dist = shortest_paths.shortest_distance_to_source_points(Triangle_mesh::Vertex_index(15)).first;
|
||||
assert(dist == 3);
|
||||
|
||||
dist = shortest_paths.shortest_distance_to_source_points(Triangle_mesh::Vertex_index(2)).first;
|
||||
assert(dist == 1);
|
||||
|
||||
dist = shortest_paths.shortest_distance_to_source_points(Triangle_mesh::Vertex_index(7)).first;
|
||||
assert(dist == 1);
|
||||
|
||||
dist = shortest_paths.shortest_distance_to_source_points(Triangle_mesh::Vertex_index(6)).first;
|
||||
assert(CGAL::abs(dist - sqrt(2.)) < 1e-7);
|
||||
}
|
||||
|
||||
{
|
||||
Triangle_mesh::Face_index f16(16), f1(1), f29(29), f6(6);
|
||||
auto h16 = halfedge(f16, mesh), h1 = halfedge(f1, mesh), h29 = halfedge(f29, mesh), h6 = halfedge(f6, mesh);
|
||||
|
||||
for(std::size_t i=0; i<3; ++i)
|
||||
{
|
||||
Surface_mesh_shortest_path shortest_paths(mesh);
|
||||
shortest_paths.add_source_point(Triangle_mesh::Vertex_index(1));
|
||||
|
||||
double dist = shortest_paths.shortest_distance_to_source_points(Triangle_mesh::Vertex_index(0)).first;
|
||||
assert(dist == 1);
|
||||
|
||||
dist = shortest_paths.shortest_distance_to_source_points(Triangle_mesh::Vertex_index(1)).first;
|
||||
assert(dist == 0);
|
||||
|
||||
auto loc = shortest_paths.locate<AABB_face_graph_traits>(Kernel::Point_3(0.5, 0, 0));
|
||||
dist = shortest_paths.shortest_distance_to_source_points(loc.first, loc.second).first;
|
||||
assert(dist == 0.5);
|
||||
|
||||
loc = shortest_paths.locate<AABB_face_graph_traits>(Kernel::Point_3(2.5, 0, 0));
|
||||
dist = shortest_paths.shortest_distance_to_source_points(loc.first, loc.second).first;
|
||||
assert(dist == 1.5);
|
||||
|
||||
dist = shortest_paths.shortest_distance_to_source_points(Triangle_mesh::Vertex_index(5)).first;
|
||||
assert(dist == 1);
|
||||
|
||||
dist = shortest_paths.shortest_distance_to_source_points(Triangle_mesh::Vertex_index(9)).first;
|
||||
assert(dist == 2);
|
||||
|
||||
dist = shortest_paths.shortest_distance_to_source_points(Triangle_mesh::Vertex_index(13)).first;
|
||||
assert(dist == 3);
|
||||
|
||||
dist = shortest_paths.shortest_distance_to_source_points(Triangle_mesh::Vertex_index(2)).first;
|
||||
assert(dist == 1);
|
||||
|
||||
h16 = next(h16, mesh);
|
||||
set_halfedge(f16, h16, mesh);
|
||||
h1 = next(h1, mesh);
|
||||
set_halfedge(f1, h1, mesh);
|
||||
h29 = next(h29, mesh);
|
||||
set_halfedge(f29, h29, mesh);
|
||||
h6 = next(h6, mesh);
|
||||
set_halfedge(f6, h6, mesh);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Triangle_mesh::Face_index f6(6);
|
||||
auto h6 = halfedge(f6, mesh);
|
||||
|
||||
for(std::size_t i=0; i<3; ++i)
|
||||
{
|
||||
Surface_mesh_shortest_path shortest_paths(mesh);
|
||||
shortest_paths.add_source_point(shortest_paths.locate<AABB_face_graph_traits>(Kernel::Point_3(1.5, 0, 0)));
|
||||
|
||||
double dist = shortest_paths.shortest_distance_to_source_points(Triangle_mesh::Vertex_index(0)).first;
|
||||
assert(dist == 1.5);
|
||||
|
||||
dist = shortest_paths.shortest_distance_to_source_points(Triangle_mesh::Vertex_index(3)).first;
|
||||
assert(dist == 1.5);
|
||||
|
||||
dist = shortest_paths.shortest_distance_to_source_points(Triangle_mesh::Vertex_index(1)).first;
|
||||
assert(dist == 0.5);
|
||||
|
||||
dist = shortest_paths.shortest_distance_to_source_points(Triangle_mesh::Vertex_index(26)).first;
|
||||
assert((dist - sqrt(2.)) < 1e-7);
|
||||
|
||||
auto loc = shortest_paths.locate<AABB_face_graph_traits>(Kernel::Point_3(1.5, 1, 0));
|
||||
dist = shortest_paths.shortest_distance_to_source_points(loc.first, loc.second).first;
|
||||
assert(dist == 1);
|
||||
|
||||
loc = shortest_paths.locate<AABB_face_graph_traits>(Kernel::Point_3(0.5, 1, 0));
|
||||
dist = shortest_paths.shortest_distance_to_source_points(loc.first, loc.second).first;
|
||||
assert(CGAL::abs(dist - sqrt(2.)) < 1e-7);
|
||||
|
||||
h6 = next(h6, mesh);
|
||||
set_halfedge(f6, h6, mesh);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Triangle_mesh::Face_index f28(28);
|
||||
auto h28 = halfedge(f28, mesh);
|
||||
Triangle_mesh::Face_index f29(29);
|
||||
auto h29 = halfedge(f29, mesh);
|
||||
|
||||
auto h = halfedge(Triangle_mesh::Vertex_index(31), Triangle_mesh::Vertex_index(25), mesh).first;
|
||||
|
||||
for(std::size_t side=0; side<2; ++side)
|
||||
{
|
||||
for(std::size_t i=0; i<3; ++i)
|
||||
{
|
||||
Surface_mesh_shortest_path shortest_paths(mesh);
|
||||
shortest_paths.add_source_point(shortest_paths.face_location(h, 0.5));
|
||||
|
||||
double dist = shortest_paths.shortest_distance_to_source_points(Triangle_mesh::Vertex_index(16)).first;
|
||||
assert(dist == 0.75);
|
||||
|
||||
dist = shortest_paths.shortest_distance_to_source_points(Triangle_mesh::Vertex_index(31)).first;
|
||||
assert(CGAL::abs(dist - 0.25) < 1e-7); // numerical issue (returns '0.25000000000000006')
|
||||
|
||||
dist = shortest_paths.shortest_distance_to_source_points(Triangle_mesh::Vertex_index(25)).first;
|
||||
assert(dist == 0.25);
|
||||
|
||||
dist = shortest_paths.shortest_distance_to_source_points(Triangle_mesh::Vertex_index(23)).first;
|
||||
assert(dist == 1.25);
|
||||
|
||||
auto loc = shortest_paths.locate<AABB_face_graph_traits>(Kernel::Point_3(1.25, 0, 0));
|
||||
dist = shortest_paths.shortest_distance_to_source_points(loc.first, loc.second).first;
|
||||
assert(dist == 0.5);
|
||||
|
||||
loc = shortest_paths.locate<AABB_face_graph_traits>(Kernel::Point_3(1.25, 1, 0));
|
||||
dist = shortest_paths.shortest_distance_to_source_points(loc.first, loc.second).first;
|
||||
assert(dist == 0.5);
|
||||
|
||||
h28 = next(h28, mesh);
|
||||
set_halfedge(f28, h28, mesh);
|
||||
h29 = next(h29, mesh);
|
||||
set_halfedge(f29, h29, mesh);
|
||||
}
|
||||
|
||||
h = opposite(h, mesh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
std::cerr.precision(17);
|
||||
std::cout.precision(17);
|
||||
|
||||
// test_all_pairs();
|
||||
test_flat_donut();
|
||||
|
||||
std::cout << "Done!" << std::endl;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,84 @@
|
|||
OFF
|
||||
32 48 0
|
||||
|
||||
0 0 0
|
||||
1 0 0
|
||||
2 0 0
|
||||
3 0 0
|
||||
0 1 0
|
||||
1 1 0
|
||||
2 1 0
|
||||
3 1 0
|
||||
0 2 0
|
||||
1 2 0
|
||||
2 2 0
|
||||
3 2 0
|
||||
0 3 0
|
||||
1 3 0
|
||||
2 3 0
|
||||
3 3 0
|
||||
0.5 0.5 0
|
||||
0.5 1.5 0
|
||||
0.5 2.5 0
|
||||
1.5 2.5 0
|
||||
2.5 2.5 0
|
||||
2.5 1.5 0
|
||||
2.5 1 0
|
||||
2.5 0.5 0
|
||||
2 0.5 0
|
||||
1.5 0.5 0
|
||||
0.5 1 0
|
||||
0.5 2 0
|
||||
1 2.5 0
|
||||
2 2.5 0
|
||||
2.5 2 0
|
||||
1 0.5 0
|
||||
3 16 4 0
|
||||
3 31 16 1
|
||||
3 17 26 5
|
||||
3 9 17 5
|
||||
3 18 27 9
|
||||
3 28 18 9
|
||||
3 2 25 1
|
||||
3 24 25 2
|
||||
3 20 11 15
|
||||
3 20 30 11
|
||||
3 10 19 9
|
||||
3 29 19 10
|
||||
3 3 23 2
|
||||
3 7 23 3
|
||||
3 21 22 7
|
||||
3 11 21 7
|
||||
3 0 1 16
|
||||
3 31 26 16
|
||||
3 31 5 26
|
||||
3 26 4 16
|
||||
3 17 4 26
|
||||
3 17 8 4
|
||||
3 27 8 17
|
||||
3 9 27 17
|
||||
3 18 8 27
|
||||
3 18 12 8
|
||||
3 13 12 18
|
||||
3 28 13 18
|
||||
3 25 5 31
|
||||
3 1 25 31
|
||||
3 6 5 25
|
||||
3 24 6 25
|
||||
3 15 14 20
|
||||
3 20 29 30
|
||||
3 30 29 10
|
||||
3 20 14 29
|
||||
3 19 13 28
|
||||
3 9 19 28
|
||||
3 14 13 19
|
||||
3 29 14 19
|
||||
3 23 6 24
|
||||
3 2 23 24
|
||||
3 22 6 23
|
||||
3 7 22 23
|
||||
3 21 6 22
|
||||
3 21 10 6
|
||||
3 30 10 21
|
||||
3 11 30 21
|
||||
|
||||
|
|
@ -4,7 +4,6 @@
|
|||
#include <algorithm>
|
||||
|
||||
#include <CGAL/boost/graph/properties.h>
|
||||
#include <CGAL/boost/graph/properties_Polyhedron_3.h>
|
||||
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
|
||||
#include <CGAL/Random.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -19,9 +19,13 @@
|
|||
#include <CGAL/Timer.h>
|
||||
#include <CGAL/Default.h>
|
||||
|
||||
#include <CGAL/Polyhedron_3.h>
|
||||
#include <CGAL/Polyhedron_items_with_id_3.h>
|
||||
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
|
||||
#include <CGAL/HalfedgeDS_default.h>
|
||||
#include <CGAL/HalfedgeDS_vertex_max_base_with_id.h>
|
||||
#include <CGAL/HalfedgeDS_halfedge_max_base_with_id.h>
|
||||
#include <CGAL/HalfedgeDS_face_max_base_with_id.h>
|
||||
|
||||
#include <CGAL/boost/graph/graph_traits_HalfedgeDS_default.h>
|
||||
#include <CGAL/boost/graph/properties_HalfedgeDS_default.h>
|
||||
#include <CGAL/boost/graph/copy_face_graph.h>
|
||||
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
|
|
@ -91,12 +95,20 @@ struct Skel_HDS_vertex_type : public HalfedgeDS_vertex_max_base_with_id<Refs, Po
|
|||
};
|
||||
|
||||
template <class vertex_descriptor>
|
||||
struct Skel_polyhedron_items_3: CGAL::Polyhedron_items_with_id_3 {
|
||||
struct Skel_polyhedron_items_3 {
|
||||
template < class Refs, class Traits>
|
||||
struct Vertex_wrapper {
|
||||
typedef typename Traits::Point_3 Point;
|
||||
typedef Skel_HDS_vertex_type< Refs, Point, std::size_t, vertex_descriptor> Vertex;
|
||||
};
|
||||
template < class Refs, class Traits>
|
||||
struct Halfedge_wrapper {
|
||||
typedef HalfedgeDS_halfedge_max_base_with_id<Refs, std::size_t> Halfedge;
|
||||
};
|
||||
template < class Refs, class Traits>
|
||||
struct Face_wrapper {
|
||||
typedef HalfedgeDS_face_max_base_with_id< Refs, Tag_false, std::size_t> Face;
|
||||
};
|
||||
};
|
||||
|
||||
} //end of namespace internal
|
||||
|
|
@ -192,7 +204,7 @@ public:
|
|||
typedef typename Traits::Vector_3 Vector;
|
||||
|
||||
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor Input_vertex_descriptor;
|
||||
typedef CGAL::Polyhedron_3<Traits,internal::Skel_polyhedron_items_3<Input_vertex_descriptor> > mTriangleMesh;
|
||||
typedef CGAL::HalfedgeDS_default<Traits,internal::Skel_polyhedron_items_3<Input_vertex_descriptor> > mTriangleMesh;
|
||||
typedef typename boost::property_map<mTriangleMesh, CGAL::vertex_point_t>::type mVertexPointMap;
|
||||
typedef typename boost::property_map<mTriangleMesh, boost::vertex_index_t>::type VertexIndexMap;
|
||||
typedef typename boost::property_map<mTriangleMesh, boost::halfedge_index_t>::type HalfedgeIndexMap;
|
||||
|
|
@ -1193,7 +1205,7 @@ private:
|
|||
vertex_descriptor vk = target(ek, m_tmesh);
|
||||
|
||||
// split the edge
|
||||
halfedge_descriptor en = m_tmesh.split_edge(ei);
|
||||
halfedge_descriptor en = Euler::split_edge(ei, m_tmesh);
|
||||
// split the incident faces
|
||||
Euler::split_face(en, next(ei,m_tmesh), m_tmesh);
|
||||
if (! is_border(ej,m_tmesh))
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue