Merge remote-tracking branch 'cgal/master' into CGAL_IO-maxGimeno

This commit is contained in:
Mael Rouxel-Labbé 2020-10-09 18:36:17 +02:00
commit f55ef7dd50
343 changed files with 9511 additions and 6937 deletions

93
.github/workflows/build_doc.yml vendored Normal file
View File

@ -0,0 +1,93 @@
name: Documentation
on:
issue_comment:
types: [created]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v3
id: get_round
with:
result-encoding: string
script: |
const asso = context.payload.comment.author_association
if(asso == 'OWNER' || asso == 'MEMBER') {
const body = context.payload.comment.body
if(body.includes("build:")) {
return body.replace('build:','')
}
}
return 'stop'
- uses: actions/github-script@v3
if: steps.get_round.outputs.result != 'stop'
id: get_pr_number
with:
result-encoding: string
script: |
//get pullrequest url
const pr_number = context.payload.issue.number
return pr_number
- uses: actions/checkout@v2
name: "checkout branch"
if: steps.get_round.outputs.result != 'stop'
with:
repository: ${{ github.repository }}
ref: refs/pull/${{ steps.get_pr_number.outputs.result }}/merge
token: ${{ secrets.PUSH_TO_CGAL_GITHUB_IO_TOKEN }}
- name: install dependencies
if: steps.get_round.outputs.result != 'stop'
run: |
set -x
sudo apt-get install -y graphviz ssh
sudo pip install lxml pyquery
wget --no-verbose -O doxygen_exe https://cgal.geometryfactory.com/~mgimeno/doxygen/build_1_8_13/bin/doxygen
sudo mv doxygen_exe /usr/bin/doxygen
sudo chmod +x /usr/bin/doxygen
git config --global user.email "maxime.gimeno@geometryfactory.com"
git config --global user.name "Maxime Gimeno"
- name: configure all
if: steps.get_round.outputs.result != 'stop'
run: |
set -ex
git clone https://CGAL:${{ secrets.PUSH_TO_CGAL_GITHUB_IO_TOKEN }}@github.com/CGAL/cgal.github.io.git --depth=5
mkdir -p build_doc && cd build_doc && cmake ../Documentation/doc
- name: Upload Doc
if: steps.get_round.outputs.result != 'stop'
run: |
set -ex
PR_NUMBER=${{ steps.get_pr_number.outputs.result }}
ROUND=${{ steps.get_round.outputs.result }}
wget --no-verbose cgal.github.io -O tmp.html
if ! egrep -q "\/$PR_NUMBER\/$ROUND" tmp.html; then
mkdir -p cgal.github.io/${PR_NUMBER}/$ROUND
cd build_doc && make -j2 doc && make -j2 doc_with_postprocessing
cp -r ./doc_output/* ../cgal.github.io/${PR_NUMBER}/$ROUND
cd ../cgal.github.io
egrep -v " ${PR_NUMBER}\." index.html > tmp.html
echo "<li><a href=https://cgal.github.io/${PR_NUMBER}/$ROUND/Manual/index.html>Manual for PR ${PR_NUMBER} ($ROUND).</a></li>" >> ./tmp.html
mv tmp.html index.html
git add ${PR_NUMBER}/$ROUND && git commit -q -a -m "Add ${PR_NUMBER} $ROUND" && git push -q -u origin master
else
exit 1
fi
- name: Post address
uses: actions/github-script@v3
if: steps.get_round.outputs.result != 'stop'
with:
script: |
const address = "The documentation is built. You can find it here : https://cgal.github.io/${{ steps.get_pr_number.outputs.result }}/${{ steps.get_round.outputs.result }}/Manual/index.html"
github.issues.createComment({
owner: "CGAL",
repo: "cgal",
issue_number: ${{ github.event.issue.number }},
body: address
});

27
.github/workflows/delete_doc.yml vendored Normal file
View File

@ -0,0 +1,27 @@
name: Documentation Removal
on:
pull_request_target:
types: [closed, removed]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.0.0
- name: delete directory
run: |
set -x
git config --global user.email "maxime.gimeno@geometryfactory.com"
git config --global user.name "Maxime Gimeno"
git clone https://maxGimeno:${{ secrets.PUSH_TO_CGAL_GITHUB_IO_TOKEN }}@github.com/CGAL/cgal.github.io.git --depth=5
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
if [ -n "$(diff -q ./index.html ./tmp.html)" ]; then
mv tmp.html index.html
#git rm -r ${PR_NUMBER} && git commit -a -m "Remove ${PR_NUMBER}" && git push -u origin master
git commit -a -m "Remove ${PR_NUMBER}" && git push -u origin master
fi

View File

@ -41,6 +41,7 @@ do
continue continue
fi fi
cd $ROOT cd $ROOT
#install openmesh only if necessary #install openmesh only if necessary
if [ "$ARG" = "CHECK" ] || [ "$ARG" = BGL ] || [ "$ARG" = Convex_hull_3 ] ||\ if [ "$ARG" = "CHECK" ] || [ "$ARG" = BGL ] || [ "$ARG" = Convex_hull_3 ] ||\
[ "$ARG" = Polygon_mesh_processing ] || [ "$ARG" = Property_map ] ||\ [ "$ARG" = Polygon_mesh_processing ] || [ "$ARG" = Property_map ] ||\
@ -92,28 +93,27 @@ cd $ROOT
exit 1 exit 1
fi fi
echo "Matrix is up to date." echo "Matrix is up to date."
#check if non standard cgal installation works
cd $ROOT
mkdir build_test
cd build_test
mytime cmake -DCMAKE_INSTALL_PREFIX=install/ -DCGAL_BUILD_THREE_DOC=TRUE ..
mytime make install
# test install with minimal downstream example
mkdir installtest
cd installtest
touch main.cpp
mkdir build
echo 'project(Example)' >> CMakeLists.txt
echo 'set(PROJECT_SRCS ${PROJECT_SOURCE_DIR}/main.cpp)' >> CMakeLists.txt
echo 'find_package(CGAL REQUIRED)' >> CMakeLists.txt
echo 'add_executable(${PROJECT_NAME} ${PROJECT_SRCS})' >> CMakeLists.txt
echo 'target_link_libraries(${PROJECT_NAME} CGAL::CGAL)' >> CMakeLists.txt
echo '#include "CGAL/remove_outliers.h"' >> main.cpp
cd build
mytime cmake -DCMAKE_INSTALL_PREFIX=../../install -DCGAL_BUILD_THREE_DOC=TRUE ..
cd ..
exit 0 exit 0
fi fi
if [ "$ARG" = "Installation" ]
then
mkdir build_dir
cd build_dir
cmake -DWITH_tests=ON -DBUILD_TESTING=ON ..
ctest -j2 -L CGAL_cmake_testsuite --output-on-failure
cd ..
rm -rf ./build_dir
#==-- configure all CGAL with -DWITH_examples=ON -DWITH_demos=ON -DWITH_tests=ON, and then launch CTest on a few labels. --==
mkdir config_dir
cd config_dir
cmake -DWITH_examples=ON -DWITH_demos=ON -DWITH_tests=ON -DBUILD_TESTING=ON ..
ctest -j2 -L AABB_tree --output-on-failure
cd ..
rm -rf ./config_dir
exit 0
fi
IFS=$old_IFS IFS=$old_IFS
if [ -n "$TRAVIS_PULL_REQUEST_BRANCH" ] && [ "$ARG" != Polyhedron_demo ]; then if [ -n "$TRAVIS_PULL_REQUEST_BRANCH" ] && [ "$ARG" != Polyhedron_demo ]; then
@ -185,6 +185,7 @@ cd $ROOT
cd "$ROOT/$DEMO" cd "$ROOT/$DEMO"
build_demo build_demo
fi fi
done done
IFS=$old_IFS IFS=$old_IFS
# Local Variables: # Local Variables:

View File

@ -578,7 +578,7 @@ public:
#ifdef CGAL_HAS_THREADS #ifdef CGAL_HAS_THREADS
mutable CGAL_MUTEX build_mutex; // mutex used to protect const calls inducing build() and build_kd_tree() mutable CGAL_MUTEX build_mutex; // mutex used to protect const calls inducing build() and build_kd_tree()
#endif #endif
public:
const Node* root_node() const { const Node* root_node() const {
CGAL_assertion(size() > 1); CGAL_assertion(size() > 1);
@ -596,7 +596,7 @@ public:
} }
return m_p_root_node; return m_p_root_node;
} }
private:
const Primitive& singleton_data() const { const Primitive& singleton_data() const {
CGAL_assertion(size() == 1); CGAL_assertion(size() == 1);
return *m_primitives.begin(); return *m_primitives.begin();

View File

@ -660,23 +660,33 @@ public:
return Equal_2(_traits); return Equal_2(_traits);
} }
/*! A functor that divides a curve into continues (x-monotone) curves. */ //! A functor for subdividing curves into x-monotone curves.
class Make_x_monotone_2 class Make_x_monotone_2
{ {
private: private:
Traits& _traits; Traits& _traits;
public: public:
Make_x_monotone_2(Traits& traits) : _traits(traits) {} Make_x_monotone_2(Traits& traits) : _traits(traits) {}
template<class OutputIterator>
OutputIterator operator() (const Curve_2& cv, OutputIterator oi) const /*! Subdivide a given curve into x-monotone subcurves and insert them into
* a given output iterator.
* \param cv the curve.
* \param oi an output iterator for the result. Its value type is a variant
* that wraps Point_2 or an X_monotone_curve_2 objects.
* \return The past-the-end iterator.
*/
template <class OutputIterator>
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const
{ {
Object_vector res (boost::apply_visitor(Make_x_monotone_2_visitor(_traits),cv.variant())); Object_vector res (boost::apply_visitor(Make_x_monotone_2_visitor(_traits),cv.variant()));
re_cast_object_vector(res,oi); re_cast_object_vector(res,oi);
return (oi); return (oi);
} }
private: private:
class Make_x_monotone_2_visitor class Make_x_monotone_2_visitor :
: public boost::static_visitor < Object_vector > public boost::static_visitor < Object_vector >
{ {
private: private:
typedef boost::static_visitor <Object_vector> Base; typedef boost::static_visitor <Object_vector> Base;
@ -1787,4 +1797,3 @@ public:
#endif // CGAL_DONT_SUBMIT #endif // CGAL_DONT_SUBMIT
#endif //CGAL_ARR_RATIONAL_ARC_TRAITS_D_1_H #endif //CGAL_ARR_RATIONAL_ARC_TRAITS_D_1_H

View File

@ -80,7 +80,7 @@ public:
Arr_rational_arc_traits_2 () Arr_rational_arc_traits_2 ()
{} {}
/// \name Functor definitions. /// \name Basic functor definitions.
//@{ //@{
/*! A functor that compares the x-coordinates of two points */ /*! A functor that compares the x-coordinates of two points */
@ -381,19 +381,22 @@ public:
{ {
return Equal_2(); return Equal_2();
} }
//@}
//! \name Intersections, subdivisions, and mergings
//@{
/*! A functor that divides a curve into continues (x-monotone) curves. */ /*! A functor that divides a curve into continues (x-monotone) curves. */
class Make_x_monotone_2 class Make_x_monotone_2
{ {
public: public:
/*! /*! Subdivide a given rational arc into x-monotone subcurves and insert them
* Cut the given conic curve (or conic arc) into x-monotone subcurves * into a given output iterator.
* and insert them to the given output iterator. * \param cv the arc.
* \param cv The curve. * \param oi an output iterator for the result. Its value type is a variant
* \param oi The output iterator, whose value-type is Object. The returned * that wraps Point_2 or an X_monotone_curve_2 objects.
* objects is a wrapper for an X_monotone_curve_2 object. * \return the past-the-end iterator.
* \return The past-the-end iterator.
*/ */
template<class OutputIterator> template<class OutputIterator>
OutputIterator operator() (const Curve_2& cv, OutputIterator oi) OutputIterator operator() (const Curve_2& cv, OutputIterator oi)

View File

@ -25,26 +25,26 @@ typedef CGAL::Curved_kernel_via_analysis_2< Algebraic_kernel_d_2 > CKvA_2;
Polynomial_2 makeParabola( ) Polynomial_2 makeParabola( )
{ {
Polynomial_2 x = CGAL::shift( Polynomial_2( 1 ), 1, 0 ); Polynomial_2 x = CGAL::shift( Polynomial_2( 1 ), 1, 0 );
Polynomial_2 y = CGAL::shift( Polynomial_2( 1 ), 1, 1 ); Polynomial_2 y = CGAL::shift( Polynomial_2( 1 ), 1, 1 );
Polynomial_2 parabola = y - x*x; Polynomial_2 parabola = y - x*x;
return parabola; return parabola;
} }
X_monotone_curve_2 makeVerticalLine( Bound x ) X_monotone_curve_2 makeVerticalLine( Bound x )
{ {
Traits traits; Traits traits;
Traits::Construct_point_2 constructPoint = Traits::Construct_point_2 constructPoint =
traits.construct_point_2_object( ); traits.construct_point_2_object( );
Traits::Construct_x_monotone_segment_2 constructSegment = Traits::Construct_x_monotone_segment_2 constructSegment =
traits.construct_x_monotone_segment_2_object( ); traits.construct_x_monotone_segment_2_object( );
std::vector< X_monotone_curve_2 > curves; std::vector< X_monotone_curve_2 > curves;
Point_2 p1 = constructPoint( Algebraic_real_1(x), Algebraic_real_1(Bound( -10000 )) ); Point_2 p1 = constructPoint( Algebraic_real_1(x), Algebraic_real_1(Bound( -10000 )) );
Point_2 p2 = constructPoint( x, Bound( +10000 ) ); Point_2 p2 = constructPoint( x, Bound( +10000 ) );
constructSegment( p1, p2, std::back_inserter( curves ) ); constructSegment( p1, p2, std::back_inserter( curves ) );
return curves[ 0 ]; return curves[ 0 ];
} }
typedef CGAL::Cartesian< Coefficient > Kernel; typedef CGAL::Cartesian< Coefficient > Kernel;
@ -52,40 +52,38 @@ typedef Kernel::Point_2 Kernel_point_2;
int main( ) int main( )
{ {
Algebraic_real_1 real( 1 ); Algebraic_real_1 real( 1 );
//CGAL::Qt::Converter< Algebraic_kernel_d_2 > testConverter; //CGAL::Qt::Converter< Algebraic_kernel_d_2 > testConverter;
//CGAL::Qt::Converter< CKvA_2 > testConverter; //CGAL::Qt::Converter< CKvA_2 > testConverter;
//CGAL::Qt::Converter< Cartesian > testConverter; //CGAL::Qt::Converter< Cartesian > testConverter;
Kernel_point_2 testPt( 1, 2 ); Kernel_point_2 testPt( 1, 2 );
Point_2 testPt2( testPt.x( ), testPt.y( ) ); Point_2 testPt2( testPt.x( ), testPt.y( ) );
Traits traits; Traits traits;
Construct_curve_2 constructCurve = traits.construct_curve_2_object( ); Construct_curve_2 constructCurve = traits.construct_curve_2_object( );
Curve_2 curve = constructCurve( makeParabola( ) ); Curve_2 curve = constructCurve( makeParabola( ) );
Make_x_monotone_2 mm = traits.make_x_monotone_2_object( ); Make_x_monotone_2 mm = traits.make_x_monotone_2_object( );
std::vector< CGAL::Object > curves; std::vector< CGAL::Object > curves;
mm( curve, std::back_inserter( curves ) ); mm( curve, std::back_inserter( curves ) );
std::cout << curves.size( ) << std::endl; std::cout << curves.size( ) << std::endl;
X_monotone_curve_2 c1; X_monotone_curve_2 c1;
CGAL::assign( c1, curves[ 0 ] ); CGAL::assign( c1, curves[ 0 ] );
double lb = -3; double lb = -3;
double ub = 3; double ub = 3;
double step = 6.0 / 1000; double step = 6.0 / 1000;
for ( int i = 0; i < 1000; ++i ) for ( int i = 0; i < 1000; ++i ) {
{ X_monotone_curve_2 c2 = makeVerticalLine( lb + step * i );
X_monotone_curve_2 c2 = makeVerticalLine( lb + step * i );
CGAL::Object o; CGAL::Object o;
CGAL::Oneset_iterator< CGAL::Object > oi( o ); CGAL::Oneset_iterator< CGAL::Object > oi( o );
Intersect_2 intersect = traits.intersect_2_object( ); Intersect_2 intersect = traits.intersect_2_object( );
intersect( c1, c2, oi ); intersect( c1, c2, oi );
std::pair< Point_2, Multiplicity > res; std::pair< Point_2, Multiplicity > res;
CGAL::assign( res, o ); CGAL::assign( res, o );
std::pair< double, double > approx = res.first.to_double( ); std::pair< double, double > approx = res.first.to_double( );
std::cout << approx.first << " " << approx.second << std::endl; std::cout << approx.first << " " << approx.second << std::endl;
} }
return 0;
return 0;
} }

View File

@ -6,28 +6,29 @@
#include <CGAL/Arr_walk_along_line_point_location.h> #include <CGAL/Arr_walk_along_line_point_location.h>
#include <CGAL/Object.h> #include <CGAL/Object.h>
typedef CGAL::Gmpq NT; typedef CGAL::Gmpq NT;
typedef CGAL::Cartesian< NT > Kernel; typedef CGAL::Cartesian<NT> Kernel;
typedef CGAL::Arr_linear_traits_2< Kernel > Traits; typedef CGAL::Arr_linear_traits_2<Kernel> Traits;
typedef CGAL::Arr_default_dcel< Traits > Dcel; typedef CGAL::Arr_default_dcel<Traits> Dcel;
typedef CGAL::Arrangement_with_history_2< Traits, Dcel > Arrangement; typedef CGAL::Arrangement_with_history_2< Traits, Dcel> Arrangement;
typedef CGAL::Arr_walk_along_line_point_location< Arrangement > WalkAlongLinePointLocationStrategy; typedef CGAL::Arr_walk_along_line_point_location<Arrangement>
typedef Kernel::Point_2 Point_2; Walk_along_line_pl;
typedef Kernel::Ray_2 Ray_2; typedef Kernel::Point_2 Point_2;
typedef Arrangement::Curve_2 Curve_2; typedef Kernel::Ray_2 Ray_2;
typedef Arrangement::Curve_2 Curve_2;
int main( ) int main( )
{ {
Point_2 p1( 0, 0 ); Point_2 p1(0, 0);
Point_2 p2( 1, 0 ); Point_2 p2(1, 0);
Ray_2 ray( p1, p2 ); Ray_2 ray(p1, p2);
Curve_2 curve( ray ); Curve_2 curve(ray);
Arrangement arr; Arrangement arr;
CGAL::insert( arr, curve ); CGAL::insert(arr, curve);
WalkAlongLinePointLocationStrategy pl( arr ); Walk_along_line_pl pl(arr);
CGAL::Object o = pl.locate( Point_2( 1, -1 ) ); auto o = pl.locate(Point_2(1, -1));
return 0; return 0;
} }

View File

@ -239,19 +239,17 @@ namespace CGAL {
const Point_2& tgt) const; const Point_2& tgt) const;
}; };
/*! Subdivide the given subcurve into x-monotone subcurves and insert them /*! Subdivide a given subcurve into x-monotone subcurves and insert them
* into the given output iterator. Since the subcurves that * into a given output iterator.
* constitute a general polycurve are not necessarily
* \f$x\f$-monotone, this functor may break them.
*/ */
class Make_x_monotone_2 { class Make_x_monotone_2 {
public: public:
/*! /*!
* \pre if `cv` is not empty then it must be continuous and well-oriented. * \pre if `cv` is not empty then it must be continuous and well-oriented.
* \param cv The subcurve. * \param cv the subcurve.
* \param oi The output iterator, whose value-type is Object. The output * \param oi an output iterator for the result. Its value type is a variant
* object is a wrapper of a X_monotone_curve_2 objects. * that wraps Point_2 or an X_monotone_curve_2 objects.
* \return The past-the-end iterator. * \return the past-the-end iterator.
*/ */
template <typename OutputIterator> template <typename OutputIterator>
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const; OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const;

View File

@ -1,57 +1,52 @@
namespace CGAL { namespace CGAL {
/*! /*! \ingroup PkgArrangementOnSurface2Funcs
\ingroup PkgArrangementOnSurface2Funcs *
* Produces the symbolic vertical decomposition of a given arrangement,
Produces the symbolic vertical decomposition of a * performing a batched vertical ray-shooting query from all arrangement
given arrangement, performing a batched vertical ray-shooting query from * vertices, such that every vertex is associated with a pair of objects, one
all arrangement vertices, such that every vertex is associated with a pair * corresponds to the arrangement feature that lies below it, and the other
of objects, one corresponds to the arrangement feature that lies below it, * corresponds to the feature that lies above it. The output of this function
and the other corresponds to the feature that lies above it. * can be readily used for inserting vertical walls and physically decomposing
The output of this function can be readily used for inserting vertical walls * the arrangement into pseudo-trapezoids. To do this, it is convenient to
and physically decomposing the arrangement into pseudo-trapezoids. To do * process the vertices in an ascending \f$ xy\f$-lexicographic order. The
this, it is convenient to process the vertices in an ascending * visible objects are therefore returned through an output iterator, which
\f$ xy\f$-lexicographic order. The visible objects are therefore returned through * pairs each finite arrangement vertex with the two features it "sees", such
an output iterator, which pairs each finite arrangement vertex with the two * that the vertices are given in ascending \f$ xy\f$-lexicographic order.
features it "sees", such that the vertices are given in ascending *
\f$ xy\f$-lexicographic order. * Produces the symbolic vertical decomposition of the `arr` arrangement. More
* precisely, it performs a batched vertical ray-shooting query from all
Produces the symbolic vertical decomposition of the `arr` arrangement. * arrangement vertices, such that every vertex is associated with a pair of
More precisely, it performs a batched vertical ray-shooting query from all * objects, one corresponding to the arrangement feature that lies below it,
arrangement vertices, such that every vertex is associated with a pair of * while the other corresponds to the feature that lies above it. The query
objects, one corresponding to the arrangement feature that lies below it, * results are returned through the output iterator, which pairs each finite
while the other corresponds to the feature that lies above it. * arrangement vertex with a pair of objects, the first represents the feature
The query results are returned through the output iterator, which pairs * below the vertex, and the second represents the feature that lies above
each finite arrangement vertex with a pair of `Object`s, the first * it. Each object is an optional variant that wraps a handle to an arrangement
represents the feature below the vertex, and the second represents the * feature. If the vertex is the top end-vertex of a vertical edge, we say that
feature that lies above it. Each `Object` may be one of the following: * there is no feature below it; similarly, if it is the bottom end-vertex of a
<UL> * vertical edge, we say that there is no feature above it. In these cases the
<LI>`Halfedge_const_handle`, if the vertex is located above (or * optional object is set to be empty; otherwise it is set as follows:
below) an edge. The given halfedge is always directed from right to left. * <UL>
In case there is no concrete edge below (or above) the vertex, and * <LI>`Halfedge_const_handle`, if the vertex is located above (or below) an
the arrangement is unbounded, then the object returned is a * edge. The given halfedge is always directed from right to left. In case
<I>fictitious</I> halfedge. * there is no concrete edge below (or above) the vertex, and the arrangement
<LI>`Face_const_handle`, in case there is no edge below (or above) * is unbounded, then the object returned is a <I>fictitious</I> halfedge.
the vertex, and the arrangement is bounded. * <LI>`Face_const_handle`, in case there is no edge below (or above)
<LI>`Vertex_const_handle`, in case the vertex is located vertically * the vertex, and the arrangement is bounded.
above (or below) another arrangement vertex. * <LI>`Vertex_const_handle`, in case the vertex is located vertically above
<LI>An empty object, in case the vertex is the top end-vertex of * (or below) another arrangement vertex.
a vertical edge, we define there is no feature below it. Similarly, if * </UL> The function returns a past-the-end iterator for its output sequence.
it is the bottom end-vertex of a vertical edge, we define that there *
is no feature above it. * \cgalHeading{Requirements}
</UL> *
The function returns a past-the-end iterator for its output sequence. * `OutputIterator::value_type` must be
* `pair<Arrangement_2::Vertex_const_handle, pair<Object, Object> >`.
\cgalHeading{Requirements} *
*/
`OutputIterator::value_type` must be
`pair<Arrangement_2::Vertex_const_handle, pair<Object, Object> >`.
*/
template<typename Traits, typename Dcel, template<typename Traits, typename Dcel,
typename OutputIterator> typename OutputIterator>
OutputIterator decompose (const Arrangement_2<Traits,Dcel>& arr, OutputIterator decompose (const Arrangement_2<Traits,Dcel>& arr,
OutputIterator oi); OutputIterator oi);
} /* namespace CGAL */ } /* namespace CGAL */

View File

@ -16,18 +16,16 @@ public:
/// A model of this concept must provide: /// A model of this concept must provide:
/// @{ /// @{
/*! /*! subdivides the input curve `c` into \f$ x\f$-monotone subcurves and
subdivides the input curve `c` into \f$ x\f$-monotone subcurves and * isolated points, and inserts the results into a range begining at the
isolated points, and inserts the results into a container through the * given output iterator `oi`. The type `OutputIterator` dereferences a
given output iterator. The value type of `OutputIterator` is * `boost::variant` that wraps either an `ArrTraits::Point_2` object or an
`CGAL::Object`, where each `Object` wraps either an * `ArrTraits::X_monotone_curve_2` object. The operator returns a past-the-end
`ArrTraits::X_monotone_curve_2` object or a `ArrTraits::Point_2` * iterator for the output sequence.
object. The operator returns a past-the-end iterator for the output */
sequence.
*/
template <typename OutputIterator> template <typename OutputIterator>
OutputIterator operator()( ArrTraits::Curve_2 c, OutputIterator operator()(ArrTraits::Curve_2 c,
OutputIterator oi); OutputIterator oi);
/// @} /// @}

View File

@ -25,106 +25,102 @@ typedef CORE::BigInt Integer;
typedef LEDA::integer Integer; typedef LEDA::integer Integer;
#endif #endif
typedef CGAL::Arr_algebraic_segment_traits_2<Integer> Arr_traits_2; typedef CGAL::Arr_algebraic_segment_traits_2<Integer> Arr_traits_2;
typedef CGAL::Arrangement_2<Arr_traits_2> Arrangement_2; typedef CGAL::Arrangement_2<Arr_traits_2> Arrangement_2;
typedef Arr_traits_2::Curve_2 Curve_2; typedef Arr_traits_2::Curve_2 Curve_2;
typedef Arr_traits_2::Polynomial_2 Polynomial_2; typedef Arr_traits_2::Polynomial_2 Polynomial_2;
typedef Arr_traits_2::Algebraic_real_1 Algebraic_real_1; typedef Arr_traits_2::Algebraic_real_1 Algebraic_real_1;
typedef Arr_traits_2::X_monotone_curve_2 X_monotone_curve_2; typedef Arr_traits_2::X_monotone_curve_2 X_monotone_curve_2;
typedef Arr_traits_2::Point_2 Point_2; typedef Arr_traits_2::Point_2 Point_2;
typedef boost::variant<Point_2, X_monotone_curve_2> Make_x_monotone_result;
int main() { int main()
{
Arr_traits_2 arr_traits;
auto construct_curve = arr_traits.construct_curve_2_object();
auto construct_x_monotone_segment =
arr_traits.construct_x_monotone_segment_2_object();
auto construct_point = arr_traits.construct_point_2_object();
auto make_x_monotone = arr_traits.make_x_monotone_2_object();
Arr_traits_2 arr_traits; Arrangement_2 arr(&arr_traits);
Arr_traits_2::Construct_curve_2 construct_curve std::vector<X_monotone_curve_2> segs;
= arr_traits.construct_curve_2_object();
Arr_traits_2::Construct_x_monotone_segment_2 construct_x_monotone_segment
= arr_traits.construct_x_monotone_segment_2_object();
Arr_traits_2::Construct_point_2 construct_point
= arr_traits.construct_point_2_object();
Arr_traits_2::Make_x_monotone_2 make_x_monotone
= arr_traits.make_x_monotone_2_object();
Arrangement_2 arr(&arr_traits); Polynomial_2 x = CGAL::shift(Polynomial_2(1),1,0);
Polynomial_2 y = CGAL::shift(Polynomial_2(1),1,1);
std::vector<X_monotone_curve_2> segs; // Construct x^4+y^3-1
Curve_2 cv0 = construct_curve(CGAL::ipower(x,4)+CGAL::ipower(y,3)-1);
// Construct all x-monotone segments using the Make_x_mononotone functor
std::vector<Make_x_monotone_result> pre_segs;
make_x_monotone(cv0, std::back_inserter(pre_segs));
// Cast all CGAL::Objects into X_monotone_segment_2
// (the vector might also contain Point_2 objects for isolated points,
// but not for this instance
for(size_t i = 0; i < pre_segs.size(); ++i) {
auto* curr_p = boost::get<X_monotone_curve_2>(&pre_segs[i]);;
CGAL_assertion(curr_p);
segs.push_back(*curr_p);
}
// Construct an ellipse with equation 2*x^2+5*y^2-7=0
Curve_2 cv1 = construct_curve(2*CGAL::ipower(x,2)+5*CGAL::ipower(y,2)-7);
Polynomial_2 x = CGAL::shift(Polynomial_2(1),1,0); // Construct point on the upper arc (counting of arc numbers starts with 0!
Polynomial_2 y = CGAL::shift(Polynomial_2(1),1,1); Point_2 p11 = construct_point(Algebraic_real_1(0),cv1,1);
// Construct x^4+y^3-1 construct_x_monotone_segment(cv1,p11,Arr_traits_2::POINT_IN_INTERIOR,
Curve_2 cv0 = construct_curve(CGAL::ipower(x,4)+CGAL::ipower(y,3)-1); std::back_inserter(segs));
// Construct all x-monotone segments using the Make_x_mononotone functor
std::vector<CGAL::Object> pre_segs;
make_x_monotone(cv0,std::back_inserter(pre_segs));
// Cast all CGAL::Objects into X_monotone_segment_2
// (the vector might also contain Point_2 objects for isolated points,
// but not for this instance
for(size_t i = 0; i < pre_segs.size(); i++ ) {
X_monotone_curve_2 curr;
bool check = CGAL::assign(curr,pre_segs[i]);
assert(check); CGAL_USE(check);
segs.push_back(curr);
}
// Construct an ellipse with equation 2*x^2+5*y^2-7=0
Curve_2 cv1 = construct_curve(2*CGAL::ipower(x,2)+5*CGAL::ipower(y,2)-7);
// Construct point on the upper arc (counting of arc numbers starts with 0! // Construct a vertical cusp x^2-y^3=0
Point_2 p11 = construct_point(Algebraic_real_1(0),cv1,1); Curve_2 cv2 = construct_curve(CGAL::ipower(x,2)-CGAL::ipower(y,3));
construct_x_monotone_segment(cv1,p11,Arr_traits_2::POINT_IN_INTERIOR, // Construct a segment containing the cusp point.
// This adds to X_monotone_curve_2 objects to the vector,
// because the cusp is a critical point
Point_2 p21 = construct_point(Algebraic_real_1(-2),cv2,0);
Point_2 p22 = construct_point(Algebraic_real_1(2),cv2,0);
construct_x_monotone_segment(cv2,p21,p22,std::back_inserter(segs));
// Construct an unbounded curve, starting at x=3
Point_2 p23 = construct_point(Algebraic_real_1(3),cv2,0);
construct_x_monotone_segment(cv2,p23,Arr_traits_2::MIN_ENDPOINT,
std::back_inserter(segs)); std::back_inserter(segs));
// Construct a vertical cusp x^2-y^3=0 // Construct another conic: y^2-x^2+1
Curve_2 cv2 = construct_curve(CGAL::ipower(x,2)-CGAL::ipower(y,3)); Curve_2 cv3 = construct_curve(CGAL::ipower(y,2)-CGAL::ipower(x,2)+1);
// Construct a segment containing the cusp point. Point_2 p31 = construct_point(Algebraic_real_1(2),cv3,1);
// This adds to X_monotone_curve_2 objects to the vector, construct_x_monotone_segment(cv3,p31,Arr_traits_2::MAX_ENDPOINT,
// because the cusp is a critical point std::back_inserter(segs));
Point_2 p21 = construct_point(Algebraic_real_1(-2),cv2,0);
Point_2 p22 = construct_point(Algebraic_real_1(2),cv2,0);
construct_x_monotone_segment(cv2,p21,p22,std::back_inserter(segs));
// Construct an unbounded curve, starting at x=3 // Construct a vertical segment
Point_2 p23 = construct_point(Algebraic_real_1(3),cv2,0); Point_2 v1 = construct_point(0,0);
construct_x_monotone_segment(cv2,p23,Arr_traits_2::MIN_ENDPOINT, Point_2 v2 = construct_point(Algebraic_real_1(0),cv1,1);
std::back_inserter(segs)); construct_x_monotone_segment(v1,v2,std::back_inserter(segs));
// Construct another conic: y^2-x^2+1 CGAL::insert(arr,segs.begin(),segs.end());
Curve_2 cv3 = construct_curve(CGAL::ipower(y,2)-CGAL::ipower(x,2)+1);
Point_2 p31 = construct_point(Algebraic_real_1(2),cv3,1); // Add some isolated points (must be wrapped into CGAL::Object)
construct_x_monotone_segment(cv3,p31,Arr_traits_2::MAX_ENDPOINT, std::vector<CGAL::Object> isolated_points;
std::back_inserter(segs)); isolated_points.push_back
(CGAL::make_object(construct_point(Algebraic_real_1(2),cv3,0)));
isolated_points.push_back
(CGAL::make_object(construct_point(Integer(1),Integer(5))));
isolated_points.push_back
(CGAL::make_object(construct_point(Algebraic_real_1(-1),
Algebraic_real_1(5))));
// Construct a vertical segment CGAL::insert(arr,isolated_points.begin(), isolated_points.end());
Point_2 v1 = construct_point(0,0);
Point_2 v2 = construct_point(Algebraic_real_1(0),cv1,1);
construct_x_monotone_segment(v1,v2,std::back_inserter(segs));
CGAL::insert(arr,segs.begin(),segs.end()); // Print the arrangement size.
std::cout << "The arrangement size:" << std::endl
<< " V = " << arr.number_of_vertices()
<< ", E = " << arr.number_of_edges()
<< ", F = " << arr.number_of_faces() << std::endl;
// Add some isolated points (must be wrapped into CGAL::Object) return 0;
std::vector<CGAL::Object> isolated_points;
isolated_points.push_back
(CGAL::make_object(construct_point(Algebraic_real_1(2),cv3,0)));
isolated_points.push_back
(CGAL::make_object(construct_point(Integer(1),Integer(5))));
isolated_points.push_back
(CGAL::make_object(construct_point(Algebraic_real_1(-1),
Algebraic_real_1(5))));
CGAL::insert(arr,isolated_points.begin(), isolated_points.end());
// Print the arrangement size.
std::cout << "The arrangement size:" << std::endl
<< " V = " << arr.number_of_vertices()
<< ", E = " << arr.number_of_edges()
<< ", F = " << arr.number_of_faces() << std::endl;
return 0;
} }
#endif #endif

View File

@ -8,16 +8,20 @@
#include <list> #include <list>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef CGAL::Arr_segment_traits_2<Kernel> Traits_2; typedef CGAL::Arr_segment_traits_2<Kernel> Traits_2;
typedef Traits_2::Point_2 Point_2; typedef Traits_2::Point_2 Point_2;
typedef Traits_2::X_monotone_curve_2 Segment_2; typedef Traits_2::X_monotone_curve_2 Segment_2;
typedef CGAL::Arrangement_2<Traits_2> Arrangement_2; typedef CGAL::Arrangement_2<Traits_2> Arrangement_2;
typedef Arrangement_2::Vertex_const_handle Vertex_const_handle; typedef Arrangement_2::Vertex_const_handle Vertex_const_handle;
typedef Arrangement_2::Halfedge_const_handle Halfedge_const_handle; typedef Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
typedef Arrangement_2::Face_const_handle Face_const_handle; typedef Arrangement_2::Face_const_handle Face_const_handle;
typedef std::pair<CGAL::Object, CGAL::Object> Object_pair;
typedef std::pair<Vertex_const_handle, Object_pair> Vert_decomp_entry; typedef boost::variant<Vertex_const_handle, Halfedge_const_handle,
typedef std::list<Vert_decomp_entry> Vert_decomp_list; Face_const_handle> Cell_type;
typedef boost::optional<Cell_type> Vert_decomp_type;
typedef std::pair<Vert_decomp_type, Vert_decomp_type> Vert_decomp_pair;
typedef std::pair<Vertex_const_handle, Vert_decomp_pair> Vert_decomp_entry;
typedef std::list<Vert_decomp_entry> Vert_decomp_list;
int main() int main()
{ {
@ -39,34 +43,41 @@ int main()
CGAL::decompose(arr, std::back_inserter(vd_list)); CGAL::decompose(arr, std::back_inserter(vd_list));
// Print the results. // Print the results.
Vert_decomp_list::const_iterator vd_iter; for (auto vd_iter = vd_list.begin(); vd_iter != vd_list.end(); ++vd_iter) {
for (vd_iter = vd_list.begin(); vd_iter != vd_list.end(); ++vd_iter) { const Vert_decomp_pair& curr = vd_iter->second;
const Object_pair& curr = vd_iter->second;
std::cout << "Vertex (" << vd_iter->first->point() << ") : "; std::cout << "Vertex (" << vd_iter->first->point() << ") : ";
Vertex_const_handle vh;
Halfedge_const_handle hh;
Face_const_handle fh;
std::cout << " feature below: "; std::cout << " feature below: ";
if (CGAL::assign(hh, curr.first)) if (! curr.first) std::cout << "EMPTY";
std::cout << '[' << hh->curve() << ']'; else {
else if (CGAL::assign(vh, curr.first)) auto* vh = boost::get<Vertex_const_handle>(&*(curr.first));
std::cout << '(' << vh->point() << ')'; if (vh) std::cout << '(' << (*vh)->point() << ')';
else if (CGAL::assign(fh, curr.first)) else {
std::cout << "NONE"; auto* hh = boost::get<Halfedge_const_handle>(&*(curr.first));
else if (hh) std::cout << '[' << (*hh)->curve() << ']';
std::cout << "EMPTY"; else {
auto* fh = boost::get<Face_const_handle>(&*(curr.first));
CGAL_assertion(fh);
std::cout << "NONE (" << (*fh)->is_unbounded() << ")";
}
}
}
std::cout << " feature above: "; std::cout << " feature above: ";
if (CGAL::assign(hh, curr.second)) if (! curr.second) std::cout << "EMPTY" << std::endl;
std::cout << '[' << hh->curve() << ']' << std::endl; else {
else if (CGAL::assign(vh, curr.second)) auto* vh = boost::get<Vertex_const_handle>(&*(curr.second));
std::cout << '(' << vh->point() << ')' << std::endl; if (vh) std::cout << '(' << (*vh)->point() << ')' << std::endl;
else if (CGAL::assign(fh, curr.second)) else {
std::cout << "NONE" << std::endl; auto* hh = boost::get<Halfedge_const_handle>(&*(curr.second));
else if (hh) std::cout << '[' << (*hh)->curve() << ']' << std::endl;
std::cout << "EMPTY" << std::endl; else {
auto* fh = boost::get<Face_const_handle>(&*(curr.second));
CGAL_assertion(fh);
std::cout << "NONE (" << (*fh)->is_unbounded() << ")" << std::endl;
}
}
}
} }
return 0; return 0;

View File

@ -33,16 +33,18 @@ typedef CGAL::Arr_Bezier_curve_traits_2<Rat_kernel, Alg_kernel, Nt_traits>
typedef Bezier_traits::Curve_2 Bezier_curve_2; typedef Bezier_traits::Curve_2 Bezier_curve_2;
typedef Bezier_traits::X_monotone_curve_2 Bezier_x_curve_2; typedef Bezier_traits::X_monotone_curve_2 Bezier_x_curve_2;
typedef CGAL::Arr_polycurve_traits_2<Bezier_traits> Polycurve_bezier_traits_2; typedef CGAL::Arr_polycurve_traits_2<Bezier_traits> Polycurve_bezier_traits_2;
typedef Polycurve_bezier_traits_2::Point_2 Point_2;
typedef Polycurve_bezier_traits_2::X_monotone_curve_2 X_mono_polycurve; typedef Polycurve_bezier_traits_2::X_monotone_curve_2 X_mono_polycurve;
typedef CGAL::Arrangement_2<Polycurve_bezier_traits_2> Arrangement_2; typedef CGAL::Arrangement_2<Polycurve_bezier_traits_2> Arrangement_2;
typedef boost::variant<Point_2, Bezier_x_curve_2> Make_x_monotone_result;
int main() int main()
{ {
Polycurve_bezier_traits_2 pc_traits; Polycurve_bezier_traits_2 pc_traits;
Bezier_traits bezier_traits; Bezier_traits bezier_traits;
Polycurve_bezier_traits_2::Construct_x_monotone_curve_2 auto construct_x_mono_polycurve =
construct_x_mono_polycurve =
pc_traits.construct_x_monotone_curve_2_object(); pc_traits.construct_x_monotone_curve_2_object();
std::vector<Bezier_x_curve_2> x_bezier_curves; std::vector<Bezier_x_curve_2> x_bezier_curves;
@ -69,11 +71,11 @@ int main()
// Read the current curve (specified by its control points). // Read the current curve (specified by its control points).
in_file >> B; in_file >> B;
//convert it into x-monotone bezier curve. //convert it into x-monotone bezier curve.
std::vector<CGAL::Object> obj_vector; std::vector<Make_x_monotone_result> obj_vector;
bezier_traits.make_x_monotone_2_object()(B, std::back_inserter(obj_vector)); bezier_traits.make_x_monotone_2_object()(B, std::back_inserter(obj_vector));
Bezier_x_curve_2 x_seg = auto* x_seg_p = boost::get<Bezier_x_curve_2>(&obj_vector[0]);
CGAL::object_cast<Bezier_x_curve_2>((obj_vector[0])); CGAL_assertion(x_seg_p);
x_curves.push_back(x_seg); x_curves.push_back(*x_seg_p);
} }
X_mono_polycurve polycurve = X_mono_polycurve polycurve =

View File

@ -8,19 +8,22 @@
#include <CGAL/Arr_vertical_decomposition_2.h> #include <CGAL/Arr_vertical_decomposition_2.h>
#include <list> #include <list>
typedef CGAL::MP_Float Number_type; typedef CGAL::MP_Float Number_type;
typedef CGAL::Cartesian<Number_type> Kernel; typedef CGAL::Cartesian<Number_type> Kernel;
typedef CGAL::Arr_linear_traits_2<Kernel> Traits_2; typedef CGAL::Arr_linear_traits_2<Kernel> Traits_2;
typedef Traits_2::Point_2 Point_2; typedef Traits_2::Point_2 Point_2;
typedef Traits_2::X_monotone_curve_2 Segment_2; typedef Traits_2::X_monotone_curve_2 Segment_2;
typedef CGAL::Arrangement_2<Traits_2> Arrangement_2; typedef CGAL::Arrangement_2<Traits_2> Arrangement_2;
typedef Arrangement_2::Vertex_const_handle Vertex_const_handle; typedef Arrangement_2::Vertex_const_handle Vertex_const_handle;
typedef Arrangement_2::Halfedge_const_handle Halfedge_const_handle; typedef Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
typedef Arrangement_2::Face_const_handle Face_const_handle; typedef Arrangement_2::Face_const_handle Face_const_handle;
typedef std::pair<Vertex_const_handle, std::pair<CGAL::Object, CGAL::Object> > typedef boost::variant<Vertex_const_handle, Halfedge_const_handle,
Vert_decomp_entry; Face_const_handle> Cell_type;
typedef std::list<Vert_decomp_entry> Vert_decomp_list; typedef boost::optional<Cell_type> Vert_decomp_type;
typedef std::pair<Vert_decomp_type, Vert_decomp_type> Vert_decomp_pair;
typedef std::pair<Vertex_const_handle, Vert_decomp_pair> Vert_decomp_entry;
typedef std::list<Vert_decomp_entry> Vert_decomp_list;
int main () int main ()
{ {
@ -43,37 +46,37 @@ int main ()
CGAL::decompose (arr, std::back_inserter(vd_list)); CGAL::decompose (arr, std::back_inserter(vd_list));
// Print the results. // Print the results.
Vert_decomp_list::const_iterator vd_iter; for (auto vd_iter = vd_list.begin(); vd_iter != vd_list.end(); ++vd_iter) {
std::pair<CGAL::Object, CGAL::Object> curr; const Vert_decomp_pair& curr = vd_iter->second;
Vertex_const_handle vh;
Halfedge_const_handle hh;
Face_const_handle fh;
for (vd_iter = vd_list.begin(); vd_iter != vd_list.end(); ++vd_iter) {
curr = vd_iter->second;
std::cout << "Vertex (" << vd_iter->first->point() << ") : "; std::cout << "Vertex (" << vd_iter->first->point() << ") : ";
std::cout << " feature below: "; std::cout << " feature below: ";
if (CGAL::assign (vh, curr.first)) if (! curr.first) std::cout << "EMPTY";
std::cout << '(' << vh->point() << ')'; else {
else if (CGAL::assign (hh, curr.first)) auto* vh = boost::get<Vertex_const_handle>(&*(curr.first));;
if (!hh->is_fictitious()) if (vh) std::cout << '(' << (*vh)->point() << ')';
std::cout << '[' << hh->curve() << ']'; else {
else auto* hh = boost::get<Halfedge_const_handle>(&*(curr.first));
std::cout << "NONE"; CGAL_assertion(hh);
else if (! (*hh)->is_fictitious())
std::cout << "EMPTY"; std::cout << '[' << (*hh)->curve() << ']';
else std::cout << "NONE";
}
}
std::cout << " feature above: "; std::cout << " feature above: ";
if (CGAL::assign (vh, curr.second)) if (! curr.second) std::cout << "EMPTY" << std::endl;
std::cout << '(' << vh->point() << ')' << std::endl; else {
else if (CGAL::assign (hh, curr.second)) auto* vh = boost::get<Vertex_const_handle>(&*(curr.second));;
if (!hh->is_fictitious()) if (vh) std::cout << '(' << (*vh)->point() << ')' << std::endl;
std::cout << '[' << hh->curve() << ']' << std::endl; else {
else auto* hh = boost::get<Halfedge_const_handle>(&*(curr.second));
std::cout << "NONE" << std::endl; CGAL_assertion(hh);
else if (! (*hh)->is_fictitious())
std::cout << "EMPTY" << std::endl; std::cout << '[' << (*hh)->curve() << ']' << std::endl;
else std::cout << "NONE" << std::endl;
}
}
} }
return 0; return 0;

View File

@ -7,9 +7,9 @@
// $Id$ // $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
// //
// Author(s) : Ron Wein <wein@post.tau.ac.il> // Author(s): Ron Wein <wein@post.tau.ac.il>
// Iddo Hanniel <iddoh@cs.technion.ac.il> // Iddo Hanniel <iddoh@cs.technion.ac.il>
// Waqar Khan <wkhan@mpi-inf.mpg.de> // Waqar Khan <wkhan@mpi-inf.mpg.de>
#ifndef CGAL_ARR_BEZIER_CURVE_TRAITS_2_H #ifndef CGAL_ARR_BEZIER_CURVE_TRAITS_2_H
#define CGAL_ARR_BEZIER_CURVE_TRAITS_2_H #define CGAL_ARR_BEZIER_CURVE_TRAITS_2_H
@ -163,7 +163,7 @@ public:
} }
//@} //@}
/// \name Functor definitions for the arrangement traits. /// \name Basic functor definitions for the arrangement traits
//@{ //@{
/*! \class Compare_x_2 /*! \class Compare_x_2
@ -473,33 +473,34 @@ public:
{ {
return (Equal_2 (p_cache)); return (Equal_2 (p_cache));
} }
//@}
//! \name Intersections, subdivisions, and mergings
//@{
/*! \class Make_x_monotone_2 /*! \class Make_x_monotone_2
* The Make_x_monotone_2 functor. * A functor for subdividing a curve into x-monotone curves.
*/ */
class Make_x_monotone_2 class Make_x_monotone_2 {
{
private: private:
Bezier_cache *p_cache; Bezier_cache* p_cache;
public: public:
/*! Constructor. */ /*! Constructor. */
Make_x_monotone_2 (Bezier_cache *cache) : Make_x_monotone_2(Bezier_cache* cache) : p_cache(cache) {}
p_cache (cache)
{}
/*! /*! Subdivide a given Bezier curve into x-monotone subcurves and insert them
* Cut the given Bezier curve into x-monotone subcurves and insert them * into a given output iterator.
* into the given output iterator. * \param cv the curve.
* \param cv The curve. * \param oi an output iterator for the result. Its value type is a variant
* \param oi The output iterator, whose value-type is Object. The returned * that wraps Point_2 or an X_monotone_curve_2 objects.
* objects is a wrapper for an X_monotone_curve_2 object. * \return the past-the-end iterator.
* \return The past-the-end iterator.
*/ */
template<class OutputIterator> template <typename OutputIterator>
OutputIterator operator() (const Curve_2& B, OutputIterator oi) const OutputIterator operator() (const Curve_2& B, OutputIterator oi) const
{ {
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
typedef typename Bounding_traits::Vertical_tangency_point typedef typename Bounding_traits::Vertical_tangency_point
Vertical_tangency_point; Vertical_tangency_point;
@ -512,20 +513,17 @@ public:
std::back_inserter(cpts)); std::back_inserter(cpts));
bound_tr.compute_vertical_tangency_points bound_tr.compute_vertical_tangency_points
(cpts, std::back_inserter (vpt_bounds)); (cpts, std::back_inserter (vpt_bounds));
// Construct Point_2 from bounded tangency points. // Construct Point_2 from bounded tangency points.
std::list<Point_2> vpts; std::list<Point_2> vpts;
bool app_ok = true; bool app_ok = true;
typename std::list<Vertical_tangency_point>::const_iterator iter;
for (iter = vpt_bounds.begin(); iter != vpt_bounds.end(); ++iter) for (auto iter = vpt_bounds.begin(); iter != vpt_bounds.end(); ++iter) {
{
const typename Bounding_traits::Bez_point_bound& bound = iter->bound; const typename Bounding_traits::Bez_point_bound& bound = iter->bound;
const typename Bounding_traits::Bez_point_bbox& bbox = iter->bbox; const typename Bounding_traits::Bez_point_bbox& bbox = iter->bbox;
if (! bound.can_refine) if (! bound.can_refine) {
{
// If we cannot refine the vertical-tangency bound anymore, then // If we cannot refine the vertical-tangency bound anymore, then
// we failed to bound the vertical tangency point. // we failed to bound the vertical tangency point.
// \todo In the future, we might want to use the info. // \todo In the future, we might want to use the info.
@ -534,28 +532,25 @@ public:
} }
// Construct an approximate vertical tangency point. // Construct an approximate vertical tangency point.
Point_2 pt; Point_2 pt;
if (bound.type == Bounding_traits::Bez_point_bound::RATIONAL_PT) if (bound.type == Bounding_traits::Bez_point_bound::RATIONAL_PT) {
{
CGAL_assertion (CGAL::compare (bound.t_min, bound.t_max) == EQUAL); CGAL_assertion (CGAL::compare (bound.t_min, bound.t_max) == EQUAL);
Rational t0 = bound.t_min; Rational t0 = bound.t_min;
pt = Point_2 (B, t0); pt = Point_2 (B, t0);
} }
else else {
{ pt.add_originator(typename Point_2::Originator(B, bound));
pt.add_originator (typename Point_2::Originator(B, bound));
} }
pt.set_bbox (bbox); pt.set_bbox(bbox);
vpts.push_back(pt); vpts.push_back(pt);
} }
// If bounding the approximated vertical-tangency points went fine, // If bounding the approximated vertical-tangency points went fine,
// use these points as endpoint for the x-monotone subcurves. // use these points as endpoint for the x-monotone subcurves.
if (app_ok) if (app_ok) {
{
// Create the x-monotone subcurves with approximate endpoints. // Create the x-monotone subcurves with approximate endpoints.
typename std::list<Point_2>::const_iterator pit; typename std::list<Point_2>::const_iterator pit;
unsigned int xid = 1; // Serial number of the subcurve. unsigned int xid = 1; // Serial number of the subcurve.
@ -563,19 +558,16 @@ public:
// Note: xid is needed in ctr of p0 (and of p1 below), // Note: xid is needed in ctr of p0 (and of p1 below),
// for handling end case of start point == end point. // for handling end case of start point == end point.
for (pit = vpts.begin(); pit != vpts.end(); ++pit) for (pit = vpts.begin(); pit != vpts.end(); ++pit) {
{ *oi++ = Make_x_monotone_result(X_monotone_curve_2(B, xid, p0, *pit,
*oi++ = CGAL::make_object (X_monotone_curve_2 (B, xid, *p_cache));
p0, *pit,
*p_cache));
xid++; xid++;
p0 = *pit; p0 = *pit;
} }
Point_2 p1(B, xid, Rational(1)); // A rational end point. Point_2 p1(B, xid, Rational(1)); // A rational end point.
*oi++ = CGAL::make_object (X_monotone_curve_2 (B, xid, *oi++ = Make_x_monotone_result(X_monotone_curve_2(B, xid, p0, p1,
p0, p1, *p_cache));
*p_cache));
return (oi); return (oi);
} }
@ -583,41 +575,34 @@ public:
// points in an exact manner. We do this by considering all t-values // points in an exact manner. We do this by considering all t-values
// on B(t) = (X(t), Y(t)), such that X'(t) = 0. // on B(t) = (X(t), Y(t)), such that X'(t) = 0.
const typename Bezier_cache::Vertical_tangency_list& const typename Bezier_cache::Vertical_tangency_list&
vt_list = p_cache->get_vertical_tangencies (B.id(), vt_list = p_cache->get_vertical_tangencies(B.id(), B.x_polynomial(),
B.x_polynomial(), B.x_norm());
B.x_norm());
// Create the x-monotone subcurves. // Create the x-monotone subcurves.
Point_2 p1; Point_2 p1;
typename Bezier_cache::Vertical_tangency_iter it; unsigned int xid = 1; // Serial number of the subcurve.
unsigned int xid = 1; // Serial number of the subcurve. Point_2 p0(B, xid, Rational(0));
Point_2 p0 (B, xid, Rational(0));
for (it = vt_list.begin(); it != vt_list.end(); ++it) for (auto it = vt_list.begin(); it != vt_list.end(); ++it) {
{ p1 = Point_2(B, *it);
p1 = Point_2 (B, *it); *oi++ = Make_x_monotone_result(X_monotone_curve_2(B, xid, p0, p1,
*oi++ = CGAL::make_object (X_monotone_curve_2 (B, xid, *p_cache));
p0, p1,
*p_cache));
xid++; xid++;
p0 = p1; p0 = p1;
} }
// Create the final subcurve. // Create the final subcurve.
p1 = Point_2 (B, xid, Rational(1)); p1 = Point_2(B, xid, Rational(1));
*oi++ = CGAL::make_object (X_monotone_curve_2 (B, xid, *oi++ = Make_x_monotone_result(X_monotone_curve_2(B, xid, p0, p1,
p0, p1, *p_cache));
*p_cache)); return oi;
return (oi);
} }
}; };
/*! Get a Make_x_monotone_2 functor object. */ /*! Get a Make_x_monotone_2 functor object. */
Make_x_monotone_2 make_x_monotone_2_object () const Make_x_monotone_2 make_x_monotone_2_object() const
{ { return (Make_x_monotone_2 (p_cache)); }
return (Make_x_monotone_2 (p_cache));
}
/*! \class Split_2 /*! \class Split_2
* The Split_2 functor. * The Split_2 functor.
@ -756,7 +741,6 @@ public:
{ {
return Merge_2(this); return Merge_2(this);
} }
//@} //@}
/// \name Functor definitions for the Boolean set-operation traits. /// \name Functor definitions for the Boolean set-operation traits.

View File

@ -22,6 +22,7 @@
*/ */
#include <CGAL/Arrangement_2/Arr_traits_adaptor_2.h> #include <CGAL/Arrangement_2/Arr_traits_adaptor_2.h>
#include <CGAL/Arr_point_location_result.h>
namespace CGAL { namespace CGAL {
@ -60,6 +61,9 @@ private:
typedef typename Arrangement_2::DInner_ccb DInner_ccb; typedef typename Arrangement_2::DInner_ccb DInner_ccb;
typedef typename Arrangement_2::DIso_vertex DIso_vertex; typedef typename Arrangement_2::DIso_vertex DIso_vertex;
typedef Arr_point_location_result<Arrangement_2> Pl_result;
typedef typename Pl_result::Type Pl_result_type;
private: private:
Arrangement_2* p_arr; // The associated arrangement. Arrangement_2* p_arr; // The associated arrangement.
@ -99,33 +103,29 @@ public:
* This object may wrap a Face_const_handle (the general case), * This object may wrap a Face_const_handle (the general case),
* or a Halfedge_const_handle (in case of an overlap). * or a Halfedge_const_handle (in case of an overlap).
*/ */
CGAL::Object locate_curve_end(const X_monotone_curve_2& cv, Pl_result_type locate_curve_end(const X_monotone_curve_2& cv,
Arr_curve_end ind, Arr_curve_end ind,
Arr_parameter_space ps_x, Arr_parameter_space ps_x,
Arr_parameter_space ps_y) const Arr_parameter_space ps_y) const
{ {
CGAL_precondition((ps_x != ARR_INTERIOR) || (ps_y != ARR_INTERIOR)); CGAL_precondition((ps_x != ARR_INTERIOR) || (ps_y != ARR_INTERIOR));
// Use the topology traits to locate the unbounded curve end. // Use the topology traits to locate the unbounded curve end.
CGAL::Object obj = auto obj = p_arr->topology_traits()->locate_curve_end(cv, ind, ps_x, ps_y);
p_arr->topology_traits()->locate_curve_end(cv, ind, ps_x, ps_y);
// Return a handle to the DCEL feature. // Return a handle to the DCEL feature.
DFace* f; DFace** f_p = boost::get<DFace*>(&obj);
if (CGAL::assign(f, obj)) if (f_p) return (Pl_result::make_result(p_arr->_const_handle_for(*f_p)));
return (CGAL::make_object(p_arr->_const_handle_for(f)));
DHalfedge* he; DHalfedge** he_p = boost::get<DHalfedge*>(&obj);
if (CGAL::assign(he, obj)) if (he_p) return (Pl_result::make_result(p_arr->_const_handle_for(*he_p)));
return (CGAL::make_object(p_arr->_const_handle_for(he)));
DVertex* v; DVertex** v_p = boost::get<DVertex*>(&obj);
if (CGAL::assign(v, obj)) if (v_p) return (Pl_result::make_result(p_arr->_const_handle_for(*v_p)));
return (CGAL::make_object(p_arr->_const_handle_for(v)));
// We should never reach here: // We should never reach here:
CGAL_error(); CGAL_error();
return Object(); return Pl_result::make_result(Vertex_const_handle());
} }
/*! /*!

View File

@ -8,7 +8,7 @@
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
// //
// //
// Author(s) : Michael Kerber <mkerber@mpi-inf.mpg.de> // Author(s): Michael Kerber <mkerber@mpi-inf.mpg.de>
// //
// ============================================================================ // ============================================================================
@ -264,138 +264,141 @@ public:
} }
template<typename OutputIterator> OutputIterator template <typename OutputIterator> OutputIterator
x_monotone_segment (Curve_2 cv, x_monotone_segment(Curve_2 cv,
Point_2 p, Point_2 p,
boost::optional<Point_2> start, boost::optional<Point_2> start,
boost::optional<Point_2> end, boost::optional<Point_2> end,
OutputIterator out) const { OutputIterator out) const
{
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
//CGAL_assertion(is_one_one(cv,p));
//CGAL_assertion(is_one_one(cv,p)); std::list<X_monotone_curve_2> segs;
std::list<X_monotone_curve_2> segs; Is_on_2 on_arc = this->_ckva()->is_on_2_object();
auto left = this->_ckva()->construct_min_vertex_2_object();
Is_on_2 on_arc auto right = this->_ckva()->construct_max_vertex_2_object();
= this->_ckva()->is_on_2_object(); Equal_2 equal = this->_ckva()->equal_2_object();
Construct_min_vertex_2 left
= this->_ckva()->construct_min_vertex_2_object();
Construct_max_vertex_2 right
= this->_ckva()->construct_max_vertex_2_object();
Equal_2 equal = this->_ckva()->equal_2_object();
std::vector<CGAL::Object> arcs;
this->_ckva()->make_x_monotone_2_object()
(cv,std::back_inserter(arcs));
typename std::vector<CGAL::Object>::const_iterator
it = arcs.begin(),helper;
X_monotone_curve_2 it_seg;
CGAL::assign(it_seg,*it);
while(it!=arcs.end()) {
if( on_arc(p,it_seg) ) {
break;
}
CGAL_assertion(it!=arcs.end());
it++;
CGAL::assign(it_seg,*it);
}
bool left_on_arc = start && on_arc(start.get(),it_seg);
bool right_on_arc = end && on_arc(end.get(),it_seg);
if( left_on_arc && right_on_arc ) {
segs.push_back(it_seg.trim(start.get(),end.get()));
}
if(left_on_arc && (!right_on_arc)) {
if(!it_seg.is_finite(CGAL::ARR_MAX_END) ||
!equal(start.get(),right(it_seg))) {
if(it_seg.is_finite(CGAL::ARR_MIN_END) && equal(start.get(),left(it_seg))) {
segs.push_back(it_seg);
} else {
X_monotone_curve_2 split1,split2;
it_seg.split(start.get(),split1,split2);
segs.push_back(split2);
}
}
}
if((!left_on_arc) && right_on_arc) {
if(!it_seg.is_finite(CGAL::ARR_MIN_END) ||
! equal(left(it_seg),end.get())) {
if(it_seg.is_finite(CGAL::ARR_MAX_END) && equal(end.get(),right(it_seg))) {
segs.push_back(it_seg);
} else {
X_monotone_curve_2 split1,split2;
it_seg.split(end.get(),split1,split2);
segs.push_back(split1);
}
}
}
if( (!left_on_arc) && (!right_on_arc)) {
segs.push_back(it_seg);
}
helper=it; // for later usage
if(! left_on_arc) {
Point_2 point_it;
while(true) {
if(it_seg.is_finite(CGAL::ARR_MIN_END) &&
is_one_one(cv,left(it_seg) ) ) {
point_it=left(it_seg);
} else {
CGAL_assertion(! start);
break;
}
CGAL_assertion(it!=arcs.begin());
it--;
CGAL::assign(it_seg,*it);
while(! on_arc(point_it,it_seg)) {
CGAL_assertion(it!=arcs.begin());
it--;
CGAL::assign(it_seg,*it);
}
if(start && on_arc(start.get(),it_seg)) {
segs.push_front(it_seg.trim(start.get(),
right(it_seg)));
break;
} else {
segs.push_front(it_seg);
}
}
}
if(! right_on_arc) {
it=helper; // reset
CGAL::assign(it_seg,*it);
Point_2 point_it;
while(true) {
if(it_seg.is_finite(CGAL::ARR_MAX_END) &&
is_one_one(cv,right(it_seg) ) ) {
point_it=right(it_seg);
} else {
CGAL_assertion(! end);
break;
}
it++;
CGAL_assertion(it!=arcs.end());
CGAL::assign(it_seg,*it);
while(! on_arc(point_it,it_seg)) {
it++;
CGAL_assertion(it!=arcs.end());
CGAL::assign(it_seg,*it);
}
if(end && on_arc(end.get(),it_seg)) {
segs.push_back(it_seg.trim(left(it_seg),end.get()));
break;
} else {
segs.push_back(it_seg);
}
}
}
std::copy(segs.begin(),segs.end(),out);
return out;
std::vector<Make_x_monotone_result> arcs;
this->_ckva()->make_x_monotone_2_object()(cv, std::back_inserter(arcs));
auto it = arcs.begin();
auto helper = it;
const auto* it_seg_p = boost::get<X_monotone_curve_2>(&(*it));
while (it != arcs.end()) {
if ( on_arc(p, *it_seg_p) ) break;
it++;
it_seg_p = boost::get<X_monotone_curve_2>(&(*it));
} }
bool left_on_arc = start && on_arc(start.get(), *it_seg_p);
bool right_on_arc = end && on_arc(end.get(), *it_seg_p);
if ( left_on_arc && right_on_arc ) {
segs.push_back(it_seg_p->trim(start.get(),end.get()));
}
if (left_on_arc && (!right_on_arc)) {
if (!it_seg_p->is_finite(CGAL::ARR_MAX_END) ||
!equal(start.get(),right(*it_seg_p))) {
if (it_seg_p->is_finite(CGAL::ARR_MIN_END) &&
equal(start.get(),left(*it_seg_p)))
{
segs.push_back(*it_seg_p);
}
else {
X_monotone_curve_2 split1,split2;
it_seg_p->split(start.get(),split1,split2);
segs.push_back(split2);
}
}
}
if ((!left_on_arc) && right_on_arc) {
if (!it_seg_p->is_finite(CGAL::ARR_MIN_END) ||
! equal(left(*it_seg_p), end.get()))
{
if (it_seg_p->is_finite(CGAL::ARR_MAX_END) &&
equal(end.get(), right(*it_seg_p)))
{
segs.push_back(*it_seg_p);
}
else {
X_monotone_curve_2 split1,split2;
it_seg_p->split(end.get(), split1, split2);
segs.push_back(split1);
}
}
}
if ( (!left_on_arc) && (!right_on_arc)) {
segs.push_back(*it_seg_p);
}
helper = it; // for later usage
if (! left_on_arc) {
Point_2 point_it;
while (true) {
if (it_seg_p->is_finite(CGAL::ARR_MIN_END) &&
is_one_one(cv, left(*it_seg_p) ) ) {
point_it = left(*it_seg_p);
} else {
CGAL_assertion(! start);
break;
}
CGAL_assertion(it != arcs.begin());
it--;
it_seg_p = boost::get<X_monotone_curve_2>(&(*it));
while (! on_arc(point_it, *it_seg_p)) {
CGAL_assertion(it != arcs.begin());
it--;
it_seg_p = boost::get<X_monotone_curve_2>(&(*it));
}
if (start && on_arc(start.get(),*it_seg_p)) {
segs.push_front(it_seg_p->trim(start.get(), right(*it_seg_p)));
break;
}
else {
segs.push_front(*it_seg_p);
}
}
}
if (! right_on_arc) {
it = helper; // reset
it_seg_p = boost::get<X_monotone_curve_2>(&(*it));
Point_2 point_it;
while (true) {
if (it_seg_p->is_finite(CGAL::ARR_MAX_END) &&
is_one_one(cv,right(*it_seg_p) ) )
{
point_it=right(*it_seg_p);
} else {
CGAL_assertion(! end);
break;
}
it++;
CGAL_assertion(it != arcs.end());
it_seg_p = boost::get<X_monotone_curve_2>(&(*it));
while(! on_arc(point_it, *it_seg_p)) {
it++;
CGAL_assertion(it != arcs.end());
it_seg_p = boost::get<X_monotone_curve_2>(&(*it));
}
if(end && on_arc(end.get(),*it_seg_p)) {
segs.push_back(it_seg_p->trim(left(*it_seg_p),end.get()));
break;
}
else {
segs.push_back(*it_seg_p);
}
}
}
std::copy(segs.begin(), segs.end(), out);
return out;
}
public: public:
template<typename OutputIterator> OutputIterator template<typename OutputIterator> OutputIterator

View File

@ -41,11 +41,9 @@ namespace Ss2 = Surface_sweep_2;
* \param oi Output: An output iterator for the query results. * \param oi Output: An output iterator for the query results.
* \pre The value-type of PointsIterator is Arrangement::Point_2, * \pre The value-type of PointsIterator is Arrangement::Point_2,
* and the value-type of OutputIterator is is pair<Point_2, Result>, * and the value-type of OutputIterator is is pair<Point_2, Result>,
* where Result is either * where Result is boost::optional<boost::variant<Vertex_const_handle,
* (i) Object or * Halfedge_const_handle,
* (ii) boost::optional<boost::variant<Vertex_const_handle, * Face_const_handle> >.
* Halfedge_const_handle,
* Face_const_handle> >.
* It represents the arrangement feature containing the point. * It represents the arrangement feature containing the point.
*/ */
template <typename GeometryTraits_2, typename TopologyTraits, template <typename GeometryTraits_2, typename TopologyTraits,

View File

@ -7,14 +7,15 @@
// $Id$ // $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
// //
// // Author(s): Ron Wein <wein@post.tau.ac.il>
// Author(s) : Ron Wein <wein@post.tau.ac.il> // Efi Fogel <efif@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il> // Eric Berberich <ericb@post.tau.ac.il>
// Eric Berberich <ericb@post.tau.ac.il>
#ifndef CGAL_ARR_BOUNDED_PLANAR_TOPOLOGY_TRAITS_2_H #ifndef CGAL_ARR_BOUNDED_PLANAR_TOPOLOGY_TRAITS_2_H
#define CGAL_ARR_BOUNDED_PLANAR_TOPOLOGY_TRAITS_2_H #define CGAL_ARR_BOUNDED_PLANAR_TOPOLOGY_TRAITS_2_H
#include <boost/variant.hpp>
#include <CGAL/license/Arrangement_on_surface_2.h> #include <CGAL/license/Arrangement_on_surface_2.h>
#include <CGAL/disable_warnings.h> #include <CGAL/disable_warnings.h>
@ -306,17 +307,18 @@ public:
* \param ps_x The boundary condition of the curve end in x. * \param ps_x The boundary condition of the curve end in x.
* \param ps_y The boundary condition of the curve end in y. * \param ps_y The boundary condition of the curve end in y.
* \pre The curve has a boundary condition in either x or y. * \pre The curve has a boundary condition in either x or y.
* \return An object that contains the curve end. * \return An object that wraps the curve end.
*/ */
CGAL::Object place_boundary_vertex(Face*, boost::optional<boost::variant<Vertex*, Halfedge*> >
const X_monotone_curve_2&, place_boundary_vertex(Face*,
Arr_curve_end, const X_monotone_curve_2&,
Arr_parameter_space /* ps_x */, Arr_curve_end,
Arr_parameter_space /* ps_y */) Arr_parameter_space /* ps_x */,
Arr_parameter_space /* ps_y */)
{ {
// This function should never be called: // This function should never be called:
CGAL_error(); CGAL_error();
return Object(); return boost::none;
} }
/*! Locate the predecessor halfedge for the given curve around a given /*! Locate the predecessor halfedge for the given curve around a given
@ -349,14 +351,17 @@ public:
* \pre The curve end is incident to the boundary. * \pre The curve end is incident to the boundary.
* \return An object that contains the curve end. * \return An object that contains the curve end.
*/ */
CGAL::Object locate_curve_end(const X_monotone_curve_2&, boost::variant<Vertex*, Halfedge*, Face*>
Arr_curve_end, locate_curve_end(const X_monotone_curve_2&,
Arr_parameter_space /* ps_x */, Arr_curve_end,
Arr_parameter_space /* ps_y */) Arr_parameter_space /* ps_x */,
Arr_parameter_space /* ps_y */)
{ {
typedef boost::variant<Vertex*, Halfedge*, Face*> Result;
// This function should never be called: // This function should never be called:
CGAL_error(); CGAL_error();
return Object(); Vertex* v(nullptr);
return Result(v);
} }
/*! Split a fictitious edge using the given vertex. /*! Split a fictitious edge using the given vertex.

View File

@ -378,46 +378,47 @@ public:
} }
//@} //@}
/// \name Functor definitions for supporting intersections. /// \name Intersections, subdivisions, and mergings
//@{ //@{
class Make_x_monotone_2 /*! \class
{ * A functor for subdividing a curve into x-monotone curves.
*/
class Make_x_monotone_2 {
private: private:
typedef Arr_circle_segment_traits_2<Kernel_, Filter> Self; typedef Arr_circle_segment_traits_2<Kernel_, Filter> Self;
bool m_use_cache; bool m_use_cache;
public: public:
Make_x_monotone_2(bool use_cache = false) : m_use_cache(use_cache) {}
Make_x_monotone_2(bool use_cache = false) : m_use_cache(use_cache) /*! Subdivide a given circular arc or line segment into x-monotone subcurves
{} * and insert them to a given output iterator.
* \param cv the curve.
/*! * \param oi the output iterator for the result. Its dereference type is a
* Cut the given conic curve (ocv.is_in_x_range (p)r conic arc) into x-monotone subcurves * variant that wraps a \c Point_2 or an \c X_monotone_curve_2
* and insert them to the given output iterator. * objects.
* \param cv The curve. * \return the past-the-end iterator.
* \param oi The output iterator, whose value-type is Object. The returned
* objects are all wrcv.is_in_x_range (p)appers X_monotone_curve_2 objects.
* \return The past-the-end iterator.
*/ */
template<class OutputIterator> template <typename OutputIterator>
OutputIterator operator() (const Curve_2& cv, OutputIterator oi) const OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const
{ {
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
// Increment the serial number of the curve cv, which will serve as its // Increment the serial number of the curve cv, which will serve as its
// unique identifier. // unique identifier.
unsigned int index = 0; unsigned int index = 0;
if(m_use_cache) if (m_use_cache) index = Self::get_index();
index = Self::get_index();
if (cv.orientation() == COLLINEAR) if (cv.orientation() == COLLINEAR) {
{
// The curve is a line segment. // The curve is a line segment.
*oi = make_object (X_monotone_curve_2 (cv.supporting_line(), *oi++ = Make_x_monotone_result(X_monotone_curve_2(cv.supporting_line(),
cv.source(), cv.target(), cv.source(),
index)); cv.target(),
++oi; index));
return (oi); return oi;
} }
// Check the case of a degenrate circle (a point). // Check the case of a degenrate circle (a point).
@ -425,12 +426,11 @@ public:
CGAL::Sign sign_rad = CGAL::sign (circ.squared_radius()); CGAL::Sign sign_rad = CGAL::sign (circ.squared_radius());
CGAL_precondition (sign_rad != NEGATIVE); CGAL_precondition (sign_rad != NEGATIVE);
if (sign_rad == ZERO) if (sign_rad == ZERO) {
{
// Create an isolated point. // Create an isolated point.
*oi = make_object (Point_2 (circ.center().x(), circ.center().y())); *oi++ = Make_x_monotone_result(Point_2(circ.center().x(),
++oi; circ.center().y()));
return (oi); return oi;
} }
// The curve is circular: compute the to vertical tangency points // The curve is circular: compute the to vertical tangency points
@ -438,84 +438,73 @@ public:
Point_2 vpts[2]; Point_2 vpts[2];
unsigned int n_vpts = cv.vertical_tangency_points (vpts); unsigned int n_vpts = cv.vertical_tangency_points (vpts);
if (cv.is_full()) if (cv.is_full()) {
{
CGAL_assertion (n_vpts == 2); CGAL_assertion (n_vpts == 2);
// Subdivide the circle into two arcs (an upper and a lower half). // Subdivide the circle into two arcs (an upper and a lower half).
*oi = make_object (X_monotone_curve_2 (circ, *oi++ = Make_x_monotone_result(X_monotone_curve_2(circ,
vpts[0], vpts[1], vpts[0], vpts[1],
cv.orientation(), cv.orientation(),
index)); index));
++oi;
*oi = make_object (X_monotone_curve_2 (circ, *oi++ = Make_x_monotone_result(X_monotone_curve_2(circ,
vpts[1], vpts[0], vpts[1], vpts[0],
cv.orientation(), cv.orientation(),
index)); index));
++oi;
} }
else else {
{
// Act according to the number of vertical tangency points. // Act according to the number of vertical tangency points.
if (n_vpts == 2) if (n_vpts == 2) {
{
// Subdivide the circular arc into three x-monotone arcs. // Subdivide the circular arc into three x-monotone arcs.
*oi = make_object (X_monotone_curve_2 (circ, *oi++ = Make_x_monotone_result(X_monotone_curve_2(circ,
cv.source(), vpts[0], cv.source(), vpts[0],
cv.orientation(), cv.orientation(),
index)); index));
++oi;
*oi = make_object (X_monotone_curve_2 (circ, *oi++ = Make_x_monotone_result(X_monotone_curve_2(circ,
vpts[0], vpts[1], vpts[0], vpts[1],
cv.orientation(), cv.orientation(),
index)); index));
++oi;
*oi = make_object (X_monotone_curve_2 (circ, *oi++ = Make_x_monotone_result(X_monotone_curve_2(circ,
vpts[1], cv.target(), vpts[1],
cv.orientation(), cv.target(),
index)); cv.orientation(),
++oi; index));
} }
else if (n_vpts == 1) else if (n_vpts == 1) {
{
// Subdivide the circular arc into two x-monotone arcs. // Subdivide the circular arc into two x-monotone arcs.
*oi = make_object (X_monotone_curve_2 (circ, *oi++ = Make_x_monotone_result(X_monotone_curve_2(circ,
cv.source(), vpts[0], cv.source(),
cv.orientation(), vpts[0],
index)); cv.orientation(),
++oi; index));
*oi = make_object (X_monotone_curve_2 (circ, *oi++ = Make_x_monotone_result(X_monotone_curve_2(circ,
vpts[0], cv.target(), vpts[0],
cv.orientation(), cv.target(),
index)); cv.orientation(),
++oi; index));
} }
else else {
{ CGAL_assertion(n_vpts == 0);
CGAL_assertion (n_vpts == 0);
// The arc is already x-monotone: // The arc is already x-monotone:
*oi = make_object (X_monotone_curve_2 (circ, *oi++ = Make_x_monotone_result(X_monotone_curve_2(circ,
cv.source(), cv.target(), cv.source(),
cv.orientation(), cv.target(),
index)); cv.orientation(),
++oi; index));
} }
} }
return (oi); return oi;
} }
}; };
/*! Get a Make_x_monotone_2 functor object. */ /*! Get a Make_x_monotone_2 functor object. */
Make_x_monotone_2 make_x_monotone_2_object () const Make_x_monotone_2 make_x_monotone_2_object() const
{ { return Make_x_monotone_2(m_use_cache); }
return Make_x_monotone_2(m_use_cache);
}
class Split_2 class Split_2
{ {

View File

@ -27,6 +27,10 @@
* Arrangement_2 package, which it is now part of. It contains a traits * Arrangement_2 package, which it is now part of. It contains a traits
* class for the arrangement package that handles circular curves. * class for the arrangement package that handles circular curves.
* It is based on the circular kernel. * It is based on the circular kernel.
*
* \todo Fix the circular-kernel make-x-monotone functor to use modern variant
* instead of the legacy CGAL::Object. Then, eliminate the special
* implementation here and directly use the kernel functor instead.
*/ */
#include <CGAL/basic.h> #include <CGAL/basic.h>
@ -109,7 +113,7 @@ public:
typedef unsigned int Multiplicity; typedef unsigned int Multiplicity;
typedef CGAL::Tag_false Has_left_category; typedef CGAL::Tag_false Has_left_category;
typedef CGAL::Tag_false Has_merge_category; typedef CGAL::Tag_false Has_merge_category;
typedef CGAL::Tag_false Has_do_intersect_category; typedef CGAL::Tag_false Has_do_intersect_category;
typedef Arr_oblivious_side_tag Left_side_category; typedef Arr_oblivious_side_tag Left_side_category;
@ -129,7 +133,7 @@ public:
typedef typename CircularKernel::Construct_circular_min_vertex_2 typedef typename CircularKernel::Construct_circular_min_vertex_2
Construct_min_vertex_2; Construct_min_vertex_2;
typedef typename CircularKernel::Equal_2 Equal_2; typedef typename CircularKernel::Equal_2 Equal_2;
typedef typename CircularKernel::Make_x_monotone_2 Make_x_monotone_2; // typedef typename CircularKernel::Make_x_monotone_2 Make_x_monotone_2;
typedef typename CircularKernel::Split_2 Split_2; typedef typename CircularKernel::Split_2 Split_2;
typedef typename CircularKernel::Intersect_2 Intersect_2; typedef typename CircularKernel::Intersect_2 Intersect_2;
typedef typename CircularKernel::Is_vertical_2 Is_vertical_2; typedef typename CircularKernel::Is_vertical_2 Is_vertical_2;
@ -149,8 +153,8 @@ public:
Equal_2 equal_2_object() const Equal_2 equal_2_object() const
{ return ck.equal_2_object(); } { return ck.equal_2_object(); }
Make_x_monotone_2 make_x_monotone_2_object() const // Make_x_monotone_2 make_x_monotone_2_object() const
{ return ck.make_x_monotone_2_object(); } // { return ck.make_x_monotone_2_object(); }
Split_2 split_2_object() const Split_2 split_2_object() const
{ return ck.split_2_object(); } { return ck.split_2_object(); }
@ -168,6 +172,34 @@ public:
{ return ck.is_vertical_2_object(); } { return ck.is_vertical_2_object(); }
//! A functor for subdividing curves into x-monotone curves.
class Make_x_monotone_2 {
public:
template <typename OutputIterator>
OutputIterator operator()(const Curve_2& arc, OutputIterator oi) const
{
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
std::vector<CGAL::Object> objs;
CircularKernel().make_x_monotone_2_object()(arc, std::back_inserter(objs));
for (const auto& obj : objs) {
if (const auto* p = CGAL::object_cast<Point_2>(&obj)) {
*oi++ = Make_x_monotone_result(*p);
continue;
}
if (const auto* xcv = CGAL::object_cast<X_monotone_curve_2>(&obj)) {
*oi++ = Make_x_monotone_result(*xcv);
continue;
}
CGAL_error();
}
return oi;
}
};
Make_x_monotone_2 make_x_monotone_2_object() const
{ return Make_x_monotone_2(); }
}; };
} // namespace CGAL } // namespace CGAL

View File

@ -27,6 +27,10 @@
* Arrangement_2 package, which it is now part of. It contains a traits * Arrangement_2 package, which it is now part of. It contains a traits
* class for the arrangement package that handles circular and linear curves. * class for the arrangement package that handles circular and linear curves.
* It is based on the circular kernel. * It is based on the circular kernel.
*
* \todo Fix the circular-kernel make-x-monotone functor to use modern variant
* instead of the legacy CGAL::Object. Then, eliminate the special
* implementation here and directly use the kernel functor instead.
*/ */
#include <vector> #include <vector>
@ -39,53 +43,35 @@
namespace CGAL { namespace CGAL {
namespace VariantFunctors{ namespace VariantFunctors{
// Takes an iterator range of Object(Line/Circular_arc), // Takes an iterator range of Object(Line/Circular_arc/Point),
// returns an Object(Variant(Line/Circular_arc)). // returns a variant of Line, Circular_arc, and Point_2.
// Do nothing for Object(Endpoint).
template <class CK, class Arc1, class Arc2, class OutputIterator> template <class CK, class Arc1, class Arc2, class OutputIterator>
OutputIterator OutputIterator
object_to_object_variant(const std::vector<CGAL::Object>& res1, object_to_object_variant(const std::vector<CGAL::Object>& res1,
OutputIterator res2) OutputIterator res2)
{ {
for (std::vector<CGAL::Object>::const_iterator it = res1.begin(); typedef typename CK::Circular_arc_point_2 Point_2;
it != res1.end(); ++it ) { typedef boost::variant<Arc1, Arc2> X_monotone_curve_2;
if (const Arc1 *arc = CGAL::object_cast< Arc1 >(&*it)){ typedef boost::variant<Point_2, X_monotone_curve_2>
boost::variant< Arc1, Arc2 > v = *arc; Make_x_monotone_result;
*res2++ = make_object(v);
for (auto it = res1.begin(); it != res1.end(); ++it) {
if (const Arc1* arc = CGAL::object_cast<Arc1>(&*it)) {
boost::variant<Arc1, Arc2> v = *arc;
*res2++ = Make_x_monotone_result(v);
} }
else if (const Arc2 *line = CGAL::object_cast< Arc2 >(&*it)){ else if (const Arc2* line = CGAL::object_cast<Arc2>(&*it)) {
boost::variant< Arc1, Arc2 > v = *line; boost::variant<Arc1, Arc2> v = *line;
*res2++ = make_object(v); *res2++ = Make_x_monotone_result(v);
} }
else{ else if (const Point_2* p = CGAL::object_cast<Point_2>(&*it)) {
*res2++ = *it; *res2++ = Make_x_monotone_result(*p);
} }
else CGAL_error();
} }
return res2; return res2;
} }
template <class CK, class Arc,
class IntersectionPoint, class XMonotoneCurve,
class InternaType, class OutputIterator>
OutputIterator
object_to_object_variant1(const std::vector<InternaType>& res,
OutputIterator oi)
{
typedef IntersectionPoint Intersection_point;
typedef XMonotoneCurve X_monotone_curve_2;
typedef boost::variant<Intersection_point, X_monotone_curve_2>
Intersection_result;
for (auto it = res.begin(); it != res.end(); ++it) {
if (const Arc* arc = boost::get<Arc>(&*it)) {
X_monotone_curve_2 cv = *arc;
*oi++ = Intersection_result(cv);
}
else *oi++ = Intersection_result(*it);
}
return oi;
}
template <class CircularKernel, class Arc1, class Arc2> template <class CircularKernel, class Arc1, class Arc2>
class Compare_y_to_right_2 class Compare_y_to_right_2
{ {
@ -147,17 +133,12 @@ namespace CGAL {
template <class CircularKernel, class Arc1, class Arc2> template <class CircularKernel, class Arc1, class Arc2>
class Equal_2 class Equal_2
#ifndef CGAL_CFG_MATCHING_BUG_6 : public CircularKernel::Equal_2
: public
CircularKernel::Equal_2
#endif
{ {
public: public:
typedef boost::variant< Arc1, Arc2 > Curve_2; typedef boost::variant< Arc1, Arc2 > Curve_2;
typedef bool result_type; typedef bool result_type;
#ifndef CGAL_CFG_MATCHING_BUG_6
using CircularKernel::Equal_2::operator(); using CircularKernel::Equal_2::operator();
#else
typedef typename CircularKernel::Circular_arc_point_2 typedef typename CircularKernel::Circular_arc_point_2
Circular_arc_point_2; Circular_arc_point_2;
typedef typename CircularKernel::Line_arc_2 Line_arc_2; typedef typename CircularKernel::Line_arc_2 Line_arc_2;
@ -185,8 +166,6 @@ namespace CGAL {
operator() ( const Circular_arc_2 &a0, const Line_arc_2 &a1) const operator() ( const Circular_arc_2 &a0, const Line_arc_2 &a1) const
{ return false; } { return false; }
#endif
result_type result_type
operator()(const Curve_2 &a0, const Curve_2 &a1) const operator()(const Curve_2 &a0, const Curve_2 &a1) const
{ {
@ -259,6 +238,7 @@ namespace CGAL {
}; };
//! A functor for subdividing curves into x-monotone curves.
template <class CircularKernel, class Arc1, class Arc2> template <class CircularKernel, class Arc1, class Arc2>
class Make_x_monotone_2 class Make_x_monotone_2
{ {
@ -268,20 +248,21 @@ namespace CGAL {
template < class OutputIterator,class Not_X_Monotone > template < class OutputIterator,class Not_X_Monotone >
OutputIterator OutputIterator
operator()(const boost::variant<Arc1, Arc2, Not_X_Monotone> &A, OutputIterator res) const operator()(const boost::variant<Arc1, Arc2, Not_X_Monotone> &A,
OutputIterator res) const
{ {
if ( const Arc1* arc1 = boost::get<Arc1>( &A ) ){ if ( const Arc1* arc1 = boost::get<Arc1>( &A ) ) {
std::vector<CGAL::Object> container; std::vector<CGAL::Object> container;
CircularKernel() CircularKernel().
.make_x_monotone_2_object()(*arc1,std::back_inserter(container)); make_x_monotone_2_object()(*arc1,std::back_inserter(container));
return object_to_object_variant<CircularKernel, Arc1, Arc2> return object_to_object_variant<CircularKernel, Arc1, Arc2>
(container, res); (container, res);
} }
else { else {
const Arc2* arc2 = boost::get<Arc2>( &A ); const Arc2* arc2 = boost::get<Arc2>( &A );
std::vector<CGAL::Object> container; std::vector<CGAL::Object> container;
CircularKernel() CircularKernel().
.make_x_monotone_2_object()(*arc2,std::back_inserter(container)); make_x_monotone_2_object()(*arc2,std::back_inserter(container));
return object_to_object_variant<CircularKernel, Arc1, Arc2> return object_to_object_variant<CircularKernel, Arc1, Arc2>
(container, res); (container, res);
} }

View File

@ -448,135 +448,127 @@ public:
} }
//@} //@}
/// \name Functor definitions for supporting intersections. /// \name Intersections, subdivisions, and mergings
//@{ //@{
class Make_x_monotone_2 /*! \class Make_x_monotone_2
{ * A functor for subdividing curves into x-monotone curves.
*/
class Make_x_monotone_2 {
typedef Arr_conic_traits_2 <Rat_kernel_, Alg_kernel_, Nt_traits_> Self; typedef Arr_conic_traits_2 <Rat_kernel_, Alg_kernel_, Nt_traits_> Self;
public:
/*! public:
* Cut the given conic curve (or conic arc) into x-monotone subcurves /*! Subdivide a given conic curve (or conic arc) into x-monotone subcurves
* and insert them to the given output iterator. * and insert them to a given output iterator.
* \param cv The curve. * \param cv the curve.
* \param oi The output iterator, whose value-type is Object. The returned * \param oi the output iterator for the result. Its dereference type is a
* objects are all wrappers X_monotone_curve_2 objects. * variant that wraps a \c Point_2 or an \c X_monotone_curve_2
* \return The past-the-end iterator. * objects.
* \return the past-the-end iterator.
*/ */
template<class OutputIterator> template <typename OutputIterator>
OutputIterator operator() (const Curve_2& cv, OutputIterator oi) const OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const
{ {
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
// Increment the serial number of the curve cv, which will serve as its // Increment the serial number of the curve cv, which will serve as its
// unique identifier. // unique identifier.
unsigned int index = Self::get_index(); auto index = Self::get_index();
Conic_id conic_id (index); Conic_id conic_id(index);
// Find the points of vertical tangency to cv and act accordingly. // Find the points of vertical tangency to cv and act accordingly.
typename Curve_2::Point_2 vtan_ps[2]; typename Curve_2::Point_2 vtan_ps[2];
int n_vtan_ps; int n_vtan_ps;
n_vtan_ps = cv.vertical_tangency_points (vtan_ps); n_vtan_ps = cv.vertical_tangency_points(vtan_ps);
if (n_vtan_ps == 0) if (n_vtan_ps == 0) {
{
// In case the given curve is already x-monotone: // In case the given curve is already x-monotone:
*oi = make_object (X_monotone_curve_2 (cv, conic_id)); *oi++ = Make_x_monotone_result(X_monotone_curve_2(cv, conic_id));
++oi; return oi;
return (oi);
} }
// Split the conic arc into x-monotone sub-curves. // Split the conic arc into x-monotone sub-curves.
if (cv.is_full_conic()) if (cv.is_full_conic()) {
{
// Make sure we have two vertical tangency points. // Make sure we have two vertical tangency points.
CGAL_assertion(n_vtan_ps == 2); CGAL_assertion(n_vtan_ps == 2);
// In case the curve is a full conic, split it into two x-monotone // In case the curve is a full conic, split it into two x-monotone
// arcs, one going from ps[0] to ps[1], and the other from ps[1] to // arcs, one going from ps[0] to ps[1], and the other from ps[1] to
// ps[0]. // ps[0].
*oi = make_object (X_monotone_curve_2 (cv, vtan_ps[0], vtan_ps[1], *oi++ = Make_x_monotone_result(X_monotone_curve_2(cv, vtan_ps[0],
conic_id)); vtan_ps[1],
++oi; conic_id));
*oi = make_object (X_monotone_curve_2 (cv, vtan_ps[1], vtan_ps[0], *oi++ = Make_x_monotone_result(X_monotone_curve_2(cv, vtan_ps[1],
conic_id)); vtan_ps[0],
++oi; conic_id));
} }
else else {
{ if (n_vtan_ps == 1) {
if (n_vtan_ps == 1)
{
// Split the arc into two x-monotone sub-curves: one going from the // Split the arc into two x-monotone sub-curves: one going from the
// arc source to ps[0], and the other from ps[0] to the target. // arc source to ps[0], and the other from ps[0] to the target.
*oi = make_object (X_monotone_curve_2 (cv, cv.source(), vtan_ps[0], *oi++ = Make_x_monotone_result(X_monotone_curve_2(cv, cv.source(),
conic_id)); vtan_ps[0],
++oi; conic_id));
*oi = make_object (X_monotone_curve_2 (cv, vtan_ps[0], cv.target(), *oi++ = Make_x_monotone_result(X_monotone_curve_2(cv, vtan_ps[0],
conic_id)); cv.target(),
++oi; conic_id));
} }
else else {
{ CGAL_assertion(n_vtan_ps == 2);
CGAL_assertion (n_vtan_ps == 2);
// Identify the first point we encounter when going from cv's source // Identify the first point we encounter when going from cv's source
// to its target, and the second point we encounter. Note that the // to its target, and the second point we encounter. Note that the
// two endpoints must both be below the line connecting the two // two endpoints must both be below the line connecting the two
// tangnecy points (or both lies above it). // tangnecy points (or both lies above it).
int ind_first = 0; int ind_first = 0;
int ind_second = 1; int ind_second = 1;
Alg_kernel_ ker; Alg_kernel_ ker;
typename Alg_kernel_::Line_2 line = typename Alg_kernel_::Line_2 line =
ker.construct_line_2_object() (vtan_ps[0], vtan_ps[1]); ker.construct_line_2_object()(vtan_ps[0], vtan_ps[1]);
const Comparison_result start_pos = const Comparison_result start_pos =
ker.compare_y_at_x_2_object() (cv.source(), line); ker.compare_y_at_x_2_object() (cv.source(), line);
const Comparison_result order_vpts = const Comparison_result order_vpts =
ker.compare_x_2_object() (vtan_ps[0], vtan_ps[1]); ker.compare_x_2_object()(vtan_ps[0], vtan_ps[1]);
CGAL_assertion (start_pos != EQUAL && CGAL_assertion(start_pos != EQUAL &&
ker.compare_y_at_x_2_object() (cv.target(), ker.compare_y_at_x_2_object()(cv.target(),
line) == start_pos); line) == start_pos);
CGAL_assertion (order_vpts != EQUAL); CGAL_assertion(order_vpts != EQUAL);
if ((cv.orientation() == COUNTERCLOCKWISE && if (((cv.orientation() == COUNTERCLOCKWISE) &&
start_pos == order_vpts) || (start_pos == order_vpts)) ||
(cv.orientation() == CLOCKWISE && ((cv.orientation() == CLOCKWISE) && (start_pos != order_vpts)))
start_pos != order_vpts))
{ {
ind_first = 1; ind_first = 1;
ind_second = 0; ind_second = 0;
} }
// Split the arc into three x-monotone sub-curves. // Split the arc into three x-monotone sub-curves.
*oi = make_object (X_monotone_curve_2 (cv, *oi++ = Make_x_monotone_result(X_monotone_curve_2(cv, cv.source(),
cv.source(), vtan_ps[ind_first],
vtan_ps[ind_first], conic_id));
conic_id));
++oi;
*oi = make_object (X_monotone_curve_2 (cv, *oi++ = Make_x_monotone_result(X_monotone_curve_2(cv,
vtan_ps[ind_first], vtan_ps[ind_first],
vtan_ps[ind_second], vtan_ps[ind_second],
conic_id)); conic_id));
++oi;
*oi = make_object (X_monotone_curve_2 (cv, *oi++ = Make_x_monotone_result(X_monotone_curve_2(cv,
vtan_ps[ind_second], vtan_ps[ind_second],
cv.target(), cv.target(),
conic_id)); conic_id));
++oi;
} }
} }
return (oi); return oi;
} }
}; };
/*! Get a Make_x_monotone_2 functor object. */ /*! Get a Make_x_monotone_2 functor object. */
Make_x_monotone_2 make_x_monotone_2_object () const Make_x_monotone_2 make_x_monotone_2_object() const
{ { return Make_x_monotone_2(); }
return Make_x_monotone_2();
}
class Split_2 class Split_2
{ {

View File

@ -101,120 +101,120 @@ public:
} }
/*! Obtain the counter of the given operation */ /*! Obtain the counter of the given operation */
unsigned int count(Operation_id id) const size_t count(Operation_id id) const
{ return m_counters[id]; } { return m_counters[id]; }
unsigned int count_compare_x() const size_t count_compare_x() const
{ return m_counters[COMPARE_X_OP]; } { return m_counters[COMPARE_X_OP]; }
unsigned int count_compare_xy() const size_t count_compare_xy() const
{ return m_counters[COMPARE_XY_OP]; } { return m_counters[COMPARE_XY_OP]; }
unsigned int count_construct_min_vertex() const size_t count_construct_min_vertex() const
{ return m_counters[CONSTRUCT_MIN_VERTEX_OP]; } { return m_counters[CONSTRUCT_MIN_VERTEX_OP]; }
unsigned int count_construct_max_vertex() const size_t count_construct_max_vertex() const
{ return m_counters[CONSTRUCT_MAX_VERTEX_OP]; } { return m_counters[CONSTRUCT_MAX_VERTEX_OP]; }
unsigned int count_is_vertical() const size_t count_is_vertical() const
{ return m_counters[IS_VERTICAL_OP]; } { return m_counters[IS_VERTICAL_OP]; }
unsigned int count_compare_y_at_x() const size_t count_compare_y_at_x() const
{ return m_counters[COMPARE_Y_AT_X_OP]; } { return m_counters[COMPARE_Y_AT_X_OP]; }
unsigned int count_equal_points() const size_t count_equal_points() const
{ return m_counters[EQUAL_POINTS_OP]; } { return m_counters[EQUAL_POINTS_OP]; }
unsigned int count_equal_curves() const size_t count_equal_curves() const
{ return m_counters[EQUAL_CURVES_OP]; } { return m_counters[EQUAL_CURVES_OP]; }
unsigned int count_compare_y_at_x_left() const size_t count_compare_y_at_x_left() const
{ return m_counters[COMPARE_Y_AT_X_LEFT_OP]; } { return m_counters[COMPARE_Y_AT_X_LEFT_OP]; }
unsigned int count_compare_y_at_x_right() const size_t count_compare_y_at_x_right() const
{ return m_counters[COMPARE_Y_AT_X_RIGHT_OP]; } { return m_counters[COMPARE_Y_AT_X_RIGHT_OP]; }
unsigned int count_make_x_monotone() const size_t count_make_x_monotone() const
{ return m_counters[MAKE_X_MONOTONE_OP]; } { return m_counters[MAKE_X_MONOTONE_OP]; }
unsigned int count_split() const size_t count_split() const
{ return m_counters[SPLIT_OP]; } { return m_counters[SPLIT_OP]; }
unsigned int count_intersect() const size_t count_intersect() const
{ return m_counters[INTERSECT_OP]; } { return m_counters[INTERSECT_OP]; }
unsigned int count_are_mergeable() const size_t count_are_mergeable() const
{ return m_counters[ARE_MERGEABLE_OP]; } { return m_counters[ARE_MERGEABLE_OP]; }
unsigned int count_merge() const size_t count_merge() const
{ return m_counters[MERGE_OP]; } { return m_counters[MERGE_OP]; }
unsigned int count_construct_opposite() const size_t count_construct_opposite() const
{ return m_counters[CONSTRUCT_OPPOSITE_OP]; } { return m_counters[CONSTRUCT_OPPOSITE_OP]; }
unsigned int count_compare_endpoints_xy() const size_t count_compare_endpoints_xy() const
{ return m_counters[COMPARE_ENDPOINTS_XY_OP]; } { return m_counters[COMPARE_ENDPOINTS_XY_OP]; }
// left-right // left-right
unsigned int count_parameter_space_in_x_curve_end() const size_t count_parameter_space_in_x_curve_end() const
{ return m_counters[PARAMETER_SPACE_IN_X_CURVE_END_OP]; } { return m_counters[PARAMETER_SPACE_IN_X_CURVE_END_OP]; }
unsigned int count_parameter_space_in_x_curve() const size_t count_parameter_space_in_x_curve() const
{ return m_counters[PARAMETER_SPACE_IN_X_CURVE_OP]; } { return m_counters[PARAMETER_SPACE_IN_X_CURVE_OP]; }
unsigned int count_parameter_space_in_x_point() const size_t count_parameter_space_in_x_point() const
{ return m_counters[PARAMETER_SPACE_IN_X_POINT_OP]; } { return m_counters[PARAMETER_SPACE_IN_X_POINT_OP]; }
unsigned int count_is_on_x_identification_point() const size_t count_is_on_x_identification_point() const
{ return m_counters[IS_ON_X_IDENTIFICATION_POINT_OP]; } { return m_counters[IS_ON_X_IDENTIFICATION_POINT_OP]; }
unsigned int count_is_on_x_identification_curve() const size_t count_is_on_x_identification_curve() const
{ return m_counters[IS_ON_X_IDENTIFICATION_CURVE_OP]; } { return m_counters[IS_ON_X_IDENTIFICATION_CURVE_OP]; }
unsigned int count_compare_y_on_boundary() const size_t count_compare_y_on_boundary() const
{ return m_counters[COMPARE_Y_ON_BOUNDARY_OP]; } { return m_counters[COMPARE_Y_ON_BOUNDARY_OP]; }
unsigned int count_compare_y_near_boundary() const size_t count_compare_y_near_boundary() const
{ return m_counters[COMPARE_Y_NEAR_BOUNDARY_OP]; } { return m_counters[COMPARE_Y_NEAR_BOUNDARY_OP]; }
// bottom-top // bottom-top
unsigned int count_parameter_space_in_y_curve_end() const size_t count_parameter_space_in_y_curve_end() const
{ return m_counters[PARAMETER_SPACE_IN_Y_CURVE_END_OP]; } { return m_counters[PARAMETER_SPACE_IN_Y_CURVE_END_OP]; }
unsigned int count_parameter_space_in_y_curve() const size_t count_parameter_space_in_y_curve() const
{ return m_counters[PARAMETER_SPACE_IN_Y_CURVE_OP]; } { return m_counters[PARAMETER_SPACE_IN_Y_CURVE_OP]; }
unsigned int count_parameter_space_in_y_point() const size_t count_parameter_space_in_y_point() const
{ return m_counters[PARAMETER_SPACE_IN_Y_POINT_OP]; } { return m_counters[PARAMETER_SPACE_IN_Y_POINT_OP]; }
unsigned int count_is_on_y_identification_point() const size_t count_is_on_y_identification_point() const
{ return m_counters[IS_ON_Y_IDENTIFICATION_POINT_OP]; } { return m_counters[IS_ON_Y_IDENTIFICATION_POINT_OP]; }
unsigned int count_is_on_y_identification_curve() const size_t count_is_on_y_identification_curve() const
{ return m_counters[IS_ON_Y_IDENTIFICATION_CURVE_OP]; } { return m_counters[IS_ON_Y_IDENTIFICATION_CURVE_OP]; }
unsigned int count_compare_x_at_limit_point_curve_end() const size_t count_compare_x_at_limit_point_curve_end() const
{ return m_counters[COMPARE_X_AT_LIMIT_POINT_CURVE_END_OP]; } { return m_counters[COMPARE_X_AT_LIMIT_POINT_CURVE_END_OP]; }
unsigned int count_compare_x_at_limit_curve_ends() const size_t count_compare_x_at_limit_curve_ends() const
{ return m_counters[COMPARE_X_AT_LIMIT_CURVE_ENDS_OP]; } { return m_counters[COMPARE_X_AT_LIMIT_CURVE_ENDS_OP]; }
unsigned int count_compare_x_near_limit() const size_t count_compare_x_near_limit() const
{ return m_counters[COMPARE_X_NEAR_LIMIT_OP]; } { return m_counters[COMPARE_X_NEAR_LIMIT_OP]; }
unsigned int count_compare_x_on_boundary_points() const size_t count_compare_x_on_boundary_points() const
{ return m_counters[COMPARE_X_ON_BOUNDARY_POINTS_OP]; } { return m_counters[COMPARE_X_ON_BOUNDARY_POINTS_OP]; }
unsigned int count_compare_x_on_boundary_point_curve_end() const size_t count_compare_x_on_boundary_point_curve_end() const
{ return m_counters[COMPARE_X_ON_BOUNDARY_POINT_CURVE_END_OP]; } { return m_counters[COMPARE_X_ON_BOUNDARY_POINT_CURVE_END_OP]; }
unsigned int count_compare_x_on_boundary_curve_ends() const size_t count_compare_x_on_boundary_curve_ends() const
{ return m_counters[COMPARE_X_ON_BOUNDARY_CURVE_ENDS_OP]; } { return m_counters[COMPARE_X_ON_BOUNDARY_CURVE_ENDS_OP]; }
unsigned int count_compare_x_near_boundary() const size_t count_compare_x_near_boundary() const
{ return m_counters[COMPARE_X_NEAR_BOUNDARY_OP]; } { return m_counters[COMPARE_X_NEAR_BOUNDARY_OP]; }
/// \name Types and functors inherited from the base /// \name Types and functors inherited from the base
@ -242,11 +242,11 @@ public:
class Compare_x_2 { class Compare_x_2 {
private: private:
typename Base::Compare_x_2 m_object; typename Base::Compare_x_2 m_object;
unsigned int& m_counter; size_t& m_counter;
public: public:
/*! Construct */ /*! Construct */
Compare_x_2(const Base* base, unsigned int& counter) : Compare_x_2(const Base* base, size_t& counter) :
m_object(base->compare_x_2_object()), m_counter(counter) {} m_object(base->compare_x_2_object()), m_counter(counter) {}
/*! Operate */ /*! Operate */
@ -258,11 +258,11 @@ public:
class Compare_xy_2 { class Compare_xy_2 {
private: private:
typename Base::Compare_xy_2 m_object; typename Base::Compare_xy_2 m_object;
unsigned int& m_counter; size_t& m_counter;
public: public:
/*! Construct */ /*! Construct */
Compare_xy_2(const Base* base, unsigned int& counter) : Compare_xy_2(const Base* base, size_t& counter) :
m_object(base->compare_xy_2_object()), m_counter(counter) {} m_object(base->compare_xy_2_object()), m_counter(counter) {}
/*! Operate */ /*! Operate */
@ -274,11 +274,11 @@ public:
class Construct_min_vertex_2 { class Construct_min_vertex_2 {
private: private:
typename Base::Construct_min_vertex_2 m_object; typename Base::Construct_min_vertex_2 m_object;
unsigned int& m_counter; size_t& m_counter;
public: public:
/*! Construct */ /*! Construct */
Construct_min_vertex_2(const Base* base, unsigned int& counter) : Construct_min_vertex_2(const Base* base, size_t& counter) :
m_object(base->construct_min_vertex_2_object()), m_counter(counter) {} m_object(base->construct_min_vertex_2_object()), m_counter(counter) {}
/*! Operate */ /*! Operate */
@ -290,11 +290,11 @@ public:
class Construct_max_vertex_2 { class Construct_max_vertex_2 {
private: private:
typename Base::Construct_max_vertex_2 m_object; typename Base::Construct_max_vertex_2 m_object;
unsigned int& m_counter; size_t& m_counter;
public: public:
/*! Construct */ /*! Construct */
Construct_max_vertex_2(const Base* base, unsigned int& counter) : Construct_max_vertex_2(const Base* base, size_t& counter) :
m_object(base->construct_max_vertex_2_object()), m_counter(counter) {} m_object(base->construct_max_vertex_2_object()), m_counter(counter) {}
/*! Operate */ /*! Operate */
@ -306,11 +306,11 @@ public:
class Is_vertical_2 { class Is_vertical_2 {
private: private:
typename Base::Is_vertical_2 m_object; typename Base::Is_vertical_2 m_object;
unsigned int& m_counter; size_t& m_counter;
public: public:
/*! Construct */ /*! Construct */
Is_vertical_2(const Base* base, unsigned int& counter) : Is_vertical_2(const Base* base, size_t& counter) :
m_object(base->is_vertical_2_object()), m_counter(counter) {} m_object(base->is_vertical_2_object()), m_counter(counter) {}
/*! Operate */ /*! Operate */
@ -324,11 +324,11 @@ public:
class Compare_y_at_x_2 { class Compare_y_at_x_2 {
private: private:
typename Base::Compare_y_at_x_2 m_object; typename Base::Compare_y_at_x_2 m_object;
unsigned int& m_counter; size_t& m_counter;
public: public:
/*! Construct */ /*! Construct */
Compare_y_at_x_2(const Base* base, unsigned int& counter) : Compare_y_at_x_2(const Base* base, size_t& counter) :
m_object(base->compare_y_at_x_2_object()), m_counter(counter) {} m_object(base->compare_y_at_x_2_object()), m_counter(counter) {}
/*! Operate */ /*! Operate */
@ -343,12 +343,12 @@ public:
class Equal_2 { class Equal_2 {
private: private:
typename Base::Equal_2 m_object; typename Base::Equal_2 m_object;
unsigned int& m_counter1; size_t& m_counter1;
unsigned int& m_counter2; size_t& m_counter2;
public: public:
/*! Construct */ /*! Construct */
Equal_2(const Base* base, unsigned int& counter1, unsigned int& counter2) : Equal_2(const Base* base, size_t& counter1, size_t& counter2) :
m_object(base->equal_2_object()), m_object(base->equal_2_object()),
m_counter1(counter1), m_counter2(counter2) m_counter1(counter1), m_counter2(counter2)
{} {}
@ -369,11 +369,11 @@ public:
class Compare_y_at_x_left_2 { class Compare_y_at_x_left_2 {
private: private:
typename Base::Compare_y_at_x_left_2 m_object; typename Base::Compare_y_at_x_left_2 m_object;
unsigned int& m_counter; size_t& m_counter;
public: public:
/*! Construct */ /*! Construct */
Compare_y_at_x_left_2(const Base* base, unsigned int& counter) : Compare_y_at_x_left_2(const Base* base, size_t& counter) :
m_object(base->compare_y_at_x_left_2_object()), m_counter(counter) {} m_object(base->compare_y_at_x_left_2_object()), m_counter(counter) {}
/*! Operate */ /*! Operate */
@ -389,11 +389,11 @@ public:
class Compare_y_at_x_right_2 { class Compare_y_at_x_right_2 {
private: private:
typename Base::Compare_y_at_x_right_2 m_object; typename Base::Compare_y_at_x_right_2 m_object;
unsigned int& m_counter; size_t& m_counter;
public: public:
/*! Construct */ /*! Construct */
Compare_y_at_x_right_2(const Base* base, unsigned int& counter) : Compare_y_at_x_right_2(const Base* base, size_t& counter) :
m_object(base->compare_y_at_x_right_2_object()), m_counter(counter) {} m_object(base->compare_y_at_x_right_2_object()), m_counter(counter) {}
/*! Operate */ /*! Operate */
@ -403,19 +403,27 @@ public:
{ ++m_counter; return m_object(xc1, xc2, p); } { ++m_counter; return m_object(xc1, xc2, p); }
}; };
/*! A functor that divides a curve into x-monotone curves. */ /*! \class Make_x_monotone_2
* A functor that subdivides a curve into x-monotone curves.
*/
class Make_x_monotone_2 { class Make_x_monotone_2 {
private: private:
typename Base::Make_x_monotone_2 m_object; typename Base::Make_x_monotone_2 m_object;
unsigned int& m_counter; size_t& m_counter;
public: public:
/*! Construct */ /*! Construct */
Make_x_monotone_2(const Base* base, unsigned int& counter) : Make_x_monotone_2(const Base* base, size_t& counter) :
m_object(base->make_x_monotone_2_object()), m_counter(counter) {} m_object(base->make_x_monotone_2_object()), m_counter(counter) {}
/*! Operate */ /*! Subdivide a given curve into x-monotone subcurves and insert them into
template<class OutputIterator> * a given output iterator.
* \param cv the curve.
* \param oi the output iterator for the result. Its value type is a variant
* that wraps Point_2 or an X_monotone_curve_2 objects.
* \return The past-the-end iterator.
*/
template <typename OutputIterator>
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const
{ ++m_counter; return m_object(cv, oi); } { ++m_counter; return m_object(cv, oi); }
}; };
@ -424,11 +432,11 @@ public:
class Split_2 { class Split_2 {
private: private:
typename Base::Split_2 m_object; typename Base::Split_2 m_object;
unsigned int& m_counter; size_t& m_counter;
public: public:
/*! Construct */ /*! Construct */
Split_2(const Base* base, unsigned int& counter) : Split_2(const Base* base, size_t& counter) :
m_object(base->split_2_object()), m_counter(counter) {} m_object(base->split_2_object()), m_counter(counter) {}
/*! Operate */ /*! Operate */
@ -441,11 +449,11 @@ public:
class Intersect_2 { class Intersect_2 {
private: private:
typename Base::Intersect_2 m_object; typename Base::Intersect_2 m_object;
unsigned int& m_counter; size_t& m_counter;
public: public:
/*! Construct */ /*! Construct */
Intersect_2(const Base* base, unsigned int& counter) : Intersect_2(const Base* base, size_t& counter) :
m_object(base->intersect_2_object()), m_counter(counter) {} m_object(base->intersect_2_object()), m_counter(counter) {}
/*! Operate */ /*! Operate */
@ -460,11 +468,11 @@ public:
class Are_mergeable_2 { class Are_mergeable_2 {
private: private:
typename Base::Are_mergeable_2 m_object; typename Base::Are_mergeable_2 m_object;
unsigned int& m_counter; size_t& m_counter;
public: public:
/*! Construct */ /*! Construct */
Are_mergeable_2(const Base* base, unsigned int& counter) : Are_mergeable_2(const Base* base, size_t& counter) :
m_object(base->are_mergeable_2_object()), m_counter(counter) {} m_object(base->are_mergeable_2_object()), m_counter(counter) {}
/*! Operate */ /*! Operate */
@ -477,11 +485,11 @@ public:
class Merge_2 { class Merge_2 {
private: private:
typename Base::Merge_2 m_object; typename Base::Merge_2 m_object;
unsigned int& m_counter; size_t& m_counter;
public: public:
/*! Construct */ /*! Construct */
Merge_2(const Base* base, unsigned int& counter) : Merge_2(const Base* base, size_t& counter) :
m_object(base->merge_2_object()), m_counter(counter) {} m_object(base->merge_2_object()), m_counter(counter) {}
/*! Operate */ /*! Operate */
@ -495,11 +503,11 @@ public:
class Construct_opposite_2 { class Construct_opposite_2 {
private: private:
typename Base::Construct_opposite_2 m_object; typename Base::Construct_opposite_2 m_object;
unsigned int& m_counter; size_t& m_counter;
public: public:
/*! Construct */ /*! Construct */
Construct_opposite_2(const Base* base, unsigned int& counter) : Construct_opposite_2(const Base* base, size_t& counter) :
m_object(base->construct_opposite_2_object()), m_counter(counter) {} m_object(base->construct_opposite_2_object()), m_counter(counter) {}
/*! Operate */ /*! Operate */
@ -513,11 +521,11 @@ public:
class Compare_endpoints_xy_2 { class Compare_endpoints_xy_2 {
private: private:
typename Base::Compare_endpoints_xy_2 m_object; typename Base::Compare_endpoints_xy_2 m_object;
unsigned int& m_counter; size_t& m_counter;
public: public:
/*! Construct */ /*! Construct */
Compare_endpoints_xy_2(const Base* base, unsigned int& counter) : Compare_endpoints_xy_2(const Base* base, size_t& counter) :
m_object(base->compare_endpoints_xy_2_object()), m_counter(counter) {} m_object(base->compare_endpoints_xy_2_object()), m_counter(counter) {}
/*! Operate */ /*! Operate */
@ -533,14 +541,14 @@ public:
class Parameter_space_in_x_2 { class Parameter_space_in_x_2 {
private: private:
typename Base::Parameter_space_in_x_2 m_object; typename Base::Parameter_space_in_x_2 m_object;
unsigned int& m_counter1; size_t& m_counter1;
unsigned int& m_counter2; size_t& m_counter2;
unsigned int& m_counter3; size_t& m_counter3;
public: public:
/*! Construct */ /*! Construct */
Parameter_space_in_x_2(const Base* base, unsigned int& counter1, Parameter_space_in_x_2(const Base* base, size_t& counter1,
unsigned int& counter2, unsigned int& counter3) : size_t& counter2, size_t& counter3) :
m_object(base->parameter_space_in_x_2_object()), m_object(base->parameter_space_in_x_2_object()),
m_counter1(counter1), m_counter1(counter1),
m_counter2(counter2), m_counter2(counter2),
@ -569,13 +577,13 @@ public:
class Is_on_x_identification_2 { class Is_on_x_identification_2 {
private: private:
typename Base::Is_on_x_identificiation_2 m_object; typename Base::Is_on_x_identificiation_2 m_object;
unsigned int& m_counter1; size_t& m_counter1;
unsigned int& m_counter2; size_t& m_counter2;
public: public:
/*! Construct */ /*! Construct */
Is_on_x_identification_2(const Base* base, Is_on_x_identification_2(const Base* base,
unsigned int& counter1, unsigned int& counter2) : size_t& counter1, size_t& counter2) :
m_object(base->is_on_x_identificiation_2_object()), m_object(base->is_on_x_identificiation_2_object()),
m_counter1(counter1), m_counter1(counter1),
m_counter2(counter2) {} m_counter2(counter2) {}
@ -597,11 +605,11 @@ public:
class Compare_y_on_boundary_2 { class Compare_y_on_boundary_2 {
private: private:
typename Base::Compare_y_on_boundary_2 m_object; typename Base::Compare_y_on_boundary_2 m_object;
unsigned int& m_counter; size_t& m_counter;
public: public:
/*! Construct */ /*! Construct */
Compare_y_on_boundary_2(const Base* base, unsigned int& counter) : Compare_y_on_boundary_2(const Base* base, size_t& counter) :
m_object(base->compare_y_on_boundary_2_object()), m_object(base->compare_y_on_boundary_2_object()),
m_counter(counter) m_counter(counter)
{} {}
@ -617,11 +625,11 @@ public:
class Compare_y_near_boundary_2 { class Compare_y_near_boundary_2 {
private: private:
typename Base::Compare_y_near_boundary_2 m_object; typename Base::Compare_y_near_boundary_2 m_object;
unsigned int& m_counter; size_t& m_counter;
public: public:
/*! Construct */ /*! Construct */
Compare_y_near_boundary_2(const Base* base, unsigned int& counter) : Compare_y_near_boundary_2(const Base* base, size_t& counter) :
m_object(base->compare_y_near_boundary_2_object()), m_counter(counter) {} m_object(base->compare_y_near_boundary_2_object()), m_counter(counter) {}
/*! Operate */ /*! Operate */
@ -639,14 +647,14 @@ public:
class Parameter_space_in_y_2 { class Parameter_space_in_y_2 {
private: private:
typename Base::Parameter_space_in_y_2 m_object; typename Base::Parameter_space_in_y_2 m_object;
unsigned int& m_counter1; size_t& m_counter1;
unsigned int& m_counter2; size_t& m_counter2;
unsigned int& m_counter3; size_t& m_counter3;
public: public:
/*! Construct */ /*! Construct */
Parameter_space_in_y_2(const Base* base, unsigned int& counter1, Parameter_space_in_y_2(const Base* base, size_t& counter1,
unsigned int& counter2, unsigned int& counter3) : size_t& counter2, size_t& counter3) :
m_object(base->parameter_space_in_y_2_object()), m_object(base->parameter_space_in_y_2_object()),
m_counter1(counter1), m_counter1(counter1),
m_counter2(counter2), m_counter2(counter2),
@ -673,13 +681,13 @@ public:
class Is_on_y_identification_2 { class Is_on_y_identification_2 {
private: private:
typename Base::Is_on_y_identificiation_2 m_object; typename Base::Is_on_y_identificiation_2 m_object;
unsigned int& m_counter1; size_t& m_counter1;
unsigned int& m_counter2; size_t& m_counter2;
public: public:
/*! Construct */ /*! Construct */
Is_on_y_identification_2(const Base* base, Is_on_y_identification_2(const Base* base,
unsigned int& counter1, unsigned int& counter2) : size_t& counter1, size_t& counter2) :
m_object(base->is_on_y_identificiation_2_object()), m_object(base->is_on_y_identificiation_2_object()),
m_counter1(counter1), m_counter1(counter1),
m_counter2(counter2) {} m_counter2(counter2) {}
@ -701,13 +709,13 @@ public:
class Compare_x_at_limit_2 { class Compare_x_at_limit_2 {
private: private:
typename Base::Compare_x_at_limit_2 m_object; typename Base::Compare_x_at_limit_2 m_object;
unsigned int& m_counter1; size_t& m_counter1;
unsigned int& m_counter2; size_t& m_counter2;
public: public:
/*! Construct */ /*! Construct */
Compare_x_at_limit_2(const Base* base, Compare_x_at_limit_2(const Base* base,
unsigned int& counter1, unsigned int& counter2) : size_t& counter1, size_t& counter2) :
m_object(base->compare_x_at_limit_2_object()), m_object(base->compare_x_at_limit_2_object()),
m_counter1(counter1), m_counter1(counter1),
m_counter2(counter2) {} m_counter2(counter2) {}
@ -733,11 +741,11 @@ public:
class Compare_x_near_limit_2 { class Compare_x_near_limit_2 {
private: private:
typename Base::Compare_x_near_limit_2 m_object; typename Base::Compare_x_near_limit_2 m_object;
unsigned int& m_counter; size_t& m_counter;
public: public:
/*! Construct */ /*! Construct */
Compare_x_near_limit_2(const Base* base, unsigned int& counter) : Compare_x_near_limit_2(const Base* base, size_t& counter) :
m_object(base->compare_x_near_limit_2_object()), m_object(base->compare_x_near_limit_2_object()),
m_counter(counter) {} m_counter(counter) {}
@ -755,14 +763,14 @@ public:
class Compare_x_on_boundary_2 { class Compare_x_on_boundary_2 {
private: private:
typename Base::Compare_x_on_boundary_2 m_object; typename Base::Compare_x_on_boundary_2 m_object;
unsigned int& m_counter1; size_t& m_counter1;
unsigned int& m_counter2; size_t& m_counter2;
unsigned int& m_counter3; size_t& m_counter3;
public: public:
/*! Construct */ /*! Construct */
Compare_x_on_boundary_2(const Base* base, unsigned int& counter1, Compare_x_on_boundary_2(const Base* base, size_t& counter1,
unsigned int& counter2, unsigned int& counter3 ) : size_t& counter2, size_t& counter3 ) :
m_object(base->compare_x_on_boundary_2_object()), m_object(base->compare_x_on_boundary_2_object()),
m_counter1(counter1), m_counter1(counter1),
m_counter2(counter2), m_counter2(counter2),
@ -794,12 +802,12 @@ public:
class Compare_x_near_boundary_2 { class Compare_x_near_boundary_2 {
private: private:
typename Base::Compare_x_near_boundary_2 m_object; typename Base::Compare_x_near_boundary_2 m_object;
unsigned int& m_counter; size_t& m_counter;
public: public:
/*! Construct */ /*! Construct */
Compare_x_near_boundary_2(const Base* base, Compare_x_near_boundary_2(const Base* base,
unsigned int& counter) : size_t& counter) :
m_object(base->compare_x_near_boundary_2_object()), m_object(base->compare_x_near_boundary_2_object()),
m_counter(counter) {} m_counter(counter) {}
@ -945,12 +953,12 @@ public:
* \param doit indicates whethet to actually inceremnt the counter or not * \param doit indicates whethet to actually inceremnt the counter or not
* \return the counter at the end of the operation * \return the counter at the end of the operation
*/ */
static unsigned int increment(bool doit = true) static size_t increment(bool doit = true)
{ {
#ifdef CGAL_NO_ATOMIC #ifdef CGAL_NO_ATOMIC
static unsigned int counter; static size_t counter;
#else #else
static CGAL::cpp11::atomic<unsigned int> counter; static CGAL::cpp11::atomic<size_t> counter;
#endif #endif
if (doit) ++counter; if (doit) ++counter;
return counter; return counter;
@ -962,7 +970,7 @@ public:
private: private:
/*! The operation counters */ /*! The operation counters */
mutable unsigned int m_counters[NUMBER_OF_OPERATIONS]; mutable size_t m_counters[NUMBER_OF_OPERATIONS];
}; };
template <class Out_stream, class Base_traits> template <class Out_stream, class Base_traits>
@ -971,8 +979,8 @@ Out_stream& operator<<(Out_stream& os,
const Arr_counting_traits_2<Base_traits>& traits) const Arr_counting_traits_2<Base_traits>& traits)
{ {
typedef Arr_counting_traits_2<Base_traits> Traits; typedef Arr_counting_traits_2<Base_traits> Traits;
unsigned int sum = 0; size_t sum = 0;
unsigned int i; size_t i;
for (i = 0; i < Traits::NUMBER_OF_OPERATIONS; ++i) for (i = 0; i < Traits::NUMBER_OF_OPERATIONS; ++i)
sum += traits.count(static_cast<typename Traits::Operation_id>(i)); sum += traits.count(static_cast<typename Traits::Operation_id>(i));
os << "# of COMPARE_X operation = " os << "# of COMPARE_X operation = "

View File

@ -27,8 +27,8 @@
#include <boost/utility/enable_if.hpp> #include <boost/utility/enable_if.hpp>
#include <boost/mpl/has_xxx.hpp> #include <boost/mpl/has_xxx.hpp>
#include <CGAL/Object.h>
#include <CGAL/tags.h> #include <CGAL/tags.h>
#include <CGAL/assertions.h>
#include <CGAL/Arr_tags.h> #include <CGAL/Arr_tags.h>
#include <CGAL/Arr_geometry_traits/Curve_data_aux.h> #include <CGAL/Arr_geometry_traits/Curve_data_aux.h>
@ -101,6 +101,12 @@ public:
/// \name Overriden functors. /// \name Overriden functors.
//@{ //@{
//! \name Intersections & subdivisions
//@{
/*! \class Make_x_monotone_2
* A functor for subdividing a curve into x-monotone curves.
*/
class Make_x_monotone_2 { class Make_x_monotone_2 {
private: private:
const Base_traits_2& m_base; const Base_traits_2& m_base;
@ -109,36 +115,36 @@ public:
/*! Constructor. */ /*! Constructor. */
Make_x_monotone_2(const Base_traits_2& base) : m_base(base) {} Make_x_monotone_2(const Base_traits_2& base) : m_base(base) {}
/*! Cut the given curve into x-monotone subcurves and insert them to the /*! Subdivide a given curve into x-monotone subcurves and insert them into
* given output iterator. As segments are always x_monotone, only one * a given output iterator.
* x-monotone curve will be contained in the iterator. * \param cv the curve.
* \param cv The curve. * \param oi the output iterator for the result. Its value type is a variant
* \param oi The output iterator, whose value-type is X_monotone_curve_2. * that wraps Point_2 or an X_monotone_curve_2 objects.
* \return The past-the-end iterator. * \return the past-the-end iterator.
*/ */
template<typename OutputIterator> template <typename OutputIterator>
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const
{ {
typedef boost::variant<Point_2, Base_x_monotone_curve_2>
Base_make_x_monotone_result;
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
// Make the original curve x-monotone. // Make the original curve x-monotone.
std::list<CGAL::Object> base_objects; std::list<Base_make_x_monotone_result> base_objects;
m_base.make_x_monotone_2_object()(cv, std::back_inserter(base_objects)); m_base.make_x_monotone_2_object()(cv, std::back_inserter(base_objects));
// Attach the data to each of the resulting x-monotone curves. // Attach the data to each of the resulting x-monotone curves.
const Base_x_monotone_curve_2* base_x_curve;
X_monotone_curve_data xdata = Convert()(cv.data()); X_monotone_curve_data xdata = Convert()(cv.data());
for (typename std::list<CGAL::Object>::const_iterator it = for (const auto& base_obj : base_objects) {
base_objects.begin(); it != base_objects.end(); ++it) if (const auto* bxcv = boost::get<Base_x_monotone_curve_2>(&base_obj)) {
{ *oi++ = Make_x_monotone_result(X_monotone_curve_2(*bxcv, xdata));
base_x_curve = object_cast<Base_x_monotone_curve_2>(&(*it)); continue;
if (base_x_curve != nullptr) {
// Current object is an x-monotone curve: Attach data to it.
*oi++ = make_object(X_monotone_curve_2(*base_x_curve, xdata));
}
else {
// Current object is an isolated point: Leave it as is.
CGAL_assertion(object_cast<Point_2>(&(*it)) != nullptr);
*oi++ = *it;
} }
// Current object is an isolated point: Leave it as is.
const auto* bp = boost::get<Point_2>(&base_obj);
CGAL_assertion(bp);
*oi++ = Make_x_monotone_result(*bp);
} }
return oi; return oi;
@ -359,6 +365,8 @@ public:
/*! Obtain a Merge_2 functor object. */ /*! Obtain a Merge_2 functor object. */
Merge_2 merge_2_object() const { return Merge_2(*this); } Merge_2 merge_2_object() const { return Merge_2(*this); }
//@}
class Construct_x_monotone_curve_2 { class Construct_x_monotone_curve_2 {
private: private:
const Base_traits_2& m_base; const Base_traits_2& m_base;

View File

@ -1358,8 +1358,9 @@ public:
/// \name Functor definitions for supporting intersections. /// \name Functor definitions for supporting intersections.
//@{ //@{
/*! A functor that divides an arc into x-monotone arcs. That are, arcs that /*! \class Make_x_monotone_2
* do not cross the identification arc. * A functor for subdividing arcs into x-monotone arcs that do not cross the
* identification arc.
*/ */
class Make_x_monotone_2 { class Make_x_monotone_2 {
protected: protected:
@ -1376,21 +1377,24 @@ public:
friend class Arr_geodesic_arc_on_sphere_traits_2<Kernel>; friend class Arr_geodesic_arc_on_sphere_traits_2<Kernel>;
public: public:
/*! Cut the given curve into x-monotone subcurves and insert them into the /*! Subdivide a given curve into x-monotone subcurves and insert them into
* given output iterator. As spherical_arcs are always x_monotone, only one * a given output iterator. As spherical_arcs are always x_monotone, only
* object will be contained in the iterator. * one object will be contained in the iterator.
* \param xc the curve. * \param xc the curve.
* \param oi the output iterator, whose value-type is Object. The output * \param oi the output iterator for the result. Its dereference type is a
* object is a wrapper of either an X_monotone_curve_2, or - in * variant that wraps a \c Point_2 or an \c X_monotone_curve_2
* case the input spherical_arc is degenerate - a Point_2 object. * objects.
* \return the past-the-end iterator. * \return the past-the-end iterator.
*/ */
template<typename OutputIterator> template <typename OutputIterator>
OutputIterator operator()(const Curve_2& c, OutputIterator oi) const OutputIterator operator()(const Curve_2& c, OutputIterator oi) const
{ {
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
if (c.is_degenerate()) { if (c.is_degenerate()) {
// The spherical_arc is a degenerate point - wrap it with an object: // The spherical_arc is a degenerate point - wrap it with an object:
*oi++ = make_object(c.right()); *oi++ = Make_x_monotone_result(c.right());
return oi; return oi;
} }
@ -1398,7 +1402,7 @@ public:
// The spherical arc is monotone - wrap it with an object: // The spherical arc is monotone - wrap it with an object:
// *oi++ = make_object(X_monotone_curve_2(c)); // *oi++ = make_object(X_monotone_curve_2(c));
const X_monotone_curve_2* xc = &c; const X_monotone_curve_2* xc = &c;
*oi++ = make_object(*xc); *oi++ = Make_x_monotone_result(*xc);
return oi; return oi;
} }
@ -1410,14 +1414,14 @@ public:
const Direction_3& pp = m_traits->pos_pole(); const Direction_3& pp = m_traits->pos_pole();
X_monotone_curve_2 xc1(np, pp, c.normal(), true, true); X_monotone_curve_2 xc1(np, pp, c.normal(), true, true);
X_monotone_curve_2 xc2(pp, np, c.normal(), true, false); X_monotone_curve_2 xc2(pp, np, c.normal(), true, false);
*oi++ = make_object(xc1); *oi++ = Make_x_monotone_result(xc1);
*oi++ = make_object(xc2); *oi++ = Make_x_monotone_result(xc2);
return oi; return oi;
} }
#if defined(CGAL_FULL_X_MONOTONE_GEODESIC_ARC_ON_SPHERE_IS_SUPPORTED) #if defined(CGAL_FULL_X_MONOTONE_GEODESIC_ARC_ON_SPHERE_IS_SUPPORTED)
// The arc is not vertical => break it at the discontinuity arc: // The arc is not vertical => break it at the discontinuity arc:
const X_monotone_curve_2 xc(c.normal()); const X_monotone_curve_2 xc(c.normal());
*oi++ = make_object(xc); *oi++ = Make_x_monotone_result(xc);
#else #else
// Full x-monotone arcs are not supported! // Full x-monotone arcs are not supported!
// Split the arc at the intersection point with the complement of the // Split the arc at the intersection point with the complement of the
@ -1428,8 +1432,8 @@ public:
Direction_3 d2(normal.dz(), 0, -(normal.dx())); Direction_3 d2(normal.dz(), 0, -(normal.dx()));
X_monotone_curve_2 xc1(d1, d2, normal, false, directed_right); X_monotone_curve_2 xc1(d1, d2, normal, false, directed_right);
X_monotone_curve_2 xc2(d2, d1, normal, false, directed_right); X_monotone_curve_2 xc2(d2, d1, normal, false, directed_right);
*oi++ = make_object(xc1); *oi++ = Make_x_monotone_result(xc1);
*oi++ = make_object(xc2); *oi++ = Make_x_monotone_result(xc2);
#endif #endif
return oi; return oi;
} }
@ -1447,16 +1451,16 @@ public:
if (source.is_min_boundary() || target.is_min_boundary()) { if (source.is_min_boundary() || target.is_min_boundary()) {
X_monotone_curve_2 xc1(source, pp, normal, true, true); X_monotone_curve_2 xc1(source, pp, normal, true, true);
X_monotone_curve_2 xc2(pp, target, normal, true, false); X_monotone_curve_2 xc2(pp, target, normal, true, false);
*oi++ = make_object(xc1); *oi++ = Make_x_monotone_result(xc1);
*oi++ = make_object(xc2); *oi++ = Make_x_monotone_result(xc2);
return oi; return oi;
} }
if (source.is_max_boundary() || target.is_max_boundary()) { if (source.is_max_boundary() || target.is_max_boundary()) {
X_monotone_curve_2 xc1(source, np, normal, true, false); X_monotone_curve_2 xc1(source, np, normal, true, false);
X_monotone_curve_2 xc2(np, target, normal, true, true); X_monotone_curve_2 xc2(np, target, normal, true, true);
*oi++ = make_object(xc1); *oi++ = Make_x_monotone_result(xc1);
*oi++ = make_object(xc2); *oi++ = Make_x_monotone_result(xc2);
return oi; return oi;
} }
@ -1476,19 +1480,19 @@ public:
(!plane_is_positive && !s_is_positive)); (!plane_is_positive && !s_is_positive));
const Point_2& pole1 = (ccw) ? pp : np; const Point_2& pole1 = (ccw) ? pp : np;
X_monotone_curve_2 xc1(source, pole1, normal, true, ccw); X_monotone_curve_2 xc1(source, pole1, normal, true, ccw);
*oi++ = make_object(xc1); *oi++ = Make_x_monotone_result(xc1);
if (s_is_positive != t_is_positive) { if (s_is_positive != t_is_positive) {
// Construct 1 more arc: // Construct 1 more arc:
X_monotone_curve_2 xc2(pole1, target, normal, true, !ccw); X_monotone_curve_2 xc2(pole1, target, normal, true, !ccw);
*oi++ = make_object(xc2); *oi++ = Make_x_monotone_result(xc2);
return oi; return oi;
} }
// Construct 2 more arcs: // Construct 2 more arcs:
const Point_2& pole2 = (ccw) ? np : pp; const Point_2& pole2 = (ccw) ? np : pp;
X_monotone_curve_2 xc2(pole1, pole2, normal, true, !ccw); X_monotone_curve_2 xc2(pole1, pole2, normal, true, !ccw);
*oi++ = make_object(xc2); *oi++ = Make_x_monotone_result(xc2);
X_monotone_curve_2 xc3(pole2, target, normal, true, ccw); X_monotone_curve_2 xc3(pole2, target, normal, true, ccw);
*oi++ = make_object(xc3); *oi++ = Make_x_monotone_result(xc3);
return oi; return oi;
} }
@ -1514,8 +1518,8 @@ public:
X_monotone_curve_2 xc1(source, p, normal, false, directed_right); X_monotone_curve_2 xc1(source, p, normal, false, directed_right);
X_monotone_curve_2 xc2(p, target, normal, false, directed_right); X_monotone_curve_2 xc2(p, target, normal, false, directed_right);
*oi++ = make_object(xc1); *oi++ = Make_x_monotone_result(xc1);
*oi++ = make_object(xc2); *oi++ = Make_x_monotone_result(xc2);
return oi; return oi;
} }
}; };

View File

@ -197,49 +197,51 @@ public:
/*! Intersect 2 planes /*! Intersect 2 planes
* \param plane1 the first plane * \param plane1 the first plane
* \param plane2 the second plane * \param plane2 the second plane
* \return a geometric object that represents the intersection. Could be * \return a variant that represents the intersection. It wraps a line of
* the line of intersection, or a plane in case plane1 and plane2 coincide. * intersection or a plane in case plane1 and plane2 coincide.
*/ */
template <class Kernel> template <typname Kernel>
CGAL::Object intersect(const Arr_plane_3<Kernel> & plane1, boost::variant<typename Kernel::Line_3, Arr_plane_3<Kernel> >
intersect(const Arr_plane_3<Kernel> & plane1,
const Arr_plane_3<Kernel> & plane2) const Arr_plane_3<Kernel> & plane2)
{ {
typedef typename Kernel::Point_3 Point_3; typedef typename Kernel::Point_3 Point_3;
typedef typename Kernel::Direction_3 Direction_3; typedef typename Kernel::Direction_3 Direction_3;
typedef typename Kernel::Line_3 Line_3; typedef typename Kernel::Line_3 Line_3;
typedef typename Kernel::FT FT; typedef typename Kernel::FT FT;
typedef boost::variant<Line_3, Arr_plane_3<Kernel> > Intersection_result;
// We know that the plane goes throgh the origin // We know that the plane goes throgh the origin
const FT & a1 = plane1.a(); const FT& a1 = plane1.a();
const FT & b1 = plane1.b(); const FT& b1 = plane1.b();
const FT & c1 = plane1.c(); const FT& c1 = plane1.c();
const FT & a2 = plane2.a(); const FT& a2 = plane2.a();
const FT & b2 = plane2.b(); const FT& b2 = plane2.b();
const FT & c2 = plane2.c(); const FT& c2 = plane2.c();
FT det = a1*b2 - a2*b1; FT det = a1*b2 - a2*b1;
if (det != 0) { if (det != 0) {
Point_3 is_pt = Point_3(0, 0, 0, det); Point_3 is_pt = Point_3(0, 0, 0, det);
Direction_3 is_dir = Direction_3(b1*c2 - c1*b2, a2*c1 - a1*c2, det); Direction_3 is_dir = Direction_3(b1*c2 - c1*b2, a2*c1 - a1*c2, det);
return make_object(Line_3(is_pt, is_dir)); return Intersection_result(Line_3(is_pt, is_dir));
} }
det = a1*c2 - a2*c1; det = a1*c2 - a2*c1;
if (det != 0) { if (det != 0) {
Point_3 is_pt = Point_3(0, 0, 0, det); Point_3 is_pt = Point_3(0, 0, 0, det);
Direction_3 is_dir = Direction_3(c1*b2 - b1*c2, det, a2*b1 - a1*b2); Direction_3 is_dir = Direction_3(c1*b2 - b1*c2, det, a2*b1 - a1*b2);
return make_object(Line_3(is_pt, is_dir)); return Intersection_result(Line_3(is_pt, is_dir));
} }
det = b1*c2 - c1*b2; det = b1*c2 - c1*b2;
if (det != 0) { if (det != 0) {
Point_3 is_pt = Point_3(0, 0, 0, det); Point_3 is_pt = Point_3(0, 0, 0, det);
Direction_3 is_dir = Direction_3(det, c1*a2 - a1*c2, a1*b2 - b1*a2); Direction_3 is_dir = Direction_3(det, c1*a2 - a1*c2, a1*b2 - b1*a2);
return make_object(Line_3(is_pt, is_dir)); return Intersection_result(Line_3(is_pt, is_dir));
} }
// degenerate case // degenerate case
return make_object(plane1); return Intersection_result(plane1);
} }
/*! Compute the image point of the projection of p under an affine /*! Compute the image point of the projection of p under an affine

View File

@ -1262,36 +1262,26 @@ private:
// the intersection of the two skewed bounding boxes. // the intersection of the two skewed bounding boxes.
Bez_point_bbox ipt_bbox; Bez_point_bbox ipt_bbox;
Control_points aux_vec; Control_points aux_vec;
CGAL::Object res;
Point_2 p;
res = f_intersect (skew1a, skew2a); auto res1 = f_intersect(skew1a, skew2a);
if (! assign (p, res)) const Point_2* p1 = boost::get<Point_2>(&*res1);
{ if (! p1) CGAL_error();
CGAL_error(); aux_vec.push_back(*p1);
}
aux_vec.push_back(p);
res = f_intersect (skew1a, skew2b); auto res2 = f_intersect(skew1a, skew2b);
if (! assign(p, res)) const Point_2* p2 = boost::get<Point_2>(&*res2);
{ if (! p2) CGAL_error();
CGAL_error(); aux_vec.push_back(*p2);
}
aux_vec.push_back(p);
res = f_intersect (skew1b, skew2a); auto res3 = f_intersect(skew1b, skew2a);
if (! assign(p, res)) const Point_2* p3 = boost::get<Point_2>(&*res3);
{ if (! p3) CGAL_error();
CGAL_error(); aux_vec.push_back(*p3);
}
aux_vec.push_back(p);
res = f_intersect (skew1b, skew2b); auto res4 = f_intersect (skew1b, skew2b);
if (!assign(p, res)) const Point_2* p4 = boost::get<Point_2>(&*res4);
{ if (! p4) CGAL_error();
CGAL_error(); aux_vec.push_back(*p4);
}
aux_vec.push_back(p);
construct_bbox (aux_vec, ipt_bbox); construct_bbox (aux_vec, ipt_bbox);

View File

@ -27,6 +27,10 @@
* Arrangement_2 package, which it is now part of. It contains a traits * Arrangement_2 package, which it is now part of. It contains a traits
* class for the arrangement package that handles linear curves. * class for the arrangement package that handles linear curves.
* It is based on the circular kernel. * It is based on the circular kernel.
*
* \todo Fix the circular-kernel make-x-monotone functor to use modern variant
* instead of the legacy CGAL::Object. Then, eliminate the special
* implementation here and directly use the kernel functor instead.
*/ */
#include <CGAL/basic.h> #include <CGAL/basic.h>
@ -73,7 +77,7 @@ public:
typedef typename CircularKernel::Compare_y_at_x_2 Compare_y_at_x_2; typedef typename CircularKernel::Compare_y_at_x_2 Compare_y_at_x_2;
typedef typename CircularKernel::Compare_y_to_right_2 Compare_y_at_x_right_2; typedef typename CircularKernel::Compare_y_to_right_2 Compare_y_at_x_right_2;
typedef typename CircularKernel::Equal_2 Equal_2; typedef typename CircularKernel::Equal_2 Equal_2;
typedef typename CircularKernel::Make_x_monotone_2 Make_x_monotone_2; // typedef typename CircularKernel::Make_x_monotone_2 Make_x_monotone_2;
typedef typename CircularKernel::Split_2 Split_2; typedef typename CircularKernel::Split_2 Split_2;
typedef typename CircularKernel::Construct_circular_min_vertex_2 typedef typename CircularKernel::Construct_circular_min_vertex_2
Construct_min_vertex_2; Construct_min_vertex_2;
@ -97,8 +101,8 @@ public:
Equal_2 equal_2_object() const Equal_2 equal_2_object() const
{ return ck.equal_2_object(); } { return ck.equal_2_object(); }
Make_x_monotone_2 make_x_monotone_2_object() const // Make_x_monotone_2 make_x_monotone_2_object() const
{ return ck.make_x_monotone_2_object(); } // { return ck.make_x_monotone_2_object(); }
Split_2 split_2_object() const Split_2 split_2_object() const
{ return ck.split_2_object(); } { return ck.split_2_object(); }
@ -115,7 +119,20 @@ public:
Is_vertical_2 is_vertical_2_object() const Is_vertical_2 is_vertical_2_object() const
{ return ck.is_vertical_2_object();} { return ck.is_vertical_2_object();}
//! A functor for subdividing curves into x-monotone curves.
class Make_x_monotone_2 {
public:
template <typename OutputIterator>
OutputIterator operator()(const Curve_2& line, OutputIterator oi) const
{
typedef boost::variant<Point_2, X_monotone_curve_2> Make_x_monotone_result;
*oi++ = Make_x_monotone_result(line);
return oi;
}
};
Make_x_monotone_2 make_x_monotone_2_object() const
{ return Make_x_monotone_2(); }
}; };
} // namespace CGAL } // namespace CGAL

View File

@ -1239,16 +1239,18 @@ public:
* given output iterator. As segments are always x_monotone, only one * given output iterator. As segments are always x_monotone, only one
* object will be contained in the iterator. * object will be contained in the iterator.
* \param cv The curve. * \param cv The curve.
* \param oi The output iterator, whose value-type is Object. The output * \param oi an output iterator for the result. Its dereference type is a
* object is a wrapper of an X_monotone_curve_2 which is * variant that wraps a \c Point_2 or an \c X_monotone_curve_2
* essentially the same as the input curve. * objects.
* \return The past-the-end iterator. * \return The past-the-end iterator.
*/ */
template <typename OutputIterator> template <typename OutputIterator>
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const
{ {
// Wrap the curve with an object. // Wrap the segment with a variant.
*oi++ = make_object(cv); typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
*oi++ = Make_x_monotone_result(cv);
return oi; return oi;
} }
}; };

View File

@ -7,14 +7,14 @@
// $Id$ // $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
// //
// Author(s) : Efi Fogel <efif@post.tau.ac.il> // Author(s): Efi Fogel <efif@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il> // Ron Wein <wein@post.tau.ac.il>
// (based on old version by: Iddo Hanniel, // (based on old version by: Iddo Hanniel,
// Eyal Flato, // Eyal Flato,
// Oren Nechushtan, // Oren Nechushtan,
// Ester Ezra, // Ester Ezra,
// Shai Hirsch, // Shai Hirsch,
// and Eugene Lipovetsky) // and Eugene Lipovetsky)
#ifndef CGAL_ARR_NON_CACHING_SEGMENT_BASIC_TRAITS_2_H #ifndef CGAL_ARR_NON_CACHING_SEGMENT_BASIC_TRAITS_2_H
#define CGAL_ARR_NON_CACHING_SEGMENT_BASIC_TRAITS_2_H #define CGAL_ARR_NON_CACHING_SEGMENT_BASIC_TRAITS_2_H

View File

@ -113,24 +113,27 @@ public:
// Traits types: // Traits types:
typedef X_monotone_curve_2 Curve_2; typedef X_monotone_curve_2 Curve_2;
/*! \class /*! \class Make_x_monotone_2
* A functor for splitting curves into x-monotone pieces. * A functor for subdividing a curve into x-monotone curves.
*/ */
class Make_x_monotone_2 { class Make_x_monotone_2 {
public: public:
/*! Subdivide a given curve into x-monotone subcurves and insert them into
/*! Cut the given segment into x-monotone subcurves and insert them into * a given output iterator. As segments are always x_monotone, only one
* the given output iterator. As segments are always x_monotone, only one
* x-monotone curve is inserted into the output iterator. * x-monotone curve is inserted into the output iterator.
* \param cv The segment. * \param cv the segment.
* \param oi The output iterator, whose value-type is Object. The output * \param oi the output iterator for the result. Its dereference type is a
* object is a wrapper of an X_monotone_curve_2 object. * variant that wraps a \c Point_2 or an \c X_monotone_curve_2
* \return The past-the-end iterator. * objects.
* \return the past-the-end iterator.
*/ */
template <typename OutputIterator> template <typename OutputIterator>
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const
{ {
*oi++ = make_object(cv); // Wrap the segment with a variant.
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
*oi++ = Make_x_monotone_result(cv);
return oi; return oi;
} }
}; };

View File

@ -42,6 +42,7 @@ public:
typedef typename Base_traits_2::X_monotone_curve_2 Base_x_monotone_curve_2; typedef typename Base_traits_2::X_monotone_curve_2 Base_x_monotone_curve_2;
typedef typename Base_traits_2::Point_2 Base_point_2; typedef typename Base_traits_2::Point_2 Base_point_2;
typedef typename Base_traits_2::Multiplicity Multiplicity;
typedef typename Base_traits_2::Construct_min_vertex_2 typedef typename Base_traits_2::Construct_min_vertex_2
Base_construct_min_vertex_2; Base_construct_min_vertex_2;

View File

@ -56,15 +56,15 @@ Arr_landmarks_point_location<Arr, Gen>::locate(const Point_2& p) const
const Vertex_const_handle* vh; const Vertex_const_handle* vh;
const Halfedge_const_handle* hh; const Halfedge_const_handle* hh;
const Face_const_handle* fh; const Face_const_handle* fh;
if ( ( vh = Result().template assign<Vertex_const_handle>(lm_location_obj) ) ) if ( ( vh = Result().template assign<Vertex_const_handle>(&lm_location_obj) ) )
out_obj = _walk_from_vertex(*vh, p, crossed_edges); out_obj = _walk_from_vertex(*vh, p, crossed_edges);
else if ( ( hh = Result().template assign<Halfedge_const_handle>(lm_location_obj) ) ) else if ( ( hh = Result().template assign<Halfedge_const_handle>(&lm_location_obj) ) )
out_obj = _walk_from_edge(*hh, landmark_point, p, crossed_edges); out_obj = _walk_from_edge(*hh, landmark_point, p, crossed_edges);
else if ( ( fh = Result().template assign<Face_const_handle>(lm_location_obj) ) ) else if ( ( fh = Result().template assign<Face_const_handle>(&lm_location_obj) ) )
out_obj = _walk_from_face(*fh, landmark_point, p, crossed_edges); out_obj = _walk_from_face(*fh, landmark_point, p, crossed_edges);
else CGAL_error_msg("lm_location_obj of an unknown type."); else CGAL_error_msg("lm_location_obj of an unknown type.");
if ( ( fh = Result().template assign<Face_const_handle>(out_obj) ) ) { if ( ( fh = Result().template assign<Face_const_handle>(&out_obj) ) ) {
// If we reached here, we did not locate the query point in any of the // If we reached here, we did not locate the query point in any of the
// holes inside the current face, so we conclude it is contained in this // holes inside the current face, so we conclude it is contained in this
// face. // face.
@ -159,7 +159,7 @@ _walk_from_vertex(Vertex_const_handle nearest_vertex,
if (new_vertex) { if (new_vertex) {
// We found a vertex closer to p; Continue using this vertex. // We found a vertex closer to p; Continue using this vertex.
const Vertex_const_handle* p_vh = const Vertex_const_handle* p_vh =
Result().template assign<Vertex_const_handle>(obj); Result().template assign<Vertex_const_handle>(&obj);
CGAL_assertion(p_vh != nullptr); CGAL_assertion(p_vh != nullptr);
vh = *p_vh; vh = *p_vh;
continue; continue;
@ -167,11 +167,12 @@ _walk_from_vertex(Vertex_const_handle nearest_vertex,
// If p is located on an edge or on a vertex, return the object // If p is located on an edge or on a vertex, return the object
// that wraps this arrangement feature. // that wraps this arrangement feature.
if (Result().template assign<Halfedge_const_handle>(obj) || if (Result().template assign<Halfedge_const_handle>(&obj) ||
Result().template assign<Vertex_const_handle>(obj)) Result().template assign<Vertex_const_handle>(&obj))
return obj; return obj;
const Face_const_handle* p_fh = Result().template assign<Face_const_handle>(obj); const Face_const_handle* p_fh =
Result().template assign<Face_const_handle>(&obj);
if (p_fh) if (p_fh)
// Walk to p from the face we have located: // Walk to p from the face we have located:
return _walk_from_face(*p_fh, vh->point(), p, crossed_edges); return _walk_from_face(*p_fh, vh->point(), p, crossed_edges);

View File

@ -44,10 +44,8 @@ Arr_simple_point_location<Arrangement>::locate(const Point_2& p) const
// Go over arrangement halfedges and check whether one of them contains // Go over arrangement halfedges and check whether one of them contains
// the query point in its interior. // the query point in its interior.
typename Traits_adaptor_2::Is_in_x_range_2 is_in_x_range = auto is_in_x_range = m_geom_traits->is_in_x_range_2_object();
m_geom_traits->is_in_x_range_2_object(); auto cmp_y_at_x = m_geom_traits->compare_y_at_x_2_object();
typename Traits_adaptor_2::Compare_y_at_x_2 cmp_y_at_x =
m_geom_traits->compare_y_at_x_2_object();
typename Arrangement::Edge_const_iterator eit; typename Arrangement::Edge_const_iterator eit;
for (eit = m_arr->edges_begin(); eit != m_arr->edges_end(); ++eit) { for (eit = m_arr->edges_begin(); eit != m_arr->edges_end(); ++eit) {
@ -71,14 +69,14 @@ Arr_simple_point_location<Arrangement>::locate(const Point_2& p) const
// In case the ray-shooting returned a vertex, we have to locate the first // In case the ray-shooting returned a vertex, we have to locate the first
// halfedge whose source vertex is v, rotating clockwise around the vertex // halfedge whose source vertex is v, rotating clockwise around the vertex
// from "6 o'clock", and to return its incident face. // from "6 o'clock", and to return its incident face.
const Vertex_const_handle* vh = Result().template assign<Vertex_const_handle>(obj); const auto* vh = Result::template assign<Vertex_const_handle>(&obj);
if (vh) { if (vh) {
Halfedge_const_handle hh = _first_around_vertex(*vh); Halfedge_const_handle hh = _first_around_vertex(*vh);
Face_const_handle fh = hh->face(); Face_const_handle fh = hh->face();
return make_result(fh); return make_result(fh);
} }
const Halfedge_const_handle* hh = Result().template assign<Halfedge_const_handle>(obj); const auto* hh = Result::template assign<Halfedge_const_handle>(&obj);
if (hh) { if (hh) {
// Make sure that the edge is directed from right to left, so that p // Make sure that the edge is directed from right to left, so that p
// (which lies below it) is contained in its incident face. If necessary, // (which lies below it) is contained in its incident face. If necessary,
@ -288,14 +286,13 @@ Arr_simple_point_location<Arrangement>::_vertical_ray_shoot(const Point_2& p,
if (! optional_empty(optional_obj)) { if (! optional_empty(optional_obj)) {
const Result_type& obj = optional_assign(optional_obj); const Result_type& obj = optional_assign(optional_obj);
const Vertex_const_handle* p_vh = Result().template assign<Vertex_const_handle>(obj); const auto* p_vh = Result::template assign<Vertex_const_handle>(&obj);
if (p_vh) { if (p_vh) {
found_vertex = true; found_vertex = true;
closest_v = *p_vh; closest_v = *p_vh;
} }
else { else {
const Halfedge_const_handle* p_hh = const auto* p_hh = Result::template assign<Halfedge_const_handle>(&obj);
Result().template assign<Halfedge_const_handle>(obj);
CGAL_assertion(p_hh != nullptr); CGAL_assertion(p_hh != nullptr);
found_halfedge = true; found_halfedge = true;
closest_he = *p_hh; closest_he = *p_hh;

View File

@ -618,7 +618,8 @@ _is_in_connected_component (const Point_2& p,
// The current curve is not vertical. Check the query point is in the // The current curve is not vertical. Check the query point is in the
// semi-open x-range (source, target] of this curve and lies below it. // semi-open x-range (source, target] of this curve and lies below it.
if (source_res != EQUAL) { if (source_res != EQUAL) {
if (closest_he == invalid_he || (closest_he->twin() == curr)) { if ((closest_he == invalid_he) ||
(closest_he->twin() == Halfedge_const_handle(curr))) {
// 1. If we have no closests halfedge, we have just found one. // 1. If we have no closests halfedge, we have just found one.
// 2. If the closest halfedge is the twin of our current halfedge, // 2. If the closest halfedge is the twin of our current halfedge,
// we can take our halfedge to be the closest one. This covers the // we can take our halfedge to be the closest one. This covers the
@ -701,7 +702,7 @@ _is_in_connected_component (const Point_2& p,
do { do {
next_non_vert = next_non_vert->next(); next_non_vert = next_non_vert->next();
CGAL_assertion (next_non_vert != curr); CGAL_assertion(next_non_vert != Halfedge_const_handle(curr));
} }
while ((! next_non_vert->is_fictitious() && while ((! next_non_vert->is_fictitious() &&
is_vertical(next_non_vert->curve())) || is_vertical(next_non_vert->curve())) ||

View File

@ -78,32 +78,34 @@ struct Arr_point_location_result {
// lead to conversion overhead, and so we rather go for the real type. // lead to conversion overhead, and so we rather go for the real type.
// Overloads for empty returns are also provided. // Overloads for empty returns are also provided.
#if CGAL_ARR_POINT_LOCATION_VERSION < 2 #if CGAL_ARR_POINT_LOCATION_VERSION < 2
template<typename T> template <typename T>
static static
inline CGAL::Object make_result(T t) { return CGAL::make_object(t); } inline Type make_result(T t) { return CGAL::make_object(t); }
static static
inline CGAL::Object empty_optional_result() { return CGAL::Object(); } inline CGAL::Object empty_optional_result() { return CGAL::Object(); }
template<typename T> template <typename T>
const T* assign(CGAL::Object obj) const { return CGAL::object_cast<T>(&obj); } static
inline const T* assign(const Type* obj) { return CGAL::object_cast<T>(obj); }
#else #else
template<typename T> template <typename T>
static static
inline Type make_result(T t) { return Type(t); } inline Type make_result(T t) { return Type(t); }
inline
static static
boost::optional<Type> empty_optional_result() { return boost::optional<Type>(); } inline boost::optional<Type> empty_optional_result()
{ return boost::optional<Type>(); }
template<typename T> template <typename T>
const T* assign(const Type& obj) const { return boost::get<T>(&obj); } static
inline const T* assign(const Type* obj) { return boost::get<T>(obj); }
#endif // CGAL_ARR_POINT_LOCATION_VERSION < 2 #endif // CGAL_ARR_POINT_LOCATION_VERSION < 2
//this one is only to remove warnings in functions //this one is only to remove warnings in functions
static static
inline Type default_result(){ inline Type default_result(){
CGAL_error_msg("This functions should never have been called!"); CGAL_error_msg("This functions should have never been called!");
return Type(); return Type();
} }
}; };

View File

@ -63,6 +63,7 @@ public:
typedef typename Subcurve_traits_2::Point_2 Point_2; typedef typename Subcurve_traits_2::Point_2 Point_2;
typedef typename Subcurve_traits_2::X_monotone_curve_2 X_monotone_subcurve_2; typedef typename Subcurve_traits_2::X_monotone_curve_2 X_monotone_subcurve_2;
typedef typename Subcurve_traits_2::Multiplicity Multiplicity;
//@} //@}

View File

@ -7,10 +7,10 @@
// $Id$ // $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
// //
// Author(s) : Efi Fogel <efif@post.tau.ac.il> // Author(s): Efi Fogel <efif@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il> // Ron Wein <wein@post.tau.ac.il>
// Dror Atariah <dror.atariah@fu-berlin.de> // Dror Atariah <dror.atariah@fu-berlin.de>
// Waqar Khan <wkhan@mpi-inf.mpg.de> // Waqar Khan <wkhan@mpi-inf.mpg.de>
#ifndef CGAL_ARR_POLYCURVE_TRAITS_2_H #ifndef CGAL_ARR_POLYCURVE_TRAITS_2_H
#define CGAL_ARR_POLYCURVE_TRAITS_2_H #define CGAL_ARR_POLYCURVE_TRAITS_2_H
@ -160,10 +160,8 @@ public:
#ifndef DOXYGEN_RUNNING #ifndef DOXYGEN_RUNNING
class Push_back_2; class Push_back_2;
#endif #endif
/*! \class
* A functor that divides an arc into x-monotone arcs. That are, arcs that //! A functor for subdividing curves into x-monotone curves.
* do not cross the identification arc.
*/
class Make_x_monotone_2 { class Make_x_monotone_2 {
protected: protected:
typedef Arr_polycurve_traits_2<Subcurve_traits_2> Polycurve_traits_2; typedef Arr_polycurve_traits_2<Subcurve_traits_2> Polycurve_traits_2;
@ -176,21 +174,24 @@ public:
m_poly_traits(traits) m_poly_traits(traits)
{} {}
/*! Cut the given curve into x-monotone sub-curves and insert them into the /*! Subdivide a given curve into x-monotone sub-curves and insert them into
* given output iterator. * a given output iterator.
* *
* \pre if `cv` is not empty then it must be continuous and well-oriented. * \pre if `cv` is not empty then it must be continuous and well-oriented.
* \param cv The curve. * \param cv the curve.
* \param oi The output iterator, whose value-type is Object. The output * \param oi an output iterator for the result. Its value type is a variant
* object is a wrapper of a X_monotone_curve_2. * that wraps Point_2 or an X_monotone_curve_2 objects.
* \return The past-the-end iterator. * \return the past-the-end iterator.
*/ */
private: private:
template <typename OutputIterator> template <typename OutputIterator>
OutputIterator operator_impl(const Curve_2& cv, OutputIterator oi, OutputIterator operator_impl(const Curve_2& cv, OutputIterator oi,
Arr_all_sides_oblivious_tag) const Arr_all_sides_oblivious_tag) const
{ {
typedef typename Curve_2::Subcurve_const_iterator const_seg_iterator; typedef boost::variant<Point_2, X_monotone_subcurve_2>
Make_x_monotone_subresult;
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
// If the polycurve is empty, return. // If the polycurve is empty, return.
if (cv.number_of_subcurves() == 0) return oi; if (cv.number_of_subcurves() == 0) return oi;
@ -204,33 +205,29 @@ public:
m_poly_traits.subcurve_traits_2()->compare_endpoints_xy_2_object(); m_poly_traits.subcurve_traits_2()->compare_endpoints_xy_2_object();
#ifdef CGAL_ALWAYS_LEFT_TO_RIGHT #ifdef CGAL_ALWAYS_LEFT_TO_RIGHT
typename Subcurve_traits_2::Construct_opposite_2 ctr_seg_opposite = auto ctr_seg_opposite =
m_poly_traits.subcurve_traits_2()->construct_opposite_2_object(); m_poly_traits.subcurve_traits_2()->construct_opposite_2_object();
#endif #endif
// Convert the input polycurve to a sequence of CGAL objects, such // Convert the input polycurve to a sequence of variant objects, such
// that each Object wraps an x-monotone subcurve. // that each object wraps an x-monotone subcurve.
std::vector<Object> x_seg_objects; std::vector<Make_x_monotone_subresult> x_seg_objects;
const_seg_iterator it_segs; for (auto its = cv.subcurves_begin(); its != cv.subcurves_end(); ++its)
for (it_segs = cv.subcurves_begin(); it_segs != cv.subcurves_end(); make_seg_x_monotone(*its, std::back_inserter(x_seg_objects));
++it_segs) auto it = x_seg_objects.begin();
make_seg_x_monotone(*it_segs, std::back_inserter(x_seg_objects)); const auto* x_seg_p = boost::get<X_monotone_subcurve_2>(&(*it));
typename std::vector<Object>::iterator it = x_seg_objects.begin(); #if ! defined (CGAL_NO_ASSERTIONS)
X_monotone_subcurve_2 x_seg; CGAL_assertion(x_seg_p != nullptr);
#if defined (CGAL_NO_ASSERTIONS)
CGAL::assign(x_seg, *it);
#else
bool assign_res = CGAL::assign(x_seg, *it);
CGAL_assertion(assign_res);
#endif #endif
// If the polycurve consists of a single x-monotone subcurve, return. // If the polycurve consists of a single x-monotone subcurve, return.
if (x_seg_objects.size() == 1) { if (x_seg_objects.size() == 1) {
#ifdef CGAL_ALWAYS_LEFT_TO_RIGHT #ifdef CGAL_ALWAYS_LEFT_TO_RIGHT
if (cmp_seg_endpts(x_seg) == LARGER) if (cmp_seg_endpts(x_seg) == LARGER)
x_seg = ctr_seg_opposite(x_seg); *oi++ = Make_x_monotone_result(ctr_x_curve(ctr_seg_opposite(*x_seg_p))); else *oi++ = Make_x_monotone_result(ctr_x_curve(*x_seg_p));
#else
*oi++ = Make_x_monotone_result(ctr_x_curve(*x_seg_p));
#endif #endif
*oi++ = make_object(ctr_x_curve(x_seg));
x_seg_objects.clear(); x_seg_objects.clear();
return oi; return oi;
} }
@ -244,39 +241,38 @@ public:
auto max_seg_v = auto max_seg_v =
m_poly_traits.subcurve_traits_2()->construct_max_vertex_2_object(); m_poly_traits.subcurve_traits_2()->construct_max_vertex_2_object();
auto equal = m_poly_traits.subcurve_traits_2()->equal_2_object(); auto equal = m_poly_traits.subcurve_traits_2()->equal_2_object();
Point_2 last_target = (cmp_seg_endpts(x_seg) == SMALLER) ? Point_2 last_target = (cmp_seg_endpts(*x_seg_p) == SMALLER) ?
max_seg_v(x_seg) : min_seg_v(x_seg); max_seg_v(*x_seg_p) : min_seg_v(*x_seg_p);
Point_2 next_src; Point_2 next_src;
); );
// The polycurve consists of at least 2 x-monotone subcurves: // The polycurve consists of at least 2 x-monotone subcurves:
Push_back_2 push_back = m_poly_traits.push_back_2_object(); Push_back_2 push_back = m_poly_traits.push_back_2_object();
typename Subcurve_traits_2::Is_vertical_2 is_seg_vertical = auto is_seg_vertical =
m_poly_traits.subcurve_traits_2()->is_vertical_2_object(); m_poly_traits.subcurve_traits_2()->is_vertical_2_object();
bool is_start_vertical = is_seg_vertical(x_seg); bool is_start_vertical = is_seg_vertical(*x_seg_p);
Comparison_result start_dir = cmp_seg_endpts(x_seg); Comparison_result start_dir = cmp_seg_endpts(*x_seg_p);
#ifdef CGAL_ALWAYS_LEFT_TO_RIGHT #ifdef CGAL_ALWAYS_LEFT_TO_RIGHT
Push_front_2 push_front = m_poly_traits.push_front_2_object(); Push_front_2 push_front = m_poly_traits.push_front_2_object();
if (cmp_seg_endpts(x_seg) == LARGER) x_seg = ctr_seg_opposite(x_seg); X_monotone_curve_2 x_polycurve = (cmp_seg_endpts(x_seg) == LARGER) ?
#endif ctr_x_curve(ctr_seg_opposite(*x_seg_p)) : ctr_x_curve(*x_seg_p);
X_monotone_curve_2 x_polycurve = ctr_x_curve(x_seg);
for (++it; it != x_seg_objects.end(); ++it){
X_monotone_subcurve_2 x_seg;
#if defined (CGAL_NO_ASSERTIONS)
CGAL::assign(x_seg, *it);
#else #else
bool assign_res = CGAL::assign(x_seg, *it); X_monotone_curve_2 x_polycurve = ctr_x_curve(*x_seg_p);
CGAL_assertion(assign_res); #endif
for (++it; it != x_seg_objects.end(); ++it) {
const auto* x_seg_p = boost::get<X_monotone_subcurve_2>(&(*it));
#if ! defined (CGAL_NO_ASSERTIONS)
CGAL_assertion(x_seg_p != nullptr);
#endif #endif
// Test that cv is continuous and well-oriented. // Test that cv is continuous and well-oriented.
CGAL_precondition_code CGAL_precondition_code
( (
next_src = (cmp_seg_endpts(x_seg) == SMALLER) ? next_src = (cmp_seg_endpts(*x_seg_p) == SMALLER) ?
min_seg_v(x_seg) : max_seg_v(x_seg); min_seg_v(*x_seg_p) : max_seg_v(*x_seg_p);
); );
CGAL_precondition_msg CGAL_precondition_msg
( (
@ -285,46 +281,50 @@ public:
); );
CGAL_precondition_code CGAL_precondition_code
( (
last_target = (cmp_seg_endpts(x_seg) == SMALLER) ? last_target = (cmp_seg_endpts(*x_seg_p) == SMALLER) ?
max_seg_v(x_seg) : min_seg_v(x_seg); max_seg_v(*x_seg_p) : min_seg_v(*x_seg_p);
); );
if ((cmp_seg_endpts(x_seg) != start_dir) || if ((cmp_seg_endpts(*x_seg_p) != start_dir) ||
(is_seg_vertical(x_seg) != is_start_vertical)) (is_seg_vertical(*x_seg_p) != is_start_vertical))
{ {
// Construct an x-monotone curve from the sub-range which was found // Construct an x-monotone curve from the sub-range which was found
*oi++ = make_object(x_polycurve); *oi++ = Make_x_monotone_result(x_polycurve);
is_start_vertical = is_seg_vertical(x_seg); is_start_vertical = is_seg_vertical(*x_seg_p);
start_dir = cmp_seg_endpts(x_seg); start_dir = cmp_seg_endpts(*x_seg_p);
#ifdef CGAL_ALWAYS_LEFT_TO_RIGHT #ifdef CGAL_ALWAYS_LEFT_TO_RIGHT
if (cmp_seg_endpts(x_seg) == LARGER) x_seg = ctr_seg_opposite(x_seg); x_polycurve = (cmp_seg_endpts(*x_seg_p) == LARGER) ?
ctr_x_curve(ctr_seg_opposite(*x_seg_p)) : ctr_x_curve(*x_seg_p);
#else
x_polycurve = ctr_x_curve(*x_seg_p);
#endif #endif
x_polycurve = ctr_x_curve(x_seg);
} }
else { else {
#ifdef CGAL_ALWAYS_LEFT_TO_RIGHT #ifdef CGAL_ALWAYS_LEFT_TO_RIGHT
if (cmp_seg_endpts(x_seg) == LARGER) { if (cmp_seg_endpts(*x_seg_p) == LARGER)
x_seg = ctr_seg_opposite(x_seg); push_front(x_polycurve, ctr_seg_opposite(*x_seg_p));
push_front(x_polycurve, x_seg);
}
else else
push_back(x_polycurve, x_seg); push_back(x_polycurve, *x_seg_p);
#else #else
push_back(x_polycurve, x_seg); push_back(x_polycurve, *x_seg_p);
#endif #endif
} }
} // for loop } // for loop
if (x_polycurve.number_of_subcurves() != 0) if (x_polycurve.number_of_subcurves() != 0)
*oi++ = make_object(x_polycurve); *oi++ = Make_x_monotone_result(x_polycurve);
x_seg_objects.clear(); x_seg_objects.clear();
return oi; return oi;
} }
template <typename OutputIterator> template <typename OutputIterator>
OutputIterator operator_impl(const Curve_2& cv, OutputIterator oi, OutputIterator operator_impl(const Curve_2& cv, OutputIterator oi,
Arr_not_all_sides_oblivious_tag) const Arr_not_all_sides_oblivious_tag) const
{ {
typedef typename Curve_2::Subcurve_const_iterator const_seg_iterator; typedef boost::variant<Point_2, X_monotone_subcurve_2>
Make_x_monotone_subresult;
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
// If the polycurve is empty, return. // If the polycurve is empty, return.
if (cv.number_of_subcurves() == 0) return oi; if (cv.number_of_subcurves() == 0) return oi;
@ -347,29 +347,25 @@ public:
m_poly_traits.subcurve_traits_2()->construct_opposite_2_object(); m_poly_traits.subcurve_traits_2()->construct_opposite_2_object();
#endif #endif
// Convert the input polycurve to a sequence of CGAL objects, such // Convert the input polycurve to a sequence of objects, such that
// that each Object wraps an x-monotone subcurve. // each object wraps an x-monotone subcurve.
std::vector<Object> x_seg_objects; std::vector<Make_x_monotone_subresult> x_seg_objects;
const_seg_iterator it_segs; for (auto its = cv.subcurves_begin(); its != cv.subcurves_end(); ++its)
for (it_segs = cv.subcurves_begin(); it_segs != cv.subcurves_end(); make_seg_x_monotone(*its, std::back_inserter(x_seg_objects));
++it_segs) auto it = x_seg_objects.begin();
make_seg_x_monotone(*it_segs, std::back_inserter(x_seg_objects)); const auto* x_seg_p = boost::get<X_monotone_subcurve_2>(&(*it));
typename std::vector<Object>::iterator it = x_seg_objects.begin(); #if ! defined (CGAL_NO_ASSERTIONS)
X_monotone_subcurve_2 x_seg; CGAL_assertion(x_seg_p != nullptr);
#if defined (CGAL_NO_ASSERTIONS)
CGAL::assign(x_seg, *it);
#else
bool assign_res = CGAL::assign(x_seg, *it);
CGAL_assertion(assign_res);
#endif #endif
// If the polycurve consists of a single x-monotone subcurve, return. // If the polycurve consists of a single x-monotone subcurve, return.
if (x_seg_objects.size() == 1) { if (x_seg_objects.size() == 1) {
#ifdef CGAL_ALWAYS_LEFT_TO_RIGHT #ifdef CGAL_ALWAYS_LEFT_TO_RIGHT
if (cmp_seg_endpts(x_seg) == LARGER) if (cmp_seg_endpts(x_seg) == LARGER)
x_seg = ctr_seg_opposite(x_seg); *oi++ = Make_x_monotone_result(ctr_x_curve(ctr_seg_opposite(*x_seg_p))); else *oi++ = Make_x_monotone_result(ctr_x_curve(*x_seg_p));
#else
*oi++ = Make_x_monotone_result(ctr_x_curve(*x_seg_p));
#endif #endif
*oi++ = make_object(ctr_x_curve(x_seg));
x_seg_objects.clear(); x_seg_objects.clear();
return oi; return oi;
} }
@ -383,39 +379,38 @@ public:
auto max_seg_v = auto max_seg_v =
m_poly_traits.subcurve_traits_2()->construct_max_vertex_2_object(); m_poly_traits.subcurve_traits_2()->construct_max_vertex_2_object();
auto equal = m_poly_traits.subcurve_traits_2()->equal_2_object(); auto equal = m_poly_traits.subcurve_traits_2()->equal_2_object();
Point_2 last_target = (cmp_seg_endpts(x_seg) == SMALLER) ? Point_2 last_target = (cmp_seg_endpts(*x_seg_p) == SMALLER) ?
max_seg_v(x_seg) : min_seg_v(x_seg); max_seg_v(*x_seg_p) : min_seg_v(*x_seg_p);
Point_2 next_src; Point_2 next_src;
); );
// The polycurve consists of at least 2 x-monotone subcurves: // The polycurve consists of at least 2 x-monotone subcurves:
Push_back_2 push_back = m_poly_traits.push_back_2_object(); Push_back_2 push_back = m_poly_traits.push_back_2_object();
typename Subcurve_traits_2::Is_vertical_2 is_seg_vertical = auto is_seg_vertical =
m_poly_traits.subcurve_traits_2()->is_vertical_2_object(); m_poly_traits.subcurve_traits_2()->is_vertical_2_object();
bool is_start_vertical = is_seg_vertical(x_seg); bool is_start_vertical = is_seg_vertical(*x_seg_p);
Comparison_result start_dir = cmp_seg_endpts(x_seg); Comparison_result start_dir = cmp_seg_endpts(*x_seg_p);
#ifdef CGAL_ALWAYS_LEFT_TO_RIGHT #ifdef CGAL_ALWAYS_LEFT_TO_RIGHT
Push_front_2 push_front = m_poly_traits.push_front_2_object(); Push_front_2 push_front = m_poly_traits.push_front_2_object();
if (cmp_seg_endpts(x_seg) == LARGER) x_seg = ctr_seg_opposite(x_seg); X_monotone_curve_2 x_polycurve = (cmp_seg_endpts(x_seg) == LARGER) ?
#endif ctr_x_curve(ctr_seg_opposite(*x_seg_p)) : ctr_x_curve(*x_seg_p);
X_monotone_curve_2 x_polycurve = ctr_x_curve(x_seg);
for (++it; it != x_seg_objects.end(); ++it){
X_monotone_subcurve_2 x_seg;
#if defined (CGAL_NO_ASSERTIONS)
CGAL::assign(x_seg, *it);
#else #else
bool assign_res = CGAL::assign(x_seg, *it); X_monotone_curve_2 x_polycurve = ctr_x_curve(*x_seg_p);
CGAL_assertion(assign_res); #endif
for (++it; it != x_seg_objects.end(); ++it) {
const auto* x_seg_p = boost::get<X_monotone_subcurve_2>(&(*it));
#if ! defined (CGAL_NO_ASSERTIONS)
CGAL_assertion(x_seg_p != nullptr);
#endif #endif
// Test that cv is continuous and well-oriented. // Test that cv is continuous and well-oriented.
CGAL_precondition_code CGAL_precondition_code
( (
next_src = (cmp_seg_endpts(x_seg) == SMALLER) ? next_src = (cmp_seg_endpts(*x_seg_p) == SMALLER) ?
min_seg_v(x_seg) : max_seg_v(x_seg); min_seg_v(*x_seg_p) : max_seg_v(*x_seg_p);
); );
CGAL_precondition_msg CGAL_precondition_msg
( (
@ -424,59 +419,61 @@ public:
); );
CGAL_precondition_code CGAL_precondition_code
( (
last_target = (cmp_seg_endpts(x_seg) == SMALLER) ? last_target = (cmp_seg_endpts(*x_seg_p) == SMALLER) ?
max_seg_v(x_seg) : min_seg_v(x_seg); max_seg_v(*x_seg_p) : min_seg_v(*x_seg_p);
); );
Arr_curve_end polycurve_target = Arr_curve_end polycurve_target =
(cmp_seg_endpts(x_polycurve[0]) == SMALLER) ? (cmp_seg_endpts(x_polycurve[0]) == SMALLER) ?
ARR_MAX_END : ARR_MIN_END; ARR_MAX_END : ARR_MIN_END;
Arr_curve_end seg_source = (cmp_seg_endpts(x_seg) == SMALLER) ? Arr_curve_end seg_source = (cmp_seg_endpts(*x_seg_p) == SMALLER) ?
ARR_MIN_END : ARR_MAX_END; ARR_MIN_END : ARR_MAX_END;
unsigned int num_segs = x_polycurve.number_of_subcurves(); auto num_segs = x_polycurve.number_of_subcurves();
if ((cmp_seg_endpts(x_seg) != start_dir) || if ((cmp_seg_endpts(*x_seg_p) != start_dir) ||
(is_seg_vertical(x_seg) != is_start_vertical)) (is_seg_vertical(*x_seg_p) != is_start_vertical))
{ {
// Construct an x-monotone curve from the sub-range which was found // Construct an x-monotone curve from the sub-range which was found
*oi++ = make_object(x_polycurve); *oi++ = Make_x_monotone_result(x_polycurve);
is_start_vertical = is_seg_vertical(x_seg); is_start_vertical = is_seg_vertical(*x_seg_p);
start_dir = cmp_seg_endpts(x_seg); start_dir = cmp_seg_endpts(*x_seg_p);
#ifdef CGAL_ALWAYS_LEFT_TO_RIGHT #ifdef CGAL_ALWAYS_LEFT_TO_RIGHT
if (cmp_seg_endpts(x_seg) == LARGER) x_seg = ctr_seg_opposite(x_seg); x_polycurve (cmp_seg_endpts(*x_seg_p) == LARGER) ?
ctr_x_curve(ctr_seg_opposite(*x_seg_p)) : ctr_x_curve(*x_seg_p);
#else
x_polycurve = ctr_x_curve(*x_seg_p);
#endif #endif
x_polycurve = ctr_x_curve(x_seg);
} }
else if (ps_x(x_polycurve[num_segs-1], polycurve_target) != else if (ps_x(x_polycurve[num_segs-1], polycurve_target) !=
ARR_INTERIOR || ARR_INTERIOR ||
ps_x(x_seg, seg_source) != ARR_INTERIOR) (ps_x(*x_seg_p, seg_source) != ARR_INTERIOR))
{ {
*oi++ = make_object(x_polycurve); *oi++ = Make_x_monotone_result(x_polycurve);
#ifdef CGAL_ALWAYS_LEFT_TO_RIGHT #ifdef CGAL_ALWAYS_LEFT_TO_RIGHT
if (cmp_seg_endpts(x_seg) == LARGER) x_seg = ctr_seg_opposite(x_seg); x_polycurve = (cmp_seg_endpts(*x_seg_p) == LARGER) ?
ctr_seg_opposite(*x_seg_p) : ctr_x_curve(*x_seg_p);
#endif #endif
x_polycurve = ctr_x_curve(x_seg); x_polycurve = ctr_x_curve(*x_seg_p);
} }
else { else {
#ifdef CGAL_ALWAYS_LEFT_TO_RIGHT #ifdef CGAL_ALWAYS_LEFT_TO_RIGHT
if (cmp_seg_endpts(x_seg) == LARGER) { if (cmp_seg_endpts(*x_seg_p) == LARGER)
x_seg = ctr_seg_opposite(x_seg); push_front(x_polycurve, ctr_seg_opposite(*x_seg_p));
push_front(x_polycurve, x_seg);
}
else else
push_back(x_polycurve, x_seg); push_back(x_polycurve, *x_seg_p);
#else #else
push_back(x_polycurve, x_seg); push_back(x_polycurve, *x_seg_p);
#endif #endif
} }
} // for loop } // for loop
if (x_polycurve.number_of_subcurves() != 0) if (x_polycurve.number_of_subcurves() != 0)
*oi++ = make_object(x_polycurve); *oi++ = Make_x_monotone_result(x_polycurve);
x_seg_objects.clear(); x_seg_objects.clear();
return oi; return oi;
} }
public:
public:
template <typename OutputIterator> template <typename OutputIterator>
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const
{ return operator_impl(cv, oi, Are_all_sides_oblivious_tag()); } { return operator_impl(cv, oi, Are_all_sides_oblivious_tag()); }

View File

@ -808,45 +808,41 @@ public:
return Equal_2(this); return Equal_2(this);
} }
/*! A functor that divides a curve into continues (x-monotone) curves. */ //! \name Intersections & subdivisions
class Make_x_monotone_2 //@{
{
public:
/*! /*! \class Make_x_monotone_2
* Cut the given conic curve (or conic arc) into x-monotone subcurves * A functor for subdividing a curve into continues x-monotone curves.
* and insert them to the given output iterator. */
* \param cv The curve. class Make_x_monotone_2 {
* \param oi The output iterator, whose value-type is Object. The returned public:
* objects is a wrapper for an X_monotone_curve_2 object. /*! Subdivide a given rational-function curve into x-monotone subcurves
* \return The past-the-end iterator. * and insert them to a given output iterator.
* \param cv the curve.
* \param oi the output iterator for the result. Its dereference type is a
* variant that wraps a \c Point_2 or an \c X_monotone_curve_2
* objects.
* \return the past-the-end iterator.
*/ */
template<typename OutputIterator> template <typename OutputIterator>
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const
{ {
// Make the rational arc continuous. typedef boost::variant<Point_2, X_monotone_curve_2>
std::list<X_monotone_curve_2> arcs; Make_x_monotone_result;
// Make the rational arc continuous.
std::list<X_monotone_curve_2> arcs;
cv.make_continuous(std::back_inserter(arcs)); cv.make_continuous(std::back_inserter(arcs));
// Create objects. // Create objects.
typename std::list<X_monotone_curve_2>::const_iterator iter; for (const auto& arc : arcs) *oi++ = Make_x_monotone_result(arc);
return oi;
for (iter = arcs.begin(); iter != arcs.end(); ++iter)
{
*oi = make_object (*iter);
++oi;
}
return (oi);
} }
}; };
/*! Obtain a Make_x_monotone_2 functor object. */ /*! Obtain a Make_x_monotone_2 functor object. */
Make_x_monotone_2 make_x_monotone_2_object() const Make_x_monotone_2 make_x_monotone_2_object() const
{ { return Make_x_monotone_2(); }
return Make_x_monotone_2();
}
/*! A functor that splits a curve at a point. */ /*! A functor that splits a curve at a point. */
class Split_2 class Split_2
@ -975,6 +971,8 @@ public:
return Merge_2(this); return Merge_2(this);
} }
//@}
/// \name Functor definitions to handle boundaries /// \name Functor definitions to handle boundaries
//@{ //@{

View File

@ -543,23 +543,30 @@ public:
//@} //@}
/// \name Functor definitions for supporting intersections. //! \name Intersections, subdivisions, and mergings
//@{ //@{
/*! \class Make_x_monotone_2
* A functor for subdividing a curve into x-monotone curves.
*/
class Make_x_monotone_2 { class Make_x_monotone_2 {
public: public:
/*! Cut the given curve into x-monotone subcurves and insert them into the /*! Subdivide a given curve into x-monotone subcurves and insert them into
* given output iterator. As segments are always x_monotone, only one * a given output iterator. As segments are always x_monotone a single
* object will be contained in the iterator. * object is inserted.
* \param cv the curve. * \param cv the curve.
* \param oi the output iterator, whose value-type is variant<.... * \param oi the output iterator for the result. Its dereference type is a
* \return the past-the-end iterator. * variant that wraps a \c Point_2 or an \c X_monotone_curve_2
* objects.
* \return the past-the-end output iterator.
*/ */
template <typename OutputIterator> template <typename OutputIterator>
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const
{ {
// Wrap the segment with an object. // Wrap the segment with a variant.
*oi++ = make_object(cv); typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
*oi++ = Make_x_monotone_result(cv);
return oi; return oi;
} }
}; };
@ -1161,6 +1168,7 @@ public:
//! \brief constructs default. //! \brief constructs default.
template <typename Kernel> template <typename Kernel>
Arr_segment_traits_2<Kernel>::_Segment_cached_2::_Segment_cached_2() : Arr_segment_traits_2<Kernel>::_Segment_cached_2::_Segment_cached_2() :
m_is_directed_right(false),
m_is_vert(false), m_is_vert(false),
m_is_degen(true) m_is_degen(true)
{} {}

View File

@ -151,23 +151,25 @@ public:
OutputIterator insert(const Vector_3 & normal1, const Vector_3 & normal2, OutputIterator insert(const Vector_3 & normal1, const Vector_3 & normal2,
OutputIterator oi) OutputIterator oi)
{ {
std::list<CGAL::Object> x_objects; typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
std::list<Make_x_monotone_result> x_objects;
make_x_monotone(normal1, normal2, std::back_inserter(x_objects)); make_x_monotone(normal1, normal2, std::back_inserter(x_objects));
typename std::list<CGAL::Object>::iterator it = x_objects.begin(); auto it = x_objects.begin();
const X_monotone_curve_2 * xc = object_cast<X_monotone_curve_2>(&(*it)); const auto* xc = boost::get<X_monotone_curve_2>(&(*it));
#if CGAL_ARR_SPHERICAL_GAUSSIAN_MAP_3_DEBUG==1 #if CGAL_ARR_SPHERICAL_GAUSSIAN_MAP_3_DEBUG==1
std::cout << "1.a. insert_in_face_interior(" << *xc << ")" << std::endl; std::cout << "1.a. insert_in_face_interior(" << *xc << ")" << std::endl;
#endif #endif
Halfedge_handle he = Halfedge_handle he = m_sgm.insert_in_face_interior(*xc, m_sgm.faces_begin());
m_sgm.insert_in_face_interior(*xc, m_sgm.faces_begin()); if (! xc->is_directed_right()) he = he->twin();
if (!xc->is_directed_right()) he = he->twin();
*oi++ = he; *oi++ = he;
++it; ++it;
if (it == x_objects.end()) return oi; if (it == x_objects.end()) return oi;
xc = object_cast<X_monotone_curve_2>(&(*it)); xc = boost::get<X_monotone_curve_2>(&(*it));
#if CGAL_ARR_SPHERICAL_GAUSSIAN_MAP_3_DEBUG==1 #if CGAL_ARR_SPHERICAL_GAUSSIAN_MAP_3_DEBUG==1
std::cout << "1.b. insert_from_vertex(" << *xc << ")" << std::endl; std::cout << "1.b. insert_from_vertex(" << *xc << ")" << std::endl;
#endif #endif
@ -190,11 +192,14 @@ public:
const Vector_3 & normal2, const Vector_3 & normal2,
OutputIterator oi) OutputIterator oi)
{ {
std::list<CGAL::Object> x_objects; typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
std::list<Make_x_monotone_result> x_objects;
make_x_monotone(normal1, normal2, std::back_inserter(x_objects)); make_x_monotone(normal1, normal2, std::back_inserter(x_objects));
typename std::list<CGAL::Object>::iterator it = x_objects.begin(); auto it = x_objects.begin();
const X_monotone_curve_2 * xc = object_cast<X_monotone_curve_2>(&(*it)); const auto* xc = boost::get<X_monotone_curve_2>(&(*it));
#if CGAL_ARR_SPHERICAL_GAUSSIAN_MAP_3_DEBUG==1 #if CGAL_ARR_SPHERICAL_GAUSSIAN_MAP_3_DEBUG==1
std::cout << "2.a. insert_from_vertex(" << *xc << ", " std::cout << "2.a. insert_from_vertex(" << *xc << ", "
<< vertex1->point() << ")" << std::endl; << vertex1->point() << ")" << std::endl;
@ -208,7 +213,7 @@ public:
++it; ++it;
if (it == x_objects.end()) return oi; if (it == x_objects.end()) return oi;
xc = object_cast<X_monotone_curve_2>(&(*it)); xc = boost::get<X_monotone_curve_2>(&(*it));
#if CGAL_ARR_SPHERICAL_GAUSSIAN_MAP_3_DEBUG==1 #if CGAL_ARR_SPHERICAL_GAUSSIAN_MAP_3_DEBUG==1
std::cout << "2.b. insert_from_vertex(" << *xc << ")" << std::endl; std::cout << "2.b. insert_from_vertex(" << *xc << ")" << std::endl;
#endif #endif
@ -231,12 +236,15 @@ public:
const Vector_3 & normal2, Vertex_handle vertex2, const Vector_3 & normal2, Vertex_handle vertex2,
OutputIterator oi) OutputIterator oi)
{ {
std::list<CGAL::Object> x_objects; typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
std::list<Make_x_monotone_result> x_objects;
make_x_monotone(normal1, normal2, std::back_inserter(x_objects)); make_x_monotone(normal1, normal2, std::back_inserter(x_objects));
typename std::list<CGAL::Object>::iterator it = x_objects.begin(); auto it = x_objects.begin();
if (x_objects.size() == 1) { if (x_objects.size() == 1) {
const X_monotone_curve_2 * xc = object_cast<X_monotone_curve_2>(&(*it)); const auto* xc = boost::get<X_monotone_curve_2>(&(*it));
#if CGAL_ARR_SPHERICAL_GAUSSIAN_MAP_3_DEBUG==1 #if CGAL_ARR_SPHERICAL_GAUSSIAN_MAP_3_DEBUG==1
std::cout << "3. insert_from_vertex(" << *xc << ")" << std::endl; std::cout << "3. insert_from_vertex(" << *xc << ")" << std::endl;
#endif #endif
@ -247,8 +255,8 @@ public:
return oi; return oi;
} }
const X_monotone_curve_2 * xc1 = object_cast<X_monotone_curve_2>(&(*it++)); const X_monotone_curve_2* xc1 = boost::get<X_monotone_curve_2>(&(*it++));
const X_monotone_curve_2 * xc2 = object_cast<X_monotone_curve_2>(&(*it)); const X_monotone_curve_2* xc2 = boost::get<X_monotone_curve_2>(&(*it));
#if CGAL_ARR_SPHERICAL_GAUSSIAN_MAP_3_DEBUG==1 #if CGAL_ARR_SPHERICAL_GAUSSIAN_MAP_3_DEBUG==1
std::cout << "3.a. insert_from_vertex(" << *xc2 << ")" << std::endl; std::cout << "3.a. insert_from_vertex(" << *xc2 << ")" << std::endl;
@ -283,11 +291,13 @@ public:
const Vector_3 & normal2, Vertex_handle vertex2, const Vector_3 & normal2, Vertex_handle vertex2,
OutputIterator oi) OutputIterator oi)
{ {
std::list<CGAL::Object> x_objects; typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
std::list<Make_x_monotone_result> x_objects;
make_x_monotone(normal1, normal2, std::back_inserter(x_objects)); make_x_monotone(normal1, normal2, std::back_inserter(x_objects));
typename std::list<CGAL::Object>::iterator it = x_objects.begin(); auto it = x_objects.begin();
if (x_objects.size() == 1) { if (x_objects.size() == 1) {
const X_monotone_curve_2 * xc = object_cast<X_monotone_curve_2>(&(*it)); const auto* xc = boost::get<X_monotone_curve_2>(&(*it));
#if CGAL_ARR_SPHERICAL_GAUSSIAN_MAP_3_DEBUG==1 #if CGAL_ARR_SPHERICAL_GAUSSIAN_MAP_3_DEBUG==1
std::cout << "4. insert_at_vertices(" << *xc << ")" << std::endl; std::cout << "4. insert_at_vertices(" << *xc << ")" << std::endl;
#endif #endif
@ -295,8 +305,8 @@ public:
return oi; return oi;
} }
const X_monotone_curve_2 * xc1 = object_cast<X_monotone_curve_2>(&(*it++)); const X_monotone_curve_2 * xc1 = boost::get<X_monotone_curve_2>(&(*it++));
const X_monotone_curve_2 * xc2 = object_cast<X_monotone_curve_2>(&(*it)); const X_monotone_curve_2 * xc2 = boost::get<X_monotone_curve_2>(&(*it));
#if CGAL_ARR_SPHERICAL_GAUSSIAN_MAP_3_DEBUG==1 #if CGAL_ARR_SPHERICAL_GAUSSIAN_MAP_3_DEBUG==1
std::cout << "4.a. insert_from_vertex(" << *xc1 std::cout << "4.a. insert_from_vertex(" << *xc1

View File

@ -35,6 +35,7 @@ void Arr_transform_on_sphere(Arrangement & arr,
typedef typename Arrangement::Geometry_traits_2 Geometry_traits_2; typedef typename Arrangement::Geometry_traits_2 Geometry_traits_2;
typedef typename Arrangement::Topology_traits Topology_traits; typedef typename Arrangement::Topology_traits Topology_traits;
typedef typename Geometry_traits_2::Point_2 Point_2;
typedef typename Geometry_traits_2::Curve_2 Curve_2; typedef typename Geometry_traits_2::Curve_2 Curve_2;
typedef typename Geometry_traits_2::X_monotone_curve_2 X_monotone_curve_2; typedef typename Geometry_traits_2::X_monotone_curve_2 X_monotone_curve_2;
@ -45,6 +46,8 @@ void Arr_transform_on_sphere(Arrangement & arr,
typedef typename Arrangement::Halfedge_around_vertex_circulator typedef typename Arrangement::Halfedge_around_vertex_circulator
Halfedge_around_vertex_circulator; Halfedge_around_vertex_circulator;
typedef boost::variant<Point_2, X_monotone_curve_2> Make_x_monotone_result;
const Geometry_traits_2 * geom_traits = arr.geometry_traits(); const Geometry_traits_2 * geom_traits = arr.geometry_traits();
Topology_traits * topol_traits = arr.topology_traits(); Topology_traits * topol_traits = arr.topology_traits();
@ -53,8 +56,7 @@ void Arr_transform_on_sphere(Arrangement & arr,
// Preprocessing loop - merge all the edges that were splited // Preprocessing loop - merge all the edges that were splited
// (meaning have a common endpoint that lies on the boundary and their degree // (meaning have a common endpoint that lies on the boundary and their degree
// is 2) on the identification curve. // is 2) on the identification curve.
for (Vertex_handle vi1 = arr.vertices_begin() ; vi1 != arr.vertices_end() ;) for (auto vi1 = arr.vertices_begin(); vi1 != arr.vertices_end(); ) {
{
Vertex_handle v_temp = vi1; Vertex_handle v_temp = vi1;
++vi1; ++vi1;
@ -63,9 +65,9 @@ void Arr_transform_on_sphere(Arrangement & arr,
Arr_parameter_space by = Arr_parameter_space by =
geom_traits->parameter_space_in_y_2_object()(v_temp->point()); geom_traits->parameter_space_in_y_2_object()(v_temp->point());
// use vertex->parameter_space_in_x() != interior || vertex->parameter_space_in_y() != interior) // use vertex->parameter_space_in_x() != interior ||
if ((bx != ARR_INTERIOR || by != ARR_INTERIOR) && (v_temp->degree() == 2)) // vertex->parameter_space_in_y() != interior)
{ if ((bx != ARR_INTERIOR || by != ARR_INTERIOR) && (v_temp->degree() == 2)) {
Curve_2 merged_cv; Curve_2 merged_cv;
Halfedge_around_vertex_circulator havc = v_temp->incident_halfedges(); Halfedge_around_vertex_circulator havc = v_temp->incident_halfedges();
Halfedge_around_vertex_circulator havc_next = havc; Halfedge_around_vertex_circulator havc_next = havc;
@ -80,16 +82,13 @@ void Arr_transform_on_sphere(Arrangement & arr,
// Compare the direction of the edges. // Compare the direction of the edges.
bool eq_direction = havc->direction() == havc_next->twin()->direction(); bool eq_direction = havc->direction() == havc_next->twin()->direction();
if (point_eq1 && normal_eq1 && eq_direction) if (point_eq1 && normal_eq1 && eq_direction) {
{ if (havc->source()->point() == havc->curve().source()) {
if (havc->source()->point() == havc->curve().source())
{
merged_cv = Curve_2(havc->source()->point(), merged_cv = Curve_2(havc->source()->point(),
havc_next->twin()->target()->point(), havc_next->twin()->target()->point(),
havc->curve().normal()); havc->curve().normal());
} }
else if (havc->source()->point() == havc->curve().target()) else if (havc->source()->point() == havc->curve().target()) {
{
merged_cv = Curve_2(havc_next->twin()->target()->point(), merged_cv = Curve_2(havc_next->twin()->target()->point(),
havc->source()->point(), havc->source()->point(),
havc->curve().normal()); havc->curve().normal());
@ -111,20 +110,17 @@ void Arr_transform_on_sphere(Arrangement & arr,
} }
//Rotate all the vertices. //Rotate all the vertices.
for (Vertex_handle vi1 = arr.vertices_begin(); vi1 != arr.vertices_end() ; for (auto vi1 = arr.vertices_begin(); vi1 != arr.vertices_end(); ++vi1) {
++vi1)
{
m_arr_access.modify_vertex_ex(vi1, aff.transform(vi1->point())); m_arr_access.modify_vertex_ex(vi1, aff.transform(vi1->point()));
} }
unsigned int num_of_edges = arr.number_of_edges(); size_t num_of_edges = arr.number_of_edges();
Edge_iterator ei1 = arr.edges_begin(); Edge_iterator ei1 = arr.edges_begin();
// Rotate all the halfedges. // Rotate all the halfedges.
// The loop is over the initial edges , since new edges are created and // The loop is over the initial edges , since new edges are created and
// added to the edges list. // added to the edges list.
for (unsigned int i=0 ; i < num_of_edges ; ++i) for (size_t i = 0; i < num_of_edges; ++i) {
{
Curve_2 new_cv; Curve_2 new_cv;
Halfedge_handle hei1 = ei1; Halfedge_handle hei1 = ei1;
@ -133,8 +129,7 @@ void Arr_transform_on_sphere(Arrangement & arr,
// Take only the halfedge that its source is equal to the source of // Take only the halfedge that its source is equal to the source of
// the curve. // the curve.
bool eq1 = hei1->source()->point() == aff.transform(hei1->curve().source()); bool eq1 = hei1->source()->point() == aff.transform(hei1->curve().source());
if (!eq1) if (!eq1) {
{
hei1 = hei1->twin(); hei1 = hei1->twin();
eq1 = hei1->source()->point() == aff.transform(hei1->curve().source()); eq1 = hei1->source()->point() == aff.transform(hei1->curve().source());
} }
@ -150,31 +145,28 @@ void Arr_transform_on_sphere(Arrangement & arr,
// Modify the edge with the new curve. // Modify the edge with the new curve.
m_arr_access.modify_edge_ex(hei1, new_cv); m_arr_access.modify_edge_ex(hei1, new_cv);
std::list<CGAL::Object> objects; std::list<Make_x_monotone_result> objects;
// Try to split the curve into x_monotone pieces. // Try to split the curve into x_monotone pieces.
geom_traits->make_x_monotone_2_object()(new_cv , std::back_inserter(objects)); geom_traits->make_x_monotone_2_object()(new_cv , std::back_inserter(objects));
// If the curve is not x-monotone - split it into 2 x_monotone parts. // If the curve is not x-monotone - split it into 2 x_monotone parts.
// Since the curves were x_monotone before , can assume that it will be // Since the curves were x_monotone before , can assume that it will be
// splited into 2 parts max. // splited into 2 parts max.
if (objects.size() == 2) if (objects.size() == 2) {
{ auto it = objects.begin();
typename std::list<CGAL::Object>::iterator it = objects.begin();
// The curve that its left vertex lies on the identification curve // The curve that its left vertex lies on the identification curve
const X_monotone_curve_2 * sub_cv1 = const auto* sub_cv1 = boost::get<X_monotone_curve_2>(&(*it));
object_cast<X_monotone_curve_2>(&(*it));
++it; ++it;
//The curve that its rigth vertex lies on the identification curve //The curve that its rigth vertex lies on the identification curve
const X_monotone_curve_2 * sub_cv2 = const auto* sub_cv2 = boost::get<X_monotone_curve_2>(&(*it));
object_cast<X_monotone_curve_2>(&(*it));
bool eq1 = (*sub_cv1).source() == hei1->source()->point(); bool eq1 = (*sub_cv1).source() == hei1->source()->point();
bool eq2 = (*sub_cv2).target() == hei1->target()->point(); bool eq2 = (*sub_cv2).target() == hei1->target()->point();
if (eq1 && eq2) if (eq1 && eq2)
m_arr_access.split_edge_ex (hei1, (*sub_cv1).target(), *sub_cv1, m_arr_access.split_edge_ex(hei1, (*sub_cv1).target(), *sub_cv1,
*sub_cv2); *sub_cv2);
else else
CGAL_error_msg CGAL_error_msg
("The new curve endpoints should be equal to the original ones"); ("The new curve endpoints should be equal to the original ones");
@ -183,25 +175,20 @@ void Arr_transform_on_sphere(Arrangement & arr,
// Update all the vertices that located on the boundary after the rotation // Update all the vertices that located on the boundary after the rotation
// with boundary conditions // with boundary conditions
for (Vertex_handle vi = arr.vertices_begin() ; vi != arr.vertices_end() ; for (auto vi = arr.vertices_begin(); vi != arr.vertices_end(); ++vi) {
++vi)
{
Arr_parameter_space bx = Arr_parameter_space bx =
geom_traits->parameter_space_in_x_2_object()(vi->point()); geom_traits->parameter_space_in_x_2_object()(vi->point());
Arr_parameter_space by = Arr_parameter_space by =
geom_traits->parameter_space_in_y_2_object()(vi->point()); geom_traits->parameter_space_in_y_2_object()(vi->point());
if (bx != ARR_INTERIOR || by != ARR_INTERIOR) if (bx != ARR_INTERIOR || by != ARR_INTERIOR) {
{
// The target of the Halfedge_around_vertex_circulator is the relevant // The target of the Halfedge_around_vertex_circulator is the relevant
// point. // point.
Halfedge_around_vertex_circulator havc = vi->incident_halfedges(); Halfedge_around_vertex_circulator havc = vi->incident_halfedges();
Arr_curve_end ind; Arr_curve_end ind =
if (geom_traits->construct_min_vertex_2_object()(havc->curve()) == vi->point()) (geom_traits->construct_min_vertex_2_object()(havc->curve()) ==
ind = ARR_MIN_END; vi->point()) ? ARR_MIN_END : ARR_MAX_END;
else
ind = ARR_MAX_END;
// Check if it was already added. // Check if it was already added.
if (topol_traits->discontinuity_vertex(havc->curve(), ind)== nullptr && if (topol_traits->discontinuity_vertex(havc->curve(), ind)== nullptr &&
@ -219,7 +206,7 @@ void Arr_transform_on_sphere(Arrangement & arr,
} }
// Transform the faces with the suitable transformation traits. // Transform the faces with the suitable transformation traits.
for(Face_handle f1 = arr.faces_begin() ; f1 != arr.faces_end() ; ++f1) for (auto f1 = arr.faces_begin(); f1 != arr.faces_end(); ++f1)
tran_tr.rotate_face(f1, aff); tran_tr.rotate_face(f1, aff);
} }

View File

@ -7,8 +7,8 @@
// $Id$ // $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
// //
// Author(s) : Efi Fogel <efif@post.tau.ac.il> // Author(s): Efi Fogel <efif@post.tau.ac.il>
// Eric Berberich <ericb@post.tau.ac.il> // Eric Berberich <ericb@post.tau.ac.il>
#ifndef CGAL_ARR_SPHERICAL_TOPOLOGY_TRAITS_2_H #ifndef CGAL_ARR_SPHERICAL_TOPOLOGY_TRAITS_2_H
#define CGAL_ARR_SPHERICAL_TOPOLOGY_TRAITS_2_H #define CGAL_ARR_SPHERICAL_TOPOLOGY_TRAITS_2_H
@ -491,11 +491,12 @@ public:
* \pre The curve has a boundary condition in either x or y. * \pre The curve has a boundary condition in either x or y.
* \return An object that contains the curve end. * \return An object that contains the curve end.
*/ */
CGAL::Object place_boundary_vertex(Face* f, boost::optional<boost::variant<Vertex*, Halfedge*> >
const X_monotone_curve_2& xc, place_boundary_vertex(Face* f,
Arr_curve_end ind, const X_monotone_curve_2& xc,
Arr_parameter_space ps_x, Arr_curve_end ind,
Arr_parameter_space ps_y); Arr_parameter_space ps_x,
Arr_parameter_space ps_y);
/*! Locate the predecessor halfedge for the given curve around a given /*! Locate the predecessor halfedge for the given curve around a given
* vertex with boundary conditions. * vertex with boundary conditions.
@ -522,9 +523,10 @@ public:
* \pre The curve end is incident to the boundary. * \pre The curve end is incident to the boundary.
* \return An object that contains the curve end. * \return An object that contains the curve end.
*/ */
CGAL::Object locate_curve_end(const X_monotone_curve_2& xc, Arr_curve_end ce, boost::variant<Vertex*, Halfedge*, Face*>
Arr_parameter_space ps_x, locate_curve_end(const X_monotone_curve_2& xc, Arr_curve_end ce,
Arr_parameter_space ps_y); Arr_parameter_space ps_x,
Arr_parameter_space ps_y);
/*! Split a fictitious edge using the given vertex. /*! Split a fictitious edge using the given vertex.
* \param e The edge to split (one of the pair of halfedges). * \param e The edge to split (one of the pair of halfedges).

View File

@ -7,9 +7,8 @@
// $Id$ // $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
// //
// // Author(s): Ron Wein <wein@post.tau.ac.il>
// Author(s) : Ron Wein <wein@post.tau.ac.il> // Efi Fogel <efif@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
#ifndef CGAL_ARR_BOUNDED_PLANAR_VERT_DEOCMP_HELPER_H #ifndef CGAL_ARR_BOUNDED_PLANAR_VERT_DEOCMP_HELPER_H
#define CGAL_ARR_BOUNDED_PLANAR_VERT_DEOCMP_HELPER_H #define CGAL_ARR_BOUNDED_PLANAR_VERT_DEOCMP_HELPER_H
@ -43,9 +42,15 @@ private:
typedef Geometry_traits_2 Gt2; typedef Geometry_traits_2 Gt2;
public: public:
typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle;
typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
typedef typename Arrangement_2::Face_const_handle Face_const_handle; typedef typename Arrangement_2::Face_const_handle Face_const_handle;
typedef typename Arrangement_2::Topology_traits Topology_traits; typedef typename Arrangement_2::Topology_traits Topology_traits;
typedef boost::variant<Vertex_const_handle, Halfedge_const_handle,
Face_const_handle> Cell_type;
typedef boost::optional<Cell_type> Vert_type;
protected: protected:
// Data members: // Data members:
const Topology_traits* m_top_traits; // The topology-traits class. const Topology_traits* m_top_traits; // The topology-traits class.
@ -76,10 +81,10 @@ public:
//@} //@}
/*! Get the current top object. */ /*! Get the current top object. */
CGAL::Object top_object() const { return CGAL::make_object(m_unb_face); } Vert_type top_object() const { return Vert_type(m_unb_face); }
/*! Get the current bottom object. */ /*! Get the current bottom object. */
CGAL::Object bottom_object() const { return CGAL::make_object(m_unb_face); } Vert_type bottom_object() const { return Vert_type(m_unb_face); }
}; };
} // namespace CGAL } // namespace CGAL

View File

@ -7,8 +7,8 @@
// $Id$ // $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
// //
// Author(s) : Efi Fogel <efif@post.tau.ac.il> // Author(s): Efi Fogel <efif@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il> // Ron Wein <wein@post.tau.ac.il>
#ifndef CGAL_ARR_SPHERICAL_TOPOLOGY_TRAITS_2_IMPL_H #ifndef CGAL_ARR_SPHERICAL_TOPOLOGY_TRAITS_2_IMPL_H
#define CGAL_ARR_SPHERICAL_TOPOLOGY_TRAITS_2_IMPL_H #define CGAL_ARR_SPHERICAL_TOPOLOGY_TRAITS_2_IMPL_H
@ -514,7 +514,10 @@ let_me_decide_the_outer_ccb(std::pair< CGAL::Sign, CGAL::Sign> signs1,
* the interior of the curve, find a place for a boundary vertex that will * the interior of the curve, find a place for a boundary vertex that will
* represent the curve end along the face boundary */ * represent the curve end along the face boundary */
template <typename GeomTraits, typename Dcel> template <typename GeomTraits, typename Dcel>
CGAL::Object boost::optional
<boost::variant
<typename Arr_spherical_topology_traits_2<GeomTraits, Dcel>::Vertex*,
typename Arr_spherical_topology_traits_2<GeomTraits, Dcel>::Halfedge*> >
Arr_spherical_topology_traits_2<GeomTraits, Dcel>:: Arr_spherical_topology_traits_2<GeomTraits, Dcel>::
place_boundary_vertex(Face* /* f */, place_boundary_vertex(Face* /* f */,
const X_monotone_curve_2& xc, Arr_curve_end ind, const X_monotone_curve_2& xc, Arr_curve_end ind,
@ -525,15 +528,18 @@ place_boundary_vertex(Face* /* f */,
, ,
Arr_parameter_space ps_y) Arr_parameter_space ps_y)
{ {
typedef boost::variant<Vertex*, Halfedge*> Non_optional_result;
typedef boost::optional<Non_optional_result> Result;
// std::cout << "place_boundary_vertex()" << std::endl; // std::cout << "place_boundary_vertex()" << std::endl;
if (ps_y == ARR_BOTTOM_BOUNDARY) { if (ps_y == ARR_BOTTOM_BOUNDARY) {
if (m_south_pole == nullptr) return Object(); if (m_south_pole == nullptr) return boost::none;
return CGAL::make_object(m_south_pole); return Result(Non_optional_result(m_south_pole));
} }
if (ps_y == ARR_TOP_BOUNDARY) { if (ps_y == ARR_TOP_BOUNDARY) {
if (m_north_pole == nullptr) return Object(); if (m_north_pole == nullptr) return boost::none;
return CGAL::make_object(m_north_pole); return Result(Non_optional_result(m_north_pole));
} }
CGAL_assertion((ps_x == ARR_LEFT_BOUNDARY) || (ps_x == ARR_RIGHT_BOUNDARY)); CGAL_assertion((ps_x == ARR_LEFT_BOUNDARY) || (ps_x == ARR_RIGHT_BOUNDARY));
@ -541,15 +547,14 @@ place_boundary_vertex(Face* /* f */,
const Point_2& key = (ind == ARR_MIN_END) ? const Point_2& key = (ind == ARR_MIN_END) ?
m_geom_traits->construct_min_vertex_2_object()(xc) : m_geom_traits->construct_min_vertex_2_object()(xc) :
m_geom_traits->construct_max_vertex_2_object()(xc); m_geom_traits->construct_max_vertex_2_object()(xc);
typename Vertex_map::iterator it = m_boundary_vertices.find(key); auto it = m_boundary_vertices.find(key);
if (it != m_boundary_vertices.end()) { if (it != m_boundary_vertices.end()) {
Vertex* v = it->second; Vertex* v = it->second;
return CGAL::make_object(v); return Result(Non_optional_result(v));
} }
// The vertex hasn't been created yet, return a null object: // The vertex hasn't been created yet, return a null object:
return Object(); return boost::none;
} }
/*! \brief locate the predecessor halfedge for the given curve around a given /*! \brief locate the predecessor halfedge for the given curve around a given
@ -585,7 +590,11 @@ locate_around_boundary_vertex(Vertex* v,
/*! \brief locates a DCEL feature that contains a given curve end. */ /*! \brief locates a DCEL feature that contains a given curve end. */
template <typename GeomTraits, typename Dcel> template <typename GeomTraits, typename Dcel>
CGAL::Object Arr_spherical_topology_traits_2<GeomTraits, Dcel>:: boost::variant
<typename Arr_spherical_topology_traits_2<GeomTraits, Dcel>::Vertex*,
typename Arr_spherical_topology_traits_2<GeomTraits, Dcel>::Halfedge*,
typename Arr_spherical_topology_traits_2<GeomTraits, Dcel>::Face*>
Arr_spherical_topology_traits_2<GeomTraits, Dcel>::
locate_curve_end(const X_monotone_curve_2& xc, Arr_curve_end ind, locate_curve_end(const X_monotone_curve_2& xc, Arr_curve_end ind,
Arr_parameter_space Arr_parameter_space
#if !defined(CGAL_NO_ASSERTIONS) #if !defined(CGAL_NO_ASSERTIONS)
@ -594,13 +603,14 @@ locate_curve_end(const X_monotone_curve_2& xc, Arr_curve_end ind,
, ,
Arr_parameter_space ps_y) Arr_parameter_space ps_y)
{ {
typedef boost::variant<Vertex*, Halfedge*, Face*> Result;
// Act according to the boundary conditions. // Act according to the boundary conditions.
if (ps_y == ARR_TOP_BOUNDARY) { if (ps_y == ARR_TOP_BOUNDARY) {
// In case the curve end coincides with the north pole, return the vertex // In case the curve end coincides with the north pole, return the vertex
// representing the north pole, if one exists. Otherwise, return the face // representing the north pole, if one exists. Otherwise, return the face
// containing this pole (the spherical face). // containing this pole (the spherical face).
if (m_north_pole != nullptr) return CGAL::make_object(m_north_pole); if (m_north_pole != nullptr) return Result(m_north_pole);
return CGAL::make_object(m_spherical_face); return Result(m_spherical_face);
} }
typename Vertex_map::iterator it; typename Vertex_map::iterator it;
@ -610,7 +620,7 @@ locate_curve_end(const X_monotone_curve_2& xc, Arr_curve_end ind,
// In case the curve end coincides with the south pole, return the vertex // In case the curve end coincides with the south pole, return the vertex
// representing the south pole, if one exists. Otherwise, search for the // representing the south pole, if one exists. Otherwise, search for the
// face containing this pole. // face containing this pole.
if (m_south_pole != nullptr) return CGAL::make_object(m_south_pole); if (m_south_pole != nullptr) return Result(m_south_pole);
it = m_boundary_vertices.begin(); it = m_boundary_vertices.begin();
} }
else { else {
@ -625,7 +635,7 @@ locate_curve_end(const X_monotone_curve_2& xc, Arr_curve_end ind,
it = m_boundary_vertices.find(key); it = m_boundary_vertices.find(key);
if (it != m_boundary_vertices.end()) { if (it != m_boundary_vertices.end()) {
v = it->second; v = it->second;
return CGAL::make_object(v); return Result(v);
} }
it = m_boundary_vertices.lower_bound(key); it = m_boundary_vertices.lower_bound(key);
@ -635,11 +645,10 @@ locate_curve_end(const X_monotone_curve_2& xc, Arr_curve_end ind,
// discontinuity that is strictly above the curve end. If there is none, // discontinuity that is strictly above the curve end. If there is none,
// we know the curve end is contained in the spherical face. Otherwise, // we know the curve end is contained in the spherical face. Otherwise,
// we return the face that lies below the vertex v. // we return the face that lies below the vertex v.
if (it == m_boundary_vertices.end()) if (it == m_boundary_vertices.end()) return Result(m_spherical_face);
return CGAL::make_object(m_spherical_face);
v = it->second; v = it->second;
return CGAL::make_object(_face_below_vertex_on_discontinuity(v)); return Result(_face_below_vertex_on_discontinuity(v));
} }
/*! \brief determines whether a given boundary vertex is redundant */ /*! \brief determines whether a given boundary vertex is redundant */

View File

@ -7,8 +7,8 @@
// $Id$ // $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
// //
// Author(s) : Ron Wein <wein@post.tau.ac.il> // Author(s): Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il> // Efi Fogel <efif@post.tau.ac.il>
#ifndef CGAL_ARR_SPHERICAL_VERT_DECOMP_HELPER_H #ifndef CGAL_ARR_SPHERICAL_VERT_DECOMP_HELPER_H
#define CGAL_ARR_SPHERICAL_VERT_DECOMP_HELPER_H #define CGAL_ARR_SPHERICAL_VERT_DECOMP_HELPER_H
@ -44,8 +44,13 @@ private:
public: public:
typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2; typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Arrangement_2::Face_const_handle Face_const_handle;
typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle; typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle;
typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
typedef typename Arrangement_2::Face_const_handle Face_const_handle;
typedef boost::variant<Vertex_const_handle, Halfedge_const_handle,
Face_const_handle> Cell_type;
typedef boost::optional<Cell_type> Vert_type;
protected: protected:
typedef typename Arrangement_2::Topology_traits Topology_traits; typedef typename Arrangement_2::Topology_traits Topology_traits;
@ -80,17 +85,17 @@ public:
//@} //@}
/*! Get the current top object. */ /*! Get the current top object. */
CGAL::Object top_object () const Vert_type top_object () const
{ {
return (m_valid_north_pole) ? return (m_valid_north_pole) ?
CGAL::make_object (m_north_pole) : CGAL::make_object (m_north_face); Vert_type(m_north_pole) : Vert_type(m_north_face);
} }
/*! Get the current bottom object. */ /*! Get the current bottom object. */
CGAL::Object bottom_object () const Vert_type bottom_object () const
{ {
return (m_valid_south_pole) ? return (m_valid_south_pole) ?
CGAL::make_object(m_south_pole) : CGAL::make_object(m_south_face); Vert_type(m_south_pole) : Vert_type(m_south_face);
} }
}; };

View File

@ -8,8 +8,8 @@
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
// //
// //
// Author(s) : Ron Wein <wein@post.tau.ac.il> // Author(s): Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il> // Efi Fogel <efif@post.tau.ac.il>
#ifndef CGAL_ARR_UNB_PLANAR_TOPOLOGY_TRAITS_2_IMPL_H #ifndef CGAL_ARR_UNB_PLANAR_TOPOLOGY_TRAITS_2_IMPL_H
#define CGAL_ARR_UNB_PLANAR_TOPOLOGY_TRAITS_2_IMPL_H #define CGAL_ARR_UNB_PLANAR_TOPOLOGY_TRAITS_2_IMPL_H
@ -296,27 +296,31 @@ are_equal(const Vertex *v,
// represent the curve end along the face boundary. // represent the curve end along the face boundary.
// //
template <typename GeomTraits, typename Dcel_> template <typename GeomTraits, typename Dcel_>
CGAL::Object boost::optional
<boost::variant
<typename Arr_unb_planar_topology_traits_2<GeomTraits, Dcel_>::Vertex*,
typename Arr_unb_planar_topology_traits_2<GeomTraits, Dcel_>::Halfedge*> >
Arr_unb_planar_topology_traits_2<GeomTraits, Dcel_>:: Arr_unb_planar_topology_traits_2<GeomTraits, Dcel_>::
place_boundary_vertex(Face *f, place_boundary_vertex(Face* f,
const X_monotone_curve_2& cv, Arr_curve_end ind, const X_monotone_curve_2& cv, Arr_curve_end ind,
Arr_parameter_space ps_x, Arr_parameter_space ps_y) Arr_parameter_space ps_x, Arr_parameter_space ps_y)
{ {
// Get a halfedge on the outer CCB of f and start traversing the CCB. typedef boost::variant<Vertex*, Halfedge*> Non_optional_result;
Halfedge *first = *(f->outer_ccbs_begin()); typedef boost::optional<Non_optional_result> Result;
Halfedge *curr = first;
bool eq_source, eq_target;
do // Get a halfedge on the outer CCB of f and start traversing the CCB.
{ Halfedge* first = *(f->outer_ccbs_begin());
Halfedge* curr = first;
bool eq_source, eq_target;
do {
// Note we consider only fictitious halfedges and check whether they // Note we consider only fictitious halfedges and check whether they
// contain the relevant curve end. // contain the relevant curve end.
if (curr->has_null_curve() && if (curr->has_null_curve() &&
_is_on_fictitious_edge (cv, ind, ps_x, ps_y, curr, _is_on_fictitious_edge(cv, ind, ps_x, ps_y, curr, eq_source, eq_target))
eq_source, eq_target))
{ {
CGAL_assertion (! eq_source && ! eq_target); CGAL_assertion(! eq_source && ! eq_target);
return (CGAL::make_object (curr)); return Result(curr);
} }
// Move to the next halfegde along the CCB. // Move to the next halfegde along the CCB.
@ -327,59 +331,58 @@ place_boundary_vertex(Face *f,
// If we reached here, we did not find a suitable halfegde, which should // If we reached here, we did not find a suitable halfegde, which should
// never happen. // never happen.
CGAL_error(); CGAL_error();
return CGAL::Object(); return boost::none;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Locate a DCEL feature that contains the given unbounded curve end. // Locate a DCEL feature that contains the given unbounded curve end.
// //
template <typename GeomTraits, typename Dcel_> template <typename GeomTraits, typename Dcel_>
CGAL::Object Arr_unb_planar_topology_traits_2<GeomTraits, Dcel_>:: boost::variant
<typename Arr_unb_planar_topology_traits_2<GeomTraits, Dcel_>::Vertex*,
typename Arr_unb_planar_topology_traits_2<GeomTraits, Dcel_>::Halfedge*,
typename Arr_unb_planar_topology_traits_2<GeomTraits, Dcel_>::Face*>
Arr_unb_planar_topology_traits_2<GeomTraits, Dcel_>::
locate_curve_end (const X_monotone_curve_2& cv, Arr_curve_end ind, locate_curve_end (const X_monotone_curve_2& cv, Arr_curve_end ind,
Arr_parameter_space ps_x, Arr_parameter_space ps_y) Arr_parameter_space ps_x, Arr_parameter_space ps_y)
{ {
typedef boost::variant<Vertex*, Halfedge*, Face*> Result;
// Start traversing the inner CCB of the fictitious face and try to locate // Start traversing the inner CCB of the fictitious face and try to locate
// a feature that contains the curve end. // a feature that contains the curve end.
Halfedge *first = *(fict_face->inner_ccbs_begin()); Halfedge* first = *(fict_face->inner_ccbs_begin());
Halfedge *curr = first; Halfedge* curr = first;
bool eq_source, eq_target; bool eq_source, eq_target;
do do {
{ if (_is_on_fictitious_edge(cv, ind, ps_x, ps_y, curr, eq_source, eq_target))
if (_is_on_fictitious_edge (cv, ind, ps_x, ps_y, curr,
eq_source, eq_target))
{ {
if (eq_source) if (eq_source) {
{
// cv's end coincides with the source vertex of the current // cv's end coincides with the source vertex of the current
// fictitious halfedge. This means that cv overlaps the curve that // fictitious halfedge. This means that cv overlaps the curve that
// is associated with the only non-fictitious halfedge incident to // is associated with the only non-fictitious halfedge incident to
// this vertex. We therefore return a pointer to this halfedge. // this vertex. We therefore return a pointer to this halfedge.
Halfedge *he = curr->opposite()->next(); Halfedge* he = curr->opposite()->next();
CGAL_assertion(! he->has_null_curve());
CGAL_assertion (! he->has_null_curve()); return Result(he);
return (CGAL::make_object (he));
} }
else if (eq_target) else if (eq_target) {
{
// cv's end coincides with the target vertex of the current // cv's end coincides with the target vertex of the current
// fictitious halfedge. This means that cv overlaps the curve that // fictitious halfedge. This means that cv overlaps the curve that
// is associated with the only non-fictitious halfedge incident to // is associated with the only non-fictitious halfedge incident to
// this vertex. We therefore return a pointer to this halfedge. // this vertex. We therefore return a pointer to this halfedge.
Halfedge *he = curr->opposite()->prev(); Halfedge* he = curr->opposite()->prev();
CGAL_assertion(! he->has_null_curve());
CGAL_assertion (! he->has_null_curve()); return Result(he);
return (CGAL::make_object (he));
} }
// The current ficitious edge contains cv's end in its interior. // The current ficitious edge contains cv's end in its interior.
// Note we use curr's twin, whose incident face is a valid // Note we use curr's twin, whose incident face is a valid
// unbounded face (whereas the incident face of curr is the fictitious // unbounded face (whereas the incident face of curr is the fictitious
// face). // face).
Face *uf = curr->opposite()->outer_ccb()->face(); Face* uf = curr->opposite()->outer_ccb()->face();
CGAL_assertion (uf->is_unbounded() && ! uf->is_fictitious()); CGAL_assertion (uf->is_unbounded() && ! uf->is_fictitious());
return (CGAL::make_object (uf)); return Result(uf);
} }
curr = curr->next(); curr = curr->next();
@ -388,7 +391,8 @@ locate_curve_end (const X_monotone_curve_2& cv, Arr_curve_end ind,
// We should never reach here. // We should never reach here.
CGAL_error(); CGAL_error();
return Object(); Vertex* v(nullptr);
return Result(v);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -7,9 +7,8 @@
// $Id$ // $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
// //
// // Author(s): Ron Wein <wein@post.tau.ac.il>
// Author(s) : Ron Wein <wein@post.tau.ac.il> // Efi Fogel <efif@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
#ifndef CGAL_ARR_UNB_PLANAR_VERT_DECOMP_HELPER_H #ifndef CGAL_ARR_UNB_PLANAR_VERT_DECOMP_HELPER_H
#define CGAL_ARR_UNB_PLANAR_VERT_DECOMP_HELPER_H #define CGAL_ARR_UNB_PLANAR_VERT_DECOMP_HELPER_H
@ -43,12 +42,16 @@ private:
typedef Geometry_traits_2 Gt2; typedef Geometry_traits_2 Gt2;
public: public:
typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle;
typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
typedef typename Arrangement_2::Face_const_handle Face_const_handle; typedef typename Arrangement_2::Face_const_handle Face_const_handle;
typedef boost::variant<Vertex_const_handle, Halfedge_const_handle,
Face_const_handle> Cell_type;
typedef boost::optional<Cell_type> Vert_type;
protected: protected:
typedef typename Arrangement_2::Topology_traits Topology_traits; typedef typename Arrangement_2::Topology_traits Topology_traits;
typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle;
// Data members: // Data members:
const Topology_traits* m_top_traits; // The topology-traits class. const Topology_traits* m_top_traits; // The topology-traits class.
@ -77,10 +80,10 @@ public:
//@} //@}
/*! Get the current top object. */ /*! Get the current top object. */
CGAL::Object top_object() const { return CGAL::make_object(m_top_fict); } Vert_type top_object() const { return Vert_type(m_top_fict); }
/*! Get the current bottom object. */ /*! Get the current bottom object. */
CGAL::Object bottom_object() const { return CGAL::make_object(m_bottom_fict); } Vert_type bottom_object() const { return Vert_type(m_bottom_fict); }
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -504,7 +504,12 @@ public:
} }
}; };
/*! A functor that divides a curve into x-monotone curves. */ //! \name Intersections & subdivisions
//@{
/*! \class Make_x_monotone_2
* A functor for subdividing curves into x-monotone curves.
*/
class Make_x_monotone_2 { class Make_x_monotone_2 {
private: private:
typename Base::Make_x_monotone_2 m_object; typename Base::Make_x_monotone_2 m_object;
@ -515,39 +520,43 @@ public:
Make_x_monotone_2(const Base * base, bool enabled = true) : Make_x_monotone_2(const Base * base, bool enabled = true) :
m_object(base->make_x_monotone_2_object()), m_enabled(enabled) {} m_object(base->make_x_monotone_2_object()), m_enabled(enabled) {}
/*! Operate /*! Subdivide a given curve into x-monotone subcurves and insert them into
* \param cv the curve * a given output iterator.
* \param oi an output iterator that contains the result. It's value * \param cv the curve.
* type is CGAL::Object, which wraps either an x-monotone curve or a point * \param oi an output iterator for the result. Its value type is a variant
* \return the output iterator * that wraps Point_2 or X_monotone_curve_2 objects.
* \return the output iterator.
*/ */
template<typename OutputIterator> template <typename OutputIterator>
OutputIterator operator()(const Curve_2 & cv, OutputIterator oi) const OutputIterator operator()(const Curve_2 & cv, OutputIterator oi) const
{ {
if (!m_enabled) return m_object(cv, oi); if (! m_enabled) return m_object(cv, oi);
std::cout << "make_x_monotone" << std::endl std::cout << "make_x_monotone" << std::endl
<< " cv: " << cv << std::endl; << " cv: " << cv << std::endl;
std::list<CGAL::Object> container;
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
std::list<Make_x_monotone_result> container;
m_object(cv, std::back_inserter(container)); m_object(cv, std::back_inserter(container));
if (container.empty()) return oi; if (container.empty()) return oi;
std::list<CGAL::Object>::iterator it; size_t i = 0;
unsigned int i = 0; for (auto it = container.begin(); it != container.end(); ++it) {
for (it = container.begin(); it != container.end(); ++it) { if (const auto* xcv = boost::get<X_monotone_curve_2>(*it)) {
X_monotone_curve_2 xcv; std::cout << " result[" << i++ << "]: xcv: " << *xcv << std::endl;
if (assign (xcv, *it)) {
std::cout << " result[" << i++ << "]: xcv: " << xcv << std::endl;
continue; continue;
} }
Point_2 p; if (const Point_2* p = boost::get<Point_2>(*it)) {
if (assign (p, *it)) { std::cout << " result[" << i++ << "]: p: " << *p << std::endl;
std::cout << " result[" << i++ << "]: p: " << p << std::endl;
continue; continue;
} }
CGAL_error();
} }
for (it = container.begin(); it != container.end(); ++it) *oi++ = *it; for (auto it = container.begin(); it != container.end(); ++it) *oi++ = *it;
container.clear(); container.clear();
return oi; return oi;
} }
@ -597,14 +606,14 @@ public:
Intersect_2(const Base* base, bool enabled = true) : Intersect_2(const Base* base, bool enabled = true) :
m_object(base->intersect_2_object()), m_enabled(enabled) {} m_object(base->intersect_2_object()), m_enabled(enabled) {}
/*! Operate /*! Compute the intersections of the two given curves and insert them into
* a given output iterator.
* \param xcv1 the first curve * \param xcv1 the first curve
* \param xcv2 the ssecond curve * \param xcv2 the ssecond curve
* \param oi an output iterator that contains the result. It's value * \param oi the output iterator for the result. It value type is a variant
* type is CGAL::Object, which wraps either an x-monotone overlapping * that wraps an x-monotone overlapping curve or a pair that
* curve or pair that consists of an intersection point and its * consists of the intersection point and its multiplicity
* multiplicity * \return the past-the-end output iterator.
* \return the output iterator
*/ */
template <typename OutputIterator> template <typename OutputIterator>
OutputIterator operator()(const X_monotone_curve_2 & xcv1, OutputIterator operator()(const X_monotone_curve_2 & xcv1,

View File

@ -7,9 +7,8 @@
// $Id$ // $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
// //
// // Author(s): Ron Wein <wein@post.tau.ac.il>
// Author(s) : Ron Wein <wein@post.tau.ac.il> // Efi Fogel <efif@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
#ifndef CGAL_ARR_UNB_PLANAR_TOPOLOGY_TRAITS_2_H #ifndef CGAL_ARR_UNB_PLANAR_TOPOLOGY_TRAITS_2_H
#define CGAL_ARR_UNB_PLANAR_TOPOLOGY_TRAITS_2_H #define CGAL_ARR_UNB_PLANAR_TOPOLOGY_TRAITS_2_H
@ -308,11 +307,12 @@ public:
* \return An object that contains the curve end. * \return An object that contains the curve end.
* In our case this object always wraps a fictitious edge. * In our case this object always wraps a fictitious edge.
*/ */
CGAL::Object place_boundary_vertex(Face* f, boost::optional<boost::variant<Vertex*, Halfedge*> >
const X_monotone_curve_2& cv, place_boundary_vertex(Face* f,
Arr_curve_end ind, const X_monotone_curve_2& cv,
Arr_parameter_space ps_x, Arr_curve_end ind,
Arr_parameter_space ps_y); Arr_parameter_space ps_x,
Arr_parameter_space ps_y);
/*! Locate the predecessor halfedge for the given curve around a given /*! Locate the predecessor halfedge for the given curve around a given
* vertex with boundary conditions. * vertex with boundary conditions.
@ -346,10 +346,11 @@ public:
* In our case this object may either wrap an unbounded face, * In our case this object may either wrap an unbounded face,
* or an edge with an end-vertex at infinity (in case of an overlap). * or an edge with an end-vertex at infinity (in case of an overlap).
*/ */
CGAL::Object locate_curve_end(const X_monotone_curve_2& cv, boost::variant<Vertex*, Halfedge*, Face*>
Arr_curve_end ind, locate_curve_end(const X_monotone_curve_2& cv,
Arr_parameter_space ps_x, Arr_curve_end ind,
Arr_parameter_space ps_y); Arr_parameter_space ps_x,
Arr_parameter_space ps_y);
/*! Split a fictitious edge using the given vertex. /*! Split a fictitious edge using the given vertex.
* \param e The edge to split (one of the pair of halfedges). * \param e The edge to split (one of the pair of halfedges).

View File

@ -7,7 +7,7 @@
// $Id$ // $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
// //
// Author(s) : Ron Wein <wein@post.tau.ac.il> // Author(s): Ron Wein <wein@post.tau.ac.il>
#ifndef CGAL_ARR_VERTICAL_DECOMPOSITION_2_H #ifndef CGAL_ARR_VERTICAL_DECOMPOSITION_2_H
#define CGAL_ARR_VERTICAL_DECOMPOSITION_2_H #define CGAL_ARR_VERTICAL_DECOMPOSITION_2_H
@ -34,14 +34,13 @@ namespace Ss2 = Surface_sweep_2;
/*! Perform a vertical decomposition of an arrangement, by performing a /*! Perform a vertical decomposition of an arrangement, by performing a
* "batched vertical ray-shooting" query from all arrangement vertices. * "batched vertical ray-shooting" query from all arrangement vertices.
* \param arr The arrangement. * \param arr The arrangement.
* \param oi Output: An output iterator of the vertices, each paired with * \param oi An output iterator of the vertices, each paired with a pair of
* a pair of arrangement features that lie below and above * arrangement features that lie below and above it, respectively.
* it, respectively. * The vertices are sorted by increasing xy-order.
* The vertices are sorted by increasing xy-order. * The OutputIterator dereferences the type \c
* pair<Vertex_const_handle, pair<Vert_type, Vert_type> >, where
* \c Vert_type is an optional handle to an arrangement feature.
* \return A past-the-end iterator for the ordered arrangement vertices. * \return A past-the-end iterator for the ordered arrangement vertices.
* \pre The value-type of OutputIterator is
* pair<Vertex_const_handle, pair<Object, Object> >, where
* the Object represents a handle to an arrangement feature.
*/ */
template <typename GeometryTraits_2, typename TopologyTraits, template <typename GeometryTraits_2, typename TopologyTraits,
typename OutputIterator> typename OutputIterator>

View File

@ -8,27 +8,29 @@
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
// //
// //
// Author(s) : Ophir Setter <ophirset@post.tau.ac.il> // Author(s) : Ophir Setter <ophirset@post.tau.ac.il>
// Efi Fogel <efifogel@gmail.com>
// //
#ifndef CGAL_ARR_COMPUTE_ZONE_VISITOR_H #ifndef CGAL_ARR_COMPUTE_ZONE_VISITOR_H
#define CGAL_ARR_COMPUTE_ZONE_VISITOR_H #define CGAL_ARR_COMPUTE_ZONE_VISITOR_H
#include <CGAL/license/Arrangement_on_surface_2.h> #include <CGAL/license/Arrangement_on_surface_2.h>
/*! \file /*! \file
* Definition of the Arr_compute_zone_visitor class. * Definition of the Arr_compute_zone_visitor class.
*/ */
#include <boost/variant.hpp>
namespace CGAL { namespace CGAL {
/*! \class /*! \class
* A visitor class for Arrangement_zone_2, which outputs the * A visitor class for Arrangement_zone_2 that outputs the zone of an
* zone of an x-monotone curve. Meaning, it output the arrangment's * x-monotone curve. Specifically, it outputs handles to the the arrangment
* vertices, edges and faces that the x-monotone curve intersects. * cells that the x-monotone curve intersects.
* The class should be templated by an Arrangement_2 class, and by an * The class should be templated by an Arrangement_2 class, and by an
* output iterator of CGAL Objects, where we store all arrangement * output iterator of a variant of types of handles to the arrangement cells
* features the x-monotone curve intersects. * that appear in the zone, namely, vertex, halfedge, and face handles.
*/ */
template <class Arrangement_, class OutputIterator_> template <class Arrangement_, class OutputIterator_>
class Arr_compute_zone_visitor class Arr_compute_zone_visitor
@ -53,7 +55,7 @@ private:
const Vertex_handle invalid_v; // Invalid vertex. const Vertex_handle invalid_v; // Invalid vertex.
OutputIterator& out_iter; // for outputing the zone objects. OutputIterator& out_iter; // for outputing the zone objects.
// Its value type is CGAL::Object. // Its value type is boost::variant.
bool output_left; // Determines wheter we should bool output_left; // Determines wheter we should
// output the left end point of a // output the left end point of a
// subcurve (to avoid outputing // subcurve (to avoid outputing
@ -65,8 +67,8 @@ public:
Arr_compute_zone_visitor (OutputIterator& oi) : Arr_compute_zone_visitor (OutputIterator& oi) :
invalid_he(), invalid_he(),
invalid_v(), invalid_v(),
out_iter (oi), out_iter(oi),
output_left (true) output_left(true)
{} {}
/*! Initialize the visitor. */ /*! Initialize the visitor. */
@ -90,50 +92,35 @@ public:
* \return A handle to the halfedge obtained from the insertion of the * \return A handle to the halfedge obtained from the insertion of the
* subcurve into the arrangement. * subcurve into the arrangement.
*/ */
Result found_subcurve (const X_monotone_curve_2&, Result found_subcurve(const X_monotone_curve_2&,
Face_handle face, Face_handle face,
Vertex_handle left_v, Halfedge_handle left_he, Vertex_handle left_v, Halfedge_handle left_he,
Vertex_handle right_v, Halfedge_handle right_he) Vertex_handle right_v, Halfedge_handle right_he)
{ {
if (output_left) typedef boost::variant<Vertex_handle, Halfedge_handle, Face_handle>
{ Zone_result;
if (output_left) {
// Only the first subcurve should output the arrangement feature incident // Only the first subcurve should output the arrangement feature incident
// to its left endpoint. This way we avoid reporting the same feature // to its left endpoint. This way we avoid reporting the same feature
// twice. // twice.
if (left_v != invalid_v) if (left_v != invalid_v) *out_iter++ = Zone_result(left_v);
{ else if (left_he != invalid_he) *out_iter++ = Zone_result(left_he);
*out_iter = CGAL::make_object (left_v);
++out_iter;
}
else if (left_he != invalid_he)
{
*out_iter = CGAL::make_object (left_he);
++out_iter;
}
output_left = false; output_left = false;
} }
// Report the face that contains the interior of the subcurve. // Report the face that contains the interior of the subcurve.
*out_iter = CGAL::make_object (face); *out_iter++ = Zone_result(face);
++out_iter;
// If the right endpoint of the subcurve is incident to an arrangement // If the right endpoint of the subcurve is incident to an arrangement
// vertex or an arrangement edge, report this feature. // vertex or an arrangement edge, report this feature.
if (right_v != invalid_v) if (right_v != invalid_v) *out_iter++ = Zone_result(right_v);
{ else if (right_he != invalid_he) *out_iter++ = Zone_result(right_he);
*out_iter = CGAL::make_object(right_v);
++out_iter;
}
else if (right_he != invalid_he)
{
*out_iter = CGAL::make_object(right_he);
++out_iter;
}
// We did not modify the arrangement, so we return an invalid handle // We did not modify the arrangement, so we return an invalid handle
// and a flag indicating that the zone-computation process should continue. // and a flag indicating that the zone-computation process should continue.
return (Result (invalid_he, false)); return Result(invalid_he, false);
} }
/*! /*!
@ -151,35 +138,28 @@ public:
Halfedge_handle he, Halfedge_handle he,
Vertex_handle left_v, Vertex_handle right_v) Vertex_handle left_v, Vertex_handle right_v)
{ {
if (output_left) typedef boost::variant<Vertex_handle, Halfedge_handle, Face_handle>
{ Zone_result;
if (output_left) {
// Only the first subcurve should output the arrangement feature incident // Only the first subcurve should output the arrangement feature incident
// to its left endpoint. This way we avoid reporting the same feature // to its left endpoint. This way we avoid reporting the same feature
// twice. // twice.
if (left_v != invalid_v) if (left_v != invalid_v) *out_iter++ = Zone_result(left_v);
{
*out_iter = CGAL::make_object (left_v);
++out_iter;
}
output_left = false; output_left = false;
} }
// Report the arrangement edge the curve currently overlaps. // Report the arrangement edge the curve currently overlaps.
*out_iter = CGAL::make_object(he); *out_iter++ = Zone_result(he);
++out_iter;
// If the right endpoint of the overlapping subcurve is incident to an // If the right endpoint of the overlapping subcurve is incident to an
// arrangement vertex, report this vertex as well. // arrangement vertex, report this vertex as well.
if (right_v != invalid_v) if (right_v != invalid_v) *out_iter++ = Zone_result(right_v);
{
*out_iter = CGAL::make_object (right_v);
++out_iter;
}
// We did not modify the arrangement, so we return an invalid handle // We did not modify the arrangement, so we return an invalid handle
// and a flag indicating that the zone-computation process should continue. // and a flag indicating that the zone-computation process should continue.
return (Result (invalid_he, false)); return Result(invalid_he, false);
} }
}; };

View File

@ -8,7 +8,6 @@
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
// $Date$ // $Date$
// //
//
// Author(s): Ron Wein <wein@post.tau.ac.il>s // Author(s): Ron Wein <wein@post.tau.ac.il>s
// Efi Fogel <efif@post.tau.ac.il> // Efi Fogel <efif@post.tau.ac.il>
// Eric Berberich <eric@mpi-inf.mpg.de> // Eric Berberich <eric@mpi-inf.mpg.de>
@ -24,7 +23,6 @@
#include <CGAL/license/Arrangement_on_surface_2.h> #include <CGAL/license/Arrangement_on_surface_2.h>
/*! \file /*! \file
* Definitions of the adaptor classes for the arrangement traits class. * Definitions of the adaptor classes for the arrangement traits class.
*/ */
@ -50,6 +48,7 @@ public:
typedef Arr_traits_basic_adaptor_2<Base> Self; typedef Arr_traits_basic_adaptor_2<Base> Self;
typedef typename Base::X_monotone_curve_2 X_monotone_curve_2; typedef typename Base::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Base::Point_2 Point_2; typedef typename Base::Point_2 Point_2;
typedef typename Base::Multiplicity Multiplicity;
// Categories // Categories
typedef typename Base::Has_left_category Has_left_category; typedef typename Base::Has_left_category Has_left_category;
@ -320,9 +319,12 @@ public:
const X_monotone_curve_2& xcv2, const X_monotone_curve_2& xcv2,
Tag_false) const Tag_false) const
{ {
std::list<CGAL::Object> intersections; typedef std::pair<Point_2, Multiplicity> Intersection_point;
typedef boost::variant<Intersection_point, X_monotone_curve_2>
Intersection_result;
std::list<Intersection_result> intersections;
m_self->intersect_2_object()(xcv1, xcv2, back_inserter(intersections)); m_self->intersect_2_object()(xcv1, xcv2, back_inserter(intersections));
return !intersections.empty(); return ! intersections.empty();
} }
}; };
@ -665,7 +667,7 @@ public:
return parameter_space_in_y(xcv, ind, Psy_2_curve_end_tag()); return parameter_space_in_y(xcv, ind, Psy_2_curve_end_tag());
} }
/*! /*!
* Obtain the location of the given curve end in y. * Obtain the location of the given curve end in y.
* \param xcv The curve. * \param xcv The curve.
* \return The location of the curve end in y direction. * \return The location of the curve end in y direction.
@ -2276,6 +2278,7 @@ public:
typedef typename Base_traits_2::Curve_2 Curve_2; typedef typename Base_traits_2::Curve_2 Curve_2;
typedef typename Base::X_monotone_curve_2 X_monotone_curve_2; typedef typename Base::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Base::Point_2 Point_2; typedef typename Base::Point_2 Point_2;
typedef typename Base::Multiplicity Multiplicity;
// Categories. // Categories.
typedef typename Base::Has_left_category Has_left_category; typedef typename Base::Has_left_category Has_left_category;
@ -2324,6 +2327,10 @@ public:
* endpoint, then by the graphs, and finally by their right-most endpoint. * endpoint, then by the graphs, and finally by their right-most endpoint.
*/ */
class Compare_xy_2 { class Compare_xy_2 {
typedef std::pair<Point_2, Multiplicity> Intersection_point;
typedef boost::variant<Intersection_point, X_monotone_curve_2>
Intersection_result;
public: public:
/*! Compare two points lexigoraphically: by x, then by y. /*! Compare two points lexigoraphically: by x, then by y.
* \param p1 the first point. * \param p1 the first point.
@ -2360,7 +2367,7 @@ public:
Comparison_result operator()(const X_monotone_curve_2& c1, Comparison_result operator()(const X_monotone_curve_2& c1,
const X_monotone_curve_2& c2) const const X_monotone_curve_2& c2) const
{ {
std::list<CGAL::Object> intersections; std::list<Intersection_result> intersections;
return operator()(c1, c2, intersections, return operator()(c1, c2, intersections,
Are_all_sides_oblivious_category()); Are_all_sides_oblivious_category());
} }
@ -2586,7 +2593,7 @@ public:
Comparison_result Comparison_result
compare_remainder(const X_monotone_curve_2& c1, compare_remainder(const X_monotone_curve_2& c1,
const X_monotone_curve_2& c2, const X_monotone_curve_2& c2,
std::list<CGAL::Object>& intersections) const std::list<Intersection_result>& intersections) const
{ {
// Right-most sections are equal. // Right-most sections are equal.
// Advance to the next respective sections: // Advance to the next respective sections:
@ -2597,9 +2604,9 @@ public:
} }
// Verify the first intersection is an overlap, remove it, and // Verify the first intersection is an overlap, remove it, and
// recursively call. // recursively call.
CGAL::Object first = intersections.front(); const X_monotone_curve_2* xcv =
X_monotone_curve_2 xcv; boost::get<X_monotone_curve_2>(&(intersections.front()));
if (!assign(xcv, first)) { if (! xcv) {
CGAL_error_msg("The first intersection is not an overlap!"); CGAL_error_msg("The first intersection is not an overlap!");
return SMALLER; return SMALLER;
} }
@ -2611,10 +2618,9 @@ public:
typedef typename Self::Split_2 Split_2; typedef typename Self::Split_2 Split_2;
Split_2 split = m_self.split_2_object(); Split_2 split = m_self.split_2_object();
X_monotone_curve_2 c11, c12, c21, c22; X_monotone_curve_2 c11, c12, c21, c22;
Construct_max_vertex_2 ctr_max = Construct_max_vertex_2 ctr_max = m_self.construct_max_vertex_2_object();
m_self.construct_max_vertex_2_object(); const Point_2& p1 = ctr_max(*xcv);
const Point_2& p1 = ctr_max(xcv); const Point_2& p2 = ctr_max(*xcv);
const Point_2& p2 = ctr_max(xcv);
split(c1, p1, c11, c12); split(c1, p1, c11, c12);
split(c2, p2, c21, c22); split(c2, p2, c21, c22);
return operator()(c12, c22, intersections, return operator()(c12, c22, intersections,
@ -2625,7 +2631,7 @@ public:
*/ */
Comparison_result operator()(const X_monotone_curve_2& c1, Comparison_result operator()(const X_monotone_curve_2& c1,
const X_monotone_curve_2& c2, const X_monotone_curve_2& c2,
std::list<CGAL::Object>& intersections, std::list<Intersection_result>& intersections,
Arr_all_sides_oblivious_tag) const Arr_all_sides_oblivious_tag) const
{ {
const Point_2& c1_min = m_self.construct_min_vertex_2_object()(c1); const Point_2& c1_min = m_self.construct_min_vertex_2_object()(c1);
@ -2646,7 +2652,7 @@ public:
*/ */
Comparison_result operator()(const X_monotone_curve_2& c1, Comparison_result operator()(const X_monotone_curve_2& c1,
const X_monotone_curve_2& c2, const X_monotone_curve_2& c2,
std::list<CGAL::Object>& intersections, std::list<Intersection_result>& intersections,
Arr_not_all_sides_oblivious_tag) const Arr_not_all_sides_oblivious_tag) const
{ {
typedef typename Base::Parameter_space_in_x_2 Parameter_space_in_x_2; typedef typename Base::Parameter_space_in_x_2 Parameter_space_in_x_2;

View File

@ -8,9 +8,9 @@
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
// //
// //
// Author(s) : Ron Wein <wein@post.tau.ac.il> // Author(s): Ron Wein <wein@post.tau.ac.il>
// Baruch Zukerman <baruchzu@post.tau.ac.il> // Baruch Zukerman <baruchzu@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il> // Efi Fogel <efif@post.tau.ac.il>
// //
#ifndef CGAL_ARRANGEMENT_ON_SURFACE_2_GLOBAL_H #ifndef CGAL_ARRANGEMENT_ON_SURFACE_2_GLOBAL_H
#define CGAL_ARRANGEMENT_ON_SURFACE_2_GLOBAL_H #define CGAL_ARRANGEMENT_ON_SURFACE_2_GLOBAL_H
@ -32,6 +32,7 @@
#include <CGAL/Arrangement_2/Arr_compute_zone_visitor.h> #include <CGAL/Arrangement_2/Arr_compute_zone_visitor.h>
#include <CGAL/Arrangement_2/Arr_do_intersect_zone_visitor.h> #include <CGAL/Arrangement_2/Arr_do_intersect_zone_visitor.h>
#include <CGAL/Arrangement_2/Arr_traits_adaptor_2.h> #include <CGAL/Arrangement_2/Arr_traits_adaptor_2.h>
#include <CGAL/Arr_point_location_result.h>
#include <CGAL/No_intersection_surface_sweep_2.h> #include <CGAL/No_intersection_surface_sweep_2.h>
#include <CGAL/Surface_sweep_2/Arr_insertion_ss_visitor.h> #include <CGAL/Surface_sweep_2/Arr_insertion_ss_visitor.h>
#include <CGAL/Surface_sweep_2/Arr_no_intersection_insertion_ss_visitor.h> #include <CGAL/Surface_sweep_2/Arr_no_intersection_insertion_ss_visitor.h>
@ -80,6 +81,10 @@ void insert(Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr,
typedef Arrangement_on_surface_2<Gt2, Tt> Arr; typedef Arrangement_on_surface_2<Gt2, Tt> Arr;
typedef ZoneVisitor Zone_visitor; typedef ZoneVisitor Zone_visitor;
typedef typename Gt2::Point_2 Point_2;
typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2;
typedef boost::variant<Point_2, X_monotone_curve_2> Make_x_monotone_result;
// Obtain an arrangement accessor. // Obtain an arrangement accessor.
Arr_accessor<Arr> arr_access(arr); Arr_accessor<Arr> arr_access(arr);
@ -88,19 +93,14 @@ void insert(Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr,
Arrangement_zone_2<Arr, Zone_visitor> arr_zone(arr, &visitor); Arrangement_zone_2<Arr, Zone_visitor> arr_zone(arr, &visitor);
// Break the input curve into x-monotone subcurves and isolated points. // Break the input curve into x-monotone subcurves and isolated points.
std::list<CGAL::Object> x_objects; std::list<Make_x_monotone_result> x_objects;
std::list<CGAL::Object>::const_iterator obj_iter; const auto* traits = arr.geometry_traits();
const typename Gt2::X_monotone_curve_2* x_curve; traits->make_x_monotone_2_object()(c, std::back_inserter(x_objects));
const typename Gt2::Point_2* iso_p;
arr.geometry_traits()->
make_x_monotone_2_object()(c, std::back_inserter(x_objects));
// Insert each x-monotone curve into the arrangement. // Insert each x-monotone curve into the arrangement.
for (obj_iter = x_objects.begin(); obj_iter != x_objects.end(); ++obj_iter) { for (const auto& x_obj : x_objects) {
// Act according to the type of the current object. // Act according to the type of the current object.
x_curve = object_cast<typename Gt2::X_monotone_curve_2>(&(*obj_iter)); const auto* x_curve = boost::get<X_monotone_curve_2>(&x_obj);
if (x_curve != nullptr) { if (x_curve != nullptr) {
// Inserting an x-monotone curve: // Inserting an x-monotone curve:
// Initialize the zone-computation object with the given curve. // Initialize the zone-computation object with the given curve.
@ -116,14 +116,13 @@ void insert(Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr,
// Notify the arrangement observers that the global operation has been // Notify the arrangement observers that the global operation has been
// completed. // completed.
arr_access.notify_after_global_change(); arr_access.notify_after_global_change();
continue;
} }
else { const auto* iso_p = boost::get<Point_2>(&x_obj);
iso_p = object_cast<typename Gt2::Point_2>(&(*obj_iter)); CGAL_assertion(iso_p != nullptr);
CGAL_assertion(iso_p != nullptr);
// Inserting a point into the arrangement: // Inserting a point into the arrangement:
insert_point(arr, *iso_p, pl); insert_point(arr, *iso_p, pl);
}
} }
} }
@ -529,7 +528,9 @@ void insert(Arrangement_on_surface_2<GeometryTraits_2,TopologyTraits>& arr,
template <typename GeometryTraits_2, typename TopologyTraits> template <typename GeometryTraits_2, typename TopologyTraits>
void insert(Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr, void insert(Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr,
const typename GeometryTraits_2::X_monotone_curve_2& c, const typename GeometryTraits_2::X_monotone_curve_2& c,
const Object& obj) typename Arr_point_location_result<
Arrangement_on_surface_2<GeometryTraits_2,
TopologyTraits> >::type obj)
{ {
typedef GeometryTraits_2 Gt2; typedef GeometryTraits_2 Gt2;
typedef TopologyTraits Tt; typedef TopologyTraits Tt;
@ -597,7 +598,8 @@ template <typename GeometryTraits_2, typename TopologyTraits>
CGAL_DEPRECATED void insert_x_monotone_curve CGAL_DEPRECATED void insert_x_monotone_curve
(Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr, (Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr,
const typename GeometryTraits_2::X_monotone_curve_2& c, const typename GeometryTraits_2::X_monotone_curve_2& c,
const Object& obj) typename Arr_point_location_result<
Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits> >::type obj)
{ {
insert(arr, c, obj); insert(arr, c, obj);
} }
@ -658,6 +660,7 @@ insert_non_intersecting_curve
Traits_adaptor_2; Traits_adaptor_2;
typedef typename Arr::Vertex_const_handle Vertex_const_handle; typedef typename Arr::Vertex_const_handle Vertex_const_handle;
typedef typename Arr::Halfedge_const_handle Halfedge_const_handle; typedef typename Arr::Halfedge_const_handle Halfedge_const_handle;
typedef typename Arr::Face_const_handle Face_const_handle;
CGAL_USE_TYPE(Halfedge_const_handle); CGAL_USE_TYPE(Halfedge_const_handle);
const Traits_adaptor_2* geom_traits = const Traits_adaptor_2* geom_traits =
@ -666,13 +669,13 @@ insert_non_intersecting_curve
// Check whether the left end has boundary conditions, and locate it in the // Check whether the left end has boundary conditions, and locate it in the
// arrangement accordingly. // arrangement accordingly.
const Arr_parameter_space bx1 = auto bx1 = geom_traits->parameter_space_in_x_2_object()(c, ARR_MIN_END);
geom_traits->parameter_space_in_x_2_object()(c, ARR_MIN_END); auto by1 = geom_traits->parameter_space_in_y_2_object()(c, ARR_MIN_END);
const Arr_parameter_space by1 =
geom_traits->parameter_space_in_y_2_object()(c, ARR_MIN_END);
CGAL::Object obj1;
const Vertex_const_handle* vh1 = nullptr; const Vertex_const_handle* vh1 = nullptr;
typedef Arr_point_location_result<Arr> Pl_result;
typename Pl_result::type obj1;
if ((bx1 == ARR_INTERIOR) && (by1 == ARR_INTERIOR)) { if ((bx1 == ARR_INTERIOR) && (by1 == ARR_INTERIOR)) {
// We have a normal left endpoint with no boundary conditions: // We have a normal left endpoint with no boundary conditions:
// use a point-location query. // use a point-location query.
@ -680,33 +683,26 @@ insert_non_intersecting_curve
// The endpoint must not lie on an existing edge, but may coincide with // The endpoint must not lie on an existing edge, but may coincide with
// and existing vertex vh1. // and existing vertex vh1.
CGAL_precondition_msg CGAL_precondition_msg(boost::get<Halfedge_const_handle>(&obj1) == nullptr,
(object_cast<Halfedge_const_handle>(&obj1) == nullptr, "The curve must not intersect an existing edge.");
"The curve must not intersect an existing edge.");
vh1 = object_cast<Vertex_const_handle>(&obj1);
} }
else { else {
// We have a left end with boundary conditions. Use the accessor to locate // We have a left end with boundary conditions. Use the accessor to locate
// the feature that contains it. // the feature that contains it.
obj1 = arr_access.locate_curve_end(c, ARR_MIN_END, bx1, by1); obj1 = arr_access.locate_curve_end(c, ARR_MIN_END, bx1, by1);
CGAL_precondition_msg(boost::get<Halfedge_const_handle>(&obj1) == nullptr,
CGAL_precondition_msg "The curve must not overlap an existing edge.");
(object_cast<Halfedge_const_handle>(&obj1) == nullptr,
"The curve must not overlap an existing edge.");
vh1 = object_cast<Vertex_const_handle>(&obj1);
} }
vh1 = Pl_result::template assign<Vertex_const_handle>(&obj1);
// Check whether the right end has boundary conditions, and locate it in the // Check whether the right end has boundary conditions, and locate it in the
// arrangement accordingly. // arrangement accordingly.
const Arr_parameter_space bx2 = auto bx2 = geom_traits->parameter_space_in_x_2_object()(c, ARR_MAX_END);
geom_traits->parameter_space_in_x_2_object()(c, ARR_MAX_END); auto by2 = geom_traits->parameter_space_in_y_2_object()(c, ARR_MAX_END);
const Arr_parameter_space by2 =
geom_traits->parameter_space_in_y_2_object()(c, ARR_MAX_END);
CGAL::Object obj2;
const Vertex_const_handle* vh2 = nullptr; const Vertex_const_handle* vh2 = nullptr;
typename Pl_result::type obj2;
if ((bx2 == ARR_INTERIOR) && (by2 == ARR_INTERIOR)) { if ((bx2 == ARR_INTERIOR) && (by2 == ARR_INTERIOR)) {
// We have a normal right endpoint with no boundary conditions: // We have a normal right endpoint with no boundary conditions:
// use a point-location query. // use a point-location query.
@ -714,11 +710,8 @@ insert_non_intersecting_curve
// The endpoint must not lie on an existing edge, but may coincide with // The endpoint must not lie on an existing edge, but may coincide with
// and existing vertex vh2. // and existing vertex vh2.
CGAL_precondition_msg CGAL_precondition_msg(boost::get<Halfedge_const_handle>(&obj2) == nullptr,
(object_cast<Halfedge_const_handle>(&obj2) == nullptr, "The curve must not intersect an existing edge.");
"The curve must not intersect an existing edge.");
vh2 = object_cast<Vertex_const_handle>(&obj2);
} }
else { else {
// We have a right end with boundary conditions. Use the accessor to locate // We have a right end with boundary conditions. Use the accessor to locate
@ -728,13 +721,10 @@ insert_non_intersecting_curve
// << ", by2: " << by2 // << ", by2: " << by2
// << std::endl; // << std::endl;
obj2 = arr_access.locate_curve_end(c, ARR_MAX_END, bx2, by2); obj2 = arr_access.locate_curve_end(c, ARR_MAX_END, bx2, by2);
CGAL_precondition_msg(boost::get<Halfedge_const_handle>(&obj2) == nullptr,
CGAL_precondition_msg "The curve must not overlap an existing edge.");
(object_cast<Halfedge_const_handle>(&obj2) == nullptr,
"The curve must not overlap an existing edge.");
vh2 = object_cast<Vertex_const_handle>(&obj2);
} }
vh2 = Pl_result::template assign<Vertex_const_handle>(&obj2);
// Notify the arrangement observers that a global operation is about to // Notify the arrangement observers that a global operation is about to
// take place. // take place.
@ -776,10 +766,8 @@ insert_non_intersecting_curve
// we must insert the curve in the interior of a face. // we must insert the curve in the interior of a face.
// In this case insert_in_face_interior() already returns a halfedge // In this case insert_in_face_interior() already returns a halfedge
// directed from left to right. // directed from left to right.
const typename Arr::Face_const_handle* fh1 = const Face_const_handle* fh1 = boost::get<Face_const_handle>(&obj1);
object_cast<typename Arr::Face_const_handle>(&obj1); const Face_const_handle* fh2 = boost::get<Face_const_handle>(&obj2);
const typename Arr::Face_const_handle* fh2 =
object_cast<typename Arr::Face_const_handle>(&obj2);
// std::cout << arr << std::endl; // std::cout << arr << std::endl;
// std::cout << "(*fh1)->number_of_outer_ccbs(): " // std::cout << "(*fh1)->number_of_outer_ccbs(): "
@ -1140,49 +1128,49 @@ insert_point(Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr,
typedef Arrangement_on_surface_2<Gt2, Tt> Arr; typedef Arrangement_on_surface_2<Gt2, Tt> Arr;
typedef typename Arr::Vertex_const_handle Vertex_const_handle;
typedef typename Arr::Halfedge_const_handle Halfedge_const_handle;
typedef typename Arr::Face_const_handle Face_const_handle;
// Act according to the type of arrangement feature that contains the point. // Act according to the type of arrangement feature that contains the point.
const typename Arr::Face_const_handle* fh;
const typename Arr::Halfedge_const_handle* hh;
const typename Arr::Vertex_const_handle* vh;
typename Arr::Vertex_handle vh_for_p; typename Arr::Vertex_handle vh_for_p;
// Locate the given point in the arrangement. // Locate the given point in the arrangement.
CGAL::Object obj = pl.locate (p); auto obj = pl.locate(p);
// Notify the arrangement observers that a global operation is about to // Notify the arrangement observers that a global operation is about to
// take place. // take place.
Arr_accessor<Arr> arr_access (arr); Arr_accessor<Arr> arr_access(arr);
arr_access.notify_before_global_change(); arr_access.notify_before_global_change();
if ((fh = object_cast<typename Arr::Face_const_handle>(&obj)) != nullptr) { const Face_const_handle* fh = boost::get<Face_const_handle>(&obj);
if (fh != nullptr) {
// p lies inside a face: Insert it as an isolated vertex it the interior of // p lies inside a face: Insert it as an isolated vertex it the interior of
// this face. // this face.
vh_for_p = arr.insert_in_face_interior(p, arr.non_const_handle (*fh)); vh_for_p = arr.insert_in_face_interior(p, arr.non_const_handle (*fh));
} }
else if ((hh = object_cast<typename Arr::Halfedge_const_handle>(&obj)) !=
nullptr)
{
// p lies in the interior of an edge: Split this edge to create a new
// vertex associated with p.
typename Gt2::X_monotone_curve_2 sub_cv1, sub_cv2;
typename Arr::Halfedge_handle split_he;
arr.geometry_traits()->split_2_object()((*hh)->curve(), p,
sub_cv1, sub_cv2);
split_he = arr.split_edge(arr.non_const_handle(*hh), sub_cv1, sub_cv2);
// The new vertex is the target of the returned halfedge.
vh_for_p = split_he->target();
}
else { else {
// In this case p lies on an existing vertex, so we just update this const Halfedge_const_handle* hh = boost::get<Halfedge_const_handle>(&obj);
// vertex. if (hh != nullptr) {
vh = object_cast<typename Arr::Vertex_const_handle>(&obj); // p lies in the interior of an edge: Split this edge to create a new
CGAL_assertion (vh != nullptr); // vertex associated with p.
typename Gt2::X_monotone_curve_2 sub_cv1, sub_cv2;
typename Arr::Halfedge_handle split_he;
vh_for_p = arr.modify_vertex (arr.non_const_handle (*vh), p); const auto* gt = arr.geometry_traits();
gt->split_2_object()((*hh)->curve(), p, sub_cv1, sub_cv2);
split_he = arr.split_edge(arr.non_const_handle(*hh), sub_cv1, sub_cv2);
// The new vertex is the target of the returned halfedge.
vh_for_p = split_he->target();
}
else {
// p lies on an existing vertex, so we just update this vertex.
const Vertex_const_handle* vh = boost::get<Vertex_const_handle>(&obj);
CGAL_assertion(vh != nullptr);
vh_for_p = arr.modify_vertex (arr.non_const_handle (*vh), p);
}
} }
// Notify the arrangement observers that the global operation has been // Notify the arrangement observers that the global operation has been
@ -1381,60 +1369,47 @@ is_valid(const Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr)
// Shoot a vertical ray from each vertex we have collected downward, and // Shoot a vertical ray from each vertex we have collected downward, and
// check that this vertex is really contained in the proper face. // check that this vertex is really contained in the proper face.
typename Gt2::Compare_y_at_x_right_2 comp_y_at_x_right = auto comp_y_at_x_right = traits->compare_y_at_x_right_2_object();
traits->compare_y_at_x_right_2_object(); auto comp_y_at_x_left = traits->compare_y_at_x_left_2_object();
typename Gt2::Compare_y_at_x_left_2 comp_y_at_x_left =
traits->compare_y_at_x_left_2_object();
typename std::list<std::pair<Vertex_const_handle,
Face_const_handle> >::iterator vf_iter;
typename Tt::Default_point_location_strategy def_pl(arr); typename Tt::Default_point_location_strategy def_pl(arr);
Vertex_const_handle curr_v;
Object obj;
Halfedge_const_handle he_below;
Vertex_const_handle v_below;
Face_const_handle in_face;
Halfedge_around_vertex_const_circulator first, circ;
bool assign_ok;
const Halfedge_const_handle invalid_he; const Halfedge_const_handle invalid_he;
for (vf_iter = vf_list.begin(); vf_iter != vf_list.end(); ++vf_iter) { Face_const_handle in_face;
for (auto vf_iter = vf_list.begin(); vf_iter != vf_list.end(); ++vf_iter) {
// Perform ray-shooting from the current vertex. // Perform ray-shooting from the current vertex.
curr_v = vf_iter->first; Vertex_const_handle curr_v = vf_iter->first;
obj = def_pl.ray_shoot_down(curr_v->point()); auto obj = def_pl.ray_shoot_down(curr_v->point());
if (CGAL::assign(he_below, obj)) { // if (CGAL::assign(he_below, obj)) {
// Hit an edge - take the incident face of the halfedge directed to the if (auto* he_below_p = boost::get<Halfedge_const_handle>(&obj)) {
// Hit an edge; take the incident face of the halfedge directed to the
// right. // right.
if (he_below->direction() == ARR_RIGHT_TO_LEFT) auto he_below = *he_below_p;
he_below = he_below->twin(); in_face = (he_below->direction() == ARR_RIGHT_TO_LEFT) ?
he_below->twin()->face() : he_below->face();
in_face = he_below->face();
} }
else if (CGAL::assign(v_below, obj)) { else if (auto* v_below_p = boost::get<Vertex_const_handle>(&obj)) {
auto v_below = *v_below_p;
// Hit a vertex. // Hit a vertex.
if (v_below->is_isolated()) in_face = v_below->face(); if (v_below->is_isolated()) in_face = v_below->face();
else { else {
// Get the first halfedge around v_below that is directed from left to // Get the first halfedge around v_below that is directed from left to
// right and the first halfedge that is directed from right to left. // right and the first halfedge that is directed from right to left.
first = circ = v_below->incident_halfedges(); Halfedge_around_vertex_const_circulator circ =
v_below->incident_halfedges();
Halfedge_around_vertex_const_circulator first = circ;
Halfedge_const_handle he_left; // A halfedge to the left of v_below. Halfedge_const_handle he_left; // A halfedge to the left of v_below.
Halfedge_const_handle he_right; // A halfedge to the right of v_below. Halfedge_const_handle he_right; // A halfedge to the right of v_below.
do { do {
if (circ->direction() == ARR_LEFT_TO_RIGHT) { if (circ->direction() == ARR_LEFT_TO_RIGHT) he_left = circ;
he_left = circ;
}
else { else {
he_right = circ; he_right = circ;
if (he_left != invalid_he && he_right != invalid_he) if ((he_left != invalid_he) && (he_right != invalid_he)) break;
break;
} }
++circ; } while(++circ != first);
} while(circ != first); CGAL_assertion((he_left != invalid_he) || (he_right != invalid_he));
CGAL_assertion (he_left != invalid_he || he_right != invalid_he);
if (he_left != invalid_he && he_right != invalid_he) { if (he_left != invalid_he && he_right != invalid_he) {
while (he_left->direction() == ARR_LEFT_TO_RIGHT) while (he_left->direction() == ARR_LEFT_TO_RIGHT)
@ -1460,26 +1435,24 @@ is_valid(const Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr)
else { else {
Comparison_result res; Comparison_result res;
Halfedge_const_handle he_curr = he_right; Halfedge_const_handle he_curr = he_right;
do {
do // as long as we have he_right halfedge which is below // as long as we have he_right halfedge which is below
{
he_right = he_curr; he_right = he_curr;
he_curr = he_right->next()->twin(); he_curr = he_right->next()->twin();
res = comp_y_at_x_right (he_curr->curve(), res = comp_y_at_x_right(he_curr->curve(),
he_right->curve(), he_right->curve(),
v_below->point()); v_below->point());
} while(res == SMALLER); } while(res == SMALLER);
in_face = he_right->face(); in_face = he_right->face();
} }
} }
} }
else { else {
auto* in_face_p = boost::get<Face_const_handle>(&obj);
CGAL_assertion(in_face_p);
in_face = *in_face_p;
// Hit nothing (an unbounded face is returned). // Hit nothing (an unbounded face is returned).
assign_ok = CGAL::assign(in_face, obj); CGAL_assertion(in_face->is_unbounded());
CGAL_assertion (assign_ok && in_face->is_unbounded());
if (! assign_ok) return false;
} }
if (vf_iter->second != in_face) { if (vf_iter->second != in_face) {
@ -1611,35 +1584,34 @@ do_intersect(Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr,
// Break the input curve into x-monotone subcurves and isolated points. // Break the input curve into x-monotone subcurves and isolated points.
typedef Arr_traits_adaptor_2<Gt2> Traits_adaptor_2; typedef Arr_traits_adaptor_2<Gt2> Traits_adaptor_2;
typedef typename Gt2::Point_2 Point_2;
typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2;
typedef boost::variant<Point_2, X_monotone_curve_2> Make_x_monotone_result;
typedef typename Arr::Face_const_handle Face_const_handle;
const Traits_adaptor_2* traits = const Traits_adaptor_2* traits =
static_cast<const Traits_adaptor_2*>(arr.geometry_traits()); static_cast<const Traits_adaptor_2*>(arr.geometry_traits());
std::list<CGAL::Object> x_objects; std::list<Make_x_monotone_result> x_objects;
std::list<CGAL::Object>::const_iterator obj_iter;
const typename Gt2::X_monotone_curve_2* x_curve;
const typename Gt2::Point_2* iso_p;
traits->make_x_monotone_2_object()(c, std::back_inserter(x_objects)); traits->make_x_monotone_2_object()(c, std::back_inserter(x_objects));
// Insert each x-monotone curve into the arrangement. // Insert each x-monotone curve into the arrangement.
for (obj_iter = x_objects.begin(); obj_iter != x_objects.end(); ++obj_iter) { for (const auto& x_obj : x_objects) {
// Act according to the type of the current object. // Act according to the type of the current object.
x_curve = object_cast<typename Gt2::X_monotone_curve_2>(&(*obj_iter)); const X_monotone_curve_2* x_curve = boost::get<X_monotone_curve_2>(&x_obj);
if (x_curve != nullptr) { if (x_curve != nullptr) {
// Check if the x-monotone subcurve intersects the arrangement. // Check if the x-monotone subcurve intersects the arrangement.
if (do_intersect(arr, *x_curve, pl) == true) if (do_intersect(arr, *x_curve, pl) == true) return true;
return true; continue;
} }
else {
iso_p = object_cast<typename Gt2::Point_2>(&(*obj_iter));
CGAL_assertion(iso_p != nullptr);
// Check whether the isolated point lies inside a face (otherwise, const Point_2* iso_p = boost::get<Point_2>(&x_obj);
// it conincides with a vertex or an edge). CGAL_assertion(iso_p != nullptr);
CGAL::Object obj = pl.locate (*iso_p);
return (object_cast<typename Arr::Face_const_handle>(&obj) != nullptr); // Check whether the isolated point lies inside a face (otherwise,
} // it conincides with a vertex or an edge).
auto obj = pl.locate(*iso_p);
if (boost::get<Face_const_handle>(&x_obj) != nullptr) return true;
} }
// If we reached here, the curve does not intersect the arrangement. // If we reached here, the curve does not intersect the arrangement.
@ -1651,8 +1623,8 @@ do_intersect(Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr,
template <typename GeometryTraits_2, typename TopologyTraits, typename Curve, template <typename GeometryTraits_2, typename TopologyTraits, typename Curve,
typename PointLocation> typename PointLocation>
bool bool
do_intersect (Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr, do_intersect(Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr,
const Curve& c, const PointLocation& pl) const Curve& c, const PointLocation& pl)
{ {
typedef GeometryTraits_2 Gt2; typedef GeometryTraits_2 Gt2;

View File

@ -7,16 +7,15 @@
// $Id$ // $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
// //
// // Author(s): Ron Wein <wein@post.tau.ac.il>
// Author(s) : Ron Wein <wein@post.tau.ac.il> // Efi Fogel <efif@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il> // Eric Berberich <eric.berberich@cgal.org>
// Eric Berberich <eric.berberich@cgal.org> // (based on old version by: Iddo Hanniel,
// (based on old version by: Iddo Hanniel, // Eyal Flato,
// Eyal Flato, // Oren Nechushtan,
// Oren Nechushtan, // Ester Ezra,
// Ester Ezra, // Shai Hirsch,
// Shai Hirsch, // and Eugene Lipovetsky)
// and Eugene Lipovetsky)
#ifndef CGAL_ARRANGEMENT_ON_SURFACE_2_IMPL_H #ifndef CGAL_ARRANGEMENT_ON_SURFACE_2_IMPL_H
#define CGAL_ARRANGEMENT_ON_SURFACE_2_IMPL_H #define CGAL_ARRANGEMENT_ON_SURFACE_2_IMPL_H
@ -32,6 +31,8 @@
* class-template. * class-template.
*/ */
#include <boost/variant.hpp>
#include <CGAL/function_objects.h> #include <CGAL/function_objects.h>
#include <CGAL/use.h> #include <CGAL/use.h>
@ -2195,16 +2196,30 @@ _place_and_set_curve_end(DFace* f,
{ {
// Use the topology traits to locate the DCEL feature that contains the // Use the topology traits to locate the DCEL feature that contains the
// given curve end. // given curve end.
CGAL::Object obj = auto obj = m_topol_traits.place_boundary_vertex(f, cv, ind, ps_x, ps_y);
m_topol_traits.place_boundary_vertex(f, cv, ind, ps_x, ps_y);
DVertex* v;
DHalfedge* fict_he;
// Act according to the result type. // Act according to the result type.
if (CGAL::assign(fict_he, obj)) {
if (! obj) {
// We have to create a new vertex that reprsents the given curve end.
DVertex* v = _create_boundary_vertex(cv, ind, ps_x, ps_y);
// Notify the topology traits on the creation of the boundary vertex.
m_topol_traits.notify_on_boundary_vertex_creation(v, cv, ind, ps_x, ps_y);
// There are no edges incident to v, therefore no predecessor halfedge.
*p_pred = nullptr;
// Return the vertex that represents the curve end.
return v;
}
DHalfedge** fict_he_p = boost::get<DHalfedge*>(&*obj);
if (fict_he_p != nullptr) {
DHalfedge* fict_he = *fict_he_p;
CGAL_assertion(fict_he != nullptr);
// The curve end is located on a fictitious edge. We first create a new // The curve end is located on a fictitious edge. We first create a new
// vertex that corresponds to the curve end. // vertex that corresponds to the curve end.
v = _create_boundary_vertex(cv, ind, ps_x, ps_y); DVertex* v = _create_boundary_vertex(cv, ind, ps_x, ps_y);
// Split the fictitious halfedge at the newly created vertex. // Split the fictitious halfedge at the newly created vertex.
// The returned halfedge is the predecessor for the insertion of the curve // The returned halfedge is the predecessor for the insertion of the curve
@ -2216,29 +2231,16 @@ _place_and_set_curve_end(DFace* f,
_notify_after_split_fictitious_edge(Halfedge_handle(*p_pred), _notify_after_split_fictitious_edge(Halfedge_handle(*p_pred),
Halfedge_handle((*p_pred)->next())); Halfedge_handle((*p_pred)->next()));
return v;
} }
else if (CGAL::assign(v, obj)) { DVertex** v_p = boost::get<DVertex*>(&*obj);
// In this case we are given an existing vertex that represents the curve CGAL_assertion(v_p != nullptr);
// end. We now have to locate the predecessor edge for the insertion of cv DVertex* v = *v_p;
// around this vertex. CGAL_assertion(v != nullptr);
*p_pred = // In this case we are given an existing vertex that represents the curve
m_topol_traits.locate_around_boundary_vertex(v, cv, ind, ps_x, ps_y); // end. We now have to locate the predecessor edge for the insertion of cv
} // around this vertex.
else { *p_pred = m_topol_traits.locate_around_boundary_vertex(v, cv, ind, ps_x, ps_y);
CGAL_assertion(obj.is_empty());
// In this case we have to create a new vertex that reprsents the given
// curve end.
v = _create_boundary_vertex(cv, ind, ps_x, ps_y);
// Notify the topology traits on the creation of the boundary vertex.
m_topol_traits.notify_on_boundary_vertex_creation(v, cv, ind, ps_x, ps_y);
// There are no edges incident to v, therefore no predecessor halfedge.
*p_pred = nullptr;
}
// Return the vertex that represents the curve end.
return v; return v;
} }

View File

@ -29,7 +29,7 @@ namespace CGAL {
// //
template <typename Arrangement, typename ZoneVisitor> template <typename Arrangement, typename ZoneVisitor>
void Arrangement_zone_2<Arrangement, ZoneVisitor>:: void Arrangement_zone_2<Arrangement, ZoneVisitor>::
init_with_hint(const X_monotone_curve_2& cv, const Object& obj) init_with_hint(const X_monotone_curve_2& cv, Pl_result_type obj)
{ {
// Set the curve and check whether its ends are bounded, therefore // Set the curve and check whether its ends are bounded, therefore
// associated with valid endpoints. // associated with valid endpoints.
@ -95,9 +95,8 @@ void Arrangement_zone_2<Arrangement, ZoneVisitor>::compute_zone()
// curve (currently m_obj stores the object containing it). // curve (currently m_obj stores the object containing it).
const Vertex_const_handle* vh; const Vertex_const_handle* vh;
const Halfedge_const_handle* hh; const Halfedge_const_handle* hh;
const Face_const_handle* fh;
if ((vh = object_cast<Vertex_const_handle>(&m_obj)) != nullptr) { if ((vh = boost::get<Vertex_const_handle>(&m_obj)) != nullptr) {
CGAL_assertion(m_has_left_pt); CGAL_assertion(m_has_left_pt);
// The left endpoint coincides with an existing vertex: // The left endpoint coincides with an existing vertex:
@ -119,7 +118,7 @@ void Arrangement_zone_2<Arrangement, ZoneVisitor>::compute_zone()
#endif #endif
} }
else if ((hh = object_cast<Halfedge_const_handle>(&m_obj)) != nullptr) { else if ((hh = boost::get<Halfedge_const_handle>(&m_obj)) != nullptr) {
if (m_has_left_pt) { if (m_has_left_pt) {
// Obtain the right halfedge from the halfedge-pair containing m_left_pt // Obtain the right halfedge from the halfedge-pair containing m_left_pt
// in their interior. // in their interior.
@ -160,7 +159,7 @@ void Arrangement_zone_2<Arrangement, ZoneVisitor>::compute_zone()
} }
else { else {
// The left endpoint lies inside a face. // The left endpoint lies inside a face.
fh = object_cast<Face_const_handle>(&m_obj); const Face_const_handle* fh = boost::get<Face_const_handle>(&m_obj);
CGAL_assertion_msg(fh != nullptr, CGAL_assertion_msg(fh != nullptr,
"Invalid object returned by the point-location query."); "Invalid object returned by the point-location query.");

View File

@ -2832,7 +2832,8 @@ void insert(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
template <typename GeomTraits, typename TopTraits> template <typename GeomTraits, typename TopTraits>
void insert(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr, void insert(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
const typename GeomTraits::X_monotone_curve_2& c, const typename GeomTraits::X_monotone_curve_2& c,
const Object& obj); typename Arr_point_location_result<
Arrangement_on_surface_2<GeomTraits, TopTraits> >::type obj);
/*! /*!
* Insert an x-monotone curve into the arrangement, such that the curve * Insert an x-monotone curve into the arrangement, such that the curve
@ -2948,16 +2949,16 @@ remove_vertex(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
template <typename GeomTraits, typename TopTraits> template <typename GeomTraits, typename TopTraits>
bool is_valid(const Arrangement_on_surface_2<GeomTraits, TopTraits>& arr); bool is_valid(const Arrangement_on_surface_2<GeomTraits, TopTraits>& arr);
/*! /*! Compute the zone of the given x-monotone curve in the existing arrangement.
* Compute the zone of the given x-monotone curve in the existing arrangement.
* Meaning, it output the arrangment's vertices, edges and faces that the * Meaning, it output the arrangment's vertices, edges and faces that the
* x-monotone curve intersects. * x-monotone curve intersects.
* \param arr The arrangement. * \param arr The arrangement.
* \param c The x-monotone curve that its zone was computed. * \param c the x-monotone curve that its zone is computed.
* \param oi Output iterator of CGAL::Object to insert the zone elements to. * \param oi the output iterator for the resulting zone elements. Its
* \param pi The point location strategy that is used to locate the starting * dereference type is a variant that wraps a \c Vertex_handle, a
* point. * \c Halfedge_handle, or a \c Face_handle.
* \return The output iterator that the curves were inserted to. * \param pl the point location strategy used to locate the starting point.
* \return the past-the-end output iterator.
*/ */
template <typename GeomTraits, typename TopTraits, template <typename GeomTraits, typename TopTraits,
typename OutputIterator, typename PointLocation> typename OutputIterator, typename PointLocation>
@ -2971,9 +2972,11 @@ OutputIterator zone(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
* Overloaded version with no point location object - the walk point-location * Overloaded version with no point location object - the walk point-location
* strategy is used as default. * strategy is used as default.
* \param arr The arrangement. * \param arr The arrangement.
* \param c The x-monotone curve that its zone was computed. * \param c the x-monotone curve that its zone was computed.
* \param oi Output iterator of CGAL::Object to insert the zone elements to. * \param oi the output iterator for the resulting zone elements. Its
* \return The output iterator that the curves were inserted to. * dereference type is a variant that wraps a \c Vertex_handle, a
* \c Halfedge_handle, or a \c Face_handle.
* \return the past-the-end output iterator.
*/ */
template <typename GeomTraits, typename TopTraits, typename OutputIterator> template <typename GeomTraits, typename TopTraits, typename OutputIterator>
OutputIterator zone(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr, OutputIterator zone(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,

View File

@ -28,6 +28,7 @@
#include <CGAL/Arr_tags.h> #include <CGAL/Arr_tags.h>
#include <CGAL/Arr_accessor.h> #include <CGAL/Arr_accessor.h>
#include <CGAL/Arrangement_2/Arr_traits_adaptor_2.h> #include <CGAL/Arrangement_2/Arr_traits_adaptor_2.h>
#include <CGAL/Arr_point_location_result.h>
#include <list> #include <list>
#include <map> #include <map>
@ -113,6 +114,9 @@ protected:
typedef std::set<const X_monotone_curve_2*> Curves_set; typedef std::set<const X_monotone_curve_2*> Curves_set;
typedef typename Curves_set::iterator Curves_set_iterator; typedef typename Curves_set::iterator Curves_set_iterator;
typedef Arr_point_location_result<Arrangement_2> Pl_result;
typedef typename Pl_result::Type Pl_result_type;
// Data members: // Data members:
Arrangement_2& m_arr; // The associated arrangement. Arrangement_2& m_arr; // The associated arrangement.
const Traits_adaptor_2* m_geom_traits; // Its associated geometry traits. const Traits_adaptor_2* m_geom_traits; // Its associated geometry traits.
@ -127,7 +131,7 @@ protected:
X_monotone_curve_2 m_cv; // The current portion of the X_monotone_curve_2 m_cv; // The current portion of the
// inserted curve. // inserted curve.
CGAL::Object m_obj; // The location of the left endpoint. Pl_result_type m_obj; // The location of the left endpoint.
bool m_has_left_pt; // Is the left end of the curve bounded. bool m_has_left_pt; // Is the left end of the curve bounded.
bool m_left_on_boundary; // Is the left point on the boundary. bool m_left_on_boundary; // Is the left point on the boundary.
Point_2 m_left_pt; // Its current left endpoint. Point_2 m_left_pt; // Its current left endpoint.
@ -247,7 +251,7 @@ public:
* \param obj An object that represents the location of the left end of the * \param obj An object that represents the location of the left end of the
* curve. * curve.
*/ */
void init_with_hint(const X_monotone_curve_2& cv, const Object& obj); void init_with_hint(const X_monotone_curve_2& cv, Pl_result_type obj);
/*! Compute the zone of the given curve and issue the apporpriate /*! Compute the zone of the given curve and issue the apporpriate
* notifications for the visitor. * notifications for the visitor.

View File

@ -1410,9 +1410,9 @@ public:
* Functor that computes the intersections of two arcs * Functor that computes the intersections of two arcs
*/ */
template < class CurvedKernelViaAnalysis_2 > template < class CurvedKernelViaAnalysis_2 >
class Intersect_2 : public class Intersect_2 :
Curved_kernel_via_analysis_2_functor_base< CurvedKernelViaAnalysis_2 > { public Curved_kernel_via_analysis_2_functor_base<CurvedKernelViaAnalysis_2>
{
public: public:
//! this instance' first template parameter //! this instance' first template parameter
typedef CurvedKernelViaAnalysis_2 Curved_kernel_via_analysis_2; typedef CurvedKernelViaAnalysis_2 Curved_kernel_via_analysis_2;
@ -1420,13 +1420,17 @@ public:
//! the base type //! the base type
typedef typedef
Curved_kernel_via_analysis_2_functor_base< Curved_kernel_via_analysis_2 > Curved_kernel_via_analysis_2_functor_base< Curved_kernel_via_analysis_2 >
Base; Base;
CGAL_CKvA_2_GRAB_BASE_FUNCTOR_TYPES CGAL_CKvA_2_GRAB_BASE_FUNCTOR_TYPES
typedef unsigned int Multiplicity;
typedef std::pair<Point_2, Multiplicity> Intersection_point;
typedef boost::variant<Intersection_point, Arc_2> Intersection_result;
//! the result type //! the result type
typedef CGAL::cpp98::iterator< std::output_iterator_tag, CGAL::Object > typedef CGAL::cpp98::iterator<std::output_iterator_tag, Intersection_result>
result_type; result_type;
//! the arity of the functor //! the arity of the functor
@ -1458,11 +1462,6 @@ public:
template < class OutputIterator > template < class OutputIterator >
OutputIterator operator()(const Arc_2& cv1, const Arc_2& cv2, OutputIterator operator()(const Arc_2& cv1, const Arc_2& cv2,
OutputIterator oi) const { OutputIterator oi) const {
typedef unsigned int Multiplicity;
typedef std::pair<Point_2, Multiplicity> Intersection_point;
typedef boost::variant<Intersection_point, Arc_2> Intersection_result;
CERR("\nintersect; cv1: " << cv1 CERR("\nintersect; cv1: " << cv1
<< ";\n cv2:" << cv2 << ""); << ";\n cv2:" << cv2 << "");
@ -1860,100 +1859,110 @@ public:
/*!\brief /*!\brief
* Functor that decomposes curve into x-monotone arcs and isolated points * Functor that decomposes curve into x-monotone arcs and isolated points
*/ */
template < class CurvedKernelViaAnalysis_2 > template <class CurvedKernelViaAnalysis_2>
class Make_x_monotone_2 : public class Make_x_monotone_2 : public
Curved_kernel_via_analysis_2_functor_base< CurvedKernelViaAnalysis_2 > { Curved_kernel_via_analysis_2_functor_base<CurvedKernelViaAnalysis_2> {
public: public:
//! this instance' first template parameter //! this instance' first template parameter
typedef CurvedKernelViaAnalysis_2 Curved_kernel_via_analysis_2; typedef CurvedKernelViaAnalysis_2 Curved_kernel_via_analysis_2;
//! the base type //! the base type
typedef typedef
Curved_kernel_via_analysis_2_functor_base< Curved_kernel_via_analysis_2 > Curved_kernel_via_analysis_2_functor_base< Curved_kernel_via_analysis_2>
Base; Base;
CGAL_CKvA_2_GRAB_BASE_FUNCTOR_TYPES CGAL_CKvA_2_GRAB_BASE_FUNCTOR_TYPES
//! the result type //! the result type
typedef CGAL::cpp98::iterator< std::output_iterator_tag, CGAL::Object > typedef CGAL::cpp98::iterator< std::output_iterator_tag, CGAL::Object>
result_type; result_type;
//! the arity of the functor //! the arity of the functor
/*!\brief /*!\brief
* Standard constructor * Standard constructor
* *
* \param kernel The kernel * \param kernel The kernel
*/ */
Make_x_monotone_2(Curved_kernel_via_analysis_2 *kernel) : Make_x_monotone_2(Curved_kernel_via_analysis_2* kernel) :
Base(kernel) { Base(kernel)
} {}
/*!\brief /*!\brief
* Decomposes a given arc into list of x-monotone arcs * Decomposes a given arc into list of x-monotone arcs
* (subcurves) and insert them to the output iterator. Since \c Arc_2 * (subcurves) and insert them to the output iterator. Since \c Arc_2
* is by definition x-monotone, an input arc is passed to the * is by definition x-monotone, an input arc is passed to the
* output iterator directly. * output iterator directly.
* *
* \param cv The arc * \param cv The arc
* \param oi The output iterator, whose value-type is Object * \param oi The output iterator, whose value-type is Object
* The returned objects are all wrappers Arc_2 objects * The returned objects are all wrappers Arc_2 objects
* \return The past-the-end iterator * \return The past-the-end iterator
*/ */
template < class OutputIterator > template <class OutputIterator>
OutputIterator operator()(const Arc_2& cv, OutputIterator oi) const { OutputIterator operator()(const Arc_2& cv, OutputIterator oi) const
{
typedef typename Curved_kernel_via_analysis_2::Point_2 Point_2;
typedef typename Curved_kernel_via_analysis_2::Arc_2 Arc_2;
typedef boost::variant<Point_2, Arc_2> Make_x_monotone_result;
*oi++ = Make_x_monotone_result(cv);
return oi;
}
*oi++ = CGAL::make_object(cv); /*!\brief
return oi; * Decomposes a given curve into list of x-monotone arcs
} * (subcurves) and isolated points and insert them to the output iterator.
*
* \param cv The curve
* \param oi The output iterator, whose value-type is Object.
* The returned objects either wrapper Arc_2 or Point_2 objects
* \return The past-the-end iterator
*/
template <class OutputIterator>
OutputIterator operator()(const Curve_analysis_2& cv, OutputIterator oi)
const
{
CGAL::internal::Make_x_monotone_2< Curved_kernel_via_analysis_2 >
make_x_monotone(Base::_ckva());
/*!\brief return make_x_monotone(cv, oi);
* Decomposes a given curve into list of x-monotone arcs }
* (subcurves) and isolated points and insert them to the output iterator.
*
* \param cv The curve
* \param oi The output iterator, whose value-type is Object.
* The returned objects either wrapper Arc_2 or Point_2 objects
* \return The past-the-end iterator
*/
template < class OutputIterator >
OutputIterator operator()(const Curve_analysis_2& cv, OutputIterator oi)
const {
CGAL::internal::Make_x_monotone_2< Curved_kernel_via_analysis_2 > /*!\brief
make_x_monotone(Base::_ckva()); * Splits an input object \c obj into x-monotone arcs and isolated points
*
* \param obj the polymorph input object: can represet \c Point_2,
* \c Arc_2, \c Non_x_monotone_arc_2 or \c Curve_analysis_2
* \param oi Output iterator that stores CGAL::Object, which either
* encapsulates \c Point_2 or \c Arc_2
* \return Past-the-end iterator of \c oi
*/
template <class OutputIterator>
OutputIterator operator()(CGAL::Object obj, OutputIterator oi)
{
typedef typename Curved_kernel_via_analysis_2::Point_2 Point_2;
typedef typename Curved_kernel_via_analysis_2::Arc_2 Arc_2;
typedef typename Curved_kernel_via_analysis_2::Non_x_monotone_arc_2
Non_x_monotone_arc_2;
typedef boost::variant<Point_2, Arc_2>
Make_x_monotone_result;
return make_x_monotone(cv, oi); Curve_analysis_2 curve;
} Point_2 p;
Arc_2 xcv;
Non_x_monotone_arc_2 nxarc;
/*!\brief if (CGAL::assign(curve, obj)) oi = (*this)(curve, oi);
* Splits an input object \c obj into x-monotone arcs and isolated points else if (CGAL::assign(nxarc, obj))
* std::cerr << "AU BACKE" << std::endl;
* \param obj the polymorph input object: can represet \c Point_2, //oi = std::transform(nxarc.begin(), nxarc.end(), oi,
* \c Arc_2, \c Non_x_monotone_arc_2 or \c Curve_analysis_2 // std::ptr_fun(CGAL::make_object<Arc_2>));
* \param oi Output iterator that stores CGAL::Object, which either else if (CGAL::assign(xcv, obj)) *oi++ = Make_x_monotone_result(xcv);
* encapsulates \c Point_2 or \c Arc_2 else if (CGAL::assign(p, obj)) *oi++ = Make_x_monotone_result(p);
* \return Past-the-end iterator of \c oi else CGAL_error();
*/ return oi;
template <class OutputIterator> }
OutputIterator operator()(CGAL::Object obj, OutputIterator oi) {
typedef typename Curved_kernel_via_analysis_2::Non_x_monotone_arc_2
Non_x_monotone_arc_2;
Curve_analysis_2 curve;
Non_x_monotone_arc_2 nxarc;
if(CGAL::assign(curve, obj))
oi = (*this)(curve, oi);
else if(CGAL::assign(nxarc, obj))
std::cerr << "AU BACKE" << std::endl;
//oi = std::transform(nxarc.begin(), nxarc.end(), oi,
// std::ptr_fun(CGAL::make_object<Arc_2>));
else // allow the remaining objects to pass through
*oi++ = obj;
return oi;
}
}; };

View File

@ -169,12 +169,10 @@ public:
Coordinate_1 asym_info1, asym_info2; Coordinate_1 asym_info1, asym_info2;
CGAL::Arr_parameter_space ps1, ps2; CGAL::Arr_parameter_space ps1, ps2;
obj1 = cv1.curve().asymptotic_value_of_arc( obj1 =
cv1.location(ce), cv1.arcno() cv1.curve().asymptotic_value_of_arc(cv1.location(ce), cv1.arcno());
); obj2 =
obj2 = cv2.curve().asymptotic_value_of_arc( cv2.curve().asymptotic_value_of_arc(cv2.location(ce), cv2.arcno());
cv2.location(ce), cv2.arcno()
);
CGAL::Comparison_result filter_res = CGAL::EQUAL; CGAL::Comparison_result filter_res = CGAL::EQUAL;

View File

@ -42,15 +42,26 @@ namespace internal {
* Isolated points are stored as \c CurvedKernelViaAnalysis_2::Point_2 objects. * Isolated points are stored as \c CurvedKernelViaAnalysis_2::Point_2 objects.
* *
* The resulting arcs and points are written to the output iterator as * The resulting arcs and points are written to the output iterator as
* polymorphic \c CGAL::Object. Past-the-end value of the iterator is returned. * polymorphic \c variant. Past-the-end value of the iterator is returned.
*
* EF: I believe that the inheritance from binary_function is not exploited,
* and thus redundant, but I keep it anyway.
*/ */
template < class CurvedKernelViaAnalysis_2, template < class CurvedKernelViaAnalysis_2,
class ConstructArc_2 = class ConstructArc_2 =
typename CurvedKernelViaAnalysis_2::Construct_arc_2 > typename CurvedKernelViaAnalysis_2::Construct_arc_2 >
struct Make_x_monotone_2 : struct Make_x_monotone_2 :
public CGAL::cpp98::binary_function< typename CurvedKernelViaAnalysis_2::Curve_2, public CGAL::cpp98::binary_function<
CGAL::cpp98::iterator<std::output_iterator_tag, CGAL::Object>, typename CurvedKernelViaAnalysis_2::Curve_2,
CGAL::cpp98::iterator<std::output_iterator_tag, CGAL::Object> > { CGAL::cpp98::iterator<std::output_iterator_tag,
boost::variant<
typename CurvedKernelViaAnalysis_2::Point_2,
typename CurvedKernelViaAnalysis_2::Arc_2> >,
CGAL::cpp98::iterator<std::output_iterator_tag,
boost::variant<
typename CurvedKernelViaAnalysis_2::Point_2,
typename CurvedKernelViaAnalysis_2::Arc_2> > >
{
//!\name Public types //!\name Public types
//!@{ //!@{
@ -87,242 +98,250 @@ struct Make_x_monotone_2 :
typedef typename Curved_kernel_via_analysis_2::Non_x_monotone_arc_2 typedef typename Curved_kernel_via_analysis_2::Non_x_monotone_arc_2
Non_x_monotone_arc_2; Non_x_monotone_arc_2;
//!@} //!@}
//!\name Constructors //!\name Constructors
//!@{ //!@{
/*!\brief /*!\brief
* Standard constructor * Standard constructor
* *
* \param kernel The kernel instance to use * \param kernel The kernel instance to use
*/ */
Make_x_monotone_2(Curved_kernel_via_analysis_2 *kernel) : Make_x_monotone_2(Curved_kernel_via_analysis_2 *kernel) :
_m_curved_kernel(kernel) { _m_curved_kernel(kernel)
CGAL_assertion(kernel != nullptr); {
CGAL_assertion(kernel != nullptr);
}
//!@}
//!\name Functor invokation
//!@{
// TODO add operator for non-x-monotone arc
/*!\brief
* Splits a curve into x-monotone arcs and isolated points
*
* \param curve The input curve
* \param oi the output iterator for the result. Its dereference type is a
* variant that wraps a Point_2 or an X_monotone_curve_2 objects.
* \return Past-the-end iterator of \c oi
*/
template <typename OutputIterator>
OutputIterator operator()(Curve_analysis_2 curve, OutputIterator oi)
{
typedef boost::variant<Point_2, Arc_2> Make_x_monotone_result;
Construct_arc_2 construct_arc_2 =
_m_curved_kernel->construct_arc_2_object();
// use CGAL::Total_degree ?
if (typename CGAL::Polynomial_traits_d<
typename Curve_analysis_2::Polynomial_2 >::
Total_degree()(curve.polynomial_2()) < 1)
{
return oi;
} }
//!@} Status_line_1 evt_line1, evt_line2,
int_line = curve.status_line_of_interval(0);
int total_events = curve.number_of_status_lines_with_event();
// handle special case of a curve without any events
if(total_events == 0) {
for (int k = 0; k < int_line.number_of_events(); k++)
*oi++ = Make_x_monotone_result(construct_arc_2(curve, k));
return oi;
}
_m_curve = curve;
typedef typename Curved_kernel_via_analysis_2::
Curve_interval_arcno_cache CIA_cache;
const CIA_cache& map_interval_arcno =
_m_curved_kernel->interval_arcno_cache();
//!\name Functor invokation typename Curved_kernel_via_analysis_2::Construct_point_2
//!@{ construct_point =
_m_curved_kernel->construct_point_2_object();
// TODO add operator for non-x-monotone arc typename CIA_cache::result_type info1, info2;
std::vector<Point_2> min_pts, max_pts;
Coordinate_1 min_x, max_x;
int i, k, n;
Arc_2 arc;
// first handle segments before first event
evt_line1 = curve.status_line_at_event(0);
max_x = evt_line1.x();
/*!\brief for (k = 0; k < evt_line1.number_of_events(); k++)
* Splits a curve into x-monotone arcs and isolated points max_pts.push_back(construct_point(max_x, curve, k));
*
* \param curve The input curve
* \param oi Output iterator that stores CGAL::Object, which either
* encapsulates Point_2 or Arc_2
* \return Past-the-end iterator of \c oi
*/
template <class OutputIterator>
OutputIterator operator()(Curve_analysis_2 curve, OutputIterator oi) {
Construct_arc_2 construct_arc_2 = //std::cout << "handling events over the 1st interval\n";
_m_curved_kernel->construct_arc_2_object(); for (k = 0; k < int_line.number_of_events(); k++) {
// use CGAL::Total_degree ?
if (typename CGAL::Polynomial_traits_d<
typename Curve_analysis_2::Polynomial_2 >::
Total_degree()(curve.polynomial_2()) < 1) {
return oi;
}
Status_line_1 evt_line1, evt_line2, info1 = map_interval_arcno(evt_line1, 1, k);
int_line = curve.status_line_of_interval(0); if (info1.second != CGAL::ARR_INTERIOR) {
int total_events = curve.number_of_status_lines_with_event(); arc = construct_arc_2(CGAL::ARR_MIN_END, max_x,
// handle special case of a curve without any events (info1.second ==
if(total_events == 0) { CGAL::ARR_BOTTOM_BOUNDARY ?
for(int k = 0; k < int_line.number_of_events(); k++) CGAL::ARR_MIN_END : CGAL::ARR_MAX_END),
*oi++ = CGAL::make_object(construct_arc_2(curve, k)); curve, k);
return oi; }
} else {
_m_curve = curve; arc = construct_arc_2(max_pts[info1.first], CGAL::ARR_MIN_END,
typedef typename Curved_kernel_via_analysis_2:: curve, k, info1.first);
Curve_interval_arcno_cache CIA_cache; }
const CIA_cache& map_interval_arcno = *oi++ = Make_x_monotone_result(arc);
_m_curved_kernel->interval_arcno_cache(); }
min_pts = max_pts;
max_pts.clear();
min_x = max_x;
typename Curved_kernel_via_analysis_2::Construct_point_2 // next handle arcs between events, including isolated points
construct_point = for (i = 0; i < total_events-1; i++) {
_m_curved_kernel->construct_point_2_object(); evt_line1 = curve.status_line_at_event(i);
evt_line2 = curve.status_line_at_event(i+1);
max_x = evt_line2.x();
oi = _handle_vertical_and_isolated(evt_line1, min_x, min_pts, oi);
typename CIA_cache::result_type info1, info2; n = evt_line2.number_of_events();
std::vector<Point_2> min_pts, max_pts; for (k = 0; k < n; k++)
Coordinate_1 min_x, max_x; max_pts.push_back(construct_point(max_x, curve, k));
int i, k, n;
Arc_2 arc;
// first handle segments before first event
evt_line1 = curve.status_line_at_event(0);
max_x = evt_line1.x();
for(k = 0; k < evt_line1.number_of_events(); k++) n = curve.status_line_of_interval(i+1).number_of_events();
max_pts.push_back(construct_point(max_x, curve, k)); CGAL::Arr_curve_end inf1_end, inf2_end;
for (k = 0; k < n; k++) {
//std::cout << "handling events over the 1st interval\n"; info1 = map_interval_arcno(evt_line1, 0, k);
for(k = 0; k < int_line.number_of_events(); k++) { info2 = map_interval_arcno(evt_line2, 1, k);
inf2_end = (info2.second == CGAL::ARR_BOTTOM_BOUNDARY ?
info1 = map_interval_arcno(evt_line1, 1, k);
if (info1.second != CGAL::ARR_INTERIOR) {
arc = construct_arc_2(CGAL::ARR_MIN_END, max_x,
(info1.second ==
CGAL::ARR_BOTTOM_BOUNDARY ?
CGAL::ARR_MIN_END : CGAL::ARR_MAX_END),
curve, k);
} else {
arc = construct_arc_2(max_pts[info1.first], CGAL::ARR_MIN_END,
curve, k, info1.first
);
}
*oi++ = CGAL::make_object(arc);
}
min_pts = max_pts;
max_pts.clear();
min_x = max_x;
// next handle arcs between events, including isolated points
for (i = 0; i < total_events-1; i++) {
evt_line1 = curve.status_line_at_event(i);
evt_line2 = curve.status_line_at_event(i+1);
max_x = evt_line2.x();
oi = _handle_vertical_and_isolated(evt_line1, min_x, min_pts, oi);
n = evt_line2.number_of_events();
for(k = 0; k < n; k++)
max_pts.push_back(construct_point(max_x, curve, k));
n = curve.status_line_of_interval(i+1).number_of_events();
CGAL::Arr_curve_end inf1_end, inf2_end;
for (k = 0; k < n; k++) {
info1 = map_interval_arcno(evt_line1, 0, k);
info2 = map_interval_arcno(evt_line2, 1, k);
inf2_end = (info2.second == CGAL::ARR_BOTTOM_BOUNDARY ?
CGAL::ARR_MIN_END : CGAL::ARR_MAX_END); CGAL::ARR_MIN_END : CGAL::ARR_MAX_END);
if (info1.second != CGAL::ARR_INTERIOR) { if (info1.second != CGAL::ARR_INTERIOR) {
inf1_end = (info1.second == CGAL::ARR_BOTTOM_BOUNDARY ? inf1_end = (info1.second == CGAL::ARR_BOTTOM_BOUNDARY ?
CGAL::ARR_MIN_END : CGAL::ARR_MAX_END); CGAL::ARR_MIN_END : CGAL::ARR_MAX_END);
if (info2.second != CGAL::ARR_INTERIOR) { if (info2.second != CGAL::ARR_INTERIOR) {
arc = construct_arc_2(min_x, inf1_end, max_x, inf2_end, arc = construct_arc_2(min_x, inf1_end, max_x, inf2_end,
curve, k); curve, k);
} else { }
arc = construct_arc_2(max_pts[info2.first], min_x, else {
inf1_end, curve, k, info2.first); arc = construct_arc_2(max_pts[info2.first], min_x,
} inf1_end, curve, k, info2.first);
} else if (info2.second != CGAL::ARR_INTERIOR) { }
arc = construct_arc_2(min_pts[info1.first], max_x,
inf2_end, curve, k, info1.first);
} else {
arc = construct_arc_2(min_pts[info1.first],
max_pts[info2.first],
curve, k, info1.first, info2.first);
}
*oi++ = CGAL::make_object(arc);
}
min_pts = max_pts;
max_pts.clear();
min_x = max_x;
} }
else if (info2.second != CGAL::ARR_INTERIOR) {
// here: min_x/min_pts hold information about the last event line arc = construct_arc_2(min_pts[info1.first], max_x,
// event_line2 - points to the last event line inf2_end, curve, k, info1.first);
// vertical line or isolated points at last event?
evt_line2 = curve.status_line_at_event(total_events-1);
min_x = evt_line2.x();
oi = _handle_vertical_and_isolated(evt_line2, min_x, min_pts, oi);
n = curve.status_line_of_interval(total_events).number_of_events();
for (k = 0; k < n; k++) {
info1 = map_interval_arcno(evt_line2, 0, k);
if (info1.second != CGAL::ARR_INTERIOR) {
arc = construct_arc_2(
CGAL::ARR_MAX_END, min_x,
(info1.second == CGAL::ARR_BOTTOM_BOUNDARY ?
CGAL::ARR_MIN_END : CGAL::ARR_MAX_END), curve, k
);
} else {
arc = construct_arc_2(min_pts[info1.first],
CGAL::ARR_MAX_END, curve, k,
info1.first);
}
*oi++ = CGAL::make_object(arc);
} }
return oi; else {
arc = construct_arc_2(min_pts[info1.first],
max_pts[info2.first],
curve, k, info1.first, info2.first);
}
*oi++ = Make_x_monotone_result(arc);
}
min_pts = max_pts;
max_pts.clear();
min_x = max_x;
} }
//!@}
// here: min_x/min_pts hold information about the last event line
// event_line2 - points to the last event line
// vertical line or isolated points at last event?
evt_line2 = curve.status_line_at_event(total_events-1);
min_x = evt_line2.x();
oi = _handle_vertical_and_isolated(evt_line2, min_x, min_pts, oi);
n = curve.status_line_of_interval(total_events).number_of_events();
for (k = 0; k < n; k++) {
info1 = map_interval_arcno(evt_line2, 0, k);
if (info1.second != CGAL::ARR_INTERIOR) {
arc = construct_arc_2(CGAL::ARR_MAX_END, min_x,
(info1.second == CGAL::ARR_BOTTOM_BOUNDARY ?
CGAL::ARR_MIN_END : CGAL::ARR_MAX_END), curve, k
);
}
else {
arc = construct_arc_2(min_pts[info1.first],
CGAL::ARR_MAX_END, curve, k,
info1.first);
}
*oi++ = Make_x_monotone_result(arc);
}
return oi;
}
//!@}
private: private:
//!\name Private members //!\name Private members
//!@{ //!@{
/*!\brief /*!\brief
* Constructs vertical arcs and isolated points at event line * Constructs vertical arcs and isolated points at event line
* *
* \param cv_line The event line in focus * \param cv_line The event line in focus
* \param x x-coordinate of event * \param x x-coordinate of event
* \param pts Points at event line * \param pts Points at event line
* \param oi Output iterator that stores CGAL::Object, which either * \param oi the output iterator for the result. Its dereference type is a
* encapsulates Point_2 or Arc_2 * variant that wraps a Point_2 or an X_monotone_curve_2 objects.
* \return Past-the-end iterator of \c oi * \return Past-the-end iterator of \c oi
*/ */
template <class OutputIterator> template <class OutputIterator>
OutputIterator _handle_vertical_and_isolated( OutputIterator
Status_line_1 cv_line, _handle_vertical_and_isolated(Status_line_1 cv_line,
Coordinate_1 x, std::vector<Point_2> pts, Coordinate_1 x, std::vector<Point_2> pts,
OutputIterator oi) const { OutputIterator oi) const
{
typedef boost::variant<Point_2, Arc_2> Make_x_monotone_result;
Construct_arc_2 construct_arc_2 = Construct_arc_2 construct_arc_2 =
_m_curved_kernel->construct_arc_2_object(); _m_curved_kernel->construct_arc_2_object();
int n = cv_line.number_of_events(), j; int n = cv_line.number_of_events(), j;
if(cv_line.covers_line()) { // look for vertical arcs if (cv_line.covers_line()) { // look for vertical arcs
if(n > 0) { if (n > 0) {
// the first vertical ray // the first vertical ray
*oi++ = CGAL::make_object( *oi++ =
construct_arc_2(pts[0], CGAL::ARR_MIN_END, _m_curve) Make_x_monotone_result(construct_arc_2(pts[0], CGAL::ARR_MIN_END,
); _m_curve));
for(j = 0; j < n-1; j++) // interior bounded arcs for (j = 0; j < n-1; j++) // interior bounded arcs
*oi++ = CGAL::make_object(construct_arc_2(pts[j], pts[j+1], *oi++ = Make_x_monotone_result(construct_arc_2(pts[j], pts[j+1],
_m_curve)); _m_curve));
// the last vertical ray // the last vertical ray
*oi++ = CGAL::make_object(construct_arc_2(pts[n-1], *oi++ =
CGAL::ARR_MAX_END, _m_curve)); Make_x_monotone_result(construct_arc_2(pts[n-1], CGAL::ARR_MAX_END,
} else // unbounded vertical line _m_curve));
*oi++ = CGAL::make_object(construct_arc_2(x, _m_curve)); }
return oi; else // unbounded vertical line
} *oi++ = Make_x_monotone_result(construct_arc_2(x, _m_curve));
// look for isolated points return oi;
std::pair<int, int> ipair;
for(j = 0; j < n; j++) {
ipair = cv_line.number_of_incident_branches(j);
if(ipair.first == 0&&ipair.second == 0) {
//std::cout << "isolated point found\n";
typename Curved_kernel_via_analysis_2::Construct_point_2
construct_point =
_m_curved_kernel->construct_point_2_object();
*oi++ = CGAL::make_object(construct_point(x, _m_curve, j));
}
}
return oi;
} }
// look for isolated points
std::pair<int, int> ipair;
for (j = 0; j < n; j++) {
ipair = cv_line.number_of_incident_branches(j);
if (ipair.first == 0&&ipair.second == 0) {
//std::cout << "isolated point found\n";
typename Curved_kernel_via_analysis_2::Construct_point_2
construct_point = _m_curved_kernel->construct_point_2_object();
//!@} *oi++ = Make_x_monotone_result(construct_point(x, _m_curve, j));
}
}
return oi;
}
//!\name Private data //!@}
//!@{
//! pointer to \c Curved_kernel_via_analysis_2 //!\name Private data
Curved_kernel_via_analysis_2 *_m_curved_kernel; //!@{
//! to avoid passing curve as a parameter //! pointer to \c Curved_kernel_via_analysis_2
Curve_analysis_2 _m_curve; Curved_kernel_via_analysis_2 *_m_curved_kernel;
//!@} //! to avoid passing curve as a parameter
}; // struct Make_x_monotone Curve_analysis_2 _m_curve;
//!@}
}; // struct Make_x_monotone
} // namespace internal } // namespace internal

View File

@ -699,13 +699,14 @@ public:
* is by definition x-monotone, an input arc is passed to the * is by definition x-monotone, an input arc is passed to the
* output iterator directly. * output iterator directly.
* \param cv The curve. * \param cv The curve.
* \param oi The output iterator, whose value-type is Object. * \param oi The output iteratorfor the result. Its dereference type is a
* The returned objects are all wrappers X_monotone_curve_2 objects. * variant that wraps a \c Point_2 or an \c X_monotone_curve_2
* \return The past-the-end iterator. * objects..
* \return The past-the-end output iterator.
*/ */
template<class OutputIterator> template<class OutputIterator>
OutputIterator operator()(const Generic_arc_2& cv, OutputIterator operator()(const Generic_arc_2& cv, OutputIterator oi) const
OutputIterator oi) const { {
*oi++ = cv; *oi++ = cv;
return oi; return oi;
} }
@ -714,32 +715,32 @@ public:
* decompose a given curve into list of x-monotone pieces * decompose a given curve into list of x-monotone pieces
* (subcurves) and insert them to the output iterator. * (subcurves) and insert them to the output iterator.
* \param cv The curve. * \param cv The curve.
* \param oi The output iterator, whose value-type is Object. * \param oi the output iterator for the result. Its dereference type is a
* The returned objects are all wrappers X_monotone_curve_2 objects. * variant that wraps a \c Point_2 or an \c X_monotone_curve_2
* \return The past-the-end iterator. * objects.
* \return The past-the-end output iterator.
*/ */
template<class OutputIterator> template<class OutputIterator>
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const { OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const {
typedef typename SweepCurvesAdapter_2::Native_arc_2 Native_arc_2; typedef typename SweepCurvesAdapter_2::Native_arc_2 Native_arc_2;
typedef typename SweepCurvesAdapter_2::Native_point_2 Native_point_2; typedef typename SweepCurvesAdapter_2::Native_point_2 Native_point_2;
typedef typename SweepCurvesAdapter_2::Generic_point_2 Generic_point_2; typedef typename SweepCurvesAdapter_2::Generic_point_2 Generic_point_2;
typedef boost::variant<Native_arc_2, Native_point_2>
Make_x_monotone_result;
typedef std::vector<CGAL::Object> Objects; std::vector<Make_x_monotone_result> objs;
Objects objs; auto make_x_monotone = _m_adapter->kernel().make_x_monotone_2_object();
_m_adapter->kernel().make_x_monotone_2_object()(cv, make_x_monotone(cv, std::back_inserter(objs));
std::back_inserter(objs));
// sort out normal and degenerate arcs // sort out normal and degenerate arcs
for(typename Objects::const_iterator it = objs.begin(); for (auto& obj : objs) {
it != objs.end(); it++) { if (auto* arc = boost::get<Native_arc_2>(&obj)) {
Native_arc_2 arc; *oi++ = Generic_arc_2(*arc);
Native_point_2 pt; continue;
if(CGAL::assign(arc, *it)) }
*oi++ = Generic_arc_2(arc); auto* pt = boost::get<Native_point_2>(&obj);
else if(CGAL::assign(pt, *it)) CGAL_assertion(pt);
*oi++ = Generic_arc_2(Generic_point_2(pt)); *oi++ = Generic_arc_2(Generic_point_2(*pt));
else
CGAL_error_msg("Bogus object..\n");
} }
return oi; return oi;
} }

View File

@ -23,7 +23,6 @@
* Defintion of the Arr_basic_insertion_traits_2<Traits,Arrangement> class. * Defintion of the Arr_basic_insertion_traits_2<Traits,Arrangement> class.
*/ */
#include <CGAL/Object.h>
#include <CGAL/Arr_tags.h> #include <CGAL/Arr_tags.h>
#include <list> #include <list>

View File

@ -23,7 +23,6 @@
*/ */
#include <CGAL/Arr_point_location_result.h> #include <CGAL/Arr_point_location_result.h>
#include <CGAL/Object.h>
#include <CGAL/Surface_sweep_2/Default_visitor_base.h> #include <CGAL/Surface_sweep_2/Default_visitor_base.h>
#include <CGAL/Default.h> #include <CGAL/Default.h>

View File

@ -8,9 +8,9 @@
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
// //
// //
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il> // Author(s): Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il> // Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il> // Efi Fogel <efif@post.tau.ac.il>
#ifndef CGAL_ARR_NO_INTERSECTION_INSERTION_SS_VISITOR_H #ifndef CGAL_ARR_NO_INTERSECTION_INSERTION_SS_VISITOR_H
#define CGAL_ARR_NO_INTERSECTION_INSERTION_SS_VISITOR_H #define CGAL_ARR_NO_INTERSECTION_INSERTION_SS_VISITOR_H

View File

@ -26,7 +26,6 @@
#include <boost/optional.hpp> #include <boost/optional.hpp>
#include <CGAL/Arr_tags.h> #include <CGAL/Arr_tags.h>
#include <CGAL/Object.h>
namespace CGAL { namespace CGAL {

View File

@ -7,9 +7,8 @@
// $Id$ // $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
// //
// // Author(s): Ron Wein <wein@post.tau.ac.il>
// Author(s) : Ron Wein <wein@post.tau.ac.il> // Efi Fogel <efifogel@gmail.com>
// Efi Fogel <efifogel@gmail.com>
#ifndef CGAL_ARR_VERT_DECOMP_SS_VISITOR_H #ifndef CGAL_ARR_VERT_DECOMP_SS_VISITOR_H
#define CGAL_ARR_VERT_DECOMP_SS_VISITOR_H #define CGAL_ARR_VERT_DECOMP_SS_VISITOR_H
@ -21,10 +20,11 @@
* Definition of the Arr_vert_decomp_ss_visitor class-template. * Definition of the Arr_vert_decomp_ss_visitor class-template.
*/ */
#include <boost/variant.hpp>
namespace CGAL { namespace CGAL {
#include <CGAL/Surface_sweep_2/Default_visitor_base.h> #include <CGAL/Surface_sweep_2/Default_visitor_base.h>
#include <CGAL/Object.h>
#include <CGAL/Default.h> #include <CGAL/Default.h>
/*! \class Arr_vert_decomp_ss_visitor /*! \class Arr_vert_decomp_ss_visitor
@ -63,13 +63,18 @@ private:
public: public:
typedef typename Helper::Arrangement_2 Arrangement_2; typedef typename Helper::Arrangement_2 Arrangement_2;
typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle; typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle;
typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
typedef typename Arrangement_2::Face_const_handle Face_const_handle;
typedef std::pair<CGAL::Object, CGAL::Object> Vert_pair; typedef boost::variant<Vertex_const_handle, Halfedge_const_handle,
Face_const_handle>
Cell_type;
typedef boost::optional<Cell_type> Vert_type;
typedef std::pair<Vert_type, Vert_type> Vert_pair;
typedef std::pair<Vertex_const_handle, Vert_pair> Vert_entry; typedef std::pair<Vertex_const_handle, Vert_pair> Vert_entry;
protected: protected:
typedef typename Base::Status_line_iterator Status_line_iterator; typedef typename Base::Status_line_iterator Status_line_iterator;
typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
//typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle; //typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle;
typedef typename Arrangement_2::Halfedge_around_vertex_const_circulator typedef typename Arrangement_2::Halfedge_around_vertex_const_circulator
Halfedge_around_vertex_const_circulator; Halfedge_around_vertex_const_circulator;
@ -84,8 +89,8 @@ protected:
// An invalid vertex handle. // An invalid vertex handle.
Vertex_const_handle m_prev_vh; // The previous vertex. Vertex_const_handle m_prev_vh; // The previous vertex.
CGAL::Object m_prev_obj_below; // The object this vertex sees below it. Vert_type m_prev_obj_below; // The object this vertex sees below it.
CGAL::Object m_prev_obj_above; // The object this vertex sees above it. Vert_type m_prev_obj_above; // The object this vertex sees above it.
Output_iterator* m_out; // An output iterator for the result. Output_iterator* m_out; // An output iterator for the result.
@ -155,7 +160,7 @@ after_handle_event(Event* event,
// Get the vertex handle associated with the current event (stored with // Get the vertex handle associated with the current event (stored with
// the point). // the point).
Vertex_const_handle vh = event->point().vertex_handle(); Vertex_const_handle vh = event->point().vertex_handle();
CGAL::Object obj_above, obj_below; Vert_type obj_above, obj_below;
// Check the feature from above. // Check the feature from above.
if (above == this->status_line_end()) { if (above == this->status_line_end()) {
@ -166,8 +171,7 @@ after_handle_event(Event* event,
else { else {
// We have a valid subcurve above the event: get its halfedge handle // We have a valid subcurve above the event: get its halfedge handle
// and associate it with the vertex. // and associate it with the vertex.
obj_above = obj_above = Vert_type((*above)->last_curve().halfedge_handle());
CGAL::make_object((*above)->last_curve().halfedge_handle());
} }
// Check if the previous vertex we handled has the same x-coordinate // Check if the previous vertex we handled has the same x-coordinate
@ -206,12 +210,12 @@ after_handle_event(Event* event,
} }
if (! vert_connected) { if (! vert_connected) {
obj_below = CGAL::make_object(m_prev_vh); obj_below = Vert_type(m_prev_vh);
m_prev_obj_above = CGAL::make_object(vh); m_prev_obj_above = Vert_type(vh);
} }
else { else {
obj_below = CGAL::Object(); obj_below = Vert_type();
m_prev_obj_above = CGAL::Object(); m_prev_obj_above = Vert_type();
} }
} }
else { else {
@ -260,19 +264,18 @@ after_handle_event(Event* event,
} }
if (! vert_connected) { if (! vert_connected) {
obj_below = CGAL::make_object(m_prev_vh); obj_below = Vert_type(m_prev_vh);
m_prev_obj_above = CGAL::make_object(vh); m_prev_obj_above = Vert_type(vh);
} }
else { else {
obj_below = CGAL::Object(); obj_below = Vert_type();
m_prev_obj_above = CGAL::Object(); m_prev_obj_above = Vert_type();
} }
} }
else { else {
// Get the halfedge handle of the subcurve below the current event and // Get the halfedge handle of the subcurve below the current event and
// associate it with its vertex. // associate it with its vertex.
obj_below = obj_below = Vert_type((*below)->last_curve().halfedge_handle());
CGAL::make_object((*below)->last_curve().halfedge_handle());
} }
} }

View File

@ -208,8 +208,7 @@ verify(InputIterator begin, InputIterator end)
typename TopolTraits::Default_point_location_strategy pl(m_arr); typename TopolTraits::Default_point_location_strategy pl(m_arr);
for (InputIterator it = begin; it != end; ++it) { for (InputIterator it = begin; it != end; ++it) {
if (m_verbose_level > 1) if (m_verbose_level > 1) print(*it);
print(*it);
// Perform (single) point location. // Perform (single) point location.
Result_type obj = pl.locate(it->first); Result_type obj = pl.locate(it->first);

View File

@ -71,10 +71,10 @@ read_xcurve(InputStream_& is, typename GeomTraits_::X_monotone_curve_2& xcv)
typedef GeomTraits_ Geom_traits; typedef GeomTraits_ Geom_traits;
Basic_number_type x1, y1, x2, y2; Basic_number_type x1, y1, x2, y2;
is >> x1 >> y1 >> x2 >> y2; is >> x1 >> y1 >> x2 >> y2;
CGAL_assertion(!is.fail()); assert(!is.fail());
Point_2 p1(x1, y1); Point_2 p1(x1, y1);
Point_2 p2(x2, y2); Point_2 p2(x2, y2);
CGAL_assertion(p1 != p2); assert(p1 != p2);
xcv = typename Geom_traits::X_monotone_curve_2(p1, p2); xcv = typename Geom_traits::X_monotone_curve_2(p1, p2);
return true; return true;
} }
@ -89,7 +89,7 @@ read_curve(InputStream_& is, typename GeomTraits_::Curve_2& cv)
is >> x1 >> y1 >> x2 >> y2; is >> x1 >> y1 >> x2 >> y2;
Point_2 p1(x1, y1); Point_2 p1(x1, y1);
Point_2 p2(x2, y2); Point_2 p2(x2, y2);
CGAL_assertion(p1 != p2); assert(p1 != p2);
cv = typename Geom_traits::Curve_2(p1, p2); cv = typename Geom_traits::Curve_2(p1, p2);
return true; return true;
} }
@ -690,21 +690,20 @@ bool IO_base_test<Base_geom_traits>::read_xsegment(InputStream_& is,
point_vector.push_back(Control_point_2(point_x, point_y)); point_vector.push_back(Control_point_2(point_x, point_y));
} }
//get the non x-monotone bezier segment //get the non x-monotone bezier segment
Subcurve_2 seg (point_vector.begin(), point_vector.end()); Subcurve_2 seg(point_vector.begin(), point_vector.end());
//convert it into x-monotone bezier segment. //convert it into x-monotone bezier segment.
std::vector<CGAL::Object> obj_vector; typedef boost::variant<Point_2, X_monotone_subcurve_2> Make_x_monotone_result;
bezier_traits.make_x_monotone_2_object()(seg, std::vector<Make_x_monotone_result> objs;
std::back_inserter(obj_vector)); bezier_traits.make_x_monotone_2_object()(seg, std::back_inserter(objs));
X_monotone_subcurve_2 x_segment = assert(! objs.empty());
CGAL::object_cast<X_monotone_subcurve_2>((obj_vector[0])); const auto* x_seg_p = boost::get<X_monotone_subcurve_2>(&(objs[0]));
assert(x_seg_p);
xseg = x_segment; xseg = *x_seg_p;
return true; return true;
} }
template <> template <>
template <typename InputStream_> template <typename InputStream_>
bool IO_base_test<Base_geom_traits>::read_xcurve(InputStream_& is, bool IO_base_test<Base_geom_traits>::read_xcurve(InputStream_& is,
@ -721,6 +720,8 @@ bool IO_base_test<Base_geom_traits>::read_xcurve(InputStream_& is,
unsigned int number_of_segments; unsigned int number_of_segments;
is >> number_of_segments; is >> number_of_segments;
typedef boost::variant<Point_2, X_monotone_subcurve_2> Make_x_monotone_result;
auto make_x_monotone = bezier_traits.make_x_monotone_2_object();
if ((type == 'x') || (type == 'X')) { if ((type == 'x') || (type == 'X')) {
for (unsigned int i=0; i<number_of_segments; ++i) { for (unsigned int i=0; i<number_of_segments; ++i) {
unsigned int num_control_points; unsigned int num_control_points;
@ -737,13 +738,12 @@ bool IO_base_test<Base_geom_traits>::read_xcurve(InputStream_& is,
Subcurve_2 seg(point_vector.begin(), point_vector.end()); Subcurve_2 seg(point_vector.begin(), point_vector.end());
//convert it into x-monotone bezier segment. //convert it into x-monotone bezier segment.
std::vector<CGAL::Object> obj_vector; std::vector<Make_x_monotone_result> objs;
bezier_traits.make_x_monotone_2_object()(seg, make_x_monotone(seg, std::back_inserter(objs));
std::back_inserter(obj_vector)); assert(! objs.empty());
X_monotone_subcurve_2 x_seg = const auto* x_seg_p = boost::get<X_monotone_subcurve_2>(&(objs[0]));
CGAL::object_cast<X_monotone_subcurve_2>((obj_vector[0])); assert(x_seg_p);
x_segments.push_back(*x_seg_p);
x_segments.push_back(x_seg);
} //for loop (number of segments) } //for loop (number of segments)
} }
@ -1470,8 +1470,8 @@ bool IO_base_test<Base_geom_traits>::read_xcurve(InputStream_& is,
X_monotone_curve_2& xcv) X_monotone_curve_2& xcv)
{ {
std::cout << std::endl; std::cout << std::endl;
std::list<CGAL::Object> x_objs; typedef boost::variant<Point_2, X_monotone_curve_2> Make_x_monotone_result;
std::list<CGAL::Object>::const_iterator xoit; std::list<Make_x_monotone_result> x_objs;
Curve_2 tmp_cv; Curve_2 tmp_cv;
is >> tmp_cv; is >> tmp_cv;
Rational B_psx = Rational(tmp_cv.control_point(0).x()); Rational B_psx = Rational(tmp_cv.control_point(0).x());
@ -1482,15 +1482,15 @@ bool IO_base_test<Base_geom_traits>::read_xcurve(InputStream_& is,
Rational(tmp_cv.control_point(tmp_cv.number_of_control_points()-1).y()); Rational(tmp_cv.control_point(tmp_cv.number_of_control_points()-1).y());
Point_2 B_ps(B_psx, B_psy); Point_2 B_ps(B_psx, B_psy);
Point_2 B_pt(B_ptx, B_pty); Point_2 B_pt(B_ptx, B_pty);
Base_geom_traits::Make_x_monotone_2 make_x_monotone = auto make_x_monotone = this->m_geom_traits.make_x_monotone_2_object();
this->m_geom_traits.make_x_monotone_2_object(); make_x_monotone(tmp_cv, std::front_inserter(x_objs));
make_x_monotone(tmp_cv, std::front_inserter (x_objs)); auto xoit = x_objs.begin();
xoit = x_objs.begin();
size_t id(0); size_t id(0);
if (!is.eof()) is >> id; if (! is.eof()) is >> id;
std::advance(xoit, id); std::advance(xoit, id);
if (CGAL::assign(xcv, *xoit)) const auto* xcv_p = boost::get<X_monotone_curve_2>(&*xoit);
return true; assert(xcv_p);
xcv = *xcv_p;
return false; return false;
} }
@ -1546,9 +1546,8 @@ bool IO_base_test<Base_geom_traits>::read_point(InputStream_& is, Point_2& p) {
is >> x; is >> x;
Base_geom_traits::X_monotone_curve_2 xcv; Base_geom_traits::X_monotone_curve_2 xcv;
CGAL::swallow(is, '('); CGAL::swallow(is, '(');
CGAL_assertion_code(bool check = ) bool check = read_xcurve(is, xcv);
read_xcurve(is, xcv); assert(check);
CGAL_assertion(check);
CGAL::swallow(is, ')'); CGAL::swallow(is, ')');
p = construct_point_2(x, xcv); p = construct_point_2(x, xcv);
@ -1558,9 +1557,8 @@ bool IO_base_test<Base_geom_traits>::read_point(InputStream_& is, Point_2& p) {
Base_geom_traits::Algebraic_real_1 x; Base_geom_traits::Algebraic_real_1 x;
is >> x; is >> x;
Base_geom_traits::Curve_2 c; Base_geom_traits::Curve_2 c;
CGAL_assertion_code(bool check = ) bool check = read_curve(is, c);
read_curve(is, c); assert(check);
CGAL_assertion(check);
int arcno = 0; int arcno = 0;
is >> arcno; is >> arcno;
p = construct_point_2(x, c, arcno); p = construct_point_2(x, c, arcno);
@ -1589,36 +1587,31 @@ bool IO_base_test<Base_geom_traits>::read_xcurve(InputStream_& is,
switch (type) { switch (type) {
case '1': { case '1': {
Curve_2 cv; Curve_2 cv;
Point_2 end_left,end_right; Point_2 end_left, end_right;
CGAL_assertion_code(bool check = ) bool check = read_curve(is,cv);
read_curve(is,cv); assert(check);
CGAL_assertion(check);
CGAL::swallow(is, '('); CGAL::swallow(is, '(');
CGAL_assertion_code(check = ) check = read_point(is,end_left);
read_point(is,end_left); assert(check);
CGAL_assertion(check);
CGAL::swallow(is, ')'); CGAL::swallow(is, ')');
CGAL::swallow(is, '('); CGAL::swallow(is, '(');
CGAL_assertion_code(check = ) check = read_point(is,end_right);
read_point(is,end_right); assert(check);
CGAL_assertion(check);
CGAL::swallow(is, ')'); CGAL::swallow(is, ')');
std::vector<Base_geom_traits::X_monotone_curve_2> xcvs; std::vector<Base_geom_traits::X_monotone_curve_2> xcvs;
construct_segment_2(cv, end_left, end_right, std::back_inserter(xcvs)); construct_segment_2(cv, end_left, end_right, std::back_inserter(xcvs));
CGAL_assertion(xcvs.size() == 1); assert(xcvs.size() == 1);
xcv = xcvs[0]; xcv = xcvs[0];
break; break;
} }
case '2': { case '2': {
Curve_2 cv; Curve_2 cv;
Point_2 p; Point_2 p;
CGAL_assertion_code(bool check = ) bool check = read_curve(is, cv);
read_curve(is, cv); assert(check);
CGAL_assertion(check);
CGAL::swallow(is, '('); CGAL::swallow(is, '(');
CGAL_assertion_code(check = ) check = read_point(is, p);
read_point(is, p); assert(check);
CGAL_assertion(check);
CGAL::swallow(is, ')'); CGAL::swallow(is, ')');
std::string site_of_p_string; std::string site_of_p_string;
Base_geom_traits::Site_of_point site_of_p; Base_geom_traits::Site_of_point site_of_p;
@ -1630,12 +1623,12 @@ bool IO_base_test<Base_geom_traits>::read_xcurve(InputStream_& is,
site_of_p = Base_geom_traits::MAX_ENDPOINT; site_of_p = Base_geom_traits::MAX_ENDPOINT;
} }
else { else {
CGAL_assertion(site_of_p_string == "POINT_IN_INTERIOR"); assert(site_of_p_string == "POINT_IN_INTERIOR");
site_of_p = Base_geom_traits::POINT_IN_INTERIOR; site_of_p = Base_geom_traits::POINT_IN_INTERIOR;
} }
std::vector<Base_geom_traits::X_monotone_curve_2> xcvs; std::vector<Base_geom_traits::X_monotone_curve_2> xcvs;
construct_segment_2(cv, p, site_of_p, std::back_inserter(xcvs)); construct_segment_2(cv, p, site_of_p, std::back_inserter(xcvs));
CGAL_assertion(xcvs.size() == 1); assert(xcvs.size() == 1);
xcv = xcvs[0]; xcv = xcvs[0];
break; break;
} }
@ -1685,7 +1678,7 @@ bool IO_base_test<Base_geom_traits>::read_xcurve(InputStream_& is,
Point_2 p1, p2; Point_2 p1, p2;
read_point(is, p1); read_point(is, p1);
read_point(is, p2); read_point(is, p2);
CGAL_assertion(p1 != p2); assert(p1 != p2);
unsigned int flag; unsigned int flag;
is >> flag; is >> flag;
@ -1707,7 +1700,7 @@ bool IO_base_test<Base_geom_traits>::read_curve(InputStream_& is, Curve_2& cv)
Point_2 p1, p2; Point_2 p1, p2;
read_point(is, p1); read_point(is, p1);
read_point(is, p2); read_point(is, p2);
CGAL_assertion(p1 != p2); assert(p1 != p2);
unsigned int flag; unsigned int flag;
is >> flag; is >> flag;
if (flag == 1) { if (flag == 1) {

View File

@ -262,7 +262,7 @@ private:
void allocate_pl() void allocate_pl()
{ {
Strategy* locator = new Strategy(); Strategy* locator = new Strategy();
CGAL_assertion(locator); assert(locator);
m_locators[id].m_variant = locator; m_locators[id].m_variant = locator;
} }

View File

@ -13,7 +13,6 @@
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <CGAL/exceptions.h> #include <CGAL/exceptions.h>
#include <CGAL/Object.h>
#include <CGAL/Arr_tags.h> #include <CGAL/Arr_tags.h>
#include <CGAL/Arr_enums.h> #include <CGAL/Arr_enums.h>
#include <CGAL/use.h> #include <CGAL/use.h>

View File

@ -13,7 +13,6 @@
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <CGAL/exceptions.h> #include <CGAL/exceptions.h>
#include <CGAL/Object.h>
#include <CGAL/Arr_tags.h> #include <CGAL/Arr_tags.h>
#include <CGAL/Arrangement_2/Arr_traits_adaptor_2_dispatching.h> #include <CGAL/Arrangement_2/Arr_traits_adaptor_2_dispatching.h>
#include <CGAL/use.h> #include <CGAL/use.h>
@ -931,22 +930,22 @@ template <typename Geom_traits_T>
bool Traits_test<Geom_traits_T>:: bool Traits_test<Geom_traits_T>::
make_x_monotone_wrapper(std::istringstream& str_stream) make_x_monotone_wrapper(std::istringstream& str_stream)
{ {
typedef Geom_traits_T Traits; typedef Geom_traits_T Traits;
typedef typename Traits::Point_2 Point_2; typedef typename Traits::Point_2 Point_2;
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
typedef boost::variant<Point_2, X_monotone_curve_2> Make_x_monotone_result;
CGAL_USE_TYPE(typename Traits::Curve_2); CGAL_USE_TYPE(typename Traits::Curve_2);
unsigned int id; unsigned int id;
str_stream >> id; str_stream >> id;
std::cout << "Test: make_x_monotone( " << this->m_curves[id] std::cout << "Test: make_x_monotone( " << this->m_curves[id] << " ) ? ";
<< " ) ? "; std::vector<Make_x_monotone_result> objs;
std::vector<CGAL::Object> object_vec;
this->m_geom_traits.make_x_monotone_2_object()(this->m_curves[id], this->m_geom_traits.make_x_monotone_2_object()(this->m_curves[id],
std::back_inserter(object_vec)); std::back_inserter(objs));
size_t num; size_t num;
str_stream >> num; str_stream >> num;
if (!this->compare(num, object_vec.size(), "size")) return false; if (!this->compare(num, objs.size(), "size")) return false;
for (size_t i = 0; i < num; ++i) { for (size_t i = 0; i < num; ++i) {
unsigned int type; // 0 - point, 1 - x-monotone curve unsigned int type; // 0 - point, 1 - x-monotone curve
@ -955,20 +954,19 @@ make_x_monotone_wrapper(std::istringstream& str_stream)
unsigned int id; // The id of the point or x-monotone unsigned int id; // The id of the point or x-monotone
str_stream >> id; // ... curve respectively str_stream >> id; // ... curve respectively
const X_monotone_curve_2 * xcv_ptr = const auto* xcv_ptr = boost::get<X_monotone_curve_2>(&(objs[i]));
CGAL::object_cast<X_monotone_curve_2> (&(object_vec[i])); if (xcv_ptr != nullptr) {
if (xcv_ptr != NULL) {
if (!this->compare(type, 1u, "type")) return false; if (!this->compare(type, 1u, "type")) return false;
if (!this->compare_curves(this->m_xcurves[id], *xcv_ptr)) return false; if (!this->compare_curves(this->m_xcurves[id], *xcv_ptr)) return false;
continue; continue;
} }
const Point_2 * pt_ptr = CGAL::object_cast<Point_2> (&(object_vec[i])); const auto* pt_ptr = boost::get<Point_2>(&(objs[i]));
assert (pt_ptr != NULL); assert(pt_ptr != nullptr);
if (!this->compare(type, 0u, "type")) return false; if (!this->compare(type, 0u, "type")) return false;
if (!this->compare_points(this->m_points[id], *pt_ptr)) return false; if (!this->compare_points(this->m_points[id], *pt_ptr)) return false;
} }
object_vec.clear(); objs.clear();
return true; return true;
} }

View File

@ -12,11 +12,11 @@
#include "IO_test.h" #include "IO_test.h"
/*! Point location test */ /*! Point location test */
template <typename GeomTraits_T, typename TopolTraits_T> template <typename GeomTraits_2, typename TopolTraits>
class Vertical_decomposition_test : public IO_test<GeomTraits_T> { class Vertical_decomposition_test : public IO_test<GeomTraits_2> {
public: public:
typedef GeomTraits_T Geom_traits; typedef GeomTraits_2 Geom_traits;
typedef TopolTraits_T Topol_traits; typedef TopolTraits Topol_traits;
private: private:
typedef IO_test<Geom_traits> Base; typedef IO_test<Geom_traits> Base;
@ -44,8 +44,11 @@ public:
typedef typename Arrangement::Edge_const_iterator Edge_const_iterator; typedef typename Arrangement::Edge_const_iterator Edge_const_iterator;
typedef typename Arrangement::Vertex_const_iterator Vertex_const_iterator; typedef typename Arrangement::Vertex_const_iterator Vertex_const_iterator;
typedef typename std::pair<CGAL::Object, CGAL::Object> Object_pair; typedef boost::variant<Vertex_const_handle, Halfedge_const_handle,
typedef typename std::pair<Vertex_const_handle, Object_pair> Face_const_handle> Cell_type;
typedef boost::optional<Cell_type> Vert_type;
typedef typename std::pair<Vert_type, Vert_type> Vert_pair;
typedef typename std::pair<Vertex_const_handle, Vert_pair>
Vert_decomp_entry; Vert_decomp_entry;
typedef typename std::list<Vert_decomp_entry> Vert_decomp_list; typedef typename std::list<Vert_decomp_entry> Vert_decomp_list;
@ -69,7 +72,7 @@ protected:
/*! Compare the results. /*! Compare the results.
*/ */
bool compare(const Result_type& expected, const CGAL::Object& actual); bool compare(const Result_type& expected, Vert_type actual);
/*! print the results. /*! print the results.
*/ */
@ -104,8 +107,8 @@ public:
/*! /*!
* Constructor from a geometry traits object. * Constructor from a geometry traits object.
*/ */
template <typename GeomTraits_T, typename TopolTraits_T> template <typename GeomTraits_2, typename TopolTraits>
Vertical_decomposition_test<GeomTraits_T, TopolTraits_T>:: Vertical_decomposition_test<GeomTraits_2, TopolTraits>::
Vertical_decomposition_test(const Geom_traits& geom_traits) : Vertical_decomposition_test(const Geom_traits& geom_traits) :
Base(geom_traits), Base(geom_traits),
m_geom_traits(geom_traits), m_geom_traits(geom_traits),
@ -113,24 +116,24 @@ Vertical_decomposition_test(const Geom_traits& geom_traits) :
{} {}
//! \brief sets the verbosity level. //! \brief sets the verbosity level.
template <typename GeomTraits_T, typename TopolTraits_T> template <typename GeomTraits_2, typename TopolTraits>
void Vertical_decomposition_test<GeomTraits_T, TopolTraits_T>:: void Vertical_decomposition_test<GeomTraits_2, TopolTraits>::
set_verbose_level(size_t verbose_level) set_verbose_level(size_t verbose_level)
{ m_verbose_level = verbose_level; } { m_verbose_level = verbose_level; }
/*! Clear the data structures */ /*! Clear the data structures */
template <typename GeomTraits_T, typename TopolTraits_T> template <typename GeomTraits_2, typename TopolTraits>
void Vertical_decomposition_test<GeomTraits_T, TopolTraits_T>::clear() void Vertical_decomposition_test<GeomTraits_2, TopolTraits>::clear()
{ {
m_arr.clear(); m_arr.clear();
Base::clear(); Base::clear();
} }
template <typename GeomTraits_T, typename TopolTraits_T> template <typename GeomTraits_2, typename TopolTraits>
bool Vertical_decomposition_test<GeomTraits_T, TopolTraits_T>::init() bool Vertical_decomposition_test<GeomTraits_2, TopolTraits>::init()
{ {
// Initialize the input. // Initialize the input.
if (!Base::init()) return false; if (! Base::init()) return false;
// Insert all into the arrangement // Insert all into the arrangement
CGAL::insert(m_arr, this->m_xcurves.begin(), this->m_xcurves.end()); CGAL::insert(m_arr, this->m_xcurves.begin(), this->m_xcurves.end());
@ -147,8 +150,8 @@ bool Vertical_decomposition_test<GeomTraits_T, TopolTraits_T>::init()
} }
//! \brief performs the test. //! \brief performs the test.
template <typename GeomTraits_T, typename TopolTraits_T> template <typename GeomTraits_2, typename TopolTraits>
bool Vertical_decomposition_test<GeomTraits_T, TopolTraits_T>::perform() bool Vertical_decomposition_test<GeomTraits_2, TopolTraits>::perform()
{ {
// Apply vertical decomposition. // Apply vertical decomposition.
Vert_decomp_list results; Vert_decomp_list results;
@ -159,51 +162,48 @@ bool Vertical_decomposition_test<GeomTraits_T, TopolTraits_T>::perform()
} }
//! \brief verifies the results. //! \brief verifies the results.
template <typename GeomTraits_T, typename TopolTraits_T> template <typename GeomTraits_2, typename TopolTraits>
template <typename InputIterator> template <typename InputIterator>
bool Vertical_decomposition_test<GeomTraits_T, TopolTraits_T>:: bool Vertical_decomposition_test<GeomTraits_2, TopolTraits>::
verify(InputIterator begin, InputIterator end) verify(InputIterator begin, InputIterator end)
{ {
typedef TopolTraits_T TopolTraits; if (m_verbose_level > 1) for (auto it = begin; it != end; ++it) print(*it);
InputIterator it;
if (m_verbose_level > 1) for (it = begin; it != end; ++it) print(*it);
// Compare the results. // Compare the results.
typename TopolTraits::Default_vertical_ray_shooting_strategy vs(m_arr); typename TopolTraits::Default_vertical_ray_shooting_strategy vs(m_arr);
for (it = begin; it != end; ++it) { for (auto it = begin; it != end; ++it) {
Vertex_const_handle vh = it->first; Vertex_const_handle vh = it->first;
const Object_pair& res = it->second; const auto& res = it->second;
const CGAL::Object& obj_below_actual = res.first; auto obj_below_actual = res.first;
const CGAL::Object& obj_above_actual = res.second; auto obj_above_actual = res.second;
Result_type obj_below_expected = vs.ray_shoot_down(vh->point()); Result_type obj_below_expected = vs.ray_shoot_down(vh->point());
Result_type obj_above_expected = vs.ray_shoot_up(vh->point()); Result_type obj_above_expected = vs.ray_shoot_up(vh->point());
if (!compare(obj_below_expected, obj_below_actual)) return false; if (! compare(obj_below_expected, obj_below_actual)) return false;
if (!compare(obj_above_expected, obj_above_actual)) return false; if (! compare(obj_above_expected, obj_above_actual)) return false;
} }
return true; return true;
} }
template <typename GeomTraits_T, typename TopolTraits_T> template <typename GeomTraits_2, typename TopolTraits>
bool Vertical_decomposition_test<GeomTraits_T, TopolTraits_T>:: bool Vertical_decomposition_test<GeomTraits_2, TopolTraits>::
compare(const Result_type& expected, const CGAL::Object& actual) compare(const Result_type& expected, Vert_type actual)
{ {
// This test does not test the case where the result is empty!
if (! actual) return false;
auto obj = *actual;
// Assign object to a fase. // Assign object to a fase.
const Face_const_handle* fh_expected = if (const auto* fh_expected = boost::get<Face_const_handle>(&(expected))) {
boost::get<Face_const_handle>(&(expected)); if (boost::get<Vertex_const_handle>(&obj)) {
if (fh_expected) {
Vertex_const_handle vh_actual;
if (CGAL::assign(vh_actual, actual)) {
std::cout << "Error: vertical decomposition!" << std::endl; std::cout << "Error: vertical decomposition!" << std::endl;
std::cout << "Expected: a face." << std::endl; std::cout << "Expected: a face." << std::endl;
std::cout << "Actual: a vertex." << std::endl; std::cout << "Actual: a vertex." << std::endl;
return false; return false;
} }
Halfedge_const_handle hh_actual; if (boost::get<Halfedge_const_handle>(&obj)) {
if (CGAL::assign(hh_actual, actual)) {
std::cout << "Error: vertical decomposition!" << std::endl; std::cout << "Error: vertical decomposition!" << std::endl;
std::cout << "Expected: a face." << std::endl; std::cout << "Expected: a face." << std::endl;
std::cout << "Actual: a halfedge." << std::endl; std::cout << "Actual: a halfedge." << std::endl;
@ -213,17 +213,15 @@ compare(const Result_type& expected, const CGAL::Object& actual)
} }
// Assign object to a halfedge. // Assign object to a halfedge.
const Halfedge_const_handle* hh_expected = const auto* hh_expected = boost::get<Halfedge_const_handle>(&(expected));
boost::get<Halfedge_const_handle>(&(expected));
if (hh_expected) { if (hh_expected) {
Halfedge_const_handle hh_actual; if (const auto* hh_actual = boost::get<Halfedge_const_handle>(&obj)) {
if (CGAL::assign(hh_actual, actual)) { if (*hh_expected == *hh_actual) return true;
if (*hh_expected == hh_actual) return true;
std::cout << "Error: vertical decomposition!" << std::endl; std::cout << "Error: vertical decomposition!" << std::endl;
std::cout << "Expected: a halfedge, " << (*hh_expected)->curve() std::cout << "Expected: a halfedge, " << (*hh_expected)->curve()
<< std::endl; << std::endl;
std::cout << "Actual: a different halfedge." << hh_actual->curve() std::cout << "Actual: a different halfedge." << (*hh_actual)->curve()
<< std::endl; << std::endl;
return false; return false;
} }
@ -232,14 +230,13 @@ compare(const Result_type& expected, const CGAL::Object& actual)
std::cout << "Expected: a halfedge, " << (*hh_expected)->curve() std::cout << "Expected: a halfedge, " << (*hh_expected)->curve()
<< std::endl; << std::endl;
Vertex_const_handle vh_actual; if (const auto* vh_actual = boost::get<Vertex_const_handle>(&obj)) {
if (CGAL::assign(vh_actual, actual)) { std::cout << "Actual: a vertex, " << (*vh_actual)->point() << std::endl;
std::cout << "Actual: a vertex, " << vh_actual->point() << std::endl;
return false; return false;
} }
Face_const_handle fh_actual; Face_const_handle fh_actual;
if (CGAL::assign(fh_actual, actual)) { if (boost::get<Face_const_handle>(&obj)) {
std::cout << "Actual: a face." << std::endl; std::cout << "Actual: a face." << std::endl;
return false; return false;
} }
@ -248,17 +245,15 @@ compare(const Result_type& expected, const CGAL::Object& actual)
} }
// Assign object to a vertex. // Assign object to a vertex.
const Vertex_const_handle* vh_expected = const auto* vh_expected = boost::get<Vertex_const_handle>(&(expected));
boost::get<Vertex_const_handle>(&(expected));
if (vh_expected) { if (vh_expected) {
Vertex_const_handle vh_actual; if (const auto* vh_actual = boost::get<Vertex_const_handle>(&obj)) {
if (CGAL::assign(vh_actual, actual)) { if (*vh_expected == *vh_actual) return true;
if (*vh_expected == vh_actual) return true;
std::cout << "Error: vertical decomposition!" << std::endl; std::cout << "Error: vertical decomposition!" << std::endl;
std::cout << "Expected: a vertex, " << (*vh_expected)->point() std::cout << "Expected: a vertex, " << (*vh_expected)->point()
<< std::endl; << std::endl;
std::cout << "Actual: a different vertex, " << vh_actual->point() std::cout << "Actual: a different vertex, " << (*vh_actual)->point()
<< std::endl; << std::endl;
return false; return false;
} }
@ -266,14 +261,12 @@ compare(const Result_type& expected, const CGAL::Object& actual)
std::cout << "Error: vertical decomposition!" << std::endl; std::cout << "Error: vertical decomposition!" << std::endl;
std::cout << "Expected: a vertex, " << (*vh_expected)->point() << std::endl; std::cout << "Expected: a vertex, " << (*vh_expected)->point() << std::endl;
Halfedge_const_handle hh_actual; if (const auto* hh_actual = boost::get<Halfedge_const_handle>(&obj)) {
if (CGAL::assign(hh_actual, actual)) { std::cout << "Actual: a halfedge, " << (*hh_actual)->curve() << std::endl;
std::cout << "Actual: a halfedge, " << hh_actual->curve() << std::endl;
return false; return false;
} }
Face_const_handle fh_actual; if (boost::get<Face_const_handle>(&obj)) {
if (CGAL::assign(fh_actual, actual)) {
std::cout << "Actual: a face." << std::endl; std::cout << "Actual: a face." << std::endl;
return false; return false;
} }
@ -285,28 +278,36 @@ compare(const Result_type& expected, const CGAL::Object& actual)
} }
//! \brief prints the results. //! \brief prints the results.
template <typename GeomTraits_T, typename TopolTraits_T> template <typename GeomTraits_2, typename TopolTraits>
void Vertical_decomposition_test<GeomTraits_T, TopolTraits_T>:: void Vertical_decomposition_test<GeomTraits_2, TopolTraits>::
print(const Vert_decomp_entry& result) print(const Vert_decomp_entry& result)
{ {
// Print the result. const auto& res = result.second;
Vertex_const_handle vh; auto obj_below = res.first;
Halfedge_const_handle hh; auto obj_above = res.second;
Face_const_handle fh;
const Object_pair& res = result.second;
std::cout << "Vertex (" << result.first->point() << ") : "; std::cout << "Vertex (" << result.first->point() << ") : ";
assert(obj_below);
auto obj = *obj_below;
std::cout << " feature below: "; std::cout << " feature below: ";
if (CGAL::assign(hh, res.first)) std::cout << '[' << hh->curve() << ']'; if (const auto* hh = boost::get<Halfedge_const_handle>(&obj))
else if (CGAL::assign(vh, res.first)) std::cout << '(' << vh->point() << ')'; std::cout << '[' << (*hh)->curve() << ']';
else if (CGAL::assign(fh, res.first)) std::cout << "NONE"; else if (const auto* vh = boost::get<Vertex_const_handle>(&obj))
std::cout << '(' << (*vh)->point() << ')';
else if (const auto* fh = boost::get<Face_const_handle>(&obj))
std::cout << "NONE";
else std::cout << "EMPTY"; else std::cout << "EMPTY";
assert(obj_above);
obj = *obj_above;
std::cout << " feature above: "; std::cout << " feature above: ";
if (CGAL::assign(hh, res.second)) std::cout << '[' << hh->curve() << ']'; if (const auto* hh = boost::get<Halfedge_const_handle>(&obj))
else if (CGAL::assign(vh, res.second)) std::cout << '(' << vh->point() << ')'; std::cout << '[' << (*hh)->curve() << ']';
else if (CGAL::assign(fh, res.second)) std::cout << "NONE"; else if (const auto* vh = boost::get<Vertex_const_handle>(&obj))
std::cout << '(' << (*vh)->point() << ')';
else if (const auto* vh = boost::get<Face_const_handle>(&obj))
std::cout << "NONE";
else std::cout << "EMPTY"; else std::cout << "EMPTY";
std::cout << std::endl; std::cout << std::endl;

View File

@ -1,64 +1,48 @@
// Constructing an arrangement of polycurves.
#include <CGAL/config.h>
#ifndef CGAL_USE_CORE
#include <iostream>
int main()
{
std::cout << "Sorry, this example needs CORE ..." << std::endl;
return 0;
}
#else
#include <CGAL/Cartesian.h>
#include <CGAL/Quotient.h>
#include <CGAL/MP_Float.h>
#include <CGAL/CORE_algebraic_number_traits.h>
#include <vector> #include <vector>
#include <list> #include <list>
#include <CGAL/config.h>
#include <CGAL/Cartesian.h>
#include <CGAL/Quotient.h>
#include <CGAL/MP_Float.h>
#include <CGAL/Arr_polyline_traits_2.h> #include <CGAL/Arr_polyline_traits_2.h>
#include <CGAL/Arr_circle_segment_traits_2.h> #include <CGAL/Arr_circle_segment_traits_2.h>
#include <CGAL/Arrangement_2.h>
/////////////// ///////////////
//circle segment traits //circle segment traits
////////////// //////////////
typedef CGAL::Quotient<CGAL::MP_Float> Number_type; typedef CGAL::Quotient<CGAL::MP_Float> Number_type;
typedef CGAL::Cartesian<Number_type> Kernel; typedef CGAL::Cartesian<Number_type> Kernel;
typedef CGAL::Arr_circle_segment_traits_2<Kernel> Arc_traits_2; typedef CGAL::Arr_circle_segment_traits_2<Kernel> Sub_traits_2;
typedef CGAL::Arr_polyline_traits_2<Arc_traits_2> Polycurve_arc_traits_2; typedef CGAL::Arr_polyline_traits_2<Sub_traits_2> Traits_2;
typedef Arc_traits_2::CoordNT CoordNT; typedef Sub_traits_2::CoordNT CoordNT;
typedef Arc_traits_2::Point_2 Arc_point_2; typedef Sub_traits_2::Point_2 Point_2;
typedef Arc_traits_2::Curve_2 Arc_section_2; typedef Sub_traits_2::Curve_2 Subcurve_2;
typedef Arc_traits_2::X_monotone_curve_2 Arc_section_x_monotone_2; typedef Sub_traits_2::X_monotone_curve_2 Subcurve_x_monotone_2;
typedef CGAL::Arrangement_2<Polycurve_arc_traits_2> Arc_arrangment_2; typedef boost::variant<Point_2, Subcurve_x_monotone_2>
Make_sub_x_monotone_result;
void check_equal() void check_equal()
{ {
Polycurve_arc_traits_2 Polycurve_traits_2; Traits_2 Polycurve_traits_2;
Polycurve_arc_traits_2::Equal_2 equal_2 = Polycurve_traits_2.equal_2_object(); auto equal_2 = Polycurve_traits_2.equal_2_object();
Polycurve_arc_traits_2::Construct_x_monotone_curve_2 auto construct_x_monotone_curve_2 =
construct_x_monotone_curve_2 =
Polycurve_traits_2.construct_x_monotone_curve_2_object(); Polycurve_traits_2.construct_x_monotone_curve_2_object();
Arc_section_2 curve1, curve2, curve3; Subcurve_2 curve1, curve2, curve3;
Kernel::Point_2 p1 = Kernel::Point_2(-5, 0); Kernel::Point_2 p1 = Kernel::Point_2(-5, 0);
Kernel::Point_2 mid = Kernel::Point_2(0, 5); Kernel::Point_2 mid = Kernel::Point_2(0, 5);
Kernel::Point_2 p2 = Kernel::Point_2(5, 0); Kernel::Point_2 p2 = Kernel::Point_2(5, 0);
curve1= Arc_section_2(p1, mid, p2); curve1= Subcurve_2(p1, mid, p2);
curve2= Arc_section_2(p1, mid, p2); curve2= Subcurve_2(p1, mid, p2);
// //make x_monotone // //make x_monotone
// Polycurve_arc_traits_2::X_monotone_curve_2 xmc1 = // Traits_2::X_monotone_curve_2 xmc1 =
// construct_x_monotone_curve_2(curve1); // construct_x_monotone_curve_2(curve1);
// Polycurve_arc_traits_2::X_monotone_curve_2 xmc2 = // Traits_2::X_monotone_curve_2 xmc2 =
// construct_x_monotone_curve_2(curve2); // construct_x_monotone_curve_2(curve2);
// Polycurve_arc_traits_2::X_monotone_curve_2 xmc3 = // Traits_2::X_monotone_curve_2 xmc3 =
// construct_x_monotone_curve_2(curve3); // construct_x_monotone_curve_2(curve3);
// //simple equal // //simple equal
@ -71,11 +55,11 @@ void check_equal()
// << ((Are_equal) ? "Equal" : "Not equal") << std::endl; // << ((Are_equal) ? "Equal" : "Not equal") << std::endl;
} }
void check_intersect(Polycurve_arc_traits_2::Make_x_monotone_2 void check_intersect(Traits_2::Make_x_monotone_2
make_x_monotone_2, make_x_monotone_2,
Polycurve_arc_traits_2::Intersect_2 intersect_2) Traits_2::Intersect_2 intersect_2)
{ {
Arc_section_2 curve1, curve2, curve3; Subcurve_2 curve1, curve2, curve3;
// Create a circular arc that correspond to the upper half of the // Create a circular arc that correspond to the upper half of the
// circle centered at (1,1) with squared radius 3. We create the // circle centered at (1,1) with squared radius 3. We create the
@ -85,24 +69,22 @@ void check_intersect(Polycurve_arc_traits_2::Make_x_monotone_2
Kernel::Circle_2 circ1 = Kernel::Circle_2(c1, 3, CGAL::CLOCKWISE); Kernel::Circle_2 circ1 = Kernel::Circle_2(c1, 3, CGAL::CLOCKWISE);
CoordNT one_minus_sqrt_3 = CoordNT(1, -1, 3); CoordNT one_minus_sqrt_3 = CoordNT(1, -1, 3);
CoordNT one_plus_sqrt_3 = CoordNT(1, 1, 3); CoordNT one_plus_sqrt_3 = CoordNT(1, 1, 3);
Arc_point_2 s1 = Arc_point_2(one_minus_sqrt_3, CoordNT(1)); Point_2 s1 = Point_2(one_minus_sqrt_3, CoordNT(1));
Arc_point_2 t1 = Arc_point_2(one_plus_sqrt_3, CoordNT(1)); Point_2 t1 = Point_2(one_plus_sqrt_3, CoordNT(1));
curve1 = Arc_section_2(circ1, s1, t1); curve1 = Subcurve_2(circ1, s1, t1);
curve2 = Arc_section_2(circ1, s1, t1); curve2 = Subcurve_2(circ1, s1, t1);
//push the same semi circle again //push the same semi circle again
//curves.push_back(Arc_section_2(circ1, s1, t1)); //curves.push_back(Subcurve_2(circ1, s1, t1));
//make x_monotone //make x_monotone
std::vector<CGAL::Object> X_monotone_curves; std::vector<Make_sub_x_monotone_result> x_monotone_curves;
make_x_monotone_2(curve1, std::back_inserter(X_monotone_curves)); make_x_monotone_2(curve1, std::back_inserter(x_monotone_curves));
make_x_monotone_2(curve2, std::back_inserter(X_monotone_curves)); make_x_monotone_2(curve2, std::back_inserter(x_monotone_curves));
Arc_section_x_monotone_2 X_monotone_curve1, X_monotone_curve2, const auto* x_curve1 = boost::get<Subcurve_x_monotone_2>(curves[0]);
X_monotone_curve3 ; const auto* x_curve2 = boost::get<Subcurve_x_monotone_2>(curves[1]);
CGAL::assign(X_monotone_curve1, X_monotone_curves[0]);
CGAL::assign(X_monotone_curve2, X_monotone_curves[1]);
std::vector<CGAL::Object> Points_of_intersection; std::vector<Intersection_result> Points_of_intersection;
//intersect_2(X_monotone_curve1, X_monotone_curve2, //intersect_2(X_monotone_curve1, X_monotone_curve2,
// std::back_inserter(Points_of_intersection)); // std::back_inserter(Points_of_intersection));
@ -113,12 +95,12 @@ void check_intersect(Polycurve_arc_traits_2::Make_x_monotone_2
Kernel::Point_2 c6 = Kernel::Point_2(0, 0); Kernel::Point_2 c6 = Kernel::Point_2(0, 0);
CoordNT sqrt_3_div_2 = CoordNT sqrt_3_div_2 =
CoordNT(Number_type(0), Number_type(1,2), Number_type(3)); CoordNT(Number_type(0), Number_type(1,2), Number_type(3));
Arc_point_2 s6 = Arc_point_2(Number_type(-1, 2), sqrt_3_div_2); Point_2 s6 = Point_2(Number_type(-1, 2), sqrt_3_div_2);
Arc_point_2 t6 = Arc_point_2(Number_type(1, 2), sqrt_3_div_2); Point_2 t6 = Point_2(Number_type(1, 2), sqrt_3_div_2);
curve3 = Arc_section_2(c6, 1, CGAL::CLOCKWISE, s6, t6); curve3 = Subcurve_2(c6, 1, CGAL::CLOCKWISE, s6, t6);
make_x_monotone_2(curve3, std::back_inserter(X_monotone_curves)); make_x_monotone_2(curve3, std::back_inserter(x_curves));
CGAL::assign(X_monotone_curve2, X_monotone_curves[2]); const auto* x_curve2 = boost::get<>(&x_curves[2]);
Points_of_intersection.clear(); Points_of_intersection.clear();
//intersect_2(X_monotone_curve1, X_monotone_curve2, //intersect_2(X_monotone_curve1, X_monotone_curve2,
@ -126,12 +108,12 @@ void check_intersect(Polycurve_arc_traits_2::Make_x_monotone_2
} }
void void
check_compare_end_points_xy_2(Polycurve_arc_traits_2::Compare_endpoints_xy_2 check_compare_end_points_xy_2(Traits_2::Compare_endpoints_xy_2
compare_endpoints_xy_2, compare_endpoints_xy_2,
Polycurve_arc_traits_2::Make_x_monotone_2 Traits_2::Make_x_monotone_2
make_x_monotone_2) make_x_monotone_2)
{ {
Arc_section_2 curve1, curve2; Subcurve_2 curve1, curve2;
// Create a circular arc that correspond to the upper half of the // Create a circular arc that correspond to the upper half of the
// circle centered at (1,1) with squared radius 3. We create the // circle centered at (1,1) with squared radius 3. We create the
@ -141,39 +123,37 @@ check_compare_end_points_xy_2(Polycurve_arc_traits_2::Compare_endpoints_xy_2
Kernel::Circle_2 circ1 = Kernel::Circle_2(c1, 3, CGAL::CLOCKWISE); Kernel::Circle_2 circ1 = Kernel::Circle_2(c1, 3, CGAL::CLOCKWISE);
CoordNT one_minus_sqrt_3 = CoordNT(1, -1, 3); CoordNT one_minus_sqrt_3 = CoordNT(1, -1, 3);
CoordNT one_plus_sqrt_3 = CoordNT(1, 1, 3); CoordNT one_plus_sqrt_3 = CoordNT(1, 1, 3);
Arc_point_2 s1 = Arc_point_2(one_minus_sqrt_3, CoordNT(1)); Point_2 s1 = Point_2(one_minus_sqrt_3, CoordNT(1));
Arc_point_2 t1 = Arc_point_2(one_plus_sqrt_3, CoordNT(1)); Point_2 t1 = Point_2(one_plus_sqrt_3, CoordNT(1));
curve1= Arc_section_2(circ1, s1, t1); curve1= Subcurve_2(circ1, s1, t1);
//make x_monotone //make x_monotone
std::vector<CGAL::Object> X_monotone_curves; std::vector<Make_sub_x_monotone_result> x_curves;
make_x_monotone_2(curve1, std::back_inserter(X_monotone_curves)); make_x_monotone_2(curve1, std::back_inserter(x_curves));
Arc_section_x_monotone_2 X_monotone_curve1, X_monotone_curve2 ; const auto* x_curve1 = boost::get<Subcurve_x_monotone_2>(&x_curves[0]);
CGAL::assign(X_monotone_curve1, X_monotone_curves[ 0 ]); const auto* x_curve2 = boost::get<Subcurve_x_monotone_2>(&x_curves[1]);
int res = compare_endpoints_xy_2(X_monotone_curve1);
auto res = compare_endpoints_xy_2(x_curve1);
std::cout<< "The first result is: " << res << std::endl; std::cout<< "The first result is: " << res << std::endl;
Kernel::Point_2 c2 = Kernel::Point_2(1, 1); Kernel::Point_2 c2 = Kernel::Point_2(1, 1);
Kernel::Circle_2 circ2 = Kernel::Circle_2(c2, 3, CGAL::COUNTERCLOCKWISE); Kernel::Circle_2 circ2 = Kernel::Circle_2(c2, 3, CGAL::COUNTERCLOCKWISE);
Arc_point_2 t2 = Arc_point_2(one_minus_sqrt_3, CoordNT(1)); Point_2 t2 = Point_2(one_minus_sqrt_3, CoordNT(1));
Arc_point_2 s2 = Arc_point_2(one_plus_sqrt_3, CoordNT(1)); Point_2 s2 = Point_2(one_plus_sqrt_3, CoordNT(1));
curve2= Arc_section_2(circ2, s1, t1); curve2 = Subcurve_2(circ2, s1, t1);
make_x_monotone_2(curve2, std::back_inserter(x_curves));
const auto* x_curve2 = boost::get<Subcurve_x_monotone_2>(&x_curves[1]);
make_x_monotone_2(curve2, std::back_inserter(X_monotone_curves)); res = compare_endpoints_xy_2(x_curve2);
CGAL::assign(X_monotone_curve2, X_monotone_curves[ 1 ]);
res = compare_endpoints_xy_2(X_monotone_curve2);
std::cout<< "The second result is: " << res << std::endl; std::cout<< "The second result is: " << res << std::endl;
} }
void check_split(Polycurve_arc_traits_2::Split_2 split_2, void check_split(Traits_2::Split_2 split_2,
Polycurve_arc_traits_2::Make_x_monotone_2 make_x_monotone_2) Traits_2::Make_x_monotone_2 make_x_monotone_2)
{ {
Arc_section_2 curve; Subcurve_2 curve;
// Create a circular arc that correspond to the upper half of the // Create a circular arc that correspond to the upper half of the
// circle centered at (1,1) with squared radius 3. We create the // circle centered at (1,1) with squared radius 3. We create the
@ -183,64 +163,59 @@ void check_split(Polycurve_arc_traits_2::Split_2 split_2,
Kernel::Circle_2 circ1 = Kernel::Circle_2(c1, 3, CGAL::CLOCKWISE); Kernel::Circle_2 circ1 = Kernel::Circle_2(c1, 3, CGAL::CLOCKWISE);
CoordNT one_minus_sqrt_3 = CoordNT(1, -1, 3); CoordNT one_minus_sqrt_3 = CoordNT(1, -1, 3);
CoordNT one_plus_sqrt_3 = CoordNT(1, 1, 3); CoordNT one_plus_sqrt_3 = CoordNT(1, 1, 3);
Arc_point_2 s1 = Arc_point_2(one_minus_sqrt_3, CoordNT(1)); Point_2 s1 = Point_2(one_minus_sqrt_3, CoordNT(1));
Arc_point_2 t1 = Arc_point_2(one_plus_sqrt_3, CoordNT(1)); Point_2 t1 = Point_2(one_plus_sqrt_3, CoordNT(1));
curve= Arc_section_2(circ1, s1, t1); curve= Subcurve_2(circ1, s1, t1);
//make x_monotone //make x_monotone
std::vector<CGAL::Object> X_monotone_curves; std::vector<Make_sub_x_monotone_result> x_curves;
make_x_monotone_2(curve, std::back_inserter(X_monotone_curves)); make_x_monotone_2(curve, std::back_inserter(x_curves));
const auto* x_curve1 = boost::get<Subcurve_x_monotone_2>(&x_curves[0]);
Arc_section_x_monotone_2 X_monotone_curve, split_x_monotone_curve1,
split_x_monotone_curve2 ;
CGAL::assign(X_monotone_curve, X_monotone_curves[0]);
// Subcurve_x_monotone_2 split_x_monotone_curve1, split_x_monotone_curve2 ;
//split_2(X_monotone_curve, Kernel::Point_2::Kernel::Point_2(1, 4), //split_2(X_monotone_curve, Kernel::Point_2::Kernel::Point_2(1, 4),
// split_x_monotone_curve1, split_x_monotone_curve2); // split_x_monotone_curve1, split_x_monotone_curve2);
} }
void check_is_vertical(Polycurve_arc_traits_2::Make_x_monotone_2 void check_is_vertical(Traits_2::Make_x_monotone_2
make_x_monotone_2, make_x_monotone_2,
Polycurve_arc_traits_2::Is_vertical_2 is_vertical) Traits_2::Is_vertical_2 is_vertical)
{ {
std::vector<Arc_section_2> curves; std::vector<Subcurve_2> curves;
// Create a circular arc defined by two endpoints and a midpoint, // Create a circular arc defined by two endpoints and a midpoint,
// all having rational coordinates. This arc is the upper-right // all having rational coordinates. This arc is the upper-right
// quarter of a circle centered at the origin with radius 5. // quarter of a circle centered at the origin with radius 5.
Kernel::Point_2 p1 = Kernel::Point_2(0, 5); Kernel::Point_2 p1 = Kernel::Point_2(0, 5);
Kernel::Point_2 mid = Kernel::Point_2(3, 4); Kernel::Point_2 mid = Kernel::Point_2(3, 4);
Kernel::Point_2 p2 = Kernel::Point_2(5, 0); Kernel::Point_2 p2 = Kernel::Point_2(5, 0);
Kernel::Point_2 p3 = Kernel::Point_2(0, -5); Kernel::Point_2 p3 = Kernel::Point_2(0, -5);
curves.push_back(Arc_section_2(p1, mid, p2)); //quarter of a circle curves.push_back(Subcurve_2(p1, mid, p2)); //quarter of a circle
curves.push_back(Arc_section_2(p1, mid, p3)); //semi-circle curves.push_back(Subcurve_2(p1, mid, p3)); //semi-circle
//convert all curves to x-monotone curves //convert all curves to x-monotone curves
std::vector<CGAL::Object> X_monotone_curves; std::vector<Make_sub_x_monotone_result> x_curves;
for(int i = 0; i < curves.size(); ++i) for (const auto& cv : curves)
make_x_monotone_2(curves[i], std::back_inserter(X_monotone_curves)); make_x_monotone_2(cv, std::back_inserter(x_curves));
//std::vector<Arc_section_x_monotone_2> x_monotone_polycurves; //std::vector<Subcurve_x_monotone_2> x_monotone_polycurves;
Arc_section_x_monotone_2 x_monotone_polycurve1, x_monotone_polycurve2; const auto* x_polycurve1 = boost::get<Subcurve_x_monotone_2>(&x_curves[0]);
CGAL::assign(x_monotone_polycurve1, X_monotone_curves[0]); const auto* x_polycurve2 = boost::get<Subcurve_x_monotone_2>(&x_curves[1]);
CGAL::assign(x_monotone_polycurve2, X_monotone_curves[1]);
bool res = is_vertical(x_monotone_polycurve1); bool res = is_vertical(x_polycurve1);
std::cout << "Is_verticle:: The xmonotone curve (quarter circle) is : " std::cout << "Is_verticle:: The xmonotone curve (quarter circle) is : "
<< ((res)? "vertical" : "not vertical") << std::endl; << ((res)? "vertical" : "not vertical") << std::endl;
res = is_vertical(x_monotone_polycurve2); res = is_vertical(x_polycurve2);
std::cout << "Is_verticle:: The xmonotone curve (Smi-circle) is : " std::cout << "Is_verticle:: The xmonotone curve (Smi-circle) is : "
<< ((res)? "vertical" : "not vertical") << std::endl; << ((res)? "vertical" : "not vertical") << std::endl;
} }
void check_compare_y_at_x_2(Polycurve_arc_traits_2::Make_x_monotone_2 void check_compare_y_at_x_2(Traits_2::Make_x_monotone_2 make_x_monotone_2,
make_x_monotone_2, Traits_2::Compare_y_at_x_2 cmp_y_at_x_2)
Polycurve_arc_traits_2::Compare_y_at_x_2
cmp_y_at_x_2)
{ {
std::vector<Arc_section_2> curves; std::vector<Subcurve_2> curves;
// Create a circular arc defined by two endpoints and a midpoint, // Create a circular arc defined by two endpoints and a midpoint,
// all having rational coordinates. This arc is the upper-right // all having rational coordinates. This arc is the upper-right
@ -249,30 +224,29 @@ void check_compare_y_at_x_2(Polycurve_arc_traits_2::Make_x_monotone_2
Kernel::Point_2 mid = Kernel::Point_2(4, 4); Kernel::Point_2 mid = Kernel::Point_2(4, 4);
Kernel::Point_2 p2 = Kernel::Point_2(7, 1); Kernel::Point_2 p2 = Kernel::Point_2(7, 1);
Kernel::Point_2 p3 = Kernel::Point_2(1, 4); Kernel::Point_2 p3 = Kernel::Point_2(1, 4);
curves.push_back(Arc_section_2(p1, mid, p2)); //quarter of a circle curves.push_back(Subcurve_2(p1, mid, p2)); //quarter of a circle
curves.push_back(Arc_section_2(p1, mid, p3)); //semi-circle curves.push_back(Subcurve_2(p1, mid, p3)); //semi-circle
//convert all curves to x-monotone curves //convert all curves to x-monotone curves
std::vector<CGAL::Object> X_monotone_curves; std::vector<Make_sub_x_monotone_result> x_curves;
for (int i = 0; i < curves.size(); ++i) for (const auto& cv : curves)
make_x_monotone_2(curves[i], std::back_inserter(X_monotone_curves)); make_x_monotone_2(cv, std::back_inserter(x_curves));
Arc_section_x_monotone_2 x_monotone_polycurve1, x_monotone_polycurve2; const auto* x_polycurve1 = boost::get<Subcurve_x_monotone_2>(&x_curves[0]);
CGAL::assign(x_monotone_polycurve1, X_monotone_curves[ 0 ]); const auto* x_polycurve2 = boost::get<Subcurve_x_monotone_2>(&x_curves[1]);
CGAL::assign(x_monotone_polycurve2, X_monotone_curves[ 1 ]);
Kernel::Point_2 p_test = Kernel::Point_2(3, 1); Kernel::Point_2 p_test = Kernel::Point_2(3, 1);
// int res = cmp_y_at_x_2(p_test, x_monotone_polycurve1); // int res = cmp_y_at_x_2(p_test, x_monotone_polycurve1);
// cmp_y_at_x_2(x_monotone_polycurve1, CGAL::ARR_MIN_END, // cmp_y_at_x_2(x_monotone_polycurve1, CGAL::ARR_MIN_END,
// x_monotone_polycurve2); // x_monotone_polycurve2);
} }
void check_push_back(Polycurve_arc_traits_2::Make_x_monotone_2 void check_push_back(Traits_2::Make_x_monotone_2
make_x_monotone_2, make_x_monotone_2,
Polycurve_arc_traits_2::Push_back_2 push_back_2) Traits_2::Push_back_2 push_back_2)
{ {
std::vector<Arc_section_2> curves; std::vector<Subcurve_2> curves;
//check if segment is pushed in empty curve. //check if segment is pushed in empty curve.
Kernel::Point_2 p1 = Kernel::Point_2(1, 1); Kernel::Point_2 p1 = Kernel::Point_2(1, 1);
@ -282,10 +256,10 @@ void check_push_back(Polycurve_arc_traits_2::Make_x_monotone_2
Kernel::Point_2 mid2 = Kernel::Point_2(10, 3); Kernel::Point_2 mid2 = Kernel::Point_2(10, 3);
Kernel::Point_2 p3 = Kernel::Point_2(7, 7); Kernel::Point_2 p3 = Kernel::Point_2(7, 7);
curves.push_back(Arc_section_2(p1, mid, p2)); curves.push_back(Subcurve_2(p1, mid, p2));
curves.push_back(Arc_section_2(p2, mid2, p3)); curves.push_back(Subcurve_2(p2, mid2, p3));
CGAL::internal::Polycurve_2<Arc_section_2, Arc_point_2> polycurve; CGAL::internal::Polycurve_2<Subcurve_2, Point_2> polycurve;
////pushing segments in polycurve ////pushing segments in polycurve
push_back_2(polycurve, curves[0]); push_back_2(polycurve, curves[0]);
@ -300,87 +274,70 @@ void check_push_back(Polycurve_arc_traits_2::Make_x_monotone_2
int main() int main()
{ {
Polycurve_arc_traits_2 Polycurve_traits_2; Traits_2 Polycurve_traits_2;
// Compare_x_2 // Compare_x_2
// Polycurve_arc_traits_2::Compare_x_2 compare_x_2 = // Traits_2::Compare_x_2 compare_x_2 =
// Polycurve_traits_2.compare_xy_2_object(); // Polycurve_traits_2.compare_xy_2_object();
// number of points // number of points
// Polycurve_arc_traits_2::Number_of_points_2 num_of_points = // Traits_2::Number_of_points_2 num_of_points =
// Polycurve_traits_2.number_of_points_2_object(); // Polycurve_traits_2.number_of_points_2_object();
//construct min vertex //construct min vertex
Polycurve_arc_traits_2::Construct_min_vertex_2 cnst_min_vertex = auto cnst_min_vertex = Polycurve_traits_2.construct_min_vertex_2_object();
Polycurve_traits_2.construct_min_vertex_2_object();
//construct max vertex //construct max vertex
Polycurve_arc_traits_2::Construct_max_vertex_2 cnst_max_vertex_2 = auto cnst_max_vertex_2 = Polycurve_traits_2.construct_max_vertex_2_object();
Polycurve_traits_2.construct_max_vertex_2_object();
//is vertical (return bool) //is vertical (return bool)
Polycurve_arc_traits_2::Is_vertical_2 is_vertical = auto is_vertical = Polycurve_traits_2.is_vertical_2_object();
Polycurve_traits_2.is_vertical_2_object();
//Compare y at x 2 (return comparison_result) //Compare y at x 2 (return comparison_result)
Polycurve_arc_traits_2::Compare_y_at_x_2 cmp_y_at_x_2 = auto cmp_y_at_x_2 = Polycurve_traits_2.compare_y_at_x_2_object();
Polycurve_traits_2.compare_y_at_x_2_object();
//compare y at x left //compare y at x left
Polycurve_arc_traits_2::Compare_y_at_x_left_2 cmp_y_at_x_left_2 = auto cmp_y_at_x_left_2 = Polycurve_traits_2.compare_y_at_x_left_2_object();
Polycurve_traits_2.compare_y_at_x_left_2_object();
//compare y at x right //compare y at x right
Polycurve_arc_traits_2::Compare_y_at_x_right_2 cmp_y_at_x_right_2 = auto cmp_y_at_x_right_2 = Polycurve_traits_2.compare_y_at_x_right_2_object();
Polycurve_traits_2.compare_y_at_x_right_2_object();
//equal_2 //equal_2
Polycurve_arc_traits_2::Equal_2 equal_2 = auto equal_2 = Polycurve_traits_2.equal_2_object();
Polycurve_traits_2.equal_2_object();
//compare end points xy_2 //compare end points xy_2
Polycurve_arc_traits_2::Compare_endpoints_xy_2 compare_endpoints_xy_2 = auto compare_endpoints_xy_2 =
Polycurve_traits_2.compare_endpoints_xy_2_object(); Polycurve_traits_2.compare_endpoints_xy_2_object();
//construct opposite //construct opposite
Polycurve_arc_traits_2::Construct_opposite_2 construct_opposite_2 = auto construct_opposite_2 = Polycurve_traits_2.construct_opposite_2_object();
Polycurve_traits_2.construct_opposite_2_object();
//make x_monotone //make x_monotone
Polycurve_arc_traits_2::Make_x_monotone_2 make_x_monotone_2 = auto make_x_monotone_2 = Polycurve_traits_2.make_x_monotone_2_object();
Polycurve_traits_2.make_x_monotone_2_object();
//push back //push back
Polycurve_arc_traits_2::Push_back_2 push_back_2 = auto push_back_2 = Polycurve_traits_2.push_back_2_object();
Polycurve_traits_2.push_back_2_object();
//push front //push front
Polycurve_arc_traits_2::Push_front_2 push_front_2 = auto push_front_2 = Polycurve_traits_2.push_front_2_object();
Polycurve_traits_2.push_front_2_object();
//split_2 //split_2
Polycurve_arc_traits_2::Split_2 split_2 = auto split_2 = Polycurve_traits_2.split_2_object();
Polycurve_traits_2.split_2_object();
//Intersect_2 //Intersect_2
Polycurve_arc_traits_2::Intersect_2 intersect_2 = auto intersect_2 = Polycurve_traits_2.intersect_2_object();
Polycurve_traits_2.intersect_2_object();
//Are_mergable //Are_mergable
Polycurve_arc_traits_2::Are_mergeable_2 are_mergeable_2 = auto are_mergeable_2 = Polycurve_traits_2.are_mergeable_2_object();
Polycurve_traits_2.are_mergeable_2_object();
//Merge_2 //Merge_2
Polycurve_arc_traits_2::Merge_2 merge_2 = auto merge_2 = Polycurve_traits_2.merge_2_object();
Polycurve_traits_2.merge_2_object();
//construct_curve_2 //construct_curve_2
Polycurve_arc_traits_2::Construct_curve_2 construct_curve_2 = auto construct_curve_2 = Polycurve_traits_2.construct_curve_2_object();
Polycurve_traits_2.construct_curve_2_object();
//construct x_monotone curve_2 //construct x_monotone curve_2
Polycurve_arc_traits_2::Construct_x_monotone_curve_2 auto construct_x_monotone_curve_2 =
construct_x_monotone_curve_2 =
Polycurve_traits_2.construct_x_monotone_curve_2_object(); Polycurve_traits_2.construct_x_monotone_curve_2_object();
//check_equal(); //check_equal();
@ -393,4 +350,3 @@ int main()
return 0; return 0;
} }
#endif

View File

@ -23,15 +23,19 @@ typedef CGAL::Cartesian<Algebraic> Alg_kernel;
typedef Rat_kernel::Point_2 Rat_point_2; typedef Rat_kernel::Point_2 Rat_point_2;
//bezier traits //bezier traits
typedef CGAL::Arr_Bezier_curve_traits_2<Rat_kernel, Alg_kernel, Nt_traits> Bezier_traits_2; typedef CGAL::Arr_Bezier_curve_traits_2<Rat_kernel, Alg_kernel, Nt_traits>
typedef Bezier_traits_2::Curve_2 Bezier_curve; Bezier_traits_2;
typedef Bezier_traits_2::X_monotone_curve_2 Bezier_x_monotone_curve; typedef Bezier_traits_2::Point_2 Bezier_point;
typedef Bezier_traits_2::Curve_2 Bezier_curve;
typedef Bezier_traits_2::X_monotone_curve_2 Bezier_x_monotone_curve;
//polyline traits //polyline traits
typedef CGAL::Arr_polyline_traits_2<Bezier_traits_2> Bezier_polycurve_traits; typedef CGAL::Arr_polyline_traits_2<Bezier_traits_2> Bezier_polycurve_traits;
typedef Bezier_polycurve_traits::Curve_2 Polycurve_bezier; typedef Bezier_polycurve_traits::Curve_2 Polycurve_bezier;
typedef Bezier_polycurve_traits::X_monotone_curve_2 X_polycurve_bezier; typedef Bezier_polycurve_traits::X_monotone_curve_2 X_polycurve_bezier;
typedef boost::variant<Bezier_point, Bezier_x_monotone_curve>
Make_x_monotone_result;
int main (int argc, char *argv[]) int main (int argc, char *argv[])
{ {
@ -51,35 +55,40 @@ int main (int argc, char *argv[])
points_vector.push_back( Rat_point_2(900,0) ); points_vector.push_back( Rat_point_2(900,0) );
Bezier_curve curve_1 (points_vector.begin(), points_vector.end()); Bezier_curve curve_1 (points_vector.begin(), points_vector.end());
std::vector<CGAL::Object> obj_vector; std::vector<Make_x_monotone_result> objs;
//creating x-mono bezier //creating x-mono bezier
bezier_traits.make_x_monotone_2_object()( curve_1, std::back_inserter(obj_vector)); bezier_traits.make_x_monotone_2_object()(curve_1, std::back_inserter(objs));
//std::cout << "number of x_curves: " << obj_vector.size() << std::endl; //std::cout << "number of x_curves: " << obj_vector.size() << std::endl;
Bezier_x_monotone_curve x_curve_1 = CGAL::object_cast<Bezier_x_monotone_curve>( (obj_vector[0]) ); const auto* x_curve_1 = boost::get<Bezier_x_monotone_curve>(&(obj_vector[0]));
assert(x_curve_1);
//std::cout << x_curve << std::endl; //std::cout << x_curve << std::endl;
points_vector.clear(); points_vector.clear();
points_vector.push_back( Rat_point_2(900,0) ); points_vector.push_back(Rat_point_2(900,0));
points_vector.push_back( Rat_point_2(1000,400) ); points_vector.push_back(Rat_point_2(1000,400));
points_vector.push_back( Rat_point_2(1500,200) ); points_vector.push_back(Rat_point_2(1500,200));
points_vector.push_back( Rat_point_2(2000,0) ); points_vector.push_back(Rat_point_2(2000,0));
Bezier_curve curve_2 (points_vector.begin(), points_vector.end()); Bezier_curve curve_2(points_vector.begin(), points_vector.end());
//creating x-monotne //creating x-monotne
obj_vector.clear(); obj_vector.clear();
bezier_traits.make_x_monotone_2_object()( curve_2, std::back_inserter(obj_vector)); bezier_traits.make_x_monotone_2_object()( curve_2, std::back_inserter(objs));
Bezier_x_monotone_curve x_curve_2 = CGAL::object_cast<Bezier_x_monotone_curve>( (obj_vector[0]) ); const auto* x_curve_2 = boost::get<Bezier_x_monotone_curve>(&(obj_vector[0]));
//push curves into polyline vectors //push curves into polyline vectors
curves_vector.push_back(curve_1); curves_vector.push_back(curve_1);
curves_vector.push_back(curve_2); curves_vector.push_back(curve_2);
x_curves_vector.push_back(x_curve_1); x_curves_vector.push_back(*x_curve_1);
x_curves_vector.push_back(x_curve_2); x_curves_vector.push_back(*x_curve_2);
//create polycurves //create polycurves
Polycurve_bezier polycurve_1 = poly_traits.construct_curve_2_object()(curves_vector.begin(), curves_vector.end()); auto ctr_curve = poly_traits.construct_curve_2_object();
X_polycurve_bezier x_polycurve_1 = poly_traits.construct_x_monotone_curve_2_object()(x_curves_vector.begin(), x_curves_vector.end()); Polycurve_bezier
polycurve_1 = ctr_curve(curves_vector.begin(), curves_vector.end());
auto ctr_x_monotone_curve = poly_traits.construct_x_monotone_curve_2_object();
X_polycurve_bezier x_polycurve_1 =
ctr_x_monotone_curve(x_curves_vector.begin(), x_curves_vector.end());
std::cout << "polycurve : " << polycurve_1 << std::endl; std::cout << "polycurve : " << polycurve_1 << std::endl;
std::cout << "x_polycurve : " << x_polycurve_1 << std::endl; std::cout << "x_polycurve : " << x_polycurve_1 << std::endl;

View File

@ -73,25 +73,31 @@ bool check_compare_y_at_x_2(Curve& cv)
return true; return true;
} }
template<typename Curve> template <typename GeometryTraits_2>
void check_intersect(const Curve& cv1, const Curve& cv2) void check_intersect(const typename GeometryTraits_2::X_monotone_curve_2& cv1,
const typename GeometryTraits_2::X_monotone_curve_2& cv2,
const GeometryTraits_2& traits)
{ {
// Polycurve_arc_traits_2 traits; // Polycurve_arc_traits_2 traits;
// std::vector<Intersection_result> objs;
// std::vector<CGAL::Object> object_vec; // traits.intersect_2_object()(cv1, cv2, std::back_inserter(objs));
// traits.intersect_2_object()(cv1, cv2, object_vec); // std::cout<< "number of intersections is: " << objs.size();
// std::cout<< "number of intersections is: " << object_vec.size();
} }
template<typename Curve> template <typename GeometryTraits_2>
void check_make_x_monotone(Curve cv) void check_make_x_monotone(typename GeometryTraits::Curve_2 cv,
const GeometryTraits_2& traits)
{ {
Polycurve_arc_traits_2 traits; typedef GeometryTraits_2 Geometry_traits_2;
std::vector<CGAL::Object> object_vec; typedef typename Geometry_traits_2::Point_2 Point_2;
typedef typename Geometry_traits_2::X_monotone_traits_2 X_monotone_traits_2;
traits.make_x_monotone_2_object()(cv, std::back_inserter(object_vec)); typedef boost::variant<Point_2, X_monotone_traits_2>
std::cout << "Number of x-monotone curves: " Make_x_monotone_result;
<< object_vec.size() << std::endl;
std::vector<Make_x_monotone_result> objs;
traits.make_x_monotone_2_object()(cv, std::back_inserter(objs));
std::cout << "Number of x-monotone curves: " << objs.size() << std::endl;
} }
template<typename Curve> template<typename Curve>
@ -198,8 +204,8 @@ int main(int argc, char* argv[])
////////////////////// //////////////////////
// check_compare_y_at_x_2(x_polycurve_1); // check_compare_y_at_x_2(x_polycurve_1);
// check_intersect(x_polycurve_1, x_polycurve_2); // check_intersect(x_polycurve_1, x_polycurve_2, traits);
//check_make_x_monotone(curve_1); //check_make_x_monotone<Polycurve_arc_traits_2>(curve_1, traits);
//checking if the cgal_assertion for curve construction for two points work //checking if the cgal_assertion for curve construction for two points work
//or not. //or not.

View File

@ -11,19 +11,19 @@ int main()
#else #else
#include <vector>
#include <list>
#include <boost/type_traits/is_same.hpp>
#include <CGAL/Cartesian.h> #include <CGAL/Cartesian.h>
#include <CGAL/Quotient.h> #include <CGAL/Quotient.h>
#include <CGAL/MP_Float.h> #include <CGAL/MP_Float.h>
#include <CGAL/CORE_algebraic_number_traits.h> #include <CGAL/CORE_algebraic_number_traits.h>
#include <vector>
#include <list>
#include <CGAL/Arr_polyline_traits_2.h> #include <CGAL/Arr_polyline_traits_2.h>
#include <CGAL/Arr_conic_traits_2.h> #include <CGAL/Arr_conic_traits_2.h>
#include <CGAL/Arrangement_2.h>
#include <CGAL/tags.h> #include <CGAL/tags.h>
#include <CGAL/Arr_tags.h> #include <CGAL/Arr_tags.h>
#include <boost/type_traits/is_same.hpp>
//////////////////// ////////////////////
//conic traits //conic traits
@ -43,7 +43,7 @@ typedef Conic_traits_2::Curve_2 Conic_curve_2;
typedef Conic_traits_2::X_monotone_curve_2 Conic_x_monotone_curve_2; typedef Conic_traits_2::X_monotone_curve_2 Conic_x_monotone_curve_2;
typedef CGAL::Arr_polyline_traits_2<Conic_traits_2> Polycurve_conic_traits_2; typedef CGAL::Arr_polyline_traits_2<Conic_traits_2> Polycurve_conic_traits_2;
typedef Polycurve_conic_traits_2::X_monotone_curve_2 Pc_x_monotone_curve_2; typedef Polycurve_conic_traits_2::X_monotone_curve_2 Pc_x_monotone_curve_2;
// typedef Polycurve_conic_traits_2::Point_2 polypoint; typedef Polycurve_conic_traits_2::Point_2 Pc_point_2;
// typedef CGAL::Arr_polyline_traits_2< // typedef CGAL::Arr_polyline_traits_2<
// CGAL::Arr_conic_traits_2<CGAL::Cartesian<BigRat>, // CGAL::Arr_conic_traits_2<CGAL::Cartesian<BigRat>,
@ -102,27 +102,36 @@ void check_equal()
<< ((are_equal) ? "equal" : "Not equal") << std::endl; << ((are_equal) ? "equal" : "Not equal") << std::endl;
} }
template <typename curve_type> template <typename Traits>
void check_intersect(curve_type &xcv1, curve_type &xcv2) void check_intersect(typename Traits::X_monotone_curve_2& xcv1,
typename Traits::X_monotone_curve_2& xcv2,
const Traits& traits)
{ {
Polycurve_conic_traits_2 traits; typedef typename Traits::Multiplicity Multiplicity;
std::vector<CGAL::Object> intersection_points; typedef typename Traits::Point_2 Point_2;
traits.intersect_2_object()(xcv1, xcv2, std::back_inserter(intersection_points)); typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
std::cout<< "Number of intersection Points: " << intersection_points.size() typedef std::pair<Multiplicity, Point_2> Intersection_point;
<< std::endl; typedef boost::variant<Intersection_point, X_monotone_curve_2>
Intersection_result;
//dynamic cast the cgal_objects std::vector<Intersection_result> intersection_points;
// std::vector< std::pair<Polycurve_conic_traits_2::Point_2, traits.intersect_2_object()(xcv1, xcv2,
// Polycurve_conic_traits_2::Multiplicity> > pm_vector; std::back_inserter(intersection_points));
// for(int i=0; i<intersection_points.size(); i++) std::cout<< "Number of intersection Points: " << intersection_points.size()
// { << std::endl;
// std::pair<Polycurve_conic_traits_2::Point_2,
// Polycurve_conic_traits_2::Multiplicity> pm = //dynamic cast the cgal_objects
// CGAL::object_cast<std::pair<Polycurve_conic_traits_2::Point_2, // std::vector< std::pair<Polycurve_conic_traits_2::Point_2,
// Polycurve_conic_traits_2::Multiplicity> > // Polycurve_conic_traits_2::Multiplicity> > pm_vector;
// (&(intersection_points[i])); // for(int i=0; i<intersection_points.size(); i++)
// pm_vector.push_back(pm); // {
// } // std::pair<Polycurve_conic_traits_2::Point_2,
// Polycurve_conic_traits_2::Multiplicity> pm =
// CGAL::object_cast<std::pair<Polycurve_conic_traits_2::Point_2,
// Polycurve_conic_traits_2::Multiplicity> >
// (&(intersection_points[i]));
// pm_vector.push_back(pm);
// }
} }
void check_compare_end_points_xy_2() void check_compare_end_points_xy_2()
@ -151,7 +160,7 @@ void check_compare_end_points_xy_2()
0, 0, 0, 0, 1, 3, // The line: y = -3. 0, 0, 0, 0, 1, 3, // The line: y = -3.
Conic_point_2(1.41, -2), // Approximation of the target. Conic_point_2(1.41, -2), // Approximation of the target.
0, 0, 0, 0, 1, 2); // The line: y = -2. 0, 0, 0, 0, 1, 2); // The line: y = -2.
CGAL_assertion(c2.is_valid()); assert(c2.is_valid());
//make polyline x-monotone curves //make polyline x-monotone curves
Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 = Polycurve_conic_traits_2::X_monotone_curve_2 polyline_xmc1 =
@ -631,22 +640,23 @@ void check_compare_y_at_x_left()
(result == CGAL::LARGER ? "Larger" : "equal")) << std::endl; (result == CGAL::LARGER ? "Larger" : "equal")) << std::endl;
} }
template <typename Curve_type> template <typename GeometryTraits>
void check_make_x_monotne_curve(Curve_type c1) void check_make_x_monotne_curve(const typename GeometryTraits::Curve_2& c1)
{ {
typename GeometryTraits::Point_2 Point_2;
typename GeometryTraits::X_monotone_curve_2 X_monotone_curve_2;
typedef boost::variant<Point_2, X_monotone_curve_2> Make_x_monotone_result;
Polycurve_conic_traits_2 traits; Polycurve_conic_traits_2 traits;
std::vector<CGAL::Object> obj_vec; std::vector<Make_x_monotone_result> objs;
traits.make_x_monotone_2_object()(c1, std::back_inserter(obj_vec)); traits.make_x_monotone_2_object()(c1, std::back_inserter(objs));
std::cout << "The polycurve is: " << c1 << std::endl; std::cout << "The polycurve is: " << c1 << std::endl;
std::cout<< "The poly curve have been split into " << objs.size()
std::cout<< "The poly curve have been split into " << obj_vec.size()
<< " polycurves" << std::endl; << " polycurves" << std::endl;
//const Pc_x_monotone_curve_2 *split_curve_1 = //const Pc_x_monotone_curve_2 *split_curve_1 =
// CGAL::object_cast<Pc_x_monotone_curve_2> (&(obj_vec[0])); // CGAL::object_cast<Pc_x_monotone_curve_2> (&(objs[0]));
//const Pc_x_monotone_curve_2 *split_curve_2 = //const Pc_x_monotone_curve_2 *split_curve_2 =
// CGAL::object_cast<Pc_x_monotone_curve_2> (&(obj_vec[1])); // CGAL::object_cast<Pc_x_monotone_curve_2> (&(objs[1]));
//std::cout << "The split curve 1 is: " << *split_curve_1 << std::endl; //std::cout << "The split curve 1 is: " << *split_curve_1 << std::endl;
//std::cout << "The split curve 2 is: " << *split_curve_2 << std::endl; //std::cout << "The split curve 2 is: " << *split_curve_2 << std::endl;
@ -726,10 +736,8 @@ int main(int argc, char* argv[])
{ {
Polycurve_conic_traits_2 traits; Polycurve_conic_traits_2 traits;
//polycurve constructors //polycurve constructors
Polycurve_conic_traits_2::Construct_x_monotone_curve_2 auto construct_x_mono_polycurve = traits.construct_x_monotone_curve_2_object();
construct_x_mono_polycurve = traits.construct_x_monotone_curve_2_object(); auto construct_polycurve = traits.construct_curve_2_object();
Polycurve_conic_traits_2::Construct_curve_2 construct_polycurve =
traits.construct_curve_2_object();
//create a curve //create a curve
@ -886,7 +894,7 @@ int main(int argc, char* argv[])
//check_split(conic_x_mono_polycurve_1, conic_x_mono_polycurve_2); //check_split(conic_x_mono_polycurve_1, conic_x_mono_polycurve_2);
// std::cout<< std::endl; // std::cout<< std::endl;
//check_make_x_monotne_curve(conic_polycurve_2); //check_make_x_monotne_curve<Point_2, Curve_2>(conic_polycurve_2);
//std::cout<< std::endl; //std::cout<< std::endl;
// check_is_vertical(); // check_is_vertical();

View File

@ -1,146 +1,131 @@
#include <CGAL/Cartesian.h> #include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Arr_segment_traits_2.h> #include <CGAL/Arr_segment_traits_2.h>
#include <CGAL/Arrangement_2.h> #include <CGAL/Arrangement_2.h>
#include <CGAL/Arr_simple_point_location.h> #include <CGAL/Arr_simple_point_location.h>
#include <CGAL/Arr_walk_along_line_point_location.h> #include <CGAL/Arr_walk_along_line_point_location.h>
#include <CGAL/Arr_trapezoid_ric_point_location.h> #include <CGAL/Arr_trapezoid_ric_point_location.h>
template <class VerticalRayShoot> template <typename VerticalRayShoot>
void vertical_ray_shooting_query void vertical_ray_shooting_query
(const VerticalRayShoot& vrs, bool shoot_up, (const VerticalRayShoot& vrs, bool shoot_up,
const typename VerticalRayShoot::Arrangement_2::Point_2& q) const typename VerticalRayShoot::Arrangement_2::Point_2& q)
{ {
// Perform the point-location query. // Perform the point-location query.
CGAL::Object obj = (shoot_up) ? vrs.ray_shoot_up (q) : auto obj = (shoot_up) ? vrs.ray_shoot_up(q) : vrs.ray_shoot_down(q);
vrs.ray_shoot_down (q);
// Print the result. // Print the result.
typedef typename VerticalRayShoot::Arrangement_2 Arrangement_2; typedef typename VerticalRayShoot::Arrangement_2 Arrangement_2;
typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle;
typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
typedef typename Arrangement_2::Face_const_handle Face_const_handle;
typename Arrangement_2::Vertex_const_handle v; if (shoot_up) std::cout << " Shooting up from (" << q << ") : ";
typename Arrangement_2::Halfedge_const_handle e; else std::cout << " Shooting down from (" << q << ") : ";
typename Arrangement_2::Face_const_handle f;
if (shoot_up) if (auto* e_p = boost::get<Halfedge_const_handle>(&obj)) {
std::cout << " Shooting up from (" << q << ") : ";
else
std::cout << " Shooting down from (" << q << ") : ";
if (CGAL::assign (e, obj))
{
// We hit an edge: // We hit an edge:
std::cout << "hit an edge: " << e->curve() << std::endl; std::cout << "hit an edge: " << (*e_p)->curve() << std::endl;
} }
else if (CGAL::assign (v, obj)) else if (auto* v_p = boost::get<Vertex_const_handle>(&obj)) {
{
// We hit a vertex: // We hit a vertex:
if (v->is_isolated()) if ((*v_p)->is_isolated())
std::cout << "hit an isolated vertex: " << v->point() << std::endl; std::cout << "hit an isolated vertex: " << (*v_p)->point() << std::endl;
else else std::cout << "hit a vertex: " << (*v_p)->point() << std::endl;
std::cout << "hit a vertex: " << v->point() << std::endl;
} }
else if (CGAL::assign (f, obj)) else if (auto* f_p = boost::get<Face_const_handle>(&obj)) {
{
// We did not hit anything: // We did not hit anything:
assert (f->is_unbounded()); assert((*f_p)->is_unbounded());
std::cout << "hit nothing." << std::endl; std::cout << "hit nothing." << std::endl;
} }
else else CGAL_error_msg( "Invalid object.");
{
CGAL_error_msg( "Invalid object.");
}
return;
} }
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef Kernel::FT Number_type;
typedef CGAL::Arr_segment_traits_2<Kernel> Traits_2;
typedef Traits_2::Point_2 Point_2;
typedef Traits_2::X_monotone_curve_2 Segment_2;
typedef CGAL::Arrangement_2<Traits_2> Arrangement_2;
typedef CGAL::Arr_simple_point_location<Arrangement_2> Simple_pl;
typedef CGAL::Arr_walk_along_line_point_location<Arrangement_2> Walk_pl;
typedef CGAL::Arr_trapezoid_ric_point_location<Arrangement_2> RIC_pl;
typedef int Number_type; int main()
typedef CGAL::Cartesian<Number_type> Kernel;
typedef CGAL::Arr_segment_traits_2<Kernel> Traits_2;
typedef Traits_2::Point_2 Point_2;
typedef Traits_2::X_monotone_curve_2 Segment_2;
typedef CGAL::Arrangement_2<Traits_2> Arrangement_2;
typedef CGAL::Arr_simple_point_location<Arrangement_2> Simple_pl;
typedef CGAL::Arr_walk_along_line_point_location<Arrangement_2> Walk_pl;
typedef CGAL::Arr_trapezoid_ric_point_location<Arrangement_2> RIC_pl;
int main ()
{ {
// Construct the arrangement. // Construct the arrangement.
Arrangement_2 arr; Arrangement_2 arr;
Simple_pl simple_pl (arr); Simple_pl simple_pl(arr);
Walk_pl walk_pl (arr); Walk_pl walk_pl(arr);
RIC_pl ric_pl (arr); RIC_pl ric_pl(arr);
insert (arr, Segment_2 (Point_2 (0, 0), Point_2 (0, 1))); insert(arr, Segment_2(Point_2(0, 0), Point_2(0, 1)));
insert (arr, Segment_2 (Point_2 (0, 3), Point_2 (0, 4))); insert(arr, Segment_2(Point_2(0, 3), Point_2(0, 4)));
insert (arr, Segment_2 (Point_2 (-1, -1), Point_2 (1, -1))); insert(arr, Segment_2(Point_2(-1, -1), Point_2(1, -1)));
insert (arr, Segment_2 (Point_2 (-1, 5), Point_2 (1, 5))); insert(arr, Segment_2(Point_2(-1, 5), Point_2(1, 5)));
// Perform the vertical ray-shooting queries. // Perform the vertical ray-shooting queries.
std::cout << "First round of queries: " << std::endl; std::cout << "First round of queries: " << std::endl;
Point_2 q1 (0, 2); Point_2 q1(0, 2);
vertical_ray_shooting_query (simple_pl, true, q1); vertical_ray_shooting_query(simple_pl, true, q1);
vertical_ray_shooting_query (walk_pl, true, q1); vertical_ray_shooting_query(walk_pl, true, q1);
vertical_ray_shooting_query (ric_pl, true, q1); vertical_ray_shooting_query(ric_pl, true, q1);
vertical_ray_shooting_query (simple_pl, false, q1); vertical_ray_shooting_query(simple_pl, false, q1);
vertical_ray_shooting_query (walk_pl, false, q1); vertical_ray_shooting_query(walk_pl, false, q1);
vertical_ray_shooting_query (ric_pl, false, q1); vertical_ray_shooting_query(ric_pl, false, q1);
Point_2 q2 (0, 1); Point_2 q2(0, 1);
vertical_ray_shooting_query (simple_pl, true, q2); vertical_ray_shooting_query(simple_pl, true, q2);
vertical_ray_shooting_query (walk_pl, true, q2); vertical_ray_shooting_query(walk_pl, true, q2);
vertical_ray_shooting_query (ric_pl, true, q2); vertical_ray_shooting_query(ric_pl, true, q2);
vertical_ray_shooting_query (simple_pl, false, q2); vertical_ray_shooting_query(simple_pl, false, q2);
vertical_ray_shooting_query (walk_pl, false, q2); vertical_ray_shooting_query(walk_pl, false, q2);
vertical_ray_shooting_query (ric_pl, false, q2); vertical_ray_shooting_query(ric_pl, false, q2);
Point_2 q3 (0, 3); Point_2 q3(0, 3);
vertical_ray_shooting_query (simple_pl, true, q3); vertical_ray_shooting_query(simple_pl, true, q3);
vertical_ray_shooting_query (walk_pl, true, q3); vertical_ray_shooting_query(walk_pl, true, q3);
vertical_ray_shooting_query (ric_pl, true, q3); vertical_ray_shooting_query(ric_pl, true, q3);
vertical_ray_shooting_query (simple_pl, false, q3); vertical_ray_shooting_query(simple_pl, false, q3);
vertical_ray_shooting_query (walk_pl, false, q3); vertical_ray_shooting_query(walk_pl, false, q3);
vertical_ray_shooting_query (ric_pl, false, q3); vertical_ray_shooting_query(ric_pl, false, q3);
// Insert additional curves and perform the ray-shooting queries again. // Insert additional curves and perform the ray-shooting queries again.
insert (arr, Segment_2 (Point_2 (-1, 0), Point_2 (1, 0))); insert (arr, Segment_2(Point_2(-1, 0), Point_2(1, 0)));
insert (arr, Segment_2 (Point_2 (-1, 4), Point_2 (1, 4))); insert (arr, Segment_2(Point_2(-1, 4), Point_2(1, 4)));
std::cout << "Second round of queries: " << std::endl; std::cout << "Second round of queries: " << std::endl;
vertical_ray_shooting_query (simple_pl, true, q1); vertical_ray_shooting_query(simple_pl, true, q1);
vertical_ray_shooting_query (walk_pl, true, q1); vertical_ray_shooting_query(walk_pl, true, q1);
vertical_ray_shooting_query (ric_pl, true, q1); vertical_ray_shooting_query(ric_pl, true, q1);
vertical_ray_shooting_query (simple_pl, false, q1); vertical_ray_shooting_query(simple_pl, false, q1);
vertical_ray_shooting_query (walk_pl, false, q1); vertical_ray_shooting_query(walk_pl, false, q1);
vertical_ray_shooting_query (ric_pl, false, q1); vertical_ray_shooting_query(ric_pl, false, q1);
vertical_ray_shooting_query (simple_pl, true, q2); vertical_ray_shooting_query(simple_pl, true, q2);
vertical_ray_shooting_query (walk_pl, true, q2); vertical_ray_shooting_query(walk_pl, true, q2);
vertical_ray_shooting_query (ric_pl, true, q2); vertical_ray_shooting_query(ric_pl, true, q2);
vertical_ray_shooting_query (simple_pl, false, q2); vertical_ray_shooting_query(simple_pl, false, q2);
vertical_ray_shooting_query (walk_pl, false, q2); vertical_ray_shooting_query(walk_pl, false, q2);
vertical_ray_shooting_query (ric_pl, false, q2); vertical_ray_shooting_query(ric_pl, false, q2);
vertical_ray_shooting_query (simple_pl, true, q3); vertical_ray_shooting_query(simple_pl, true, q3);
vertical_ray_shooting_query (walk_pl, true, q3); vertical_ray_shooting_query(walk_pl, true, q3);
vertical_ray_shooting_query (ric_pl, true, q3); vertical_ray_shooting_query(ric_pl, true, q3);
vertical_ray_shooting_query (simple_pl, false, q3); vertical_ray_shooting_query(simple_pl, false, q3);
vertical_ray_shooting_query (walk_pl, false, q3); vertical_ray_shooting_query(walk_pl, false, q3);
vertical_ray_shooting_query (ric_pl, false, q3); vertical_ray_shooting_query(ric_pl, false, q3);
return (0); return (0);
} }

View File

@ -8,13 +8,17 @@
#include <CGAL/Arr_segment_traits_2.h> #include <CGAL/Arr_segment_traits_2.h>
#include <CGAL/Arrangement_2.h> #include <CGAL/Arrangement_2.h>
typedef CGAL::Quotient<int> Number_type; typedef CGAL::Quotient<int> Number_type;
typedef CGAL::Simple_cartesian<Number_type> Kernel; typedef CGAL::Simple_cartesian<Number_type> Kernel;
typedef CGAL::Arr_segment_traits_2<Kernel> Traits_2; typedef CGAL::Arr_segment_traits_2<Kernel> Traits_2;
typedef Traits_2::Point_2 Point_2; typedef Traits_2::Point_2 Point_2;
typedef Traits_2::X_monotone_curve_2 Segment_2; typedef Traits_2::X_monotone_curve_2 Segment_2;
typedef CGAL::Arrangement_2<Traits_2> Arrangement_2; typedef CGAL::Arrangement_2<Traits_2> Arrangement_2;
typedef Arrangement_2::Halfedge_handle Halfedge_handle; typedef Arrangement_2::Vertex_handle Vertex_handle;
typedef Arrangement_2::Halfedge_handle Halfedge_handle;
typedef Arrangement_2::Face_handle Face_handle;
typedef boost::variant<Vertex_handle, Halfedge_handle, Face_handle>
Zone_result;
#define N_SEGMENTS 3 #define N_SEGMENTS 3
@ -40,7 +44,7 @@ int main ()
for (k = 0; k < N_SEGMENTS; k++) for (k = 0; k < N_SEGMENTS; k++)
{ {
std::list<CGAL::Object> zone_elems; std::list<Zone_result> zone_elems;
zone(arr, segs[k], std::back_inserter(zone_elems)); zone(arr, segs[k], std::back_inserter(zone_elems));
std::size_t zone_actual_comp = zone_elems.size(); std::size_t zone_actual_comp = zone_elems.size();

View File

@ -38,8 +38,9 @@ CGAL::copy_face_graph(g1, g2);
// specifying named parameters for the second graph // specifying named parameters for the second graph
CGAL::copy_face_graph(g1, g2, CGAL::copy_face_graph(g1, g2,
CGAL::parameters::all_default(), CGAL::parameters::vertex_point_map(vpm) //parameter for g1
CGAL::parameters::vertex_point_map(vpm_2)); .vertex_to_vertex_map(v2v), //other parameter for g1
CGAL::parameters::all_default()); //parameter for g2
\endcode \endcode
*/ */
˛ ˛

View File

@ -443,7 +443,7 @@ the requirement for traversal of all faces in a graph.
/// \defgroup PkgBGLPropertiesDynamic Dynamic Properties /// \defgroup PkgBGLPropertiesDynamic Dynamic Properties
/// \ingroup PkgBGLRef /// \ingroup PkgBGLRef
/// \defgroup PkgBGLGraphExternalIndices External Indices /// \defgroup BGLGraphExternalIndices External Indices
/// \ingroup PkgBGLRef /// \ingroup PkgBGLRef
/// \defgroup PkgBGLHelperFct Helper Functions /// \defgroup PkgBGLHelperFct Helper Functions

View File

@ -77,7 +77,7 @@ int main(int argc, char** argv)
// http://www.boost.org/libs/property_map/doc/vector_property_map.html // http://www.boost.org/libs/property_map/doc/vector_property_map.html
// for details. // for details.
boost::vector_property_map<Vector, Face_index_map> boost::vector_property_map<Vector, Face_index_map>
normals(get(CGAL::face_index, lcc)); normals(static_cast<unsigned>(num_faces(lcc)), get(CGAL::face_index, lcc));
calculate_face_normals( calculate_face_normals(
lcc // Graph lcc // Graph

View File

@ -82,7 +82,7 @@ int main(int argc, char** argv)
// http://www.boost.org/libs/property_map/doc/vector_property_map.html // http://www.boost.org/libs/property_map/doc/vector_property_map.html
// for details. // for details.
boost::vector_property_map<Vector, Face_index_map> boost::vector_property_map<Vector, Face_index_map>
normals(get(CGAL::face_index, P)); normals(static_cast<unsigned>(num_faces(P)), get(CGAL::face_index, P));
calculate_face_normals( calculate_face_normals(
P // Graph P // Graph

View File

@ -13,6 +13,8 @@
#define CGAL_EULER_OPERATIONS_H #define CGAL_EULER_OPERATIONS_H
#include <stdexcept> #include <stdexcept>
#include <algorithm>
#include <vector>
#include <boost/graph/graph_traits.hpp> #include <boost/graph/graph_traits.hpp>
#include <CGAL/boost/graph/properties.h> #include <CGAL/boost/graph/properties.h>
@ -558,6 +560,127 @@ add_edge(typename boost::graph_traits<Graph>::vertex_descriptor s,
return e; return e;
} }
/**
* checks whether a new face defined by a range of vertices (identified by their descriptors,
* `boost::graph_traits<Graph>::%vertex_descriptor`) can be added.
*/
template <typename VertexRange,typename PMesh>
bool can_add_face(const VertexRange& vrange, const PMesh& sm)
{
typedef typename boost::graph_traits<PMesh>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<PMesh>::halfedge_descriptor halfedge_descriptor;
std::vector<typename boost::graph_traits<PMesh>::vertex_descriptor> face(vrange.begin(), vrange.end());
std::size_t N = face.size();
std::vector<vertex_descriptor> f2(face);
std::sort(f2.begin(), f2.end());
typename std::vector<vertex_descriptor>::iterator it = std::unique(f2.begin(),f2.end());
if((N > 0) && (it != f2.end())){
return false;
}
if(N < 3){
return false;
}
face.push_back(face.front());
for(std::size_t i=0; i < N; ++i){
halfedge_descriptor hd;
bool found;
boost::tie(hd,found) = halfedge(face[i],face[i+1],sm);
if(found && (! is_border(hd,sm))){
return false;
}
}
for(std::size_t i=0; i < N; ++i){
if(halfedge(face[i],sm) == boost::graph_traits<PMesh>::null_halfedge()){
continue;
}
if(! is_border(face[i],sm)){
return false;
}
}
//Test if all halfedges of the new face
//are possibly consecutive border halfedges in the HDS.
//Possibly because it may be not directly encoded in the HDS
//(using next() function ). This situation can occur when one or
//more facets share only a vertex: For example, the new facet we try to add
//would make the vertex indices[i] a manifold but this should be forbidden
//if a facet only incident to that vertex has already been inserted.
//We check this for each vertex of the sequence.
for(std::size_t i = 0; i < N; ++i) {
std::size_t prev_index= (i-1+N)%N;
std::size_t next_index= (i+1)%N;
vertex_descriptor previous_vertex = face[ prev_index ];
vertex_descriptor next_vertex = face[ next_index ];
halfedge_descriptor halfedge_around_vertex = halfedge(face[i],sm);
if ( halfedge_around_vertex == boost::graph_traits<PMesh>::null_halfedge() ||
halfedge(previous_vertex,sm) == boost::graph_traits<PMesh>::null_halfedge()||
halfedge(next_vertex,sm) == boost::graph_traits<PMesh>::null_halfedge()
) continue;
halfedge_descriptor start=halfedge_around_vertex;
//halfedges pointing to/running out from vertex indices[i]
//and that need to be possibly consecutive
halfedge_descriptor prev_hd= boost::graph_traits<PMesh>::null_halfedge(),next_hd= boost::graph_traits<PMesh>::null_halfedge();
halfedge_around_vertex = opposite(next(halfedge_around_vertex,sm),sm);
//look for a halfedge incident to vertex indices[i]
//and which opposite is incident to previous_vertex
do{
if(target(opposite(halfedge_around_vertex,sm),sm)==previous_vertex){
prev_hd=halfedge_around_vertex;
CGAL_precondition(is_border(prev_hd,sm));
break;
}
halfedge_around_vertex = opposite(next(halfedge_around_vertex,sm),sm);
}
while (halfedge_around_vertex!=start);
if (prev_hd != boost::graph_traits<PMesh>::null_halfedge()){
halfedge_around_vertex = opposite(next(halfedge_around_vertex,sm),sm);
//prev_hd and next are already consecutive in the HDS
if (target(opposite(halfedge_around_vertex,sm),sm)==next_vertex) continue;
//look for a border halfedge which opposite is
//incident to next_vertex: set next halfedge
do
{
if (target(opposite(halfedge_around_vertex,sm),sm)==next_vertex){
next_hd = opposite(halfedge_around_vertex,sm);
break;
}
halfedge_around_vertex = opposite(next(halfedge_around_vertex,sm),sm);
}
while(halfedge_around_vertex != prev_hd);
if (next_hd==boost::graph_traits<PMesh>::null_halfedge()) continue;
//check if no constraint prevents
//prev_hd and next_hd to be adjacent:
do{
halfedge_around_vertex = opposite(next(halfedge_around_vertex, sm),sm);
if ( is_border(opposite(halfedge_around_vertex,sm),sm) ) break;
}
while (halfedge_around_vertex != prev_hd);
if (halfedge_around_vertex == prev_hd) return false;
start = halfedge_around_vertex;
}
}
return true;
}
/** /**
* adds a new face defined by a range of vertices (identified by their descriptors, * adds a new face defined by a range of vertices (identified by their descriptors,
* `boost::graph_traits<Graph>::%vertex_descriptor`). * `boost::graph_traits<Graph>::%vertex_descriptor`).

View File

@ -104,6 +104,66 @@ struct Face_filtered_graph
typedef Face_filtered_graph<Graph, FIMap, VIMap, HIMap> Self; typedef Face_filtered_graph<Graph, FIMap, VIMap, HIMap> Self;
/*!
* \brief constructs an empty face filtered graph (no face is selected)
*
* \tparam NamedParameters a sequence of named parameters
*
* \param graph the underlying graph.
*
* \param np optional sequence of named parameters among the ones listed below
*
* \cgalNamedParamsBegin
* \cgalParamNBegin{vertex_index_map}
* \cgalParamDescription{a property map associating to each vertex of `graph` a unique index between `0` and `num_vertices(graph) - 1`}
* \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits<Graph>::%vertex_descriptor`
* as key type and `std::size_t` as value type}
* \cgalParamDefault{an automatically indexed internal map}
* \cgalParamExtra{If this parameter is not passed, internal machinery will create and initialize
* a face index property map, either using the internal property map if it exists
* or using an external map. The latter might result in - slightly - worsened performance
* in case of non-constant complexity for index access.}
* \cgalParamNEnd
*
* \cgalParamNBegin{halfedge_index_map}
* \cgalParamDescription{a property map associating to each halfedge of `graph` a unique index between `0` and `num_halfedges(graph) - 1`}
* \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits<Graph>::%halfedge_descriptor`
* as key type and `std::size_t` as value type}
* \cgalParamDefault{an automatically indexed internal map}
* \cgalParamExtra{If this parameter is not passed, internal machinery will create and initialize
* a face index property map, either using the internal property map if it exists
* or using an external map. The latter might result in - slightly - worsened performance
* in case of non-constant complexity for index access.}
* \cgalParamNEnd
*
* \cgalParamNBegin{face_index_map}
* \cgalParamDescription{a property map associating to each face of `graph` a unique index between `0` and `num_faces(graph) - 1`}
* \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits<Graph>::%face_descriptor`
* as key type and `std::size_t` as value type}
* \cgalParamDefault{an automatically indexed internal map}
* \cgalParamExtra{If this parameter is not passed, internal machinery will create and initialize
* a face index property map, either using the internal property map if it exists
* or using an external map. The latter might result in - slightly - worsened performance
* in case of non-constant complexity for index access.}
* \cgalParamNEnd
* \cgalNamedParamsEnd
*/
template <class CGAL_BGL_NP_TEMPLATE_PARAMETERS>
Face_filtered_graph(const Graph& graph,
const CGAL_BGL_NP_CLASS& np)
: _graph(const_cast<Graph&>(graph))
, fimap(CGAL::get_initialized_face_index_map(graph, np))
, vimap(CGAL::get_initialized_vertex_index_map(graph, np))
, himap(CGAL::get_initialized_halfedge_index_map(graph, np))
, selected_faces(num_faces(graph), 0)
, selected_vertices(num_vertices(graph), 0)
, selected_halfedges(num_halfedges(graph), 0)
{}
Face_filtered_graph(const Graph& graph)
:Face_filtered_graph(graph, parameters::all_default())
{}
/*! /*!
* \brief Constructor where the set of selected faces is specified as a range of patch ids. * \brief Constructor where the set of selected faces is specified as a range of patch ids.
* *

View File

@ -1,4 +1,3 @@
#ifndef CGAL_BOOST_GRAPH_ALPHA_EXPANSION_GRAPHCUT_H
// Copyright (c) 2014 GeometryFactory (France). All rights reserved. // Copyright (c) 2014 GeometryFactory (France). All rights reserved.
// //
// This file is part of CGAL (www.cgal.org) // This file is part of CGAL (www.cgal.org)
@ -10,6 +9,7 @@
// //
// Author(s) : Ilker O. Yaz, Simon Giraudot // Author(s) : Ilker O. Yaz, Simon Giraudot
#ifndef CGAL_BOOST_GRAPH_ALPHA_EXPANSION_GRAPHCUT_H
#define CGAL_BOOST_GRAPH_ALPHA_EXPANSION_GRAPHCUT_H #define CGAL_BOOST_GRAPH_ALPHA_EXPANSION_GRAPHCUT_H
#include <CGAL/Iterator_range.h> #include <CGAL/Iterator_range.h>

View File

@ -15,21 +15,6 @@
// This will push/pop a VC15 warning // This will push/pop a VC15 warning
#include <CGAL/boost/graph/Named_function_parameters.h> #include <CGAL/boost/graph/Named_function_parameters.h>
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/version.hpp>
#include <climits>
#if BOOST_VERSION == 105400
#ifdef BOOST_GRAPH_DIJKSTRA_HPP
# pragma message \
"Warning: the header file boost/graph/dijkstra_shortest_paths.hpp " \
"of boost 1.54 contains a bug that may impact some functions in CGAL. " \
"Please consider including CGAL/boost/graph/dijkstra_shortest_paths.hpp " \
"before boost header"
#endif
#include <CGAL/boost/graph/dijkstra_shortest_paths.hpp>
#else
#include <boost/graph/dijkstra_shortest_paths.hpp>
#endif
#endif // CGAL_BOOST_GRAPH_DIJKSTRA_SHORTEST_PATHS_H #endif // CGAL_BOOST_GRAPH_DIJKSTRA_SHORTEST_PATHS_H

View File

@ -1,633 +0,0 @@
// This file is a copy of the file distributed with boost 1.55
// It is distributed with CGAL to work around a bug in boost 1.54
// and must be used only with boost 1.54 by including
// CGAL/boost/graph/dijkstra_shortest_paths.hpp
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
//=======================================================================
//
// $URL$
// $Id$
// SPDX-License-Identifier: BSL-1.0
//
// Revision History:
// 04 April 2001: Added named parameter variant. (Jeremy Siek)
// 01 April 2001: Modified to use new <boost/limits.hpp> header. (JMaddock)
//
#ifndef BOOST_GRAPH_DIJKSTRA_HPP
#define BOOST_GRAPH_DIJKSTRA_HPP
#include <functional>
#include <boost/limits.hpp>
#include <boost/graph/named_function_params.hpp>
#include <boost/graph/breadth_first_search.hpp>
#include <boost/graph/relax.hpp>
#include <boost/pending/indirect_cmp.hpp>
#include <boost/graph/exception.hpp>
#include <boost/pending/relaxed_heap.hpp>
#include <boost/graph/overloading.hpp>
#include <boost/smart_ptr.hpp>
#include <boost/graph/detail/d_ary_heap.hpp>
#include <boost/graph/two_bit_color_map.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/property_map/vector_property_map.hpp>
#include <boost/type_traits.hpp>
#include <boost/concept/assert.hpp>
#ifdef BOOST_GRAPH_DIJKSTRA_TESTING
# include <boost/pending/mutable_queue.hpp>
#endif // BOOST_GRAPH_DIJKSTRA_TESTING
namespace boost {
/**
* @brief Updates a particular value in a queue used by Dijkstra's
* algorithm.
*
* This routine is called by Dijkstra's algorithm after it has
* decreased the distance from the source vertex to the given @p
* vertex. By default, this routine will just call @c
* Q.update(vertex). However, other queues may provide more
* specialized versions of this routine.
*
* @param Q the queue that will be updated.
* @param vertex the vertex whose distance has been updated
* @param old_distance the previous distance to @p vertex
*/
template<typename Buffer, typename Vertex, typename DistanceType>
inline void
dijkstra_queue_update(Buffer& Q, Vertex vertex, DistanceType old_distance)
{
(void)old_distance;
Q.update(vertex);
}
#ifdef BOOST_GRAPH_DIJKSTRA_TESTING
// This is a misnomer now: it now just refers to the "default heap", which is
// currently d-ary (d=4) but can be changed by a #define.
static bool dijkstra_relaxed_heap = true;
#endif
template <class Visitor, class Graph>
struct DijkstraVisitorConcept {
void constraints() {
// commented to avoid an unused vaiable warning
// BOOST_CONCEPT_ASSERT(( CopyConstructibleConcept<Visitor> ));
vis.initialize_vertex(u, g);
vis.discover_vertex(u, g);
vis.examine_vertex(u, g);
vis.examine_edge(e, g);
vis.edge_relaxed(e, g);
vis.edge_not_relaxed(e, g);
vis.finish_vertex(u, g);
}
Visitor vis;
Graph g;
typename graph_traits<Graph>::vertex_descriptor u;
typename graph_traits<Graph>::edge_descriptor e;
};
template <class Visitors = null_visitor>
class dijkstra_visitor : public bfs_visitor<Visitors> {
public:
dijkstra_visitor() { }
dijkstra_visitor(Visitors vis)
: bfs_visitor<Visitors>(vis) { }
template <class Edge, class Graph>
void edge_relaxed(Edge e, Graph& g) {
invoke_visitors(this->m_vis, e, g, on_edge_relaxed());
}
template <class Edge, class Graph>
void edge_not_relaxed(Edge e, Graph& g) {
invoke_visitors(this->m_vis, e, g, on_edge_not_relaxed());
}
private:
template <class Edge, class Graph>
void tree_edge(Edge /* u */, Graph& /* g */) { }
};
template <class Visitors>
dijkstra_visitor<Visitors>
make_dijkstra_visitor(Visitors vis) {
return dijkstra_visitor<Visitors>(vis);
}
typedef dijkstra_visitor<> default_dijkstra_visitor;
namespace detail {
template <class UniformCostVisitor, class UpdatableQueue,
class WeightMap, class PredecessorMap, class DistanceMap,
class BinaryFunction, class BinaryPredicate>
struct dijkstra_bfs_visitor
{
typedef typename property_traits<DistanceMap>::value_type D;
typedef typename property_traits<WeightMap>::value_type W;
dijkstra_bfs_visitor(UniformCostVisitor vis, UpdatableQueue& Q,
WeightMap w, PredecessorMap p, DistanceMap d,
BinaryFunction combine, BinaryPredicate compare,
D zero)
: m_vis(vis), m_Q(Q), m_weight(w), m_predecessor(p), m_distance(d),
m_combine(combine), m_compare(compare), m_zero(zero) { }
template <class Edge, class Graph>
void tree_edge(Edge e, Graph& g) {
bool decreased = relax(e, g, m_weight, m_predecessor, m_distance,
m_combine, m_compare);
if (decreased)
m_vis.edge_relaxed(e, g);
else
m_vis.edge_not_relaxed(e, g);
}
template <class Edge, class Graph>
void gray_target(Edge e, Graph& g) {
D old_distance = get(m_distance, target(e, g));
bool decreased = relax(e, g, m_weight, m_predecessor, m_distance,
m_combine, m_compare);
if (decreased) {
dijkstra_queue_update(m_Q, target(e, g), old_distance);
m_vis.edge_relaxed(e, g);
} else
m_vis.edge_not_relaxed(e, g);
}
template <class Vertex, class Graph>
void initialize_vertex(Vertex u, Graph& g)
{ m_vis.initialize_vertex(u, g); }
template <class Edge, class Graph>
void non_tree_edge(Edge, Graph&) { }
template <class Vertex, class Graph>
void discover_vertex(Vertex u, Graph& g) { m_vis.discover_vertex(u, g); }
template <class Vertex, class Graph>
void examine_vertex(Vertex u, Graph& g) { m_vis.examine_vertex(u, g); }
template <class Edge, class Graph>
void examine_edge(Edge e, Graph& g) {
// Test for negative-weight edges:
//
// Reasons that other comparisons do not work:
//
// m_compare(e_weight, D(0)):
// m_compare only needs to work on distances, not weights, and those
// types do not need to be the same (bug 8398,
// https://svn.boost.org/trac/boost/ticket/8398).
// m_compare(m_combine(source_dist, e_weight), source_dist):
// if m_combine is project2nd (as in prim_minimum_spanning_tree),
// this test will claim that the edge weight is negative whenever
// the edge weight is less than source_dist, even if both of those
// are positive (bug 9012,
// https://svn.boost.org/trac/boost/ticket/9012).
// m_compare(m_combine(e_weight, source_dist), source_dist):
// would fix project2nd issue, but documentation only requires that
// m_combine be able to take a distance and a weight (in that order)
// and return a distance.
// W e_weight = get(m_weight, e);
// sd_plus_ew = source_dist + e_weight.
// D sd_plus_ew = m_combine(source_dist, e_weight);
// sd_plus_2ew = source_dist + 2 * e_weight.
// D sd_plus_2ew = m_combine(sd_plus_ew, e_weight);
// The test here is equivalent to e_weight < 0 if m_combine has a
// cancellation law, but always returns false when m_combine is a
// projection operator.
if (m_compare(m_combine(m_zero, get(m_weight, e)), m_zero))
boost::throw_exception(negative_edge());
// End of test for negative-weight edges.
m_vis.examine_edge(e, g);
}
template <class Edge, class Graph>
void black_target(Edge, Graph&) { }
template <class Vertex, class Graph>
void finish_vertex(Vertex u, Graph& g) { m_vis.finish_vertex(u, g); }
UniformCostVisitor m_vis;
UpdatableQueue& m_Q;
WeightMap m_weight;
PredecessorMap m_predecessor;
DistanceMap m_distance;
BinaryFunction m_combine;
BinaryPredicate m_compare;
D m_zero;
};
} // namespace detail
namespace detail {
template <class Graph, class IndexMap, class Value, bool KnownNumVertices>
struct vertex_property_map_generator_helper {};
template <class Graph, class IndexMap, class Value>
struct vertex_property_map_generator_helper<Graph, IndexMap, Value, true> {
typedef boost::iterator_property_map<Value*, IndexMap> type;
static type build(const Graph& g, const IndexMap& index, boost::scoped_array<Value>& array_holder) {
array_holder.reset(new Value[num_vertices(g)]);
std::fill(array_holder.get(), array_holder.get() + num_vertices(g), Value());
return make_iterator_property_map(array_holder.get(), index);
}
};
template <class Graph, class IndexMap, class Value>
struct vertex_property_map_generator_helper<Graph, IndexMap, Value, false> {
typedef boost::vector_property_map<Value, IndexMap> type;
static type build(const Graph& /* g */, const IndexMap& index, boost::scoped_array<Value>& /* array_holder */) {
return boost::make_vector_property_map<Value>(index);
}
};
template <class Graph, class IndexMap, class Value>
struct vertex_property_map_generator {
typedef boost::is_base_and_derived<
boost::vertex_list_graph_tag,
typename boost::graph_traits<Graph>::traversal_category>
known_num_vertices;
typedef vertex_property_map_generator_helper<Graph, IndexMap, Value, known_num_vertices::value> helper;
typedef typename helper::type type;
static type build(const Graph& g, const IndexMap& index, boost::scoped_array<Value>& array_holder) {
return helper::build(g, index, array_holder);
}
};
}
namespace detail {
template <class Graph, class IndexMap, bool KnownNumVertices>
struct default_color_map_generator_helper {};
template <class Graph, class IndexMap>
struct default_color_map_generator_helper<Graph, IndexMap, true> {
typedef boost::two_bit_color_map<IndexMap> type;
static type build(const Graph& g, const IndexMap& index) {
size_t nv = num_vertices(g);
return boost::two_bit_color_map<IndexMap>(nv, index);
}
};
template <class Graph, class IndexMap>
struct default_color_map_generator_helper<Graph, IndexMap, false> {
typedef boost::vector_property_map<boost::two_bit_color_type, IndexMap> type;
static type build(const Graph& /* g */, const IndexMap& index) {
return boost::make_vector_property_map<boost::two_bit_color_type>(index);
}
};
template <class Graph, class IndexMap>
struct default_color_map_generator {
typedef boost::is_base_and_derived<
boost::vertex_list_graph_tag,
typename boost::graph_traits<Graph>::traversal_category>
known_num_vertices;
typedef default_color_map_generator_helper<Graph, IndexMap, known_num_vertices::value> helper;
typedef typename helper::type type;
static type build(const Graph& g, const IndexMap& index) {
return helper::build(g, index);
}
};
}
// Call breadth first search with default color map.
template <class Graph, class SourceInputIter, class DijkstraVisitor,
class PredecessorMap, class DistanceMap,
class WeightMap, class IndexMap, class Compare, class Combine,
class DistZero>
inline void
dijkstra_shortest_paths_no_init
(const Graph& g,
SourceInputIter s_begin, SourceInputIter s_end,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
IndexMap index_map,
Compare compare, Combine combine, DistZero zero,
DijkstraVisitor vis)
{
typedef
detail::default_color_map_generator<Graph, IndexMap>
ColorMapHelper;
typedef typename ColorMapHelper::type ColorMap;
ColorMap color =
ColorMapHelper::build(g, index_map);
dijkstra_shortest_paths_no_init( g, s_begin, s_end, predecessor, distance, weight,
index_map, compare, combine, zero, vis,
color);
}
// Call breadth first search with default color map.
template <class Graph, class DijkstraVisitor,
class PredecessorMap, class DistanceMap,
class WeightMap, class IndexMap, class Compare, class Combine,
class DistZero>
inline void
dijkstra_shortest_paths_no_init
(const Graph& g,
typename graph_traits<Graph>::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
IndexMap index_map,
Compare compare, Combine combine, DistZero zero,
DijkstraVisitor vis)
{
dijkstra_shortest_paths_no_init(g, &s, &s + 1, predecessor, distance,
weight, index_map, compare, combine, zero,
vis);
}
// Call breadth first search
template <class Graph, class SourceInputIter, class DijkstraVisitor,
class PredecessorMap, class DistanceMap,
class WeightMap, class IndexMap, class Compare, class Combine,
class DistZero, class ColorMap>
inline void
dijkstra_shortest_paths_no_init
(const Graph& g,
SourceInputIter s_begin, SourceInputIter s_end,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
IndexMap index_map,
Compare compare, Combine combine, DistZero zero,
DijkstraVisitor vis, ColorMap color)
{
typedef indirect_cmp<DistanceMap, Compare> IndirectCmp;
IndirectCmp icmp(distance, compare);
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
#ifdef BOOST_GRAPH_DIJKSTRA_TESTING
if (!dijkstra_relaxed_heap) {
typedef mutable_queue<Vertex, std::vector<Vertex>, IndirectCmp, IndexMap>
MutableQueue;
MutableQueue Q(num_vertices(g), icmp, index_map);
detail::dijkstra_bfs_visitor<DijkstraVisitor, MutableQueue, WeightMap,
PredecessorMap, DistanceMap, Combine, Compare>
bfs_vis(vis, Q, weight, predecessor, distance, combine, compare, zero);
breadth_first_visit(g, s_begin, s_end, Q, bfs_vis, color);
return;
}
#endif // BOOST_GRAPH_DIJKSTRA_TESTING
#ifdef BOOST_GRAPH_DIJKSTRA_USE_RELAXED_HEAP
typedef relaxed_heap<Vertex, IndirectCmp, IndexMap> MutableQueue;
MutableQueue Q(num_vertices(g), icmp, index_map);
#else // Now the default: use a d-ary heap
boost::scoped_array<std::size_t> index_in_heap_map_holder;
typedef
detail::vertex_property_map_generator<Graph, IndexMap, std::size_t>
IndexInHeapMapHelper;
typedef typename IndexInHeapMapHelper::type IndexInHeapMap;
IndexInHeapMap index_in_heap =
IndexInHeapMapHelper::build(g, index_map, index_in_heap_map_holder);
typedef d_ary_heap_indirect<Vertex, 4, IndexInHeapMap, DistanceMap, Compare>
MutableQueue;
MutableQueue Q(distance, index_in_heap, compare);
#endif // Relaxed heap
detail::dijkstra_bfs_visitor<DijkstraVisitor, MutableQueue, WeightMap,
PredecessorMap, DistanceMap, Combine, Compare>
bfs_vis(vis, Q, weight, predecessor, distance, combine, compare, zero);
breadth_first_visit(g, s_begin, s_end, Q, bfs_vis, color);
}
// Call breadth first search
template <class Graph, class DijkstraVisitor,
class PredecessorMap, class DistanceMap,
class WeightMap, class IndexMap, class Compare, class Combine,
class DistZero, class ColorMap>
inline void
dijkstra_shortest_paths_no_init
(const Graph& g,
typename graph_traits<Graph>::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
IndexMap index_map,
Compare compare, Combine combine, DistZero zero,
DijkstraVisitor vis, ColorMap color)
{
dijkstra_shortest_paths_no_init(g, &s, &s + 1, predecessor, distance,
weight, index_map, compare, combine,
zero, vis, color);
}
// Initialize distances and call breadth first search with default color map
template <class VertexListGraph, class SourceInputIter, class DijkstraVisitor,
class PredecessorMap, class DistanceMap,
class WeightMap, class IndexMap, class Compare, class Combine,
class DistInf, class DistZero, typename T, typename Tag,
typename Base>
inline void
dijkstra_shortest_paths
(const VertexListGraph& g,
SourceInputIter s_begin, SourceInputIter s_end,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
IndexMap index_map,
Compare compare, Combine combine, DistInf inf, DistZero zero,
DijkstraVisitor vis,
const bgl_named_params<T, Tag, Base>&
BOOST_GRAPH_ENABLE_IF_MODELS_PARM(VertexListGraph,vertex_list_graph_tag))
{
boost::two_bit_color_map<IndexMap> color(num_vertices(g), index_map);
dijkstra_shortest_paths(g, s_begin, s_end, predecessor, distance, weight,
index_map, compare, combine, inf, zero, vis,
color);
}
// Initialize distances and call breadth first search with default color map
template <class VertexListGraph, class DijkstraVisitor,
class PredecessorMap, class DistanceMap,
class WeightMap, class IndexMap, class Compare, class Combine,
class DistInf, class DistZero, typename T, typename Tag,
typename Base>
inline void
dijkstra_shortest_paths
(const VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
IndexMap index_map,
Compare compare, Combine combine, DistInf inf, DistZero zero,
DijkstraVisitor vis,
const bgl_named_params<T, Tag, Base>&
BOOST_GRAPH_ENABLE_IF_MODELS_PARM(VertexListGraph,vertex_list_graph_tag))
{
dijkstra_shortest_paths(g, &s, &s + 1, predecessor, distance, weight,
index_map, compare, combine, inf, zero, vis);
}
// Initialize distances and call breadth first search
template <class VertexListGraph, class SourceInputIter, class DijkstraVisitor,
class PredecessorMap, class DistanceMap,
class WeightMap, class IndexMap, class Compare, class Combine,
class DistInf, class DistZero, class ColorMap>
inline void
dijkstra_shortest_paths
(const VertexListGraph& g,
SourceInputIter s_begin, SourceInputIter s_end,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
IndexMap index_map,
Compare compare, Combine combine, DistInf inf, DistZero zero,
DijkstraVisitor vis, ColorMap color)
{
typedef typename property_traits<ColorMap>::value_type ColorValue;
typedef color_traits<ColorValue> Color;
typename graph_traits<VertexListGraph>::vertex_iterator ui, ui_end;
for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) {
vis.initialize_vertex(*ui, g);
put(distance, *ui, inf);
put(predecessor, *ui, *ui);
put(color, *ui, Color::white());
}
for (SourceInputIter it = s_begin; it != s_end; ++it) {
put(distance, *it, zero);
}
dijkstra_shortest_paths_no_init(g, s_begin, s_end, predecessor, distance,
weight, index_map, compare, combine, zero, vis,
color);
}
// Initialize distances and call breadth first search
template <class VertexListGraph, class DijkstraVisitor,
class PredecessorMap, class DistanceMap,
class WeightMap, class IndexMap, class Compare, class Combine,
class DistInf, class DistZero, class ColorMap>
inline void
dijkstra_shortest_paths
(const VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
IndexMap index_map,
Compare compare, Combine combine, DistInf inf, DistZero zero,
DijkstraVisitor vis, ColorMap color)
{
dijkstra_shortest_paths(g, &s, &s + 1, predecessor, distance, weight,
index_map, compare, combine, inf, zero,
vis, color);
}
// Initialize distances and call breadth first search
template <class VertexListGraph, class SourceInputIter,
class DijkstraVisitor,
class PredecessorMap, class DistanceMap,
class WeightMap, class IndexMap, class Compare, class Combine,
class DistInf, class DistZero>
inline void
dijkstra_shortest_paths
(const VertexListGraph& g,
SourceInputIter s_begin, SourceInputIter s_end,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
IndexMap index_map,
Compare compare, Combine combine, DistInf inf, DistZero zero,
DijkstraVisitor vis)
{
dijkstra_shortest_paths(g, s_begin, s_end, predecessor, distance,
weight, index_map,
compare, combine, inf, zero, vis,
no_named_parameters());
}
// Initialize distances and call breadth first search
template <class VertexListGraph, class DijkstraVisitor,
class PredecessorMap, class DistanceMap,
class WeightMap, class IndexMap, class Compare, class Combine,
class DistInf, class DistZero>
inline void
dijkstra_shortest_paths
(const VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
IndexMap index_map,
Compare compare, Combine combine, DistInf inf, DistZero zero,
DijkstraVisitor vis)
{
dijkstra_shortest_paths(g, &s, &s + 1, predecessor, distance,
weight, index_map,
compare, combine, inf, zero, vis);
}
namespace detail {
// Handle defaults for PredecessorMap and
// Distance Compare, Combine, Inf and Zero
template <class VertexListGraph, class DistanceMap, class WeightMap,
class IndexMap, class Params>
inline void
dijkstra_dispatch2
(const VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
DistanceMap distance, WeightMap weight, IndexMap index_map,
const Params& params)
{
// Default for predecessor map
dummy_property_map p_map;
typedef typename property_traits<DistanceMap>::value_type D;
D inf = choose_param(get_param(params, distance_inf_t()),
(std::numeric_limits<D>::max)());
dijkstra_shortest_paths
(g, s,
choose_param(get_param(params, vertex_predecessor), p_map),
distance, weight, index_map,
choose_param(get_param(params, distance_compare_t()),
std::less<D>()),
choose_param(get_param(params, distance_combine_t()),
closed_plus<D>(inf)),
inf,
choose_param(get_param(params, distance_zero_t()),
D()),
choose_param(get_param(params, graph_visitor),
make_dijkstra_visitor(null_visitor())),
params);
}
template <class VertexListGraph, class DistanceMap, class WeightMap,
class IndexMap, class Params>
inline void
dijkstra_dispatch1
(const VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
DistanceMap distance, WeightMap weight, IndexMap index_map,
const Params& params)
{
// Default for distance map
typedef typename property_traits<WeightMap>::value_type D;
typename std::vector<D>::size_type
n = is_default_param(distance) ? num_vertices(g) : 1;
std::vector<D> distance_map(n);
detail::dijkstra_dispatch2
(g, s, choose_param(distance, make_iterator_property_map
(distance_map.begin(), index_map,
distance_map[0])),
weight, index_map, params);
}
} // namespace detail
// Named Parameter Variant
template <class VertexListGraph, class Param, class Tag, class Rest>
inline void
dijkstra_shortest_paths
(const VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
const bgl_named_params<Param,Tag,Rest>& params)
{
// Default for edge weight and vertex index map is to ask for them
// from the graph. Default for the visitor is null_visitor.
detail::dijkstra_dispatch1
(g, s,
get_param(params, vertex_distance),
choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
choose_const_pmap(get_param(params, vertex_index), g, vertex_index),
params);
}
} // namespace boost
#ifdef BOOST_GRAPH_USE_MPI
# include <boost/graph/distributed/dijkstra_shortest_paths.hpp>
#endif
#endif // BOOST_GRAPH_DIJKSTRA_HPP

View File

@ -20,13 +20,6 @@
#include <CGAL/boost/graph/IO/STL.h> #include <CGAL/boost/graph/IO/STL.h>
#include <CGAL/boost/graph/IO/VTK.h> #include <CGAL/boost/graph/IO/VTK.h>
#include <CGAL/boost/graph/IO/WRL.h> #include <CGAL/boost/graph/IO/WRL.h>
\param os the output stream
\param g the graph to be written
\param os the output stream
\param g the graph to be written
\param is the input stream
\param g the graph to be read
#include <CGAL/boost/graph/IO/polygon_mesh_io.h> #include <CGAL/boost/graph/IO/polygon_mesh_io.h>
#endif // CGAL_BOOST_GRAPH_IO_H #endif // CGAL_BOOST_GRAPH_IO_H

View File

@ -1,18 +1,8 @@
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
//=======================================================================
// Copyright (c) 2007-2015 GeometryFactory (France). All rights reserved. // Copyright (c) 2007-2015 GeometryFactory (France). All rights reserved.
// //
// $URL$ // $URL$
// $Id$ // $Id$
// SPDX-License-Identifier: BSL-1.0 // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
// //
// Author(s) : Andreas Fabri, Fernando Cacciola, Jane Tournois // Author(s) : Andreas Fabri, Fernando Cacciola, Jane Tournois
@ -299,7 +289,6 @@ CGAL_DEF_GET_INITIALIZED_INDEX_MAP(face, typename boost::graph_traits<Graph>::fa
> ::type type; > ::type type;
}; };
namespace internal { namespace internal {
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_nested_type_iterator, iterator, false) BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_nested_type_iterator, iterator, false)
} }

View File

@ -15,7 +15,7 @@ CGAL_add_named_parameter(halfedge_index_t, halfedge_index, halfedge_index_map)
CGAL_add_named_parameter(edge_index_t, edge_index, edge_index_map) CGAL_add_named_parameter(edge_index_t, edge_index, edge_index_map)
CGAL_add_named_parameter(face_index_t, face_index, face_index_map) CGAL_add_named_parameter(face_index_t, face_index, face_index_map)
CGAL_add_named_parameter(vertex_index_t, vertex_index, vertex_index_map) CGAL_add_named_parameter(vertex_index_t, vertex_index, vertex_index_map)
CGAL_add_named_parameter(graph_visitor_t, graph_visitor, visitor) CGAL_add_named_parameter(visitor_t, visitor, visitor)
CGAL_add_named_parameter(point_t, point_map, point_map) CGAL_add_named_parameter(point_t, point_map, point_map)
@ -186,7 +186,6 @@ CGAL_add_named_parameter(pca_plane_t, pca_plane, pca_plane)
CGAL_add_named_parameter(remesh_boundaries_t, remesh_boundaries, remesh_boundaries) CGAL_add_named_parameter(remesh_boundaries_t, remesh_boundaries, remesh_boundaries)
CGAL_add_named_parameter(cell_selector_t, cell_selector, cell_selector) CGAL_add_named_parameter(cell_selector_t, cell_selector, cell_selector)
CGAL_add_named_parameter(facet_is_constrained_t, facet_is_constrained, facet_is_constrained_map) CGAL_add_named_parameter(facet_is_constrained_t, facet_is_constrained, facet_is_constrained_map)
CGAL_add_named_parameter(remeshing_visitor_t, remeshing_visitor, remeshing_visitor)
CGAL_add_named_parameter(smooth_constrained_edges_t, smooth_constrained_edges, smooth_constrained_edges) CGAL_add_named_parameter(smooth_constrained_edges_t, smooth_constrained_edges, smooth_constrained_edges)
// output parameters // output parameters

View File

@ -83,6 +83,8 @@ create_single_source_cgal_program( "test_Face_filtered_graph.cpp" )
create_single_source_cgal_program( "test_Euler_operations.cpp" ) create_single_source_cgal_program( "test_Euler_operations.cpp" )
create_single_source_cgal_program( "test_test_face.cpp" )
create_single_source_cgal_program( "test_Collapse_edge.cpp" ) create_single_source_cgal_program( "test_Collapse_edge.cpp" )
create_single_source_cgal_program( "test_graph_traits.cpp" ) create_single_source_cgal_program( "test_graph_traits.cpp" )

View File

@ -28,7 +28,7 @@ void test(const NamedParameters& np)
// Named parameters that we use in CGAL // Named parameters that we use in CGAL
assert(get_parameter(np, CGAL::internal_np::vertex_index).v == 0); assert(get_parameter(np, CGAL::internal_np::vertex_index).v == 0);
assert(get_parameter(np, CGAL::internal_np::graph_visitor).v == 1); assert(get_parameter(np, CGAL::internal_np::visitor).v == 1);
assert(get_parameter(np, CGAL::internal_np::vertex_point).v == 2); assert(get_parameter(np, CGAL::internal_np::vertex_point).v == 2);
assert(get_parameter(np, CGAL::internal_np::halfedge_index).v == 3); assert(get_parameter(np, CGAL::internal_np::halfedge_index).v == 3);
assert(get_parameter(np, CGAL::internal_np::edge_index).v == 4); assert(get_parameter(np, CGAL::internal_np::edge_index).v == 4);
@ -130,7 +130,7 @@ void test(const NamedParameters& np)
// Named parameters that we use in CGAL // Named parameters that we use in CGAL
check_same_type<0>(get_parameter(np, CGAL::internal_np::vertex_index)); check_same_type<0>(get_parameter(np, CGAL::internal_np::vertex_index));
check_same_type<1>(get_parameter(np, CGAL::internal_np::graph_visitor)); check_same_type<1>(get_parameter(np, CGAL::internal_np::visitor));
check_same_type<2>(get_parameter(np, CGAL::internal_np::vertex_point)); check_same_type<2>(get_parameter(np, CGAL::internal_np::vertex_point));
check_same_type<3>(get_parameter(np, CGAL::internal_np::halfedge_index)); check_same_type<3>(get_parameter(np, CGAL::internal_np::halfedge_index));
check_same_type<4>(get_parameter(np, CGAL::internal_np::edge_index)); check_same_type<4>(get_parameter(np, CGAL::internal_np::edge_index));

View File

@ -0,0 +1,60 @@
#include <CGAL/Surface_mesh.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/boost/graph/Euler_operations.h>
#include <vector>
#include <iostream>
typedef CGAL::Simple_cartesian<double> K;
typedef K::Point_3 Point_3;
typedef CGAL::Surface_mesh<Point_3> SM;
typedef boost::graph_traits<SM>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<SM>::vertex_iterator vertex_iterator;
typedef std::vector<vertex_descriptor> V;
int main()
{
{
SM sm;
vertex_descriptor vp = CGAL::add_vertex(sm);
vertex_descriptor vq = CGAL::add_vertex(sm);
vertex_descriptor vr = CGAL::add_vertex(sm);
vertex_descriptor vs = CGAL::add_vertex(sm);
std::array<vertex_descriptor,0> face0;
assert( ! CGAL::Euler::can_add_face(face0,sm) );
std::array<vertex_descriptor,1> face1;
assert( ! CGAL::Euler::can_add_face(face1,sm) );
std::array<vertex_descriptor,2> face2;
assert( ! CGAL::Euler::can_add_face(face2,sm) );
std::array<vertex_descriptor,3> face = { vp, vq, vr };
CGAL::Euler::add_face(face, sm);
assert( ! CGAL::Euler::can_add_face(face,sm) );
std::swap(face[0],face[1]);
assert( CGAL::Euler::can_add_face(face,sm) );
face[2] = vs;
assert( CGAL::Euler::can_add_face(face,sm) );
std::swap(face[0],face[1]);
assert( ! CGAL::Euler::can_add_face(face,sm) );
}
{
SM sm;
Point_3 p(0,0,0), q(1,0,0), r(0,1,0), s(0,0,1);
CGAL::make_tetrahedron(p, q, r, s, sm);
std::array<vertex_descriptor,3> face;
vertex_iterator it = vertices(sm).first;
face[0] = *it;
++it;
face[1] = *it;
face[2] = CGAL::add_vertex(sm);
assert( ! CGAL::Euler::can_add_face(face,sm) );
std::swap(face[0],face[1]);
assert( ! CGAL::Euler::can_add_face(face,sm) );
}
return 0;
}

View File

@ -9,37 +9,16 @@ namespace CGAL {
\authors Kaspar Fischer, Bernd G&auml;rtner, Thomas Herrmann, Michael Hoffmann, and Sven Sch&ouml;nherr \authors Kaspar Fischer, Bernd G&auml;rtner, Thomas Herrmann, Michael Hoffmann, and Sven Sch&ouml;nherr
\image html ball.png \image html ball.png
\image latex ball.png
This chapter describes algorithms which for a given point set compute This chapter describes algorithms which for a given point set compute
the <i>best</i> circumscribing object from a specific the <i>best</i> circumscribing object from a specific
class. If the class consists of all spheres in \f$ d\f$-dimensional class. If the class consists of all spheres in \f$ d\f$-dimensional
Euclidean space and <i>best</i> is defined as having smallest radius, Euclidean space and <i>best</i> is defined as having smallest radius,
then we obtain the smallest enclosing sphere problem already mentioned then we obtain the smallest enclosing sphere.
above.
In the following example a smallest enclosing circle
(`Min_circle_2<Traits>`) is constructed from points
on a line and written to standard output. The example
shows that it is advisable to switch on random shuffling
in order to deal with a <i>bad</i> order of the input points.
\cgalExample{Min_circle_2/min_circle_2.cpp}
Other classes for which we provide solutions are ellipses \section SectBoundingIntroduction Introduction
(`Min_ellipse_2<Traits>`), rectangles
(`min_rectangle_2()`), parallelograms
(`min_parallelogram_2()`) and strips (`min_strip_2()`)
in the plane, with appropriate optimality criteria. For arbitrary
dimensions we provide smallest enclosing spheres for points
(`Min_sphere_d<Traits>`) and spheres for spheres
(`Min_sphere_of_spheres_d<Traits>`), smallest enclosing
annuli (`Min_annulus_d<Traits>`), and approximate
minimum-volume enclosing ellipsoid with user-specified
approximation ratio (`Approximate_min_ellipsoid_d<Traits>`).
\image html annulus.png
\image latex annulus.png
Bounding volumes can be used to obtain simple approximations of Bounding volumes can be used to obtain simple approximations of
complicated objects. For example, consider the problem of deciding complicated objects. For example, consider the problem of deciding
@ -60,13 +39,74 @@ geometric properties of objects. For example, the smallest enclosing
annulus of a point set can be used to test whether a set of points is annulus of a point set can be used to test whether a set of points is
approximately cospherical. Here, the width of the annulus (or its approximately cospherical. Here, the width of the annulus (or its
area, or still another criterion that we use) is a good measure for area, or still another criterion that we use) is a good measure for
this property. The largest area triangle is for example used in this property.
heuristics for matching archaeological aerial photographs. Largest
perimeter triangles are used in scoring cross country soaring flights, \section SectBoundingSphere Bounding Spheres in dD
where the goal is basically to fly as far as possible, but still
return to the departure airfield. To score simply based on the total We provide the class `Min_sphere_of_spheres_d<Traits>` for arbitrary dimensions
distance flown is not a good measure, since circling in thermals to compute the smallest enclosing spheres for points as well as for spheres.
allows to increase it easily. The dimension as well as the input type depend on the chosen traits class.
The following example is for 2D points
\cgalExample{Min_circle_2/min_circle_2.cpp}
The example for 2D circles as input looks rather similar.
\cgalExample{Min_sphere_of_spheres_d/min_sphere_of_spheres_d_2.cpp}
\subsection SectBoundingSphereHomogeneous Bounding Spheres for the Homogeneous Kernel
In the previous section we saw that we used `Min_sphere_of_spheres_d`
to compute the smallest circle for points. This package also provides
the classes `Min_circle_2` and `Min_sphere_d`, but they are slower,
and they should only be used in case of homogeneous coordinates which
are not supported by `Min_sphere_of_spheres_d`.
In the following example a smallest enclosing circle
(`Min_circle_2<Traits>`) is constructed from points
on a line and written to standard output. The example
shows that it is advisable to switch on random shuffling
in order to deal with a <i>bad</i> order of the input points.
\cgalExample{Min_circle_2/min_circle_homogeneous_2.cpp}
\section SectBoundingAnnulus Bounding Annulus in dD
We provide the class `Min_annulus_d<Traits>` for arbitrary dimensions
to compute the smalles enclosing annulus for a set of points.
In 2D the annulus consists of two concentric circles, in 3D of
two concentric spheres.
\image html annulus.png
\section SectBounding2D Various Bounding Areas in 2D
Other classes for which we provide solutions are ellipses
(`Min_ellipse_2<Traits>`), rectangles
(`min_rectangle_2()`), parallelograms
(`min_parallelogram_2()`) and strips (`min_strip_2()`)
in the plane, with appropriate optimality criteria.
\section SectBoundingEllipsoid Approximate Bounding Ellipsoid in dD
While this package provides an exact smallest 2D ellipse, it also
provides the class `Approximate_min_ellipsoid_d<Traits>` to compute
an approximate minimum-volume enclosing ellipsoid with user-specified
approximation ratio.
\section SectBoundingPcenter Rectangular P-Center
Bounding volumes also define geometric "center points" of objects. Bounding volumes also define geometric "center points" of objects.
For example, if two objects are to be matched (approximately), one For example, if two objects are to be matched (approximately), one
@ -81,8 +121,6 @@ planar point set with between two and four minimal boxes
three boxes; the center points are shown in red. three boxes; the center points are shown in red.
\image html pcenter.png \image html pcenter.png
\image latex pcenter.png
*/ */
} /* namespace CGAL */ } /* namespace CGAL */

View File

@ -191,7 +191,7 @@ to iterate over the %Cartesian coordinates of the direction of a fixed
axis of the computed ellipsoid, see axis of the computed ellipsoid, see
`axis_direction_cartesian_begin()`. `axis_direction_cartesian_begin()`.
*/ */
typedef unspecified_type Axis_direction_iterator; typedef unspecified_type Axes_direction_coordinate_iterator;
/// @} /// @}

View File

@ -24,17 +24,17 @@ The underlying algorithm can cope with all kinds of input, e.g. \f$ P\f$ may be
empty or points may occur more than once. The algorithm computes a support empty or points may occur more than once. The algorithm computes a support
set \f$ S\f$ which remains fixed until the next set, insert, or clear operation. set \f$ S\f$ which remains fixed until the next set, insert, or clear operation.
\tparam Traits must be a model for `OptimisationDTraits`. \tparam Traits must be a model for `MinSphereAnnulusDTraits`.
We provide the models `Optimisation_d_traits_2`, We provide the models `Min_sphere_annulus_d_traits_2`,
`Optimisation_d_traits_3`, and `Optimisation_d_traits_d` using the `Min_sphere_annulus_d_traits_3`, and `Min_sphere_annulus_d_traits_d` using the
two-, three-, and \f$ d\f$-dimensional \cgal kernel, respectively. two-, three-, and \f$ d\f$-dimensional \cgal kernel, respectively.
\sa `CGAL::Min_sphere_d<Traits>` \sa `CGAL::Min_sphere_d<Traits>`
\sa `CGAL::Optimisation_d_traits_2<K,ET,NT>` \sa `CGAL::Min_sphere_annulus_d_traits_2<K,ET,NT>`
\sa `CGAL::Optimisation_d_traits_3<K,ET,NT>` \sa `CGAL::Min_sphere_annulus_d_traits_3<K,ET,NT>`
\sa `CGAL::Optimisation_d_traits_d<K,ET,NT>` \sa `CGAL::Min_sphere_annulus_d_traits_d<K,ET,NT>`
\sa `OptimisationDTraits` \sa `MinSphereAnnulusDTraits`
\cgalHeading{Implementation} \cgalHeading{Implementation}

View File

@ -23,9 +23,9 @@ The underlying algorithm can cope with all kinds of input, e.g. \f$ P\f$ may be
empty or points may occur more than once. The algorithm computes a support empty or points may occur more than once. The algorithm computes a support
set \f$ S\f$ which remains fixed until the next insert or clear operation. set \f$ S\f$ which remains fixed until the next insert or clear operation.
<B>Please note:</B> This class is (almost) obsolete. The class \note This class is (almost) obsolete. The class
`CGAL::Min_sphere_of_spheres_d<Traits>` solves a more general problem `CGAL::Min_sphere_of_spheres_d<Traits>` solves a more general problem
and is faster then `Min_circle_2` even if used only for points in two and is faster than `Min_circle_2` even if used only for points in two
dimensions as input. Most importantly, dimensions as input. Most importantly,
`CGAL::Min_sphere_of_spheres_d<Traits>` has `CGAL::Min_sphere_of_spheres_d<Traits>` has
a specialized implementation for floating-point arithmetic which a specialized implementation for floating-point arithmetic which

Some files were not shown because too many files have changed in this diff Show More