Overhaul & enhance SLS's free functions to provide & complete the advertised API

This commit is contained in:
Mael Rouxel-Labbé 2020-10-08 22:54:11 +02:00
parent e9c3531145
commit 9051fc1d23
7 changed files with 373 additions and 274 deletions

View File

@ -0,0 +1,86 @@
// Copyright (c) 2007 Fernando Luis Cacciola Carballal. 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) : Fernando Cacciola <fernando_cacciola@ciudad.com.ar>
#ifndef CGAL_STRAIGHT_SKELETON_POLYGON_ITERATOR_H
#define CGAL_STRAIGHT_SKELETON_POLYGON_ITERATOR_H 1
#include <CGAL/license/Straight_skeleton_2.h>
#include <CGAL/Polygon_with_holes_2.h>
#include <boost/shared_ptr.hpp>
namespace CGAL {
namespace CGAL_SS_i {
// to distinguish between SequenceContainers of points, and GeneralPolygonWithHoles_2
BOOST_MPL_HAS_XXX_TRAIT_DEF(Hole_const_iterator)
// Generic container
template<class Poly>
inline typename Poly::const_iterator vertices_begin ( Poly const& aPoly )
{ return aPoly.begin() ; }
template<class Poly>
inline typename Poly::const_iterator vertices_end ( Poly const& aPoly )
{ return aPoly.end() ; }
template<class Poly>
inline typename Poly::const_iterator vertices_begin ( boost::shared_ptr<Poly> const& aPoly )
{ return aPoly->begin() ; }
template<class Poly>
inline typename Poly::const_iterator vertices_end ( boost::shared_ptr<Poly> const& aPoly )
{ return aPoly->end() ; }
// Polygon_2
template<class K, class C>
inline typename Polygon_2<K,C>::Vertex_const_iterator
vertices_begin ( Polygon_2<K,C> const& aPoly )
{ return aPoly.vertices_begin() ; }
template<class K, class C>
inline typename Polygon_2<K,C>::Vertex_const_iterator
vertices_end( Polygon_2<K,C> const& aPoly )
{ return aPoly.vertices_end() ; }
template<class K, class C>
inline typename Polygon_2<K,C>::Vertex_const_iterator vertices_begin ( boost::shared_ptr<Polygon_2<K,C> > const& aPoly )
{ return aPoly->vertices_begin() ; }
template<class K, class C>
inline typename Polygon_2<K,C>::Vertex_const_iterator vertices_end( boost::shared_ptr<Polygon_2<K,C> > const& aPoly )
{ return aPoly->vertices_end() ; }
// Polygon_with_holes_2
template<class K, class C>
inline typename Polygon_with_holes_2<K,C>::Polygon_2::Vertex_const_iterator
vertices_begin ( Polygon_with_holes_2<K,C> const& aPoly )
{ return aPoly.outer_boundary().vertices_begin() ; }
template<class K, class C>
inline typename Polygon_with_holes_2<K,C>::Polygon_2::Vertex_const_iterator
vertices_end( Polygon_with_holes_2<K,C> const& aPoly )
{ return aPoly.outer_boundary().vertices_end() ; }
template<class K, class C>
inline typename Polygon_with_holes_2<K,C>::Polygon_2::Vertex_const_iterator
vertices_begin ( boost::shared_ptr<Polygon_with_holes_2<K,C> > const& aPoly )
{ return aPoly->outer_boundary().vertices_begin() ; }
template<class K, class C>
inline typename Polygon_with_holes_2<K,C>::Polygon_2::Vertex_const_iterator
vertices_end( boost::shared_ptr<Polygon_with_holes_2<K,C> > const& aPoly )
{ return aPoly->outer_boundary().vertices_end() ; }
} // namespace CGAL_SS_i
} // namespace CGAL
#endif // CGAL_STRAIGHT_SKELETON_POLYGON_ITERATOR_H //

View File

@ -14,8 +14,11 @@
#include <CGAL/license/Straight_skeleton_2.h>
#include <CGAL/Straight_skeleton_2/Polygon_iterators.h>
#include <CGAL/Polygon_with_holes_2.h>
#include <boost/range/value_type.hpp>
#include <boost/shared_ptr.hpp>
#include <algorithm>
@ -34,23 +37,19 @@ namespace CGAL {
// Outer polygons do not contain other outer polygons, only holes
// Every hole is contained in one and only one outer polygon
//
template<class K, class InputPolygonPtrIterator, class OutputPolygonWithHolesPtrIterator>
template<class K, class InputPolygonPtrIterator, class OutputPolygonWithHolesPtrIterator,
class PolygonWithHoles = Polygon_with_holes_2<K> >
bool arrange_offset_polygons_2 ( InputPolygonPtrIterator aBegin
, InputPolygonPtrIterator aEnd
, OutputPolygonWithHolesPtrIterator rOut
, K const&
, const K&
)
{
typedef typename std::iterator_traits<InputPolygonPtrIterator>::difference_type difference_type ;
typedef typename std::iterator_traits<InputPolygonPtrIterator>::value_type PolygonPtr ;
typedef Polygon_2<K> Polygon ;
typedef Polygon_with_holes_2<K> PolygonWithHoles ;
typedef boost::shared_ptr<Polygon> PolygonPtr ;
typedef boost::shared_ptr<PolygonWithHoles> PolygonWithHolesPtr ;
typedef typename Polygon::Vertex_const_iterator Vertex_const_iterator ;
difference_type lSize = std::distance(aBegin,aEnd);
std::vector<PolygonWithHolesPtr> lTable(lSize);
@ -59,7 +58,7 @@ bool arrange_offset_polygons_2 ( InputPolygonPtrIterator aBegin
{
difference_type lIdx = std::distance(aBegin,it);
PolygonPtr lPoly = *it ;
const PolygonPtr lPoly = *it ;
Orientation lOrient = lPoly->orientation();
// It's an outer boundary
@ -73,7 +72,7 @@ bool arrange_offset_polygons_2 ( InputPolygonPtrIterator aBegin
for ( InputPolygonPtrIterator it = aBegin ; it != aEnd ; ++ it )
{
PolygonPtr lPoly = *it ;
const PolygonPtr lPoly = *it ;
difference_type lIdx = std::distance(aBegin,it);
@ -86,7 +85,7 @@ bool arrange_offset_polygons_2 ( InputPolygonPtrIterator aBegin
{
PolygonWithHolesPtr lOuter = lTable[j];
if ( lOuter )
for ( Vertex_const_iterator v = lPoly->vertices_begin(), ve = lPoly->vertices_end(); v != ve && !lParent ; ++ v )
for ( auto v = CGAL_SS_i::vertices_begin(lPoly), ve = CGAL_SS_i::vertices_end(lPoly); v != ve && !lParent ; ++ v )
if ( lOuter->outer_boundary().bounded_side(*v) == ON_BOUNDED_SIDE )
lParent = lOuter ;
}
@ -100,25 +99,34 @@ bool arrange_offset_polygons_2 ( InputPolygonPtrIterator aBegin
return true;
}
template<class K, class C>
std::vector< boost::shared_ptr< Polygon_with_holes_2<K,C> > >
template<class PolygonWithHoles, class Polygon>
std::vector< boost::shared_ptr<PolygonWithHoles> >
inline
arrange_offset_polygons_2 ( std::vector< boost::shared_ptr< Polygon_2<K,C> > > const& aPolygons, bool& no_error)
arrange_offset_polygons_2 ( std::vector<boost::shared_ptr<Polygon> > const& aPolygons,
bool& no_error)
{
std::vector< boost::shared_ptr< Polygon_with_holes_2<K,C> > > rResult ;
typedef std::vector< boost::shared_ptr<PolygonWithHoles> > result_type ;
typedef std::back_insert_iterator<result_type> Back_inserter;
no_error = arrange_offset_polygons_2(aPolygons.begin(), aPolygons.end(), std::back_inserter(rResult), K() ) ;
typedef typename PolygonWithHoles::General_polygon_2 Polygon_2 ;
typedef typename Kernel_traits<typename boost::range_value<Polygon_2>::type>::Kernel K ;
typedef typename std::vector<boost::shared_ptr<Polygon> >::const_iterator PolygonIterator ;
result_type rResult ;
no_error = arrange_offset_polygons_2<K, PolygonIterator, Back_inserter, PolygonWithHoles>(
aPolygons.begin(), aPolygons.end(), std::back_inserter(rResult), K() ) ;
return rResult ;
}
template<class K, class C>
std::vector< boost::shared_ptr< Polygon_with_holes_2<K,C> > >
template<class PolygonWithHoles, class Polygon>
std::vector< boost::shared_ptr<PolygonWithHoles> >
inline
arrange_offset_polygons_2 ( std::vector< boost::shared_ptr< Polygon_2<K,C> > > const& aPolygons)
arrange_offset_polygons_2 ( std::vector<boost::shared_ptr<Polygon> > const& aPolygons)
{
bool no_error;
return arrange_offset_polygons_2(aPolygons, no_error);
return arrange_offset_polygons_2<PolygonWithHoles>(aPolygons, no_error);
}
} // end namespace CGAL

View File

@ -46,7 +46,7 @@ boost::optional< typename Traits::FT > compute_outer_frame_margin ( ForwardPoint
typedef boost::optional<Point_2> OptionalPoint_2 ;
FT lMaxSDist(0.0) ;
FT lMaxSDist(0) ;
ForwardPointIterator lLast = std::prev(aEnd) ;

View File

@ -19,29 +19,88 @@
#include <CGAL/Polygon_offset_builder_2.h>
#include <CGAL/Straight_skeleton_converter_2.h>
#include <CGAL/Straight_skeleton_builder_2.h>
#include <CGAL/Straight_skeleton_2/Polygon_iterators.h>
#include <CGAL/assertions.h>
#include <CGAL/Cartesian_converter.h>
#include <CGAL/Kernel_traits.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/Polygon_with_holes_2.h>
#include <CGAL/tags.h>
#include <boost/optional/optional.hpp>
#include <boost/range/value_type.hpp>
#include <boost/shared_ptr.hpp>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <type_traits>
#include <vector>
namespace CGAL {
namespace CGAL_SS_i {
template<class U, class V> struct Is_same_type { typedef Tag_false type ; } ;
template<class U, class V>
struct Is_same_type { typedef Tag_false type ; } ;
template<class U> struct Is_same_type<U,U> { typedef Tag_true type ; } ;
template<class U>
struct Is_same_type<U,U> { typedef Tag_true type ; } ;
// The return type of create_interior/exterior_skeleton_and_offset_polygons_2:
// - if polygon input is a model of 'GeneralPolygonWithHoles_2', the return type
// should be the internal (hole-less) polygon type GeneralPolygonWithHoles_2::General_polygon_2
// - if polygon input is just a sequence container of points (e.g. Polygon_2), then the same type
// is expected in output
template <typename Polygon, typename OfK,
bool has_holes = CGAL_SS_i::has_Hole_const_iterator<Polygon>::value>
struct Default_return_polygon_type // Polygon type supports holes
{
typedef typename std::conditional<std::is_same<
typename Kernel_traits<typename boost::range_value<
typename Polygon::General_polygon_2>::type>::Kernel,
OfK>::value,
typename Polygon::General_polygon_2, // correct kernel
CGAL::Polygon_2<OfK> /*incorrect kernel*/ >::type type;
};
template <typename Polygon, typename OfK>
struct Default_return_polygon_type<Polygon, OfK, false> // Polygon type does NOT support holes
{
typedef typename std::conditional<std::is_same<
typename Kernel_traits<typename boost::range_value<Polygon>::type>::Kernel,
OfK>::value,
Polygon, // correct kernel
CGAL::Polygon_2<OfK> /*incorrect kernel*/ >::type type;
};
// The return type of create_interior/exterior_skeleton_and_offset_polygons_with_holes_2:
// - if polygon input is a model of 'GeneralPolygonWithHoles_2', the return type should be the same
// - if polygon input is just a sequence container of points (e.g. Polygon_2), then use
// General_polygon_with_holes_2<Polygon>
template <typename Polygon, typename OfK,
bool has_holes = CGAL_SS_i::has_Hole_const_iterator<Polygon>::value>
struct Default_return_polygon_with_holes_type // Polygon type supports holes
{
typedef typename std::conditional<std::is_same<
typename Kernel_traits<typename boost::range_value<
typename Polygon::General_polygon_2>::type>::Kernel,
OfK>::value,
Polygon, // correct kernel
CGAL::Polygon_with_holes_2<OfK> /*incorrect kernel*/ >::type type;
};
template <typename Polygon, typename OfK>
struct Default_return_polygon_with_holes_type<Polygon, OfK, false> // Polygon type does NOT support holes
{
// Maybe on paper the `conditional<true>` should be `General_polygon_with_holes_2<Polygon>`...
typedef typename std::conditional<std::is_same<
typename Kernel_traits<typename boost::range_value<Polygon>::type>::Kernel,
OfK>::value,
CGAL::Polygon_with_holes_2<OfK>, // correct kernel but no holes
CGAL::Polygon_with_holes_2<OfK> /*incorrect kernel*/ >::type type;
};
template<class FT, class PointIterator, class HoleIterator, class K>
boost::shared_ptr< Straight_skeleton_2<K> >
@ -87,7 +146,7 @@ create_partial_exterior_straight_skeleton_2 ( FT const& aMaxOffset
, K const& k // aka 'SK'
)
{
CGAL_precondition( aMaxOffset > static_cast<FT>(0) ) ;
CGAL_precondition( aMaxOffset > 0 ) ;
typedef typename std::iterator_traits<PointIterator>::value_type Point_2;
typedef typename Kernel_traits<Point_2>::Kernel IK;
@ -191,33 +250,25 @@ Skeleton const& dereference ( boost::shared_ptr<Skeleton> const& ss )
} // namespace CGAL_SS_i
template<class Polygon, class FT, class Skeleton, class K>
std::vector< boost::shared_ptr<Polygon> >
template<class OutPolygon, class FT, class Skeleton, class K>
std::vector< boost::shared_ptr<OutPolygon> >
inline
create_offset_polygons_2(const FT& aOffset,
const Skeleton& aSs,
const K& k)
{
typename CGAL_SS_i::Is_same_type<K, typename Skeleton::Traits>::type same_kernel;
return CGAL_SS_i::create_offset_polygons_2<Polygon>(aOffset, aSs, k, same_kernel);
return CGAL_SS_i::create_offset_polygons_2<OutPolygon>(aOffset, aSs, k, same_kernel);
}
template<class OfK, class C, class FT, class Skeleton>
std::vector< boost::shared_ptr<Polygon_2<OfK, C> > >
template<class Polygon = Polygon_2<Exact_predicates_inexact_constructions_kernel>,
class FT, class Skeleton>
std::vector< boost::shared_ptr<Polygon> >
inline
create_offset_polygons_2(const FT& aOffset,
const Skeleton& aSs)
{
return create_offset_polygons_2<Polygon_2<OfK, C> >(aOffset, aSs, OfK()); // @fixme EPICK
}
template<class OfK, class C, class FT, class Skeleton>
std::vector< boost::shared_ptr<Polygon_with_holes_2<OfK, C> > >
inline
create_offset_polygons_2(const FT& aOffset,
const Skeleton& aSs)
{
return create_offset_polygons_2<Polygon_with_holes_2<OfK, C> >(aOffset, aSs, OfK());
return create_offset_polygons_2<Polygon>(aOffset, aSs, Exact_predicates_inexact_constructions_kernel());
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -225,17 +276,18 @@ create_offset_polygons_2(const FT& aOffset,
////////////////////////////////////////////////////////////////////////////////////////////////////
/// INTERIOR
template<class FT, class Polygon, class HoleIterator, class OfK, class SsK>
std::vector< boost::shared_ptr<Polygon> >
template<class FT, class APolygon, class HoleIterator, class OfK, class SsK,
class OutPolygon = typename CGAL_SS_i::Default_return_polygon_type<APolygon, OfK>::type>
std::vector< boost::shared_ptr<OutPolygon> >
inline
create_interior_skeleton_and_offset_polygons_2(const FT& aOffset,
const Polygon& aOuterBoundary,
const APolygon& aOuterBoundary,
HoleIterator aHolesBegin,
HoleIterator aHolesEnd,
const OfK& ofk,
const SsK& ssk)
{
return create_offset_polygons_2<Polygon>(
return create_offset_polygons_2<OutPolygon>(
aOffset,
CGAL_SS_i::dereference(
CGAL_SS_i::create_partial_interior_straight_skeleton_2(
@ -248,63 +300,63 @@ create_interior_skeleton_and_offset_polygons_2(const FT& aOffset,
ofk);
}
template<class FT, class Polygon, class HoleIterator, class OfK>
std::vector< boost::shared_ptr<Polygon> >
template<class FT, class APolygon, class HoleIterator, class OfK,
class OutPolygon = typename CGAL_SS_i::Default_return_polygon_type<APolygon, OfK>::type>
std::vector< boost::shared_ptr<OutPolygon> >
inline
create_interior_skeleton_and_offset_polygons_2(const FT& aOffset,
const Polygon& aOuterBoundary,
const APolygon& aOuterBoundary,
HoleIterator aHolesBegin,
HoleIterator aHolesEnd,
const OfK& ofk)
{
return create_interior_skeleton_and_offset_polygons_2(aOffset, aOuterBoundary,
aHolesBegin, aHolesEnd,
ofk, ofk);
ofk,
Exact_predicates_inexact_constructions_kernel());
}
template<class FT, class Polygon, class OfK, class SsK>
std::vector< boost::shared_ptr<Polygon> >
// Overload where Polygon actually is a simple polygon (no holes)
template<class FT, class APolygon, class OfK, class SsK,
class OutPolygon = typename CGAL_SS_i::Default_return_polygon_type<APolygon, OfK>::type>
std::vector< boost::shared_ptr<OutPolygon> >
inline
create_interior_skeleton_and_offset_polygons_2(const FT& aOffset,
const Polygon& aPoly,
const APolygon& aPoly,
const OfK& ofk,
const SsK& ssk)
const SsK& ssk,
typename std::enable_if<
! CGAL_SS_i::has_Hole_const_iterator<APolygon>::value>::type* = nullptr)
{
std::vector<Polygon> no_holes;
std::vector<APolygon> no_holes;
return create_interior_skeleton_and_offset_polygons_2(aOffset, aPoly,
no_holes.begin(), no_holes.end(),
ofk, ssk);
}
template<class FT, class Polygon, class OfK>
std::vector< boost::shared_ptr<Polygon> >
// Overloads common to both polygons with and without holes, a simple polygon is 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> >
inline
create_interior_skeleton_and_offset_polygons_2(const FT& aOffset,
const Polygon& aPoly,
const APolygon& aPoly,
const OfK& ofk)
{
std::vector<Polygon> no_holes ;
return create_interior_skeleton_and_offset_polygons_2(aOffset, aPoly, ofk,
Exact_predicates_inexact_constructions_kernel());
}
template<class FT, class APolygon,
class OutPolygon = typename CGAL_SS_i::Default_return_polygon_type<
APolygon, Exact_predicates_inexact_constructions_kernel>::type>
std::vector<boost::shared_ptr<OutPolygon> >
inline
create_interior_skeleton_and_offset_polygons_2(const FT& aOffset,
const APolygon& aPoly)
{
return create_interior_skeleton_and_offset_polygons_2(aOffset, aPoly,
no_holes.begin(), no_holes.end(),
ofk, ofk);
}
template<class FT, class OfK, class C>
std::vector< boost::shared_ptr<Polygon_2<OfK, C> > >
inline
create_interior_skeleton_and_offset_polygons_2(const FT& aOffset,
const Polygon_2<OfK, C>& aPoly)
{
return create_interior_skeleton_and_offset_polygons_2(aOffset, aPoly, OfK());
}
template<class FT, class OfK, class C>
std::vector< boost::shared_ptr<Polygon_with_holes_2<OfK, C>> >
inline
create_interior_skeleton_and_offset_polygons_2(const FT& aOffset,
const Polygon_with_holes_2<OfK, C>& aPoly)
{
return create_interior_skeleton_and_offset_polygons_2(aOffset, aPoly, OfK());
Exact_predicates_inexact_constructions_kernel());
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -312,54 +364,58 @@ create_interior_skeleton_and_offset_polygons_2(const FT& aOffset,
////////////////////////////////////////////////////////////////////////////////////////////////////
/// EXTERIOR
template<class FT, class Polygon, class OfK, class SsK>
std::vector< boost::shared_ptr<Polygon> >
/*! create_exterior_skeleton_and_offset_polygons_2 (no sorting of the result) */
// Overload where Polygon actually is a simple polygon (no holes)
template<class FT, class APolygon, class OfK, class SsK,
class OutPolygon = typename CGAL_SS_i::Default_return_polygon_type<APolygon, OfK>::type>
std::vector< boost::shared_ptr<OutPolygon> >
inline
create_exterior_skeleton_and_offset_polygons_2(const FT& aOffset,
const Polygon& aPoly,
const APolygon& aPoly,
const OfK& ofk,
const SsK& ssk)
const SsK& ssk,
typename std::enable_if<
! CGAL_SS_i::has_Hole_const_iterator<APolygon>::value>::type* = nullptr)
{
return create_offset_polygons_2<Polygon>(
aOffset,
CGAL_SS_i::dereference(
CGAL_SS_i::create_partial_exterior_straight_skeleton_2(
aOffset,
CGAL_SS_i::vertices_begin(aPoly),
CGAL_SS_i::vertices_end (aPoly),
ssk)),
ofk);
std::cout << typeid(OutPolygon).name() << std::endl;
// return create_offset_polygons_2<OutPolygon>(
// aOffset,
// CGAL_SS_i::dereference(
// CGAL_SS_i::create_partial_exterior_straight_skeleton_2(
// aOffset,
// CGAL_SS_i::vertices_begin(aPoly),
// CGAL_SS_i::vertices_end (aPoly),
// ssk)),
// ofk);
return std::vector< boost::shared_ptr<OutPolygon> >();
}
template<class FT, class Polygon, class OfK>
std::vector< boost::shared_ptr<Polygon> >
// Overloads common to both polygons with and without holes, a simple polygon is 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> >
inline
create_exterior_skeleton_and_offset_polygons_2(const FT& aOffset,
const Polygon& aPoly,
const APolygon& aPoly,
const OfK& ofk)
{
return create_exterior_skeleton_and_offset_polygons_2(aOffset, aPoly, ofk, ofk);
return create_exterior_skeleton_and_offset_polygons_2(aOffset, aPoly, ofk,
Exact_predicates_inexact_constructions_kernel());
}
template<class FT, class OfK, class C>
std::vector< boost::shared_ptr<Polygon_2<OfK, C> > >
template<class FT, class APolygon,
class OutPolygon = typename CGAL_SS_i::Default_return_polygon_type<
APolygon, Exact_predicates_inexact_constructions_kernel>::type>
std::vector< boost::shared_ptr<OutPolygon> >
inline
create_exterior_skeleton_and_offset_polygons_2(const FT& aOffset,
const Polygon_2<OfK, C>& aPoly)
const APolygon& aPoly)
{
return create_exterior_skeleton_and_offset_polygons_2(aOffset, aPoly, OfK());
}
template<class FT, class OfK, class C>
std::vector<boost::shared_ptr<Polygon_with_holes_2<OfK, C> > >
inline
create_exterior_skeleton_and_offset_polygons_2(const FT& aOffset,
const Polygon_with_holes_2<OfK, C>& aPoly)
{
return create_exterior_skeleton_and_offset_polygons_2(aOffset, aPoly, OfK());
return create_exterior_skeleton_and_offset_polygons_2(aOffset, aPoly,
Exact_predicates_inexact_constructions_kernel());
}
} // end namespace CGAL
#endif
// EOF //

View File

@ -16,10 +16,14 @@
#include <CGAL/arrange_offset_polygons_2.h>
#include <CGAL/create_offset_polygons_2.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/Polygon_with_holes_2.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <boost/shared_ptr.hpp>
#include <type_traits>
#include <vector>
namespace CGAL {
@ -29,71 +33,63 @@ namespace CGAL {
////////////////////////////////////////////////////////////////////////////////////////////////////
/// INTERIOR
// create_interior_skeleton_and_offset_polygons_2
/*! create_interior_skeleton_and_offset_polygons_2 (no sorting of the result) */
template<class FT, class OfK, class SsK, class C>
std::vector< boost::shared_ptr< Polygon_2<OfK, C> > >
// overload where PolygonWithHoles actually is a type of Polygon that supports holes
template<class FT, class PolygonWithHoles, class OfK, class SsK,
class OutPolygon = typename CGAL_SS_i::Default_return_polygon_type<PolygonWithHoles, OfK>::type> // Hole-less polygon type
std::vector<boost::shared_ptr<OutPolygon> >
inline
create_interior_skeleton_and_offset_polygons_2(const FT& aOffset,
const Polygon_with_holes_2<OfK, C>& aPoly,
const PolygonWithHoles& aPoly,
const OfK& ofk,
const SsK& ssk)
const SsK& ssk,
typename std::enable_if<
CGAL_SS_i::has_Hole_const_iterator<PolygonWithHoles>::value>::type* = nullptr)
{
return create_interior_skeleton_and_offset_polygons_2(aOffset, aPoly.outer_boundary(),
aPoly.holes_begin(), aPoly.holes_end(),
ofk, ssk);
}
template<class FT, class OfK, class C>
std::vector< boost::shared_ptr< Polygon_2<OfK, C> > >
inline
create_interior_skeleton_and_offset_polygons_2(const FT& aOffset,
const Polygon_with_holes_2<OfK, C>& aPoly,
const OfK& ofk)
{
return create_interior_skeleton_and_offset_polygons_2(aOffset, aPoly, ofk, ofk);
}
/*! create_interior_skeleton_and_offset_polygons_with_holes_2 (orders the resulting polygons) */
template<class FT, class OfK, class C>
std::vector< boost::shared_ptr< Polygon_2<OfK, C> > >
inline
create_interior_skeleton_and_offset_polygons_2(const FT& aOffset,
const Polygon_with_holes_2<OfK, C>& aPoly)
{
OfK ofk;
return create_interior_skeleton_and_offset_polygons_2(aOffset, aPoly, ofk, ofk);
}
// create_interior_skeleton_and_offset_polygons_with_holes_2
template<class FT, class OfK, class SsK, class C>
std::vector< boost::shared_ptr< Polygon_with_holes_2<OfK, C> > >
// 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_interior_skeleton_and_offset_polygons_with_holes_2(const FT& aOffset,
const Polygon_with_holes_2<OfK, C>& aPoly,
const Polygon& aPoly,
const OfK& ofk,
const SsK& ssk)
{
return arrange_offset_polygons_2(create_interior_skeleton_and_offset_polygons_2(aOffset, aPoly, ofk, ssk));
return arrange_offset_polygons_2<OutPolygonWithHoles>(
create_interior_skeleton_and_offset_polygons_2(aOffset, aPoly, ofk, ssk));
}
template<class FT, class OfK, class C>
std::vector< boost::shared_ptr< Polygon_with_holes_2<OfK, C> > >
template<class FT, class Polygon, class OfK,
class OutPolygonWithHoles = typename CGAL_SS_i::Default_return_polygon_with_holes_type<Polygon, OfK>::type>
std::vector<boost::shared_ptr<OutPolygonWithHoles> >
inline
create_interior_skeleton_and_offset_polygons_with_holes_2(const FT& aOffset,
const Polygon_with_holes_2<OfK, C>& aPoly,
const Polygon& aPoly,
const OfK& ofk)
{
return create_interior_skeleton_and_offset_polygons_with_holes_2(aOffset, aPoly, ofk, ofk);
return create_interior_skeleton_and_offset_polygons_with_holes_2(aOffset, aPoly, ofk,
Exact_predicates_inexact_constructions_kernel());
}
template<class FT, class OfK, class C>
std::vector< boost::shared_ptr< Polygon_with_holes_2<OfK, C> > >
template<class FT, class Polygon,
class OutPolygonWithHoles = typename CGAL_SS_i::Default_return_polygon_with_holes_type<
Polygon, Exact_predicates_inexact_constructions_kernel>::type>
std::vector<boost::shared_ptr<OutPolygonWithHoles> >
inline
create_interior_skeleton_and_offset_polygons_with_holes_2(const FT& aOffset,
const Polygon_with_holes_2<OfK, C>& aPoly)
const Polygon& aPoly)
{
return create_interior_skeleton_and_offset_polygons_with_holes_2(aOffset, aPoly, OfK());
return create_interior_skeleton_and_offset_polygons_with_holes_2(aOffset, aPoly,
Exact_predicates_inexact_constructions_kernel());
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -101,35 +97,61 @@ create_interior_skeleton_and_offset_polygons_with_holes_2(const FT& aOffset,
////////////////////////////////////////////////////////////////////////////////////////////////////
/// EXTERIOR
template<class FT, class OfK, class SsK, class C>
std::vector<boost::shared_ptr<Polygon_with_holes_2<OfK, C> > >
/*! create_interior_skeleton_and_offset_polygons_2 with a polygon with holes */
// overload where PolygonWithHoles actually is a type of Polygon that supports holes
template<class FT, class PolygonWithHoles, class OfK, class SsK,
class OutPolygon = typename CGAL_SS_i::Default_return_polygon_type<PolygonWithHoles, OfK>::type>
std::vector<boost::shared_ptr<OutPolygon> >
inline
create_exterior_skeleton_and_offset_polygons_2(const FT& aOffset,
const PolygonWithHoles& aPoly,
const OfK& ofk,
const SsK& ssk,
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);
}
/*! 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_2<OfK, C>& aPoly,
const Polygon& aPoly,
const OfK& ofk,
const SsK& ssk)
{
return arrange_offset_polygons_2(
return arrange_offset_polygons_2<OutPolygonWithHoles>(
create_exterior_skeleton_and_offset_polygons_2(aOffset, aPoly, ofk, ssk));
}
template<class FT, class OfK, class C>
std::vector<boost::shared_ptr<Polygon_with_holes_2<OfK, C> > >
template<class FT, class Polygon, class OfK,
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_2<OfK, C>& aPoly,
const Polygon& aPoly,
const OfK& ofk)
{
return create_exterior_skeleton_and_offset_polygons_with_holes_2(aOffset, aPoly, ofk, ofk);
return create_exterior_skeleton_and_offset_polygons_with_holes_2(aOffset, aPoly, ofk,
Exact_predicates_inexact_constructions_kernel());
}
template<class FT, class OfK, class C>
std::vector<boost::shared_ptr<Polygon_with_holes_2<OfK, C> > >
template<class FT, class Polygon,
class OutPolygonWithHoles = typename CGAL_SS_i::Default_return_polygon_with_holes_type<
Polygon, Exact_predicates_inexact_constructions_kernel>::type>
std::vector<boost::shared_ptr<OutPolygonWithHoles> >
inline
create_exterior_skeleton_and_offset_polygons_with_holes_2(const FT& aOffset,
const Polygon_2<OfK, C>& aPoly)
const Polygon& aPoly)
{
return create_exterior_skeleton_and_offset_polygons_with_holes_2(aOffset, aPoly, OfK());
return create_exterior_skeleton_and_offset_polygons_with_holes_2(aOffset, aPoly,
Exact_predicates_inexact_constructions_kernel());
}
} // end namespace CGAL

View File

@ -17,6 +17,9 @@
#include <CGAL/compute_outer_frame_margin.h>
#include <CGAL/Straight_skeleton_builder_2.h>
#include <CGAL/Polygon_with_holes_2.h>
#include <CGAL/Straight_skeleton_2/Polygon_iterators.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <boost/optional/optional.hpp>
#include <boost/shared_ptr.hpp>
@ -27,57 +30,6 @@
namespace CGAL {
namespace CGAL_SS_i {
// Generic
template<class Poly>
inline typename Poly::const_iterator vertices_begin ( Poly const& aPoly ) { return aPoly.begin() ; }
template<class Poly>
inline typename Poly::const_iterator vertices_end ( Poly const& aPoly ) { return aPoly.end() ; }
template<class Poly>
inline typename Poly::const_iterator vertices_begin ( boost::shared_ptr<Poly> const& aPoly ) { return aPoly->begin() ; }
template<class Poly>
inline typename Poly::const_iterator vertices_end ( boost::shared_ptr<Poly> const& aPoly ) { return aPoly->end() ; }
// Polygon_2
template<class K, class C>
inline typename Polygon_2<K,C>::Vertex_const_iterator vertices_begin ( Polygon_2<K,C> const& aPoly )
{ return aPoly.vertices_begin() ; }
template<class K, class C>
inline typename Polygon_2<K,C>::Vertex_const_iterator vertices_end( Polygon_2<K,C> const& aPoly )
{ return aPoly.vertices_end() ; }
template<class K, class C>
inline typename Polygon_2<K,C>::Vertex_const_iterator vertices_begin ( boost::shared_ptr<Polygon_2<K,C> > const& aPoly )
{ return aPoly->vertices_begin() ; }
template<class K, class C>
inline typename Polygon_2<K,C>::Vertex_const_iterator vertices_end( boost::shared_ptr<Polygon_2<K,C> > const& aPoly )
{ return aPoly->vertices_end() ; }
// Polygon_with_holes_2
template<class K, class C>
inline typename Polygon_with_holes_2<K,C>::Vertex_const_iterator vertices_begin ( Polygon_with_holes_2<K,C> const& aPoly )
{ return aPoly.outer_boundary().vertices_begin() ; }
template<class K, class C>
inline typename Polygon_with_holes_2<K,C>::Vertex_const_iterator vertices_end( Polygon_with_holes_2<K,C> const& aPoly )
{ return aPoly.outer_boundary().vertices_end() ; }
template<class K, class C>
inline typename Polygon_with_holes_2<K,C>::Vertex_const_iterator vertices_begin ( boost::shared_ptr<Polygon_with_holes_2<K,C> > const& aPoly )
{ return aPoly->outer_boundary().vertices_begin() ; }
template<class K, class C>
inline typename Polygon_with_holes_2<K,C>::Vertex_const_iterator vertices_end( boost::shared_ptr<Polygon_with_holes_2<K,C> > const& aPoly )
{ return aPoly->outer_boundary().vertices_end() ; }
}
template<class PointIterator, class HoleIterator, class K>
boost::shared_ptr< Straight_skeleton_2<K> >
create_interior_straight_skeleton_2 ( PointIterator aOuterContour_VerticesBegin
@ -133,7 +85,10 @@ create_interior_straight_skeleton_2 ( PointIterator aOuterContour_VerticesBegin
, K const& k
)
{
std::vector< Polygon_2<K> > no_holes ;
typedef typename std::iterator_traits<PointIterator>::value_type InputPoint ;
typedef typename Kernel_traits<InputPoint>::Kernel InputKernel ;
std::vector< Polygon_2<InputKernel> > no_holes ;
return create_interior_straight_skeleton_2(aOuterContour_VerticesBegin
,aOuterContour_VerticesEnd
,no_holes.begin()
@ -155,23 +110,15 @@ create_interior_straight_skeleton_2 ( PointIterator aOuterContour_VerticesBegin
);
}
template<class K, class C>
template<class Polygon, class K>
boost::shared_ptr< Straight_skeleton_2<K> >
inline
create_interior_straight_skeleton_2 ( Polygon_2<K, C> const& aOutContour, K const& k )
{
CGAL_precondition(aOutContour.is_simple() || !"The input polygon is not simple.");
return create_interior_straight_skeleton_2(CGAL_SS_i::vertices_begin(aOutContour)
,CGAL_SS_i::vertices_end(aOutContour)
,k
);
}
template<class Polygon, class K, class C>
boost::shared_ptr< Straight_skeleton_2<K> >
inline
create_interior_straight_skeleton_2 ( Polygon_with_holes_2<K, C> const& aOutContour, K const& k )
create_interior_straight_skeleton_2 ( Polygon const& aOutContour,
K const& k,
typename std::enable_if<
! CGAL_SS_i::has_Hole_const_iterator<Polygon>::value>::type* = nullptr)
{
// CGAL_precondition(aOutContour.is_simple() || !"The input polygon is not simple.");
return create_interior_straight_skeleton_2(CGAL_SS_i::vertices_begin(aOutContour)
,CGAL_SS_i::vertices_end(aOutContour)
,k
@ -199,27 +146,33 @@ create_exterior_straight_skeleton_2 ( FT const& aMaxOffset
, K const& k
)
{
typedef typename std::iterator_traits<PointIterator>::value_type Point_2 ;
CGAL_precondition( aMaxOffset > 0 ) ;
typedef Straight_skeleton_2<K> Ss ;
typedef boost::shared_ptr<Ss> SsPtr ;
typedef typename std::iterator_traits<PointIterator>::value_type Point_2 ;
typedef typename Kernel_traits<Point_2>::Kernel IK;
typedef typename IK::FT IFT;
SsPtr rSkeleton ;
boost::shared_ptr<Straight_skeleton_2<K> > rSkeleton;
boost::optional<FT> margin = compute_outer_frame_margin( aVerticesBegin
, aVerticesEnd
, aMaxOffset
);
// That's because we might not have FT == IK::FT (e.g. `double` and `Core`)
// Note that we can also have IK != K (e.g. `Simple_cartesian<Core>` and `EPICK`)
IFT lOffset = aMaxOffset;
// @todo This likely should be done in the kernel K rather than the input kernel (i.e. the same
// converter stuff that is done in `create_partial_exterior_straight_skeleton_2`?).
boost::optional<IFT> margin = compute_outer_frame_margin( aVerticesBegin,
aVerticesEnd,
lOffset );
if ( margin )
{
double lm = CGAL::to_double(*margin);
Bbox_2 bbox = bbox_2(aVerticesBegin, aVerticesEnd);
FT fxmin = bbox.xmin() - *margin ;
FT fxmax = bbox.xmax() + *margin ;
FT fymin = bbox.ymin() - *margin ;
FT fymax = bbox.ymax() + *margin ;
FT fxmin = bbox.xmin() - lm ;
FT fxmax = bbox.xmax() + lm ;
FT fymin = bbox.ymin() - lm ;
FT fymax = bbox.ymax() + lm ;
Point_2 frame[4] ;
@ -257,20 +210,6 @@ create_exterior_straight_skeleton_2 ( FT const& aMaxOffset
);
}
template<class FT, class K, class C>
boost::shared_ptr< Straight_skeleton_2<K> >
inline
create_exterior_straight_skeleton_2 ( FT const& aMaxOffset, Polygon_2<K, C> const& aPoly, K const& k )
{
CGAL_precondition(aPoly.is_simple() || !"The input polygon is not simple.");
return create_exterior_straight_skeleton_2(aMaxOffset
,CGAL_SS_i::vertices_begin(aPoly)
,CGAL_SS_i::vertices_end (aPoly)
,k
);
}
template<class FT, class Polygon, class K>
boost::shared_ptr< Straight_skeleton_2<K> >
inline
@ -297,4 +236,3 @@ create_exterior_straight_skeleton_2 ( FT const& aMaxOffset, Polygon const& aPoly
} // end namespace CGAL
#endif // CGAL_STRAIGHT_SKELETON_BUILDER_2_H //
// EOF //

View File

@ -16,15 +16,23 @@
#include <CGAL/create_straight_skeleton_2.h>
#include <CGAL/Polygon_with_holes_2.h>
#include <CGAL/Straight_skeleton_2/Polygon_iterators.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <boost/shared_ptr.hpp>
#include <type_traits>
namespace CGAL {
template<class K, class C>
template<class K, class Polygon>
boost::shared_ptr< Straight_skeleton_2<K> >
inline
create_interior_straight_skeleton_2 ( Polygon_with_holes_2<K,C> const& aPolyWithHoles, K const& k )
create_interior_straight_skeleton_2 ( Polygon const& aPolyWithHoles,
K const& k,
typename std::enable_if<
CGAL_SS_i::has_Hole_const_iterator<Polygon>::value>::type* = nullptr)
{
return create_interior_straight_skeleton_2(aPolyWithHoles.outer_boundary().vertices_begin()
,aPolyWithHoles.outer_boundary().vertices_end ()
@ -34,28 +42,9 @@ create_interior_straight_skeleton_2 ( Polygon_with_holes_2<K,C> const& aPolyWith
);
}
template<class K, class C>
boost::shared_ptr< Straight_skeleton_2<K> >
inline
create_interior_straight_skeleton_2 ( Polygon_with_holes_2<K,C> const& aPolyWithHoles )
{
return create_interior_straight_skeleton_2(aPolyWithHoles, K());
}
template<class FT, class K, class C>
boost::shared_ptr< Straight_skeleton_2<K> >
inline
create_exterior_straight_skeleton_2 ( FT const& aMaxOffset, Polygon_with_holes_2<K, C> const& aPoly, K const& k )
{
CGAL_precondition(aPoly.outer_boundary().is_simple() || !"The input polygon is not simple.");
return create_exterior_straight_skeleton_2(aMaxOffset
,CGAL_SS_i::vertices_begin(aPoly)
,CGAL_SS_i::vertices_end (aPoly)
,k
);
}
// create_exterior_straight_skeleton_2() for polygon with holes is simply in create_straight_skeleton_2.h
// as the holes do not matter.
} // end namespace CGAL
#endif // CGAL_STRAIGHT_SKELETON_BUILDER_2_H //
// EOF //