Merge branch 'master' into Polygon_mesh_processing-triangulate_hole_with_cdt2-danston

This commit is contained in:
Dmitry Anisimov 2020-10-07 10:55:57 +02:00 committed by GitHub
commit d5b24c4b05
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
862 changed files with 80826 additions and 13796 deletions

10
.gitattributes vendored
View File

@ -5,7 +5,7 @@
# to native line endings on checkout.
*.cpp text
*.c text
*.h text
*.h text linguist-language=C++
*.hpp text
*.tex text
*.txt text
@ -18,7 +18,6 @@
*.js text
*.hmtl text
*.bib text
*.sh text
*.css text
*.ui text
*.qrc text
@ -29,13 +28,18 @@
*.xyz text
*.qhcp text
*.qhp text
*.pwn text
*.pwn text linguist-detectable=false
*.poly text
*.rb text
*.perl text
*.pdb text
# Nef_3 data files
*.EH linguist-detectable=false
*.SH linguist-detectable=false
# Declare files that will always have LF line endings on checkout.
*.sh text eol=lf
Documentation/Doxyfile text eol=lf
Documentation/pkglist_filter text eol=lf
Installation/update_CHANGES text eol=lf

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 -a -m "Add ${PR_NUMBER} $ROUND" && git push -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

@ -1,5 +1,5 @@
language: cpp
dist: xenial
dist: bionic
sudo: required
git:
depth: 3
@ -49,16 +49,16 @@ env:
- PACKAGE='Surface_mesh_parameterization Surface_mesh_segmentation Surface_mesh_shortest_path '
- PACKAGE='Surface_mesh_simplification Surface_mesh_skeletonization Surface_mesh_topology '
- PACKAGE='Surface_mesher Surface_sweep_2 TDS_2 '
- PACKAGE='TDS_3 Testsuite Three '
- PACKAGE='Triangulation Triangulation_2 Triangulation_3 '
- PACKAGE='Union_find Visibility_2 Voronoi_diagram_2 '
- PACKAGE='wininst '
- PACKAGE='TDS_3 Testsuite Tetrahedral_remeshing '
- PACKAGE='Three Triangulation Triangulation_2 '
- PACKAGE='Triangulation_3 Union_find Visibility_2 '
- PACKAGE='Voronoi_diagram_2 wininst '
compiler: clang
install:
- echo "$PWD"
- if [ -n "$TRAVIS_PULL_REQUEST_BRANCH" ] && [ "$PACKAGE" != CHECK ]; then DO_IGNORE=FALSE; for ARG in $(echo "$PACKAGE");do if [ "$ARG" = "Maintenance" ]; then continue; fi; . $PWD/.travis/test_package.sh "$PWD" "$ARG"; echo "DO_IGNORE is $DO_IGNORE"; if [ "$DO_IGNORE" = "FALSE" ]; then break; fi; done; if [ "$DO_IGNORE" = "TRUE" ]; then travis_terminate 0; fi;fi
- /usr/bin/time -f 'Spend time of %C -- %E (real)' bash .travis/install.sh
- export CXX=clang++ CC=clang;
- export CXX=clang++-10 CC=clang-10;
before_script:
- wget -O doxygen_exe https://cgal.geometryfactory.com/~mgimeno/doxygen_exe
- sudo mv doxygen_exe /usr/bin/doxygen

View File

@ -11,7 +11,7 @@ function mytime {
function build_examples {
mkdir -p build-travis
cd build-travis
mytime cmake -DCGAL_DIR="/usr/local/lib/cmake/CGAL" -DCMAKE_CXX_FLAGS="${CXX_FLAGS}" -DCGAL_BUILD_THREE_DOC=TRUE ..
mytime cmake -DCGAL_DIR="/usr/local/lib/cmake/CGAL" -DCMAKE_CXX_FLAGS="${CXX_FLAGS}" ..
mytime make -j2 VERBOSE=1
}
@ -41,6 +41,7 @@ do
continue
fi
cd $ROOT
#install openmesh only if necessary
if [ "$ARG" = "CHECK" ] || [ "$ARG" = BGL ] || [ "$ARG" = Convex_hull_3 ] ||\
[ "$ARG" = Polygon_mesh_processing ] || [ "$ARG" = Property_map ] ||\
@ -92,28 +93,27 @@ cd $ROOT
exit 1
fi
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
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
if [ -n "$TRAVIS_PULL_REQUEST_BRANCH" ] && [ "$ARG" != Polyhedron_demo ]; then
@ -185,6 +185,7 @@ cd $ROOT
cd "$ROOT/$DEMO"
build_demo
fi
done
IFS=$old_IFS
# Local Variables:

View File

@ -2,14 +2,15 @@
[ -n "$CGAL_DEBUG_TRAVIS" ] && set -x
DONE=0
sudo add-apt-repository ppa:mikhailnov/pulseeffects -y
sudo apt-get update
while [ $DONE = 0 ]
do
DONE=1 && sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install clang zsh \
flex bison cmake graphviz libgmp-dev libmpfr-dev libmpfi-dev zlib1g-dev libeigen3-dev libboost-dev \
libboost-system-dev libboost-program-options-dev libboost-thread-dev libboost-iostreams-dev \
DONE=1 && sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install clang-10 zsh \
flex bison cmake graphviz libgmp-dev libmpfr-dev libmpfi-dev zlib1g-dev libeigen3-dev \
qtbase5-dev libqt5sql5-sqlite libqt5opengl5-dev qtscript5-dev libqt5svg5-dev qttools5-dev qttools5-dev-tools qml-module-qtgraphicaleffects libopencv-dev mesa-common-dev libmetis-dev libglu1-mesa-dev \
|| DONE=0 && sudo apt-get update
libboost1.72-dev || DONE=0 && sudo apt-get update
done
exit 0

View File

@ -129,6 +129,7 @@ Surface_sweep_2
TDS_2
TDS_3
Testsuite
Tetrahedral_remeshing
Three
Triangulation
Triangulation_2

View File

@ -1,5 +1,5 @@
language: cpp
dist: xenial
dist: bionic
sudo: required
git:
depth: 3
@ -12,7 +12,7 @@ install:
- echo "$PWD"
- if [ -n "$TRAVIS_PULL_REQUEST_BRANCH" ] && [ "$PACKAGE" != CHECK ]; then DO_IGNORE=FALSE; for ARG in $(echo "$PACKAGE");do if [ "$ARG" = "Maintenance" ]; then continue; fi; . $PWD/.travis/test_package.sh "$PWD" "$ARG"; echo "DO_IGNORE is $DO_IGNORE"; if [ "$DO_IGNORE" = "FALSE" ]; then break; fi; done; if [ "$DO_IGNORE" = "TRUE" ]; then travis_terminate 0; fi;fi
- /usr/bin/time -f 'Spend time of %C -- %E (real)' bash .travis/install.sh
- export CXX=clang++ CC=clang;
- export CXX=clang++-10 CC=clang-10;
before_script:
- wget -O doxygen_exe https://cgal.geometryfactory.com/~mgimeno/doxygen_exe
- sudo mv doxygen_exe /usr/bin/doxygen

View File

@ -45,8 +45,7 @@ Scene::Scene()
m_blue_ramp.build_blue();
m_max_distance_function = (FT)0.0;
texture = new Texture(m_grid_size,m_grid_size);
startTimer(0);
ready_to_cut = false;
ready_to_cut = true;
are_buffers_initialized = false;
gl_init = false;
@ -519,6 +518,7 @@ void Scene::changed()
compute_elements(_UNSIGNED);
else
compute_elements(_SIGNED);
ready_to_cut=false;
are_buffers_initialized = false;
}
@ -1226,12 +1226,16 @@ void Scene::cut_segment_plane()
m_cut_plane = CUT_SEGMENTS;
changed();
}
void Scene::updateCutPlane()
{
ready_to_cut = true;
QTimer::singleShot(0,this,SLOT(cutting_plane()));
}
void Scene::cutting_plane(bool override)
{
if(ready_to_cut || override)
{
ready_to_cut = false;
switch( m_cut_plane )
{
case UNSIGNED_FACETS:
@ -1304,13 +1308,13 @@ void Scene::refine_loop()
void Scene::activate_cutting_plane()
{
connect(m_frame, SIGNAL(modified()), this, SLOT(cutting_plane()));
connect(m_frame, SIGNAL(modified()), this, SLOT(updateCutPlane()));
m_view_plane = true;
}
void Scene::deactivate_cutting_plane()
{
disconnect(m_frame, SIGNAL(modified()), this, SLOT(cutting_plane()));
disconnect(m_frame, SIGNAL(modified()), this, SLOT(updateCutPlane()));
m_view_plane = false;
}
void Scene::initGL()
@ -1326,10 +1330,3 @@ void Scene::initGL()
compile_shaders();
gl_init = true;
}
void Scene::timerEvent(QTimerEvent *)
{
if(manipulatedFrame()->isSpinning())
set_fast_distance(true);
ready_to_cut = true;
}

View File

@ -173,6 +173,8 @@ private:
void attrib_buffers(CGAL::QGLViewer*);
void compile_shaders();
void compute_texture(int, int, Color_ramp, Color_ramp);
private slots:
void updateCutPlane();
public:
// file menu
@ -251,8 +253,6 @@ public:
void activate_cutting_plane();
void deactivate_cutting_plane();
//timer sends a top when all the events are finished
void timerEvent(QTimerEvent *);
public slots:

View File

@ -189,7 +189,7 @@ example illustrates this for two polyhedral surfaces.
\subsection aabb_tree_examples_7 Trees of Custom Primitives
The AABB tree example folder contains three examples of trees
constructed with customize primitives. In \ref AABB_tree/AABB_custom_example.cpp "AABB_custom_example.cpp"
constructed with custom primitives. In \ref AABB_tree/AABB_custom_example.cpp "AABB_custom_example.cpp"
the primitive contains triangles which are defined by three pointers
to custom points. In \ref AABB_tree/AABB_custom_triangle_soup_example.cpp "AABB_custom_triangle_soup_example.cpp" all input
triangles are stored into a single array so as to form a triangle

View File

@ -112,7 +112,7 @@ public:
/*!
Id type:
- `boost::graph_traits<FaceGraph>::%face_descriptor` if `OneFaceGraphPerTree` is `CGAL::Tag_true`
- `std::pair<boost::graph_traits<FaceGraph>::%face_descriptor, FaceGraph>` if `OneFaceGraphPerTree` is `CGAL::Tag_false`
- `std::pair<boost::graph_traits<FaceGraph>::%face_descriptor, const FaceGraph*>` if `OneFaceGraphPerTree` is `CGAL::Tag_false`
*/
unspecified_type Id;

View File

@ -125,8 +125,8 @@ public:
typedef Kernel_traits<Point>::Kernel::Segment_3 Datum;
/*!
Id type:
- `boost::graph_traits<HalfedgeGraph>::%edge_descriptor if `OneHalfedgeGraphPerTree` is `Tag_true`
- `std::pair<boost::graph_traits<HalfedgeGraph>::edge_descriptor, HalfedgeGraph>` if `OneHalfedgeGraphPerTree` is `Tag_false`
- `boost::graph_traits<HalfedgeGraph>::%edge_descriptor` if `OneHalfedgeGraphPerTree` is `Tag_true`
- `std::pair<boost::graph_traits<HalfedgeGraph>::%edge_descriptor, const HalfedgeGraph*>` if `OneHalfedgeGraphPerTree` is `Tag_false`
*/
unspecified_type Id;
/// @}
@ -202,4 +202,3 @@ public:
#include <CGAL/enable_warnings.h>
#endif // CGAL_AABB_HALFEDGE_GRAPH_SEGMENT_PRIMITIVE_H

View File

@ -171,9 +171,11 @@ class AABB_tree;
/// \sa `AABBPrimitiveWithSharedData`
template<typename GeomTraits, typename AABBPrimitive, typename BboxMap = Default>
class AABB_traits:
public internal::AABB_tree::AABB_traits_base<AABBPrimitive>,
class AABB_traits
#ifndef DOXYGEN_RUNNING
: public internal::AABB_tree::AABB_traits_base<AABBPrimitive>,
public internal::AABB_tree::AABB_traits_base_2<GeomTraits>
#endif
{
typedef typename CGAL::Object Object;
public:

View File

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

View File

@ -1,6 +1,7 @@
#include <iostream>
#include <fstream>
#include <algorithm>
#include <array>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Shape_detection/Efficient_RANSAC.h>
@ -36,7 +37,7 @@ typedef CGAL::Triangulation_data_structure_3<LVb,LCb> Tds;
typedef CGAL::Delaunay_triangulation_3<Kernel,Tds> Triangulation_3;
typedef Triangulation_3::Vertex_handle Vertex_handle;
typedef CGAL::cpp11::array<std::size_t,3> Facet;
typedef std::array<std::size_t,3> Facet;
// Functor to init the advancing front algorithm with indexed points

View File

@ -1,10 +1,10 @@
#include <iostream>
#include <fstream>
#include <algorithm>
#include <array>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Advancing_front_surface_reconstruction.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/array.h>
#include <CGAL/disable_warnings.h>
typedef std::array<std::size_t,3> Facet;

View File

@ -660,23 +660,33 @@ public:
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
{
private:
Traits& _traits;
public:
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()));
re_cast_object_vector(res,oi);
return (oi);
}
private:
class Make_x_monotone_2_visitor
: public boost::static_visitor < Object_vector >
class Make_x_monotone_2_visitor :
public boost::static_visitor < Object_vector >
{
private:
typedef boost::static_visitor <Object_vector> Base;
@ -1787,4 +1797,3 @@ public:
#endif // CGAL_DONT_SUBMIT
#endif //CGAL_ARR_RATIONAL_ARC_TRAITS_D_1_H

View File

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

View File

@ -22,8 +22,8 @@ ArrangementDemoGraphicsView::ArrangementDemoGraphicsView( QWidget* parent ) :
gridColor( ::Qt::black ),
backgroundColor( ::Qt::white )
{
QMatrix m( 1.0, 0.0, 0.0, -1.0, 0.0, 0.0 );
this->setMatrix( m );
QTransform m( 1.0, 0.0, 0.0, -1.0, 0.0, 0.0 );
this->setTransform( m );
this->setBackgroundBrush( QBrush( backgroundColor ) );
}

View File

@ -43,7 +43,7 @@ class ArrangementDemoPropertiesDialog : public QDialog
};
ArrangementDemoPropertiesDialog( ArrangementDemoWindow* parent_ = 0,
Qt::WindowFlags f = 0 );
Qt::WindowFlags f = Qt::WindowType(0));
QVariant property( int index );
protected:

View File

@ -14,7 +14,7 @@
#include "ui_NewTabDialog.h"
#include <QButtonGroup>
NewTabDialog::NewTabDialog( QWidget* parent, Qt::WindowFlags f ) :
NewTabDialog::NewTabDialog( QWidget* parent, Qt::WindowFlags f) :
QDialog( parent, f ),
ui( new Ui::NewTabDialog ),
buttonGroup( new QButtonGroup )

View File

@ -23,7 +23,7 @@ namespace Ui
class NewTabDialog : public QDialog
{
public:
NewTabDialog( QWidget* parent = 0, Qt::WindowFlags f = 0 );
NewTabDialog( QWidget* parent = 0, Qt::WindowFlags f = Qt::WindowType(0) );
int checkedId( ) const;
protected:

View File

@ -29,7 +29,7 @@ class OverlayDialog : public QDialog
ARRANGEMENT = 32
} OverlayDialogRole;
OverlayDialog( ArrangementDemoWindow* parent, Qt::WindowFlags f = 0 );
OverlayDialog( ArrangementDemoWindow* parent, Qt::WindowFlags f = Qt::WindowType(0) );
std::vector< CGAL::Object > selectedArrangements( ) const;

View File

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

View File

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

View File

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

View File

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

View File

@ -25,106 +25,102 @@ typedef CORE::BigInt Integer;
typedef LEDA::integer Integer;
#endif
typedef CGAL::Arr_algebraic_segment_traits_2<Integer> Arr_traits_2;
typedef CGAL::Arrangement_2<Arr_traits_2> Arrangement_2;
typedef Arr_traits_2::Curve_2 Curve_2;
typedef Arr_traits_2::Polynomial_2 Polynomial_2;
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::Point_2 Point_2;
typedef CGAL::Arr_algebraic_segment_traits_2<Integer> Arr_traits_2;
typedef CGAL::Arrangement_2<Arr_traits_2> Arrangement_2;
typedef Arr_traits_2::Curve_2 Curve_2;
typedef Arr_traits_2::Polynomial_2 Polynomial_2;
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::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
= 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();
std::vector<X_monotone_curve_2> segs;
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);
Polynomial_2 y = CGAL::shift(Polynomial_2(1),1,1);
// Construct point on the upper arc (counting of arc numbers starts with 0!
Point_2 p11 = construct_point(Algebraic_real_1(0),cv1,1);
// 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<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_x_monotone_segment(cv1,p11,Arr_traits_2::POINT_IN_INTERIOR,
std::back_inserter(segs));
// Construct point on the upper arc (counting of arc numbers starts with 0!
Point_2 p11 = construct_point(Algebraic_real_1(0),cv1,1);
// Construct a vertical cusp x^2-y^3=0
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));
// Construct a vertical cusp x^2-y^3=0
Curve_2 cv2 = construct_curve(CGAL::ipower(x,2)-CGAL::ipower(y,3));
// Construct another conic: y^2-x^2+1
Curve_2 cv3 = construct_curve(CGAL::ipower(y,2)-CGAL::ipower(x,2)+1);
// 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));
Point_2 p31 = construct_point(Algebraic_real_1(2),cv3,1);
construct_x_monotone_segment(cv3,p31,Arr_traits_2::MAX_ENDPOINT,
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));
// Construct a vertical segment
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));
// Construct another conic: y^2-x^2+1
Curve_2 cv3 = construct_curve(CGAL::ipower(y,2)-CGAL::ipower(x,2)+1);
CGAL::insert(arr,segs.begin(),segs.end());
Point_2 p31 = construct_point(Algebraic_real_1(2),cv3,1);
construct_x_monotone_segment(cv3,p31,Arr_traits_2::MAX_ENDPOINT,
std::back_inserter(segs));
// Add some isolated points (must be wrapped into CGAL::Object)
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))));
// Construct a vertical segment
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,isolated_points.begin(), isolated_points.end());
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)
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;
return 0;
}
#endif

View File

@ -8,16 +8,20 @@
#include <list>
typedef CGAL::Exact_predicates_inexact_constructions_kernel 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 Arrangement_2::Vertex_const_handle Vertex_const_handle;
typedef Arrangement_2::Halfedge_const_handle Halfedge_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 std::list<Vert_decomp_entry> Vert_decomp_list;
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 Arrangement_2::Vertex_const_handle Vertex_const_handle;
typedef Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
typedef 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_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()
{
@ -39,34 +43,41 @@ int main()
CGAL::decompose(arr, std::back_inserter(vd_list));
// Print the results.
Vert_decomp_list::const_iterator vd_iter;
for (vd_iter = vd_list.begin(); vd_iter != vd_list.end(); ++vd_iter) {
const Object_pair& curr = vd_iter->second;
for (auto vd_iter = vd_list.begin(); vd_iter != vd_list.end(); ++vd_iter) {
const Vert_decomp_pair& curr = vd_iter->second;
std::cout << "Vertex (" << vd_iter->first->point() << ") : ";
Vertex_const_handle vh;
Halfedge_const_handle hh;
Face_const_handle fh;
std::cout << " feature below: ";
if (CGAL::assign(hh, curr.first))
std::cout << '[' << hh->curve() << ']';
else if (CGAL::assign(vh, curr.first))
std::cout << '(' << vh->point() << ')';
else if (CGAL::assign(fh, curr.first))
std::cout << "NONE";
else
std::cout << "EMPTY";
if (! curr.first) std::cout << "EMPTY";
else {
auto* vh = boost::get<Vertex_const_handle>(&*(curr.first));
if (vh) std::cout << '(' << (*vh)->point() << ')';
else {
auto* hh = boost::get<Halfedge_const_handle>(&*(curr.first));
if (hh) std::cout << '[' << (*hh)->curve() << ']';
else {
auto* fh = boost::get<Face_const_handle>(&*(curr.first));
CGAL_assertion(fh);
std::cout << "NONE (" << (*fh)->is_unbounded() << ")";
}
}
}
std::cout << " feature above: ";
if (CGAL::assign(hh, curr.second))
std::cout << '[' << hh->curve() << ']' << std::endl;
else if (CGAL::assign(vh, curr.second))
std::cout << '(' << vh->point() << ')' << std::endl;
else if (CGAL::assign(fh, curr.second))
std::cout << "NONE" << std::endl;
else
std::cout << "EMPTY" << std::endl;
if (! curr.second) std::cout << "EMPTY" << std::endl;
else {
auto* vh = boost::get<Vertex_const_handle>(&*(curr.second));
if (vh) std::cout << '(' << (*vh)->point() << ')' << std::endl;
else {
auto* hh = boost::get<Halfedge_const_handle>(&*(curr.second));
if (hh) std::cout << '[' << (*hh)->curve() << ']' << 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;

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::X_monotone_curve_2 Bezier_x_curve_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 CGAL::Arrangement_2<Polycurve_bezier_traits_2> Arrangement_2;
typedef boost::variant<Point_2, Bezier_x_curve_2> Make_x_monotone_result;
int main()
{
Polycurve_bezier_traits_2 pc_traits;
Bezier_traits bezier_traits;
Polycurve_bezier_traits_2::Construct_x_monotone_curve_2
construct_x_mono_polycurve =
auto construct_x_mono_polycurve =
pc_traits.construct_x_monotone_curve_2_object();
std::vector<Bezier_x_curve_2> x_bezier_curves;
@ -69,11 +71,11 @@ int main()
// Read the current curve (specified by its control points).
in_file >> B;
//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_x_curve_2 x_seg =
CGAL::object_cast<Bezier_x_curve_2>((obj_vector[0]));
x_curves.push_back(x_seg);
auto* x_seg_p = boost::get<Bezier_x_curve_2>(&obj_vector[0]);
CGAL_assertion(x_seg_p);
x_curves.push_back(*x_seg_p);
}
X_mono_polycurve polycurve =

View File

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

View File

@ -7,9 +7,9 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Ron Wein <wein@post.tau.ac.il>
// Iddo Hanniel <iddoh@cs.technion.ac.il>
// Waqar Khan <wkhan@mpi-inf.mpg.de>
// Author(s): Ron Wein <wein@post.tau.ac.il>
// Iddo Hanniel <iddoh@cs.technion.ac.il>
// Waqar Khan <wkhan@mpi-inf.mpg.de>
#ifndef 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
@ -473,33 +473,34 @@ public:
{
return (Equal_2 (p_cache));
}
//@}
//! \name Intersections, subdivisions, and mergings
//@{
/*! \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:
Bezier_cache *p_cache;
Bezier_cache* p_cache;
public:
/*! Constructor. */
Make_x_monotone_2 (Bezier_cache *cache) :
p_cache (cache)
{}
Make_x_monotone_2(Bezier_cache* cache) : p_cache(cache) {}
/*!
* Cut the given Bezier curve into x-monotone subcurves and insert them
* into the given output iterator.
* \param cv The curve.
* \param oi The output iterator, whose value-type is Object. The returned
* objects is a wrapper for an X_monotone_curve_2 object.
* \return The past-the-end iterator.
/*! Subdivide a given Bezier 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>
template <typename OutputIterator>
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
Vertical_tangency_point;
@ -512,20 +513,17 @@ public:
std::back_inserter(cpts));
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.
std::list<Point_2> vpts;
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_bbox& bbox = iter->bbox;
if (! bound.can_refine)
{
if (! bound.can_refine) {
// If we cannot refine the vertical-tangency bound anymore, then
// we failed to bound the vertical tangency point.
// \todo In the future, we might want to use the info.
@ -534,28 +532,25 @@ public:
}
// 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);
Rational t0 = bound.t_min;
Rational t0 = bound.t_min;
pt = Point_2 (B, t0);
}
else
{
pt.add_originator (typename Point_2::Originator(B, bound));
else {
pt.add_originator(typename Point_2::Originator(B, bound));
}
pt.set_bbox (bbox);
pt.set_bbox(bbox);
vpts.push_back(pt);
}
// If bounding the approximated vertical-tangency points went fine,
// use these points as endpoint for the x-monotone subcurves.
if (app_ok)
{
if (app_ok) {
// Create the x-monotone subcurves with approximate endpoints.
typename std::list<Point_2>::const_iterator pit;
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),
// for handling end case of start point == end point.
for (pit = vpts.begin(); pit != vpts.end(); ++pit)
{
*oi++ = CGAL::make_object (X_monotone_curve_2 (B, xid,
p0, *pit,
*p_cache));
for (pit = vpts.begin(); pit != vpts.end(); ++pit) {
*oi++ = Make_x_monotone_result(X_monotone_curve_2(B, xid, p0, *pit,
*p_cache));
xid++;
p0 = *pit;
}
Point_2 p1(B, xid, Rational(1)); // A rational end point.
*oi++ = CGAL::make_object (X_monotone_curve_2 (B, xid,
p0, p1,
*p_cache));
*oi++ = Make_x_monotone_result(X_monotone_curve_2(B, xid, p0, p1,
*p_cache));
return (oi);
}
@ -583,41 +575,34 @@ public:
// 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.
const typename Bezier_cache::Vertical_tangency_list&
vt_list = p_cache->get_vertical_tangencies (B.id(),
B.x_polynomial(),
B.x_norm());
vt_list = p_cache->get_vertical_tangencies(B.id(), B.x_polynomial(),
B.x_norm());
// Create the x-monotone subcurves.
Point_2 p1;
typename Bezier_cache::Vertical_tangency_iter it;
unsigned int xid = 1; // Serial number of the subcurve.
Point_2 p0 (B, xid, Rational(0));
Point_2 p1;
unsigned int xid = 1; // Serial number of the subcurve.
Point_2 p0(B, xid, Rational(0));
for (it = vt_list.begin(); it != vt_list.end(); ++it)
{
p1 = Point_2 (B, *it);
*oi++ = CGAL::make_object (X_monotone_curve_2 (B, xid,
p0, p1,
*p_cache));
for (auto it = vt_list.begin(); it != vt_list.end(); ++it) {
p1 = Point_2(B, *it);
*oi++ = Make_x_monotone_result(X_monotone_curve_2(B, xid, p0, p1,
*p_cache));
xid++;
p0 = p1;
}
// Create the final subcurve.
p1 = Point_2 (B, xid, Rational(1));
*oi++ = CGAL::make_object (X_monotone_curve_2 (B, xid,
p0, p1,
*p_cache));
return (oi);
p1 = Point_2(B, xid, Rational(1));
*oi++ = Make_x_monotone_result(X_monotone_curve_2(B, xid, p0, p1,
*p_cache));
return oi;
}
};
/*! Get a Make_x_monotone_2 functor object. */
Make_x_monotone_2 make_x_monotone_2_object () const
{
return (Make_x_monotone_2 (p_cache));
}
Make_x_monotone_2 make_x_monotone_2_object() const
{ return (Make_x_monotone_2 (p_cache)); }
/*! \class Split_2
* The Split_2 functor.
@ -756,7 +741,6 @@ public:
{
return Merge_2(this);
}
//@}
/// \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/Arr_point_location_result.h>
namespace CGAL {
@ -60,6 +61,9 @@ private:
typedef typename Arrangement_2::DInner_ccb DInner_ccb;
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:
Arrangement_2* p_arr; // The associated arrangement.
@ -99,33 +103,29 @@ public:
* This object may wrap a Face_const_handle (the general case),
* or a Halfedge_const_handle (in case of an overlap).
*/
CGAL::Object locate_curve_end(const X_monotone_curve_2& cv,
Arr_curve_end ind,
Arr_parameter_space ps_x,
Arr_parameter_space ps_y) const
Pl_result_type locate_curve_end(const X_monotone_curve_2& cv,
Arr_curve_end ind,
Arr_parameter_space ps_x,
Arr_parameter_space ps_y) const
{
CGAL_precondition((ps_x != ARR_INTERIOR) || (ps_y != ARR_INTERIOR));
// Use the topology traits to locate the unbounded curve end.
CGAL::Object obj =
p_arr->topology_traits()->locate_curve_end(cv, ind, ps_x, ps_y);
auto obj = p_arr->topology_traits()->locate_curve_end(cv, ind, ps_x, ps_y);
// Return a handle to the DCEL feature.
DFace* f;
if (CGAL::assign(f, obj))
return (CGAL::make_object(p_arr->_const_handle_for(f)));
DFace** f_p = boost::get<DFace*>(&obj);
if (f_p) return (Pl_result::make_result(p_arr->_const_handle_for(*f_p)));
DHalfedge* he;
if (CGAL::assign(he, obj))
return (CGAL::make_object(p_arr->_const_handle_for(he)));
DHalfedge** he_p = boost::get<DHalfedge*>(&obj);
if (he_p) return (Pl_result::make_result(p_arr->_const_handle_for(*he_p)));
DVertex* v;
if (CGAL::assign(v, obj))
return (CGAL::make_object(p_arr->_const_handle_for(v)));
DVertex** v_p = boost::get<DVertex*>(&obj);
if (v_p) return (Pl_result::make_result(p_arr->_const_handle_for(*v_p)));
// We should never reach here:
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
//
//
// 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
x_monotone_segment (Curve_2 cv,
Point_2 p,
boost::optional<Point_2> start,
boost::optional<Point_2> end,
OutputIterator out) const {
template <typename OutputIterator> OutputIterator
x_monotone_segment(Curve_2 cv,
Point_2 p,
boost::optional<Point_2> start,
boost::optional<Point_2> end,
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();
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;
Is_on_2 on_arc = this->_ckva()->is_on_2_object();
auto left = this->_ckva()->construct_min_vertex_2_object();
auto right = this->_ckva()->construct_max_vertex_2_object();
Equal_2 equal = this->_ckva()->equal_2_object();
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:
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.
* \pre The value-type of PointsIterator is Arrangement::Point_2,
* and the value-type of OutputIterator is is pair<Point_2, Result>,
* where Result is either
* (i) Object or
* (ii) boost::optional<boost::variant<Vertex_const_handle,
* Halfedge_const_handle,
* Face_const_handle> >.
* where Result is boost::optional<boost::variant<Vertex_const_handle,
* Halfedge_const_handle,
* Face_const_handle> >.
* It represents the arrangement feature containing the point.
*/
template <typename GeometryTraits_2, typename TopologyTraits,

View File

@ -7,14 +7,15 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Eric Berberich <ericb@post.tau.ac.il>
// Author(s): Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Eric Berberich <ericb@post.tau.ac.il>
#ifndef 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/disable_warnings.h>
@ -306,17 +307,18 @@ public:
* \param ps_x The boundary condition of the curve end in x.
* \param ps_y The boundary condition of the curve end in 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*,
const X_monotone_curve_2&,
Arr_curve_end,
Arr_parameter_space /* ps_x */,
Arr_parameter_space /* ps_y */)
boost::optional<boost::variant<Vertex*, Halfedge*> >
place_boundary_vertex(Face*,
const X_monotone_curve_2&,
Arr_curve_end,
Arr_parameter_space /* ps_x */,
Arr_parameter_space /* ps_y */)
{
// This function should never be called:
CGAL_error();
return Object();
return boost::none;
}
/*! 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.
* \return An object that contains the curve end.
*/
CGAL::Object locate_curve_end(const X_monotone_curve_2&,
Arr_curve_end,
Arr_parameter_space /* ps_x */,
Arr_parameter_space /* ps_y */)
boost::variant<Vertex*, Halfedge*, Face*>
locate_curve_end(const X_monotone_curve_2&,
Arr_curve_end,
Arr_parameter_space /* ps_x */,
Arr_parameter_space /* ps_y */)
{
typedef boost::variant<Vertex*, Halfedge*, Face*> Result;
// This function should never be called:
CGAL_error();
return Object();
Vertex* v(nullptr);
return Result(v);
}
/*! 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:
typedef Arr_circle_segment_traits_2<Kernel_, Filter> Self;
bool m_use_cache;
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)
{}
/*!
* Cut the given conic curve (ocv.is_in_x_range (p)r conic arc) into x-monotone subcurves
* and insert them to the given output iterator.
* \param cv The curve.
* \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.
/*! 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
* variant that wraps a \c Point_2 or an \c X_monotone_curve_2
* objects.
* \return the past-the-end iterator.
*/
template<class OutputIterator>
OutputIterator operator() (const Curve_2& cv, OutputIterator oi) const
template <typename OutputIterator>
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
// unique identifier.
unsigned int index = 0;
if(m_use_cache)
index = Self::get_index();
unsigned int index = 0;
if (m_use_cache) index = Self::get_index();
if (cv.orientation() == COLLINEAR)
{
if (cv.orientation() == COLLINEAR) {
// The curve is a line segment.
*oi = make_object (X_monotone_curve_2 (cv.supporting_line(),
cv.source(), cv.target(),
index));
++oi;
return (oi);
*oi++ = Make_x_monotone_result(X_monotone_curve_2(cv.supporting_line(),
cv.source(),
cv.target(),
index));
return oi;
}
// Check the case of a degenrate circle (a point).
@ -425,12 +426,11 @@ public:
CGAL::Sign sign_rad = CGAL::sign (circ.squared_radius());
CGAL_precondition (sign_rad != NEGATIVE);
if (sign_rad == ZERO)
{
if (sign_rad == ZERO) {
// Create an isolated point.
*oi = make_object (Point_2 (circ.center().x(), circ.center().y()));
++oi;
return (oi);
*oi++ = Make_x_monotone_result(Point_2(circ.center().x(),
circ.center().y()));
return oi;
}
// The curve is circular: compute the to vertical tangency points
@ -438,84 +438,73 @@ public:
Point_2 vpts[2];
unsigned int n_vpts = cv.vertical_tangency_points (vpts);
if (cv.is_full())
{
if (cv.is_full()) {
CGAL_assertion (n_vpts == 2);
// Subdivide the circle into two arcs (an upper and a lower half).
*oi = make_object (X_monotone_curve_2 (circ,
vpts[0], vpts[1],
cv.orientation(),
index));
++oi;
*oi++ = Make_x_monotone_result(X_monotone_curve_2(circ,
vpts[0], vpts[1],
cv.orientation(),
index));
*oi = make_object (X_monotone_curve_2 (circ,
vpts[1], vpts[0],
cv.orientation(),
index));
++oi;
*oi++ = Make_x_monotone_result(X_monotone_curve_2(circ,
vpts[1], vpts[0],
cv.orientation(),
index));
}
else
{
else {
// 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.
*oi = make_object (X_monotone_curve_2 (circ,
cv.source(), vpts[0],
cv.orientation(),
index));
++oi;
*oi++ = Make_x_monotone_result(X_monotone_curve_2(circ,
cv.source(), vpts[0],
cv.orientation(),
index));
*oi = make_object (X_monotone_curve_2 (circ,
vpts[0], vpts[1],
cv.orientation(),
index));
++oi;
*oi++ = Make_x_monotone_result(X_monotone_curve_2(circ,
vpts[0], vpts[1],
cv.orientation(),
index));
*oi = make_object (X_monotone_curve_2 (circ,
vpts[1], cv.target(),
cv.orientation(),
index));
++oi;
*oi++ = Make_x_monotone_result(X_monotone_curve_2(circ,
vpts[1],
cv.target(),
cv.orientation(),
index));
}
else if (n_vpts == 1)
{
else if (n_vpts == 1) {
// Subdivide the circular arc into two x-monotone arcs.
*oi = make_object (X_monotone_curve_2 (circ,
cv.source(), vpts[0],
cv.orientation(),
index));
++oi;
*oi++ = Make_x_monotone_result(X_monotone_curve_2(circ,
cv.source(),
vpts[0],
cv.orientation(),
index));
*oi = make_object (X_monotone_curve_2 (circ,
vpts[0], cv.target(),
cv.orientation(),
index));
++oi;
*oi++ = Make_x_monotone_result(X_monotone_curve_2(circ,
vpts[0],
cv.target(),
cv.orientation(),
index));
}
else
{
CGAL_assertion (n_vpts == 0);
else {
CGAL_assertion(n_vpts == 0);
// The arc is already x-monotone:
*oi = make_object (X_monotone_curve_2 (circ,
cv.source(), cv.target(),
cv.orientation(),
index));
++oi;
*oi++ = Make_x_monotone_result(X_monotone_curve_2(circ,
cv.source(),
cv.target(),
cv.orientation(),
index));
}
}
return (oi);
return oi;
}
};
/*! Get a Make_x_monotone_2 functor object. */
Make_x_monotone_2 make_x_monotone_2_object () const
{
return Make_x_monotone_2(m_use_cache);
}
Make_x_monotone_2 make_x_monotone_2_object() const
{ return Make_x_monotone_2(m_use_cache); }
class Split_2
{

View File

@ -27,6 +27,10 @@
* Arrangement_2 package, which it is now part of. It contains a traits
* class for the arrangement package that handles circular curves.
* 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>
@ -109,7 +113,7 @@ public:
typedef unsigned int Multiplicity;
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 Arr_oblivious_side_tag Left_side_category;
@ -129,7 +133,7 @@ public:
typedef typename CircularKernel::Construct_circular_min_vertex_2
Construct_min_vertex_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::Intersect_2 Intersect_2;
typedef typename CircularKernel::Is_vertical_2 Is_vertical_2;
@ -149,8 +153,8 @@ public:
Equal_2 equal_2_object() const
{ return ck.equal_2_object(); }
Make_x_monotone_2 make_x_monotone_2_object() const
{ return ck.make_x_monotone_2_object(); }
// Make_x_monotone_2 make_x_monotone_2_object() const
// { return ck.make_x_monotone_2_object(); }
Split_2 split_2_object() const
{ return ck.split_2_object(); }
@ -168,6 +172,34 @@ public:
{ 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

View File

@ -27,6 +27,10 @@
* Arrangement_2 package, which it is now part of. It contains a traits
* class for the arrangement package that handles circular and linear curves.
* 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>
@ -39,53 +43,35 @@
namespace CGAL {
namespace VariantFunctors{
// Takes an iterator range of Object(Line/Circular_arc),
// returns an Object(Variant(Line/Circular_arc)).
// Do nothing for Object(Endpoint).
// Takes an iterator range of Object(Line/Circular_arc/Point),
// returns a variant of Line, Circular_arc, and Point_2.
template <class CK, class Arc1, class Arc2, class OutputIterator>
OutputIterator
object_to_object_variant(const std::vector<CGAL::Object>& res1,
OutputIterator res2)
{
for (std::vector<CGAL::Object>::const_iterator it = res1.begin();
it != res1.end(); ++it ) {
if (const Arc1 *arc = CGAL::object_cast< Arc1 >(&*it)){
boost::variant< Arc1, Arc2 > v = *arc;
*res2++ = make_object(v);
typedef typename CK::Circular_arc_point_2 Point_2;
typedef boost::variant<Arc1, Arc2> X_monotone_curve_2;
typedef boost::variant<Point_2, X_monotone_curve_2>
Make_x_monotone_result;
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)){
boost::variant< Arc1, Arc2 > v = *line;
*res2++ = make_object(v);
else if (const Arc2* line = CGAL::object_cast<Arc2>(&*it)) {
boost::variant<Arc1, Arc2> v = *line;
*res2++ = Make_x_monotone_result(v);
}
else{
*res2++ = *it;
else if (const Point_2* p = CGAL::object_cast<Point_2>(&*it)) {
*res2++ = Make_x_monotone_result(*p);
}
else CGAL_error();
}
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>
class Compare_y_to_right_2
{
@ -147,17 +133,12 @@ namespace CGAL {
template <class CircularKernel, class Arc1, class Arc2>
class Equal_2
#ifndef CGAL_CFG_MATCHING_BUG_6
: public
CircularKernel::Equal_2
#endif
: public CircularKernel::Equal_2
{
public:
typedef boost::variant< Arc1, Arc2 > Curve_2;
typedef bool result_type;
#ifndef CGAL_CFG_MATCHING_BUG_6
using CircularKernel::Equal_2::operator();
#else
typedef typename CircularKernel::Circular_arc_point_2
Circular_arc_point_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
{ return false; }
#endif
result_type
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>
class Make_x_monotone_2
{
@ -268,20 +248,21 @@ namespace CGAL {
template < class OutputIterator,class Not_X_Monotone >
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;
CircularKernel()
.make_x_monotone_2_object()(*arc1,std::back_inserter(container));
CircularKernel().
make_x_monotone_2_object()(*arc1,std::back_inserter(container));
return object_to_object_variant<CircularKernel, Arc1, Arc2>
(container, res);
}
else {
const Arc2* arc2 = boost::get<Arc2>( &A );
std::vector<CGAL::Object> container;
CircularKernel()
.make_x_monotone_2_object()(*arc2,std::back_inserter(container));
CircularKernel().
make_x_monotone_2_object()(*arc2,std::back_inserter(container));
return object_to_object_variant<CircularKernel, Arc1, Arc2>
(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;
public:
/*!
* Cut the given conic curve (or conic arc) into x-monotone subcurves
* and insert them to the given output iterator.
* \param cv The curve.
* \param oi The output iterator, whose value-type is Object. The returned
* objects are all wrappers X_monotone_curve_2 objects.
* \return The past-the-end iterator.
public:
/*! Subdivide a given conic curve (or conic arc) 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
* variant that wraps a \c Point_2 or an \c X_monotone_curve_2
* objects.
* \return the past-the-end iterator.
*/
template<class OutputIterator>
OutputIterator operator() (const Curve_2& cv, OutputIterator oi) const
template <typename OutputIterator>
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
// unique identifier.
unsigned int index = Self::get_index();
Conic_id conic_id (index);
auto index = Self::get_index();
Conic_id conic_id(index);
// Find the points of vertical tangency to cv and act accordingly.
typename Curve_2::Point_2 vtan_ps[2];
int n_vtan_ps;
typename Curve_2::Point_2 vtan_ps[2];
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:
*oi = make_object (X_monotone_curve_2 (cv, conic_id));
++oi;
return (oi);
*oi++ = Make_x_monotone_result(X_monotone_curve_2(cv, conic_id));
return oi;
}
// 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.
CGAL_assertion(n_vtan_ps == 2);
// 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
// ps[0].
*oi = make_object (X_monotone_curve_2 (cv, vtan_ps[0], vtan_ps[1],
conic_id));
++oi;
*oi = make_object (X_monotone_curve_2 (cv, vtan_ps[1], vtan_ps[0],
conic_id));
++oi;
*oi++ = Make_x_monotone_result(X_monotone_curve_2(cv, vtan_ps[0],
vtan_ps[1],
conic_id));
*oi++ = Make_x_monotone_result(X_monotone_curve_2(cv, vtan_ps[1],
vtan_ps[0],
conic_id));
}
else
{
if (n_vtan_ps == 1)
{
else {
if (n_vtan_ps == 1) {
// 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.
*oi = make_object (X_monotone_curve_2 (cv, cv.source(), vtan_ps[0],
conic_id));
++oi;
*oi = make_object (X_monotone_curve_2 (cv, vtan_ps[0], cv.target(),
conic_id));
++oi;
*oi++ = Make_x_monotone_result(X_monotone_curve_2(cv, cv.source(),
vtan_ps[0],
conic_id));
*oi++ = Make_x_monotone_result(X_monotone_curve_2(cv, vtan_ps[0],
cv.target(),
conic_id));
}
else
{
CGAL_assertion (n_vtan_ps == 2);
else {
CGAL_assertion(n_vtan_ps == 2);
// Identify the first point we encounter when going from cv's source
// to its target, and the second point we encounter. Note that the
// two endpoints must both be below the line connecting the two
// tangnecy points (or both lies above it).
int ind_first = 0;
int ind_second = 1;
Alg_kernel_ ker;
typename Alg_kernel_::Line_2 line =
ker.construct_line_2_object() (vtan_ps[0], vtan_ps[1]);
const Comparison_result start_pos =
int ind_first = 0;
int ind_second = 1;
Alg_kernel_ ker;
typename Alg_kernel_::Line_2 line =
ker.construct_line_2_object()(vtan_ps[0], vtan_ps[1]);
const Comparison_result start_pos =
ker.compare_y_at_x_2_object() (cv.source(), line);
const Comparison_result order_vpts =
ker.compare_x_2_object() (vtan_ps[0], vtan_ps[1]);
const Comparison_result order_vpts =
ker.compare_x_2_object()(vtan_ps[0], vtan_ps[1]);
CGAL_assertion (start_pos != EQUAL &&
ker.compare_y_at_x_2_object() (cv.target(),
line) == start_pos);
CGAL_assertion (order_vpts != EQUAL);
CGAL_assertion(start_pos != EQUAL &&
ker.compare_y_at_x_2_object()(cv.target(),
line) == start_pos);
CGAL_assertion(order_vpts != EQUAL);
if ((cv.orientation() == COUNTERCLOCKWISE &&
start_pos == order_vpts) ||
(cv.orientation() == CLOCKWISE &&
start_pos != order_vpts))
if (((cv.orientation() == COUNTERCLOCKWISE) &&
(start_pos == order_vpts)) ||
((cv.orientation() == CLOCKWISE) && (start_pos != order_vpts)))
{
ind_first = 1;
ind_second = 0;
}
// Split the arc into three x-monotone sub-curves.
*oi = make_object (X_monotone_curve_2 (cv,
cv.source(),
vtan_ps[ind_first],
conic_id));
++oi;
*oi++ = Make_x_monotone_result(X_monotone_curve_2(cv, cv.source(),
vtan_ps[ind_first],
conic_id));
*oi = make_object (X_monotone_curve_2 (cv,
vtan_ps[ind_first],
vtan_ps[ind_second],
conic_id));
++oi;
*oi++ = Make_x_monotone_result(X_monotone_curve_2(cv,
vtan_ps[ind_first],
vtan_ps[ind_second],
conic_id));
*oi = make_object (X_monotone_curve_2 (cv,
vtan_ps[ind_second],
cv.target(),
conic_id));
++oi;
*oi++ = Make_x_monotone_result(X_monotone_curve_2(cv,
vtan_ps[ind_second],
cv.target(),
conic_id));
}
}
return (oi);
return oi;
}
};
/*! Get a Make_x_monotone_2 functor object. */
Make_x_monotone_2 make_x_monotone_2_object () const
{
return Make_x_monotone_2();
}
Make_x_monotone_2 make_x_monotone_2_object() const
{ return Make_x_monotone_2(); }
class Split_2
{

View File

@ -101,120 +101,120 @@ public:
}
/*! 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]; }
unsigned int count_compare_x() const
size_t count_compare_x() const
{ return m_counters[COMPARE_X_OP]; }
unsigned int count_compare_xy() const
size_t count_compare_xy() const
{ 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]; }
unsigned int count_construct_max_vertex() const
size_t count_construct_max_vertex() const
{ 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]; }
unsigned int count_compare_y_at_x() const
size_t count_compare_y_at_x() const
{ 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]; }
unsigned int count_equal_curves() const
size_t count_equal_curves() const
{ 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]; }
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]; }
unsigned int count_make_x_monotone() const
size_t count_make_x_monotone() const
{ return m_counters[MAKE_X_MONOTONE_OP]; }
unsigned int count_split() const
size_t count_split() const
{ return m_counters[SPLIT_OP]; }
unsigned int count_intersect() const
size_t count_intersect() const
{ return m_counters[INTERSECT_OP]; }
unsigned int count_are_mergeable() const
size_t count_are_mergeable() const
{ return m_counters[ARE_MERGEABLE_OP]; }
unsigned int count_merge() const
size_t count_merge() const
{ return m_counters[MERGE_OP]; }
unsigned int count_construct_opposite() const
size_t count_construct_opposite() const
{ 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]; }
// 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]; }
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]; }
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]; }
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]; }
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]; }
unsigned int count_compare_y_on_boundary() const
size_t count_compare_y_on_boundary() const
{ 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]; }
// 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]; }
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]; }
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]; }
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]; }
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]; }
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]; }
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]; }
unsigned int count_compare_x_near_limit() const
size_t count_compare_x_near_limit() const
{ 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]; }
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]; }
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]; }
unsigned int count_compare_x_near_boundary() const
size_t count_compare_x_near_boundary() const
{ return m_counters[COMPARE_X_NEAR_BOUNDARY_OP]; }
/// \name Types and functors inherited from the base
@ -242,11 +242,11 @@ public:
class Compare_x_2 {
private:
typename Base::Compare_x_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! 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) {}
/*! Operate */
@ -258,11 +258,11 @@ public:
class Compare_xy_2 {
private:
typename Base::Compare_xy_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! 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) {}
/*! Operate */
@ -274,11 +274,11 @@ public:
class Construct_min_vertex_2 {
private:
typename Base::Construct_min_vertex_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! 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) {}
/*! Operate */
@ -290,11 +290,11 @@ public:
class Construct_max_vertex_2 {
private:
typename Base::Construct_max_vertex_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! 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) {}
/*! Operate */
@ -306,11 +306,11 @@ public:
class Is_vertical_2 {
private:
typename Base::Is_vertical_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! 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) {}
/*! Operate */
@ -324,11 +324,11 @@ public:
class Compare_y_at_x_2 {
private:
typename Base::Compare_y_at_x_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! 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) {}
/*! Operate */
@ -343,12 +343,12 @@ public:
class Equal_2 {
private:
typename Base::Equal_2 m_object;
unsigned int& m_counter1;
unsigned int& m_counter2;
size_t& m_counter1;
size_t& m_counter2;
public:
/*! 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_counter1(counter1), m_counter2(counter2)
{}
@ -369,11 +369,11 @@ public:
class Compare_y_at_x_left_2 {
private:
typename Base::Compare_y_at_x_left_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! 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) {}
/*! Operate */
@ -389,11 +389,11 @@ public:
class Compare_y_at_x_right_2 {
private:
typename Base::Compare_y_at_x_right_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! 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) {}
/*! Operate */
@ -403,19 +403,27 @@ public:
{ ++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 {
private:
typename Base::Make_x_monotone_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! 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) {}
/*! Operate */
template<class OutputIterator>
/*! Subdivide a given curve into x-monotone subcurves and insert them into
* 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
{ ++m_counter; return m_object(cv, oi); }
};
@ -424,11 +432,11 @@ public:
class Split_2 {
private:
typename Base::Split_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! 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) {}
/*! Operate */
@ -441,11 +449,11 @@ public:
class Intersect_2 {
private:
typename Base::Intersect_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! 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) {}
/*! Operate */
@ -460,11 +468,11 @@ public:
class Are_mergeable_2 {
private:
typename Base::Are_mergeable_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! 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) {}
/*! Operate */
@ -477,11 +485,11 @@ public:
class Merge_2 {
private:
typename Base::Merge_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! 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) {}
/*! Operate */
@ -495,11 +503,11 @@ public:
class Construct_opposite_2 {
private:
typename Base::Construct_opposite_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! 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) {}
/*! Operate */
@ -513,11 +521,11 @@ public:
class Compare_endpoints_xy_2 {
private:
typename Base::Compare_endpoints_xy_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! 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) {}
/*! Operate */
@ -533,14 +541,14 @@ public:
class Parameter_space_in_x_2 {
private:
typename Base::Parameter_space_in_x_2 m_object;
unsigned int& m_counter1;
unsigned int& m_counter2;
unsigned int& m_counter3;
size_t& m_counter1;
size_t& m_counter2;
size_t& m_counter3;
public:
/*! Construct */
Parameter_space_in_x_2(const Base* base, unsigned int& counter1,
unsigned int& counter2, unsigned int& counter3) :
Parameter_space_in_x_2(const Base* base, size_t& counter1,
size_t& counter2, size_t& counter3) :
m_object(base->parameter_space_in_x_2_object()),
m_counter1(counter1),
m_counter2(counter2),
@ -569,13 +577,13 @@ public:
class Is_on_x_identification_2 {
private:
typename Base::Is_on_x_identificiation_2 m_object;
unsigned int& m_counter1;
unsigned int& m_counter2;
size_t& m_counter1;
size_t& m_counter2;
public:
/*! Construct */
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_counter1(counter1),
m_counter2(counter2) {}
@ -597,11 +605,11 @@ public:
class Compare_y_on_boundary_2 {
private:
typename Base::Compare_y_on_boundary_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! 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_counter(counter)
{}
@ -617,11 +625,11 @@ public:
class Compare_y_near_boundary_2 {
private:
typename Base::Compare_y_near_boundary_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! 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) {}
/*! Operate */
@ -639,14 +647,14 @@ public:
class Parameter_space_in_y_2 {
private:
typename Base::Parameter_space_in_y_2 m_object;
unsigned int& m_counter1;
unsigned int& m_counter2;
unsigned int& m_counter3;
size_t& m_counter1;
size_t& m_counter2;
size_t& m_counter3;
public:
/*! Construct */
Parameter_space_in_y_2(const Base* base, unsigned int& counter1,
unsigned int& counter2, unsigned int& counter3) :
Parameter_space_in_y_2(const Base* base, size_t& counter1,
size_t& counter2, size_t& counter3) :
m_object(base->parameter_space_in_y_2_object()),
m_counter1(counter1),
m_counter2(counter2),
@ -673,13 +681,13 @@ public:
class Is_on_y_identification_2 {
private:
typename Base::Is_on_y_identificiation_2 m_object;
unsigned int& m_counter1;
unsigned int& m_counter2;
size_t& m_counter1;
size_t& m_counter2;
public:
/*! Construct */
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_counter1(counter1),
m_counter2(counter2) {}
@ -701,13 +709,13 @@ public:
class Compare_x_at_limit_2 {
private:
typename Base::Compare_x_at_limit_2 m_object;
unsigned int& m_counter1;
unsigned int& m_counter2;
size_t& m_counter1;
size_t& m_counter2;
public:
/*! Construct */
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_counter1(counter1),
m_counter2(counter2) {}
@ -733,11 +741,11 @@ public:
class Compare_x_near_limit_2 {
private:
typename Base::Compare_x_near_limit_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! 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_counter(counter) {}
@ -755,14 +763,14 @@ public:
class Compare_x_on_boundary_2 {
private:
typename Base::Compare_x_on_boundary_2 m_object;
unsigned int& m_counter1;
unsigned int& m_counter2;
unsigned int& m_counter3;
size_t& m_counter1;
size_t& m_counter2;
size_t& m_counter3;
public:
/*! Construct */
Compare_x_on_boundary_2(const Base* base, unsigned int& counter1,
unsigned int& counter2, unsigned int& counter3 ) :
Compare_x_on_boundary_2(const Base* base, size_t& counter1,
size_t& counter2, size_t& counter3 ) :
m_object(base->compare_x_on_boundary_2_object()),
m_counter1(counter1),
m_counter2(counter2),
@ -794,12 +802,12 @@ public:
class Compare_x_near_boundary_2 {
private:
typename Base::Compare_x_near_boundary_2 m_object;
unsigned int& m_counter;
size_t& m_counter;
public:
/*! Construct */
Compare_x_near_boundary_2(const Base* base,
unsigned int& counter) :
size_t& counter) :
m_object(base->compare_x_near_boundary_2_object()),
m_counter(counter) {}
@ -945,12 +953,12 @@ public:
* \param doit indicates whethet to actually inceremnt the counter or not
* \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
static unsigned int counter;
static size_t counter;
#else
static CGAL::cpp11::atomic<unsigned int> counter;
static CGAL::cpp11::atomic<size_t> counter;
#endif
if (doit) ++counter;
return counter;
@ -962,7 +970,7 @@ public:
private:
/*! 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>
@ -971,8 +979,8 @@ Out_stream& operator<<(Out_stream& os,
const Arr_counting_traits_2<Base_traits>& traits)
{
typedef Arr_counting_traits_2<Base_traits> Traits;
unsigned int sum = 0;
unsigned int i;
size_t sum = 0;
size_t i;
for (i = 0; i < Traits::NUMBER_OF_OPERATIONS; ++i)
sum += traits.count(static_cast<typename Traits::Operation_id>(i));
os << "# of COMPARE_X operation = "

View File

@ -27,8 +27,8 @@
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <CGAL/Object.h>
#include <CGAL/tags.h>
#include <CGAL/assertions.h>
#include <CGAL/Arr_tags.h>
#include <CGAL/Arr_geometry_traits/Curve_data_aux.h>
@ -101,6 +101,12 @@ public:
/// \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 {
private:
const Base_traits_2& m_base;
@ -109,36 +115,36 @@ public:
/*! Constructor. */
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
* given output iterator. As segments are always x_monotone, only one
* x-monotone curve will be contained in the iterator.
* \param cv The curve.
* \param oi The output iterator, whose value-type is X_monotone_curve_2.
* \return The past-the-end iterator.
/*! Subdivide a given curve into x-monotone subcurves and insert them into
* 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>
template <typename OutputIterator>
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.
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));
// 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());
for (typename std::list<CGAL::Object>::const_iterator it =
base_objects.begin(); it != base_objects.end(); ++it)
{
base_x_curve = object_cast<Base_x_monotone_curve_2>(&(*it));
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;
for (const auto& base_obj : base_objects) {
if (const auto* bxcv = boost::get<Base_x_monotone_curve_2>(&base_obj)) {
*oi++ = Make_x_monotone_result(X_monotone_curve_2(*bxcv, xdata));
continue;
}
// 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;
@ -359,6 +365,8 @@ public:
/*! Obtain a Merge_2 functor object. */
Merge_2 merge_2_object() const { return Merge_2(*this); }
//@}
class Construct_x_monotone_curve_2 {
private:
const Base_traits_2& m_base;

View File

@ -34,6 +34,7 @@
#include <CGAL/Arrangement_2/Arrangement_2_iterators.h>
#include <CGAL/assertions.h>
#include <boost/pool/pool_alloc.hpp>
namespace CGAL {
@ -876,7 +877,7 @@ public:
* The arrangement DCEL class.
*/
template <class V, class H, class F,
class Allocator = CGAL_ALLOCATOR(int) >
class Allocator = boost::fast_pool_allocator<int> >
class Arr_dcel_base {
public:
// Define the vertex, halfedge and face types.

View File

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

View File

@ -197,49 +197,51 @@ public:
/*! Intersect 2 planes
* \param plane1 the first plane
* \param plane2 the second plane
* \return a geometric object that represents the intersection. Could be
* the line of intersection, or a plane in case plane1 and plane2 coincide.
* \return a variant that represents the intersection. It wraps a line of
* intersection or a plane in case plane1 and plane2 coincide.
*/
template <class Kernel>
CGAL::Object intersect(const Arr_plane_3<Kernel> & plane1,
template <typname Kernel>
boost::variant<typename Kernel::Line_3, Arr_plane_3<Kernel> >
intersect(const Arr_plane_3<Kernel> & plane1,
const Arr_plane_3<Kernel> & plane2)
{
typedef typename Kernel::Point_3 Point_3;
typedef typename Kernel::Direction_3 Direction_3;
typedef typename Kernel::Line_3 Line_3;
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
const FT & a1 = plane1.a();
const FT & b1 = plane1.b();
const FT & c1 = plane1.c();
const FT& a1 = plane1.a();
const FT& b1 = plane1.b();
const FT& c1 = plane1.c();
const FT & a2 = plane2.a();
const FT & b2 = plane2.b();
const FT & c2 = plane2.c();
const FT& a2 = plane2.a();
const FT& b2 = plane2.b();
const FT& c2 = plane2.c();
FT det = a1*b2 - a2*b1;
if (det != 0) {
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);
return make_object(Line_3(is_pt, is_dir));
return Intersection_result(Line_3(is_pt, is_dir));
}
det = a1*c2 - a2*c1;
if (det != 0) {
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);
return make_object(Line_3(is_pt, is_dir));
return Intersection_result(Line_3(is_pt, is_dir));
}
det = b1*c2 - c1*b2;
if (det != 0) {
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);
return make_object(Line_3(is_pt, is_dir));
return Intersection_result(Line_3(is_pt, is_dir));
}
// degenerate case
return make_object(plane1);
return Intersection_result(plane1);
}
/*! 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.
Bez_point_bbox ipt_bbox;
Control_points aux_vec;
CGAL::Object res;
Point_2 p;
res = f_intersect (skew1a, skew2a);
if (! assign (p, res))
{
CGAL_error();
}
aux_vec.push_back(p);
auto res1 = f_intersect(skew1a, skew2a);
const Point_2* p1 = boost::get<Point_2>(&*res1);
if (! p1) CGAL_error();
aux_vec.push_back(*p1);
res = f_intersect (skew1a, skew2b);
if (! assign(p, res))
{
CGAL_error();
}
aux_vec.push_back(p);
auto res2 = f_intersect(skew1a, skew2b);
const Point_2* p2 = boost::get<Point_2>(&*res2);
if (! p2) CGAL_error();
aux_vec.push_back(*p2);
res = f_intersect (skew1b, skew2a);
if (! assign(p, res))
{
CGAL_error();
}
aux_vec.push_back(p);
auto res3 = f_intersect(skew1b, skew2a);
const Point_2* p3 = boost::get<Point_2>(&*res3);
if (! p3) CGAL_error();
aux_vec.push_back(*p3);
res = f_intersect (skew1b, skew2b);
if (!assign(p, res))
{
CGAL_error();
}
aux_vec.push_back(p);
auto res4 = f_intersect (skew1b, skew2b);
const Point_2* p4 = boost::get<Point_2>(&*res4);
if (! p4) CGAL_error();
aux_vec.push_back(*p4);
construct_bbox (aux_vec, ipt_bbox);

View File

@ -251,7 +251,7 @@ private:
const Polynomial& polyY_1, const Integer& normY_1,
const Polynomial& polyX_2, const Integer& normX_2,
const Polynomial& polyY_2, const Integer& normY_2,
Parameter_list& s_vals) const;
Parameter_list& s_vals, bool find_out_of_range=false) const;
/*!
* Compute all s-parameter values of the self intersection of (X(s), Y(s))
@ -407,7 +407,7 @@ _Bezier_cache<NtTraits>::get_intersections
do_ovlp = _intersection_params (polyX_2, normX_2, polyY_2, normY_2,
polyX_1, normX_1, polyY_1, normY_1,
t_vals);
t_vals, true);
CGAL_assertion (! do_ovlp);
@ -457,21 +457,14 @@ _Bezier_cache<NtTraits>::get_intersections
const Algebraic one (1);
unsigned int k;
//pointers are used to set the list pts1_ptr as the one with the less values
Point_list* pts1_ptr=&pts1;
Point_list* pts2_ptr=&pts2;
bool swapt=pts1.size() > pts2.size();
if (swapt)
std::swap(pts1_ptr,pts2_ptr);
for (pit1 = pts1_ptr->begin(); pit1 != pts1_ptr->end(); ++pit1)
for (pit1 = pts1.begin(); pit1 != pts1.end(); ++pit1)
{
// Construct a vector of distances from the current point to all other
// points in the pts2 list.
const int n_pts2 = static_cast<int>(pts2_ptr->size());
const int n_pts2 = static_cast<int>(pts2.size());
std::vector<Distance_iter> dist_vec (n_pts2);
for (k = 0, pit2 = pts2_ptr->begin(); pit2 != pts2_ptr->end(); k++, ++pit2)
for (k = 0, pit2 = pts2.begin(); pit2 != pts2.end(); k++, ++pit2)
{
// Compute the approximate distance between the teo current points.
dx = pit1->app_x - pit2->app_x;
@ -508,7 +501,7 @@ _Bezier_cache<NtTraits>::get_intersections
pit1->y = pit2->y;
// Remove this point from pts2, as we found a match for it.
pts2_ptr->erase (pit2);
pts2.erase (pit2);
found = true;
}
}
@ -528,15 +521,15 @@ _Bezier_cache<NtTraits>::get_intersections
pit1->y = pit2->y;
// Remove this point from pts2, as we found a match for it.
pts2_ptr->erase (pit2);
pts2.erase (pit2);
}
// Check that s- and t-values both lie in the legal range of [0,1].
CGAL_assertion(CGAL::sign (s) != NEGATIVE && CGAL::compare (s, one) != LARGER &&
CGAL::sign (t) != NEGATIVE && CGAL::compare (t, one) != LARGER);
if (!swapt) info.first.push_back(Intersection_point(s, t,pit1->x, pit1->y));
else info.first.push_back(Intersection_point(t, s,pit1->x, pit1->y));
if(CGAL::sign (s) != NEGATIVE && CGAL::compare (s, one) != LARGER &&
CGAL::sign (t) != NEGATIVE && CGAL::compare (t, one) != LARGER)
{
info.first.push_back(Intersection_point(s, t,pit1->x, pit1->y));
}
}
info.second = false;
@ -580,7 +573,7 @@ bool _Bezier_cache<NtTraits>::_intersection_params
const Polynomial& polyY_1, const Integer& normY_1,
const Polynomial& polyX_2, const Integer& normX_2,
const Polynomial& polyY_2, const Integer& normY_2,
Parameter_list& s_vals) const
Parameter_list& s_vals, bool find_out_of_range) const
{
// Clear the output parameter list.
if (! s_vals.empty())
@ -631,8 +624,12 @@ bool _Bezier_cache<NtTraits>::_intersection_params
}
// Compute the roots of the resultant polynomial and mark that the curves do
// not overlap. The roots we are interested in must be in the interval [0,1].
nt_traits.compute_polynomial_roots (res,0,1,std::back_inserter (s_vals));
// not overlap. The roots we are interested in are usually in the interval [0,1].
if (find_out_of_range)
nt_traits.compute_polynomial_roots (res,std::back_inserter (s_vals));
else
nt_traits.compute_polynomial_roots (res,0,1,std::back_inserter (s_vals));
return (false);
}
@ -656,7 +653,7 @@ void _Bezier_cache<NtTraits>::_self_intersection_params
// II: Y(t) - Y(s) / (t - s) = 0
//
Integer *coeffs;
int i, k;
int i;
// Consruct the bivariate polynomial that corresponds to Equation I.
// Note that we represent a bivariate polynomial as a vector of univariate
@ -670,12 +667,11 @@ void _Bezier_cache<NtTraits>::_self_intersection_params
coeffs = new Integer [degX];
for (i = 0; i < degX; i++)
{
for (k = i + 1; k < degX; k++)
coeffs[k - i - 1] = nt_traits.get_coefficient (polyX, k);
coeffs[i] = nt_traits.get_coefficient(polyX, i + 1);
coeffsX_st[i] = nt_traits.construct_polynomial (coeffs, degX - i - 1);
}
for (i = 0; i < degX; i++)
coeffsX_st[degX - i - 1] =
nt_traits.construct_polynomial(coeffs + i, degX - i - 1);
delete[] coeffs;
@ -688,12 +684,11 @@ void _Bezier_cache<NtTraits>::_self_intersection_params
coeffs = new Integer [degY];
for (i = 0; i < degY; i++)
{
for (k = i + 1; k < degY; k++)
coeffs[k - i - 1] = nt_traits.get_coefficient (polyY, k);
coeffs[i] = nt_traits.get_coefficient(polyY, i + 1);
coeffsY_st[i] = nt_traits.construct_polynomial (coeffs, degY - i - 1);
}
for (i = 0; i < degY; i++)
coeffsY_st[degY - i - 1] =
nt_traits.construct_polynomial(coeffs + i, degY - i - 1);
delete[] coeffs;

View File

@ -1641,17 +1641,43 @@ void _Bezier_point_2_rep<RatKer, AlgKer, NtTrt, BndTrt>::_make_exact
const Algebraic t_min = nt_traits.convert (orig2.point_bound().t_min);
const Algebraic t_max = nt_traits.convert (orig2.point_bound().t_max);
bool self_intersecting = (org_it1->curve().id() == org_it2->curve().id());
for (intr_it = intr_list.begin(); intr_it != intr_list.end(); ++intr_it)
{
if (CGAL::compare (intr_it->s, s_min) != SMALLER &&
CGAL::compare (intr_it->s, s_max) != LARGER &&
CGAL::compare (intr_it->t, t_min) != SMALLER &&
CGAL::compare (intr_it->t, t_max) != LARGER)
auto in_bounding_interval =
[](const auto& s_, const auto& s_min_, const auto& s_max_) -> bool {
return CGAL::compare(s_, s_min_) != SMALLER &&
CGAL::compare(s_, s_max_) != LARGER;
};
bool st_in_st_range = in_bounding_interval(intr_it->s, s_min, s_max) &&
in_bounding_interval(intr_it->t, t_min, t_max);
bool ts_in_st_range = false;
if (st_in_st_range)
{
// Update the originators.
orig1.set_parameter (intr_it->s);
orig2.set_parameter (intr_it->t);
orig1.set_parameter(intr_it->s);
orig2.set_parameter(intr_it->t);
}
else if (self_intersecting)
{
// check whether s is in t range, and t is in s range
// s and t can be interchanged in case of self intersections
ts_in_st_range = in_bounding_interval(intr_it->t, s_min, s_max) &&
in_bounding_interval(intr_it->s, t_min, t_max);
if (ts_in_st_range)
{
// Update the originators.
orig1.set_parameter(intr_it->t);
orig2.set_parameter(intr_it->s);
}
}
if (st_in_st_range || ts_in_st_range)
{
// Set the exact point coordinates.
p_alg_x = new Algebraic (intr_it->x);
p_alg_y = new Algebraic (intr_it->y);

View File

@ -1139,10 +1139,11 @@ _Bezier_x_monotone_2<RatKer, AlgKer, NtTrt, BndTrt>::compare_to_left
Originator_iterator org = p.get_originator(_curve, _xid);
CGAL_assertion(org != p.originators_end());
CGAL_assertion(_inc_to_right != cv._inc_to_right);
if (org->point_bound().type == Bez_point_bound::VERTICAL_TANGENCY_PT)
{
CGAL_assertion(_inc_to_right != cv._inc_to_right);
if (! p.is_exact())
{
// Comparison based on the control polygon of the bounded vertical

View File

@ -27,6 +27,10 @@
* Arrangement_2 package, which it is now part of. It contains a traits
* class for the arrangement package that handles linear curves.
* 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>
@ -73,7 +77,7 @@ public:
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::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::Construct_circular_min_vertex_2
Construct_min_vertex_2;
@ -97,8 +101,8 @@ public:
Equal_2 equal_2_object() const
{ return ck.equal_2_object(); }
Make_x_monotone_2 make_x_monotone_2_object() const
{ return ck.make_x_monotone_2_object(); }
// Make_x_monotone_2 make_x_monotone_2_object() const
// { return ck.make_x_monotone_2_object(); }
Split_2 split_2_object() const
{ return ck.split_2_object(); }
@ -115,7 +119,20 @@ public:
Is_vertical_2 is_vertical_2_object() const
{ 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

View File

@ -1239,16 +1239,18 @@ public:
* given output iterator. As segments are always x_monotone, only one
* object will be contained in the iterator.
* \param cv The curve.
* \param oi The output iterator, whose value-type is Object. The output
* object is a wrapper of an X_monotone_curve_2 which is
* essentially the same as the input curve.
* \param oi an 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>
OutputIterator operator()(const Curve_2& cv, OutputIterator oi) const
{
// Wrap the curve with an object.
*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;
}
};

View File

@ -7,14 +7,14 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Efi Fogel <efif@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// (based on old version by: Iddo Hanniel,
// Eyal Flato,
// Oren Nechushtan,
// Ester Ezra,
// Shai Hirsch,
// and Eugene Lipovetsky)
// Author(s): Efi Fogel <efif@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// (based on old version by: Iddo Hanniel,
// Eyal Flato,
// Oren Nechushtan,
// Ester Ezra,
// Shai Hirsch,
// and Eugene Lipovetsky)
#ifndef 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:
typedef X_monotone_curve_2 Curve_2;
/*! \class
* A functor for splitting curves into x-monotone pieces.
/*! \class Make_x_monotone_2
* A functor for subdividing a curve into x-monotone curves.
*/
class Make_x_monotone_2 {
public:
/*! Cut the given segment into x-monotone subcurves and insert them into
* the given output iterator. As segments are always x_monotone, only one
/*! Subdivide a given curve into x-monotone subcurves and insert them into
* a given output iterator. As segments are always x_monotone, only one
* x-monotone curve is inserted into the output iterator.
* \param cv The segment.
* \param oi The output iterator, whose value-type is Object. The output
* object is a wrapper of an X_monotone_curve_2 object.
* \return The past-the-end iterator.
* \param cv the segment.
* \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>
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;
}
};

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::Point_2 Base_point_2;
typedef typename Base_traits_2::Multiplicity Multiplicity;
typedef typename Base_traits_2::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 Halfedge_const_handle* hh;
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);
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);
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);
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
// holes inside the current face, so we conclude it is contained in this
// face.
@ -159,7 +159,7 @@ _walk_from_vertex(Vertex_const_handle nearest_vertex,
if (new_vertex) {
// We found a vertex closer to p; Continue using this vertex.
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);
vh = *p_vh;
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
// that wraps this arrangement feature.
if (Result().template assign<Halfedge_const_handle>(obj) ||
Result().template assign<Vertex_const_handle>(obj))
if (Result().template assign<Halfedge_const_handle>(&obj) ||
Result().template assign<Vertex_const_handle>(&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)
// Walk to p from the face we have located:
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
// the query point in its interior.
typename Traits_adaptor_2::Is_in_x_range_2 is_in_x_range =
m_geom_traits->is_in_x_range_2_object();
typename Traits_adaptor_2::Compare_y_at_x_2 cmp_y_at_x =
m_geom_traits->compare_y_at_x_2_object();
auto is_in_x_range = m_geom_traits->is_in_x_range_2_object();
auto cmp_y_at_x = m_geom_traits->compare_y_at_x_2_object();
typename Arrangement::Edge_const_iterator 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
// halfedge whose source vertex is v, rotating clockwise around the vertex
// 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) {
Halfedge_const_handle hh = _first_around_vertex(*vh);
Face_const_handle fh = hh->face();
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) {
// 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,
@ -288,14 +286,13 @@ Arr_simple_point_location<Arrangement>::_vertical_ray_shoot(const Point_2& p,
if (! optional_empty(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) {
found_vertex = true;
closest_v = *p_vh;
}
else {
const Halfedge_const_handle* p_hh =
Result().template assign<Halfedge_const_handle>(obj);
const auto* p_hh = Result::template assign<Halfedge_const_handle>(&obj);
CGAL_assertion(p_hh != nullptr);
found_halfedge = true;
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
// semi-open x-range (source, target] of this curve and lies below it.
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.
// 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
@ -701,7 +702,7 @@ _is_in_connected_component (const Point_2& p,
do {
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() &&
is_vertical(next_non_vert->curve())) ||

View File

@ -142,7 +142,7 @@ public:
private:
Trpz_parameter_space* ptr() const { return (Trpz_parameter_space*)(PTR.p); }
Trpz_parameter_space* ptr() const { return (Trpz_parameter_space*)(PTR); }
#ifndef CGAL_TD_DEBUG
@ -323,7 +323,7 @@ public:
{
//define the initial trapezoid: left, right, btm, top are at infinity.
// its type is TD_TRAPEZOID ,it is on all boundaries, and has no neighbours
PTR.p = new Trpz_parameter_space
PTR = new Trpz_parameter_space
(Traits::vtx_at_left_infinity(),
Traits::vtx_at_right_infinity(),
Traits::he_at_bottom_infinity(),
@ -353,7 +353,7 @@ public:
else //tp == TD_VERTEX
type_flag |= CGAL_TD_VERTEX;
PTR.p = new Trpz_parameter_space
PTR = new Trpz_parameter_space
(l, r, b, t, type_flag | boundness_flag, lb, lt, rb, rt);
m_dag_node = node;
}
@ -370,7 +370,7 @@ public:
Self* rb = 0, Self* rt = 0,
Dag_node* node = 0)
{
PTR.p = new Trpz_parameter_space
PTR = new Trpz_parameter_space
(l ? *l : Traits::vtx_at_left_infinity(),
r ? *r : Traits::vtx_at_right_infinity(),
b ? *b : Traits::he_at_bottom_infinity(),
@ -436,7 +436,7 @@ public:
/*! Access the trapezoid id (PTR). */
CGAL_TD_INLINE unsigned long id() const
{
return (unsigned long) PTR.p;
return (unsigned long) PTR;
}
/*! Access trapezoid left. */

View File

@ -135,7 +135,7 @@ public:
private:
Data* ptr() const { return (Data*)(PTR.p); }
Data* ptr() const { return (Data*)(PTR); }
#ifndef CGAL_TD_DEBUG
@ -194,7 +194,7 @@ public:
Td_active_edge ()
{
PTR.p = new Data
PTR = new Data
(Traits::empty_he_handle(), Td_map_item(0), nullptr);
//m_dag_node = nullptr;
}
@ -204,7 +204,7 @@ public:
boost::optional<Td_map_item&> next = boost::none)
{
PTR.p = new Data(he, (next) ? *next : Td_map_item(0), node);
PTR = new Data(he, (next) ? *next : Td_map_item(0), node);
//m_dag_node = node;
}
@ -261,7 +261,7 @@ public:
/*! Access the trapezoid id (PTR). */
CGAL_TD_INLINE unsigned long id() const
{
return (unsigned long) PTR.p;
return (unsigned long) PTR;
}

View File

@ -129,7 +129,7 @@ public:
};
private:
Data* ptr() const { return (Data*)(PTR.p); }
Data* ptr() const { return (Data*)(PTR); }
Curve_end vtx_to_ce(Vertex_const_handle v) const
{
@ -180,14 +180,14 @@ public:
Td_active_fictitious_vertex()
{
PTR.p = new Data(Traits::empty_vtx_handle(), Traits::empty_he_handle(), nullptr);
PTR = new Data(Traits::empty_vtx_handle(), Traits::empty_he_handle(), nullptr);
}
/*! Constructor given Vertex & Halfedge handles. */
Td_active_fictitious_vertex(Vertex_const_handle v,
Halfedge_const_handle cw_he,
Dag_node* node = 0)
{ PTR.p = new Data(v, cw_he, node); }
{ PTR = new Data(v, cw_he, node); }
/*! Copy constructor. */
@ -224,7 +224,7 @@ public:
inline const Self& self() const { return *this; }
/*! Access the trapezoid id (PTR). */
inline unsigned long id() const { return (unsigned long) PTR.p; }
inline unsigned long id() const { return (unsigned long) PTR; }
/*! Access trapezoid left.
* filters out the infinite case which returns predefined dummy values

View File

@ -144,7 +144,7 @@ public:
private:
Data* ptr() const { return (Data*)(PTR.p); }
Data* ptr() const { return (Data*)(PTR); }
public:
@ -255,7 +255,7 @@ private:
{
//define the initial trapezoid: left, right, btm, top are at infinity.
// has no neighbours
PTR.p = new Data
PTR = new Data
(Traits::empty_vtx_handle(),
Traits::empty_vtx_handle(),
Traits::empty_he_handle(),
@ -274,7 +274,7 @@ private:
boost::optional<Td_map_item&> rt = boost::none,
Dag_node* node = 0)
{
PTR.p = new Data (l, r, b, t, (lb) ? *lb : Td_map_item(0), (lt) ? *lt : Td_map_item(0),
PTR = new Data (l, r, b, t, (lb) ? *lb : Td_map_item(0), (lt) ? *lt : Td_map_item(0),
(rb) ? *rb : Td_map_item(0), (rt) ? *rt : Td_map_item(0), node);
//m_dag_node = node;
}
@ -332,7 +332,7 @@ private:
/*! Access the trapezoid id (PTR). */
inline unsigned long id() const
{
return (unsigned long) PTR.p;
return (unsigned long) PTR;
}
/*! Access trapezoid left.

View File

@ -134,7 +134,7 @@ public:
};
private:
Data* ptr() const { return (Data*)(PTR.p); }
Data* ptr() const { return (Data*)(PTR); }
Curve_end vtx_to_ce(Vertex_const_handle v) const
{
@ -184,14 +184,14 @@ public:
Td_active_vertex()
{
PTR.p = new Data(Traits::empty_vtx_handle(), Traits::empty_he_handle(), nullptr);
PTR = new Data(Traits::empty_vtx_handle(), Traits::empty_he_handle(), nullptr);
}
/*! Constructor given Vertex & Halfedge handles. */
Td_active_vertex(Vertex_const_handle v, Halfedge_const_handle cw_he,
Dag_node* node = 0)
{ PTR.p = new Data(v, cw_he, node); }
{ PTR = new Data(v, cw_he, node); }
/*! Copy constructor. */
@ -228,7 +228,7 @@ public:
inline const Self& self() const { return *this; }
/*! Access the trapezoid id (PTR). */
inline unsigned long id() const { return (unsigned long) PTR.p; }
inline unsigned long id() const { return (unsigned long) PTR; }
inline Vertex_const_handle vertex() const { return ptr()->v; }

View File

@ -41,14 +41,14 @@ public: //iddo (for CC-7.2) maybe protected?
typedef const T & const_reference;
protected:
void init() { PTR.p = 0; }
void init() { PTR = 0; }
public:
Td_dag_base() {init();}
Td_dag_base(const Td_dag_base<T> & x) : Handle(x) {}
Td_dag_base & operator=(const Td_dag_base<T> & x)
{Handle::operator=(x); return *this; }
bool operator!() const { return PTR.p == 0; }
bool operator!() const { return PTR == 0; }
};
template<class T>
@ -96,9 +96,9 @@ public:
Td_dag(){}
Td_dag(const Td_dag_handle& dag):Td_dag_handle(dag){}
Td_dag(const Self& dag):Td_dag_handle(dag){}
Td_dag(const T& rootValue){PTR.p = new node(rootValue);}
Td_dag(const T& rootValue){PTR = new node(rootValue);}
Td_dag(const T& rootValue, const Self& left, const Self& right)
{PTR.p = new node(rootValue, left, right); rebalance_depth();}
{PTR = new node(rootValue, left, right); rebalance_depth();}
~Td_dag(){}
/* --------information retrieval -------*/
@ -145,7 +145,7 @@ public:
}
bool operator==(const Self& b) const
{
return PTR.p==b.PTR.p;
return PTR==b.PTR;
}
bool operator!=(const Self& b) const
{
@ -189,7 +189,7 @@ public:
// detach left son,redirect to dummy
set_left(dummy);
// set left son pointer to 0
ptr()->leftPtr.PTR.p=0;
ptr()->leftPtr.PTR=0;
// delete dummy Td_dag
delete dummy.ptr();
}
@ -204,7 +204,7 @@ public:
// detach right son,redirect to dummy
set_right(dummy);
// set right son pointer to 0
ptr()->rightPtr.PTR.p=0;
ptr()->rightPtr.PTR=0;
// delete dummy Td_dag
delete dummy.ptr();
}
@ -371,7 +371,7 @@ protected:
}
#endif
private:
node* ptr() const {return (node*)PTR.p;}
node* ptr() const {return (node*)PTR;}
};
template<class T,class Traits>
@ -441,7 +441,7 @@ template<class T> std::ostream& operator<<(std::ostream& out,
tech notes:
The code is Handle designed.
left(),right() are designed to cope with Handle(Handle& x)
precondition x.PTR.p!=0
precondition x.PTR!=0
operator=() performs shallow copy
operator*() returns data type
output is done as a binary tree.

View File

@ -39,7 +39,7 @@ template<class Traits>
class Td_dag_node_base : public Handle
{
protected:
void init() { PTR.p = 0; } //MICHAL: I think it is not used - so need to be removed
void init() { PTR = 0; } //MICHAL: I think it is not used - so need to be removed
public:
//c'tors
@ -57,12 +57,12 @@ public:
return *this;
}
//bool operator!() const { return PTR.p == 0; } //MICHAL: maybe use ptr(), and also can change to is_null or something similar
bool is_null() const { return PTR.p == 0; }
Rep * ptr() const { return (Rep*) PTR.p; }
//bool operator!() const { return PTR == 0; } //MICHAL: maybe use ptr(), and also can change to is_null or something similar
bool is_null() const { return PTR == 0; }
Rep * ptr() const { return (Rep*) PTR; }
protected:
//Rep *& ptr() { return (Rep*) PTR.p; }
void set_ptr(Rep* rep) { PTR.p = rep; }
//Rep *& ptr() { return (Rep*) PTR; }
void set_ptr(Rep* rep) { PTR = rep; }
};
@ -94,7 +94,7 @@ public:
#ifndef CGAL_CFG_USING_BASE_MEMBER_BUG_2
public:
//using Td_dag_node_handle::PTR.p;
//using Td_dag_node_handle::PTR;
//using Td_dag_node_handle::operator!;
#endif //CGAL_CFG_USING_BASE_MEMBER_BUG_2
@ -549,7 +549,7 @@ protected:
private:
Node* node() const { return (Node*)Base::PTR.p; }
Node* node() const { return (Node*)Base::PTR; }
};
@ -629,7 +629,7 @@ std::ostream& operator<< (std::ostream& out,
tech notes:
The code is Handle designed.
left_child(),right_child() are designed to cope with Handle(Handle& x)
precondition x.PTR.p!=0
precondition x.PTR!=0
operator=() performs shallow copy
operator*() returns data type
output is done as a binary tree.

View File

@ -128,7 +128,7 @@ public:
private:
Data* ptr() const { return (Data*)(PTR.p); }
Data* ptr() const { return (Data*)(PTR); }
#ifndef CGAL_TD_DEBUG
@ -161,7 +161,7 @@ public:
/*! Constructor given Vertex & Halfedge handles. */
Td_inactive_edge (boost::shared_ptr<X_monotone_curve_2>& cv, Dag_node* node = nullptr)
{
PTR.p = new Data(cv,node);
PTR = new Data(cv,node);
}
/*! Copy constructor. */
@ -215,7 +215,7 @@ public:
/*! Access the trapezoid id (PTR). */
inline unsigned long id() const
{
return (unsigned long) PTR.p;
return (unsigned long) PTR;
}
inline X_monotone_curve_2& curve() const

View File

@ -133,7 +133,7 @@ public:
private:
Data* ptr() const { return (Data*)(PTR.p); }
Data* ptr() const { return (Data*)(PTR); }
Curve_end vtx_to_ce(Vertex_const_handle v) const
{
@ -185,7 +185,7 @@ public:
{
Curve_end v_ce(vtx_to_ce(v_before_rem));
PTR.p = new Data( v_ce.cv(), v_ce.ce(), node);
PTR = new Data( v_ce.cv(), v_ce.ce(), node);
}
@ -241,7 +241,7 @@ public:
/*! Access the trapezoid id (PTR). */
inline unsigned long id() const
{
return (unsigned long) PTR.p;
return (unsigned long) PTR;
}

View File

@ -127,7 +127,7 @@ public:
private:
Data* ptr() const { return (Data*)(PTR.p); }
Data* ptr() const { return (Data*)(PTR); }
#ifndef CGAL_TD_DEBUG
@ -162,7 +162,7 @@ public:
/*! Constructor given Vertex & Halfedge handles. */
Td_inactive_vertex (Vertex_const_handle v_before_rem, Dag_node* node = nullptr)
{
PTR.p = new Data(v_before_rem->point(), node);
PTR = new Data(v_before_rem->point(), node);
}
@ -217,7 +217,7 @@ public:
/*! Access the trapezoid id (PTR). */
inline unsigned long id() const
{
return (unsigned long) PTR.p;
return (unsigned long) PTR;
}
inline Point& point() const

View File

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

View File

@ -63,6 +63,7 @@ public:
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::Multiplicity Multiplicity;
//@}

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -151,23 +151,25 @@ public:
OutputIterator insert(const Vector_3 & normal1, const Vector_3 & normal2,
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));
typename std::list<CGAL::Object>::iterator it = x_objects.begin();
const X_monotone_curve_2 * xc = object_cast<X_monotone_curve_2>(&(*it));
auto it = x_objects.begin();
const auto* xc = boost::get<X_monotone_curve_2>(&(*it));
#if CGAL_ARR_SPHERICAL_GAUSSIAN_MAP_3_DEBUG==1
std::cout << "1.a. insert_in_face_interior(" << *xc << ")" << std::endl;
#endif
Halfedge_handle he =
m_sgm.insert_in_face_interior(*xc, m_sgm.faces_begin());
if (!xc->is_directed_right()) he = he->twin();
Halfedge_handle he = m_sgm.insert_in_face_interior(*xc, m_sgm.faces_begin());
if (! xc->is_directed_right()) he = he->twin();
*oi++ = he;
++it;
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
std::cout << "1.b. insert_from_vertex(" << *xc << ")" << std::endl;
#endif
@ -190,11 +192,14 @@ public:
const Vector_3 & normal2,
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));
typename std::list<CGAL::Object>::iterator it = x_objects.begin();
const X_monotone_curve_2 * xc = object_cast<X_monotone_curve_2>(&(*it));
auto it = x_objects.begin();
const auto* xc = boost::get<X_monotone_curve_2>(&(*it));
#if CGAL_ARR_SPHERICAL_GAUSSIAN_MAP_3_DEBUG==1
std::cout << "2.a. insert_from_vertex(" << *xc << ", "
<< vertex1->point() << ")" << std::endl;
@ -208,7 +213,7 @@ public:
++it;
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
std::cout << "2.b. insert_from_vertex(" << *xc << ")" << std::endl;
#endif
@ -231,12 +236,15 @@ public:
const Vector_3 & normal2, Vertex_handle vertex2,
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));
typename std::list<CGAL::Object>::iterator it = x_objects.begin();
auto it = x_objects.begin();
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
std::cout << "3. insert_from_vertex(" << *xc << ")" << std::endl;
#endif
@ -247,8 +255,8 @@ public:
return oi;
}
const X_monotone_curve_2 * xc1 = object_cast<X_monotone_curve_2>(&(*it++));
const X_monotone_curve_2 * xc2 = 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 = boost::get<X_monotone_curve_2>(&(*it));
#if CGAL_ARR_SPHERICAL_GAUSSIAN_MAP_3_DEBUG==1
std::cout << "3.a. insert_from_vertex(" << *xc2 << ")" << std::endl;
@ -283,11 +291,13 @@ public:
const Vector_3 & normal2, Vertex_handle vertex2,
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));
typename std::list<CGAL::Object>::iterator it = x_objects.begin();
auto it = x_objects.begin();
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
std::cout << "4. insert_at_vertices(" << *xc << ")" << std::endl;
#endif
@ -295,8 +305,8 @@ public:
return oi;
}
const X_monotone_curve_2 * xc1 = object_cast<X_monotone_curve_2>(&(*it++));
const X_monotone_curve_2 * xc2 = 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 = boost::get<X_monotone_curve_2>(&(*it));
#if CGAL_ARR_SPHERICAL_GAUSSIAN_MAP_3_DEBUG==1
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::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::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
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();
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
// (meaning have a common endpoint that lies on the boundary and their degree
// 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;
++vi1;
@ -63,9 +65,9 @@ void Arr_transform_on_sphere(Arrangement & arr,
Arr_parameter_space by =
geom_traits->parameter_space_in_y_2_object()(v_temp->point());
// use vertex->parameter_space_in_x() != interior || vertex->parameter_space_in_y() != interior)
if ((bx != ARR_INTERIOR || by != ARR_INTERIOR) && (v_temp->degree() == 2))
{
// use vertex->parameter_space_in_x() != interior ||
// vertex->parameter_space_in_y() != interior)
if ((bx != ARR_INTERIOR || by != ARR_INTERIOR) && (v_temp->degree() == 2)) {
Curve_2 merged_cv;
Halfedge_around_vertex_circulator havc = v_temp->incident_halfedges();
Halfedge_around_vertex_circulator havc_next = havc;
@ -80,16 +82,13 @@ void Arr_transform_on_sphere(Arrangement & arr,
// Compare the direction of the edges.
bool eq_direction = havc->direction() == havc_next->twin()->direction();
if (point_eq1 && normal_eq1 && eq_direction)
{
if (havc->source()->point() == havc->curve().source())
{
if (point_eq1 && normal_eq1 && eq_direction) {
if (havc->source()->point() == havc->curve().source()) {
merged_cv = Curve_2(havc->source()->point(),
havc_next->twin()->target()->point(),
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(),
havc->source()->point(),
havc->curve().normal());
@ -111,20 +110,17 @@ void Arr_transform_on_sphere(Arrangement & arr,
}
//Rotate all the vertices.
for (Vertex_handle vi1 = arr.vertices_begin(); vi1 != arr.vertices_end() ;
++vi1)
{
for (auto vi1 = arr.vertices_begin(); vi1 != arr.vertices_end(); ++vi1) {
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();
// Rotate all the halfedges.
// The loop is over the initial edges , since new edges are created and
// 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;
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
// the curve.
bool eq1 = hei1->source()->point() == aff.transform(hei1->curve().source());
if (!eq1)
{
if (!eq1) {
hei1 = hei1->twin();
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.
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.
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.
// Since the curves were x_monotone before , can assume that it will be
// splited into 2 parts max.
if (objects.size() == 2)
{
typename std::list<CGAL::Object>::iterator it = objects.begin();
if (objects.size() == 2) {
auto it = objects.begin();
// The curve that its left vertex lies on the identification curve
const X_monotone_curve_2 * sub_cv1 =
object_cast<X_monotone_curve_2>(&(*it));
const auto* sub_cv1 = boost::get<X_monotone_curve_2>(&(*it));
++it;
//The curve that its rigth vertex lies on the identification curve
const X_monotone_curve_2 * sub_cv2 =
object_cast<X_monotone_curve_2>(&(*it));
const auto* sub_cv2 = boost::get<X_monotone_curve_2>(&(*it));
bool eq1 = (*sub_cv1).source() == hei1->source()->point();
bool eq2 = (*sub_cv2).target() == hei1->target()->point();
if (eq1 && eq2)
m_arr_access.split_edge_ex (hei1, (*sub_cv1).target(), *sub_cv1,
*sub_cv2);
m_arr_access.split_edge_ex(hei1, (*sub_cv1).target(), *sub_cv1,
*sub_cv2);
else
CGAL_error_msg
("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
// with boundary conditions
for (Vertex_handle vi = arr.vertices_begin() ; vi != arr.vertices_end() ;
++vi)
{
for (auto vi = arr.vertices_begin(); vi != arr.vertices_end(); ++vi) {
Arr_parameter_space bx =
geom_traits->parameter_space_in_x_2_object()(vi->point());
Arr_parameter_space by =
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
// point.
Halfedge_around_vertex_circulator havc = vi->incident_halfedges();
Arr_curve_end ind;
if (geom_traits->construct_min_vertex_2_object()(havc->curve()) == vi->point())
ind = ARR_MIN_END;
else
ind = ARR_MAX_END;
Arr_curve_end ind =
(geom_traits->construct_min_vertex_2_object()(havc->curve()) ==
vi->point()) ? ARR_MIN_END : ARR_MAX_END;
// Check if it was already added.
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.
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);
}

View File

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

View File

@ -7,9 +7,8 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Author(s): Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
#ifndef 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;
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::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:
// Data members:
const Topology_traits* m_top_traits; // The topology-traits class.
@ -76,10 +81,10 @@ public:
//@}
/*! 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. */
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

View File

@ -7,8 +7,8 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Efi Fogel <efif@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Author(s): Efi Fogel <efif@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
#ifndef 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
* represent the curve end along the face boundary */
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>::
place_boundary_vertex(Face* /* f */,
const X_monotone_curve_2& xc, Arr_curve_end ind,
@ -525,15 +528,18 @@ place_boundary_vertex(Face* /* f */,
,
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;
if (ps_y == ARR_BOTTOM_BOUNDARY) {
if (m_south_pole == nullptr) return Object();
return CGAL::make_object(m_south_pole);
if (m_south_pole == nullptr) return boost::none;
return Result(Non_optional_result(m_south_pole));
}
if (ps_y == ARR_TOP_BOUNDARY) {
if (m_north_pole == nullptr) return Object();
return CGAL::make_object(m_north_pole);
if (m_north_pole == nullptr) return boost::none;
return Result(Non_optional_result(m_north_pole));
}
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) ?
m_geom_traits->construct_min_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()) {
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:
return Object();
return boost::none;
}
/*! \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. */
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,
Arr_parameter_space
#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)
{
typedef boost::variant<Vertex*, Halfedge*, Face*> Result;
// Act according to the boundary conditions.
if (ps_y == ARR_TOP_BOUNDARY) {
// In case the curve end coincides with the north pole, return the vertex
// representing the north pole, if one exists. Otherwise, return the face
// containing this pole (the spherical face).
if (m_north_pole != nullptr) return CGAL::make_object(m_north_pole);
return CGAL::make_object(m_spherical_face);
if (m_north_pole != nullptr) return Result(m_north_pole);
return Result(m_spherical_face);
}
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
// representing the south pole, if one exists. Otherwise, search for the
// 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();
}
else {
@ -625,7 +635,7 @@ locate_curve_end(const X_monotone_curve_2& xc, Arr_curve_end ind,
it = m_boundary_vertices.find(key);
if (it != m_boundary_vertices.end()) {
v = it->second;
return CGAL::make_object(v);
return Result(v);
}
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,
// we know the curve end is contained in the spherical face. Otherwise,
// we return the face that lies below the vertex v.
if (it == m_boundary_vertices.end())
return CGAL::make_object(m_spherical_face);
if (it == m_boundary_vertices.end()) return Result(m_spherical_face);
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 */

View File

@ -7,8 +7,8 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Author(s): Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
#ifndef CGAL_ARR_SPHERICAL_VERT_DECOMP_HELPER_H
#define CGAL_ARR_SPHERICAL_VERT_DECOMP_HELPER_H
@ -44,8 +44,13 @@ private:
public:
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::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:
typedef typename Arrangement_2::Topology_traits Topology_traits;
@ -80,17 +85,17 @@ public:
//@}
/*! Get the current top object. */
CGAL::Object top_object () const
Vert_type top_object () const
{
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. */
CGAL::Object bottom_object () const
Vert_type bottom_object () const
{
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
//
//
// Author(s) : Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Author(s): Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
#ifndef 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.
//
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_>::
place_boundary_vertex(Face *f,
place_boundary_vertex(Face* f,
const X_monotone_curve_2& cv, Arr_curve_end ind,
Arr_parameter_space ps_x, Arr_parameter_space ps_y)
{
// 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;
typedef boost::variant<Vertex*, Halfedge*> Non_optional_result;
typedef boost::optional<Non_optional_result> Result;
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
// contain the relevant curve end.
if (curr->has_null_curve() &&
_is_on_fictitious_edge (cv, ind, ps_x, ps_y, curr,
eq_source, eq_target))
_is_on_fictitious_edge(cv, ind, ps_x, ps_y, curr, eq_source, eq_target))
{
CGAL_assertion (! eq_source && ! eq_target);
return (CGAL::make_object (curr));
CGAL_assertion(! eq_source && ! eq_target);
return Result(curr);
}
// 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
// never happen.
CGAL_error();
return CGAL::Object();
return boost::none;
}
//-----------------------------------------------------------------------------
// Locate a DCEL feature that contains the given unbounded curve end.
//
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,
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
// a feature that contains the curve end.
Halfedge *first = *(fict_face->inner_ccbs_begin());
Halfedge *curr = first;
bool eq_source, eq_target;
Halfedge* first = *(fict_face->inner_ccbs_begin());
Halfedge* curr = first;
bool eq_source, eq_target;
do
{
if (_is_on_fictitious_edge (cv, ind, ps_x, ps_y, curr,
eq_source, eq_target))
do {
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
// fictitious halfedge. This means that cv overlaps the curve that
// is associated with the only non-fictitious halfedge incident to
// this vertex. We therefore return a pointer to this halfedge.
Halfedge *he = curr->opposite()->next();
CGAL_assertion (! he->has_null_curve());
return (CGAL::make_object (he));
Halfedge* he = curr->opposite()->next();
CGAL_assertion(! he->has_null_curve());
return Result(he);
}
else if (eq_target)
{
else if (eq_target) {
// cv's end coincides with the target vertex of the current
// fictitious halfedge. This means that cv overlaps the curve that
// is associated with the only non-fictitious halfedge incident to
// this vertex. We therefore return a pointer to this halfedge.
Halfedge *he = curr->opposite()->prev();
CGAL_assertion (! he->has_null_curve());
return (CGAL::make_object (he));
Halfedge* he = curr->opposite()->prev();
CGAL_assertion(! he->has_null_curve());
return Result(he);
}
// The current ficitious edge contains cv's end in its interior.
// Note we use curr's twin, whose incident face is a valid
// unbounded face (whereas the incident face of curr is the fictitious
// face).
Face *uf = curr->opposite()->outer_ccb()->face();
Face* uf = curr->opposite()->outer_ccb()->face();
CGAL_assertion (uf->is_unbounded() && ! uf->is_fictitious());
return (CGAL::make_object (uf));
return Result(uf);
}
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.
CGAL_error();
return Object();
Vertex* v(nullptr);
return Result(v);
}
//-----------------------------------------------------------------------------

View File

@ -7,9 +7,8 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Author(s): Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
#ifndef 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;
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 boost::variant<Vertex_const_handle, Halfedge_const_handle,
Face_const_handle> Cell_type;
typedef boost::optional<Cell_type> Vert_type;
protected:
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:
const Topology_traits* m_top_traits; // The topology-traits class.
@ -77,10 +80,10 @@ public:
//@}
/*! 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. */
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 {
private:
typename Base::Make_x_monotone_2 m_object;
@ -515,39 +520,43 @@ public:
Make_x_monotone_2(const Base * base, bool enabled = true) :
m_object(base->make_x_monotone_2_object()), m_enabled(enabled) {}
/*! Operate
* \param cv the curve
* \param oi an output iterator that contains the result. It's value
* type is CGAL::Object, which wraps either an x-monotone curve or a point
* \return the output iterator
/*! 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 X_monotone_curve_2 objects.
* \return the output iterator.
*/
template<typename OutputIterator>
template <typename OutputIterator>
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
<< " 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));
if (container.empty()) return oi;
std::list<CGAL::Object>::iterator it;
unsigned int i = 0;
for (it = container.begin(); it != container.end(); ++it) {
X_monotone_curve_2 xcv;
if (assign (xcv, *it)) {
std::cout << " result[" << i++ << "]: xcv: " << xcv << std::endl;
size_t i = 0;
for (auto it = container.begin(); it != container.end(); ++it) {
if (const auto* xcv = boost::get<X_monotone_curve_2>(*it)) {
std::cout << " result[" << i++ << "]: xcv: " << *xcv << std::endl;
continue;
}
Point_2 p;
if (assign (p, *it)) {
std::cout << " result[" << i++ << "]: p: " << p << std::endl;
if (const Point_2* p = boost::get<Point_2>(*it)) {
std::cout << " result[" << i++ << "]: p: " << *p << std::endl;
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();
return oi;
}
@ -597,14 +606,14 @@ public:
Intersect_2(const Base* base, bool enabled = true) :
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 xcv2 the ssecond curve
* \param oi an output iterator that contains the result. It's value
* type is CGAL::Object, which wraps either an x-monotone overlapping
* curve or pair that consists of an intersection point and its
* multiplicity
* \return the output iterator
* \param oi the output iterator for the result. It value type is a variant
* that wraps an x-monotone overlapping curve or a pair that
* consists of the intersection point and its multiplicity
* \return the past-the-end output iterator.
*/
template <typename OutputIterator>
OutputIterator operator()(const X_monotone_curve_2 & xcv1,

View File

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

View File

@ -7,7 +7,7 @@
// $Id$
// 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
#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
* "batched vertical ray-shooting" query from all arrangement vertices.
* \param arr The arrangement.
* \param oi Output: An output iterator of the vertices, each paired with
* a pair of arrangement features that lie below and above
* it, respectively.
* The vertices are sorted by increasing xy-order.
* \param oi An output iterator of the vertices, each paired with a pair of
* arrangement features that lie below and above it, respectively.
* 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.
* \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,
typename OutputIterator>

View File

@ -8,27 +8,29 @@
// 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
#define CGAL_ARR_COMPUTE_ZONE_VISITOR_H
#include <CGAL/license/Arrangement_on_surface_2.h>
/*! \file
* Definition of the Arr_compute_zone_visitor class.
*/
#include <boost/variant.hpp>
namespace CGAL {
/*! \class
* A visitor class for Arrangement_zone_2, which outputs the
* zone of an x-monotone curve. Meaning, it output the arrangment's
* vertices, edges and faces that the x-monotone curve intersects.
* A visitor class for Arrangement_zone_2 that outputs the zone of an
* x-monotone curve. Specifically, it outputs handles to the the arrangment
* cells that the x-monotone curve intersects.
* The class should be templated by an Arrangement_2 class, and by an
* output iterator of CGAL Objects, where we store all arrangement
* features the x-monotone curve intersects.
* output iterator of a variant of types of handles to the arrangement cells
* that appear in the zone, namely, vertex, halfedge, and face handles.
*/
template <class Arrangement_, class OutputIterator_>
class Arr_compute_zone_visitor
@ -53,7 +55,7 @@ private:
const Vertex_handle invalid_v; // Invalid vertex.
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
// output the left end point of a
// subcurve (to avoid outputing
@ -65,8 +67,8 @@ public:
Arr_compute_zone_visitor (OutputIterator& oi) :
invalid_he(),
invalid_v(),
out_iter (oi),
output_left (true)
out_iter(oi),
output_left(true)
{}
/*! Initialize the visitor. */
@ -90,50 +92,35 @@ public:
* \return A handle to the halfedge obtained from the insertion of the
* subcurve into the arrangement.
*/
Result found_subcurve (const X_monotone_curve_2&,
Face_handle face,
Vertex_handle left_v, Halfedge_handle left_he,
Vertex_handle right_v, Halfedge_handle right_he)
Result found_subcurve(const X_monotone_curve_2&,
Face_handle face,
Vertex_handle left_v, Halfedge_handle left_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
// to its left endpoint. This way we avoid reporting the same feature
// twice.
if (left_v != invalid_v)
{
*out_iter = CGAL::make_object (left_v);
++out_iter;
}
else if (left_he != invalid_he)
{
*out_iter = CGAL::make_object (left_he);
++out_iter;
}
if (left_v != invalid_v) *out_iter++ = Zone_result(left_v);
else if (left_he != invalid_he) *out_iter++ = Zone_result(left_he);
output_left = false;
}
// Report the face that contains the interior of the subcurve.
*out_iter = CGAL::make_object (face);
++out_iter;
*out_iter++ = Zone_result(face);
// If the right endpoint of the subcurve is incident to an arrangement
// vertex or an arrangement edge, report this feature.
if (right_v != invalid_v)
{
*out_iter = CGAL::make_object(right_v);
++out_iter;
}
else if (right_he != invalid_he)
{
*out_iter = CGAL::make_object(right_he);
++out_iter;
}
if (right_v != invalid_v) *out_iter++ = Zone_result(right_v);
else if (right_he != invalid_he) *out_iter++ = Zone_result(right_he);
// We did not modify the arrangement, so we return an invalid handle
// 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,
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
// to its left endpoint. This way we avoid reporting the same feature
// twice.
if (left_v != invalid_v)
{
*out_iter = CGAL::make_object (left_v);
++out_iter;
}
if (left_v != invalid_v) *out_iter++ = Zone_result(left_v);
output_left = false;
}
// Report the arrangement edge the curve currently overlaps.
*out_iter = CGAL::make_object(he);
++out_iter;
*out_iter++ = Zone_result(he);
// If the right endpoint of the overlapping subcurve is incident to an
// arrangement vertex, report this vertex as well.
if (right_v != invalid_v)
{
*out_iter = CGAL::make_object (right_v);
++out_iter;
}
if (right_v != invalid_v) *out_iter++ = Zone_result(right_v);
// We did not modify the arrangement, so we return an invalid handle
// 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
// $Date$
//
//
// Author(s): Ron Wein <wein@post.tau.ac.il>s
// Efi Fogel <efif@post.tau.ac.il>
// Eric Berberich <eric@mpi-inf.mpg.de>
@ -24,7 +23,6 @@
#include <CGAL/license/Arrangement_on_surface_2.h>
/*! \file
* Definitions of the adaptor classes for the arrangement traits class.
*/
@ -50,6 +48,7 @@ public:
typedef Arr_traits_basic_adaptor_2<Base> Self;
typedef typename Base::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Base::Point_2 Point_2;
typedef typename Base::Multiplicity Multiplicity;
// Categories
typedef typename Base::Has_left_category Has_left_category;
@ -320,9 +319,12 @@ public:
const X_monotone_curve_2& xcv2,
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));
return !intersections.empty();
return ! intersections.empty();
}
};
@ -665,7 +667,7 @@ public:
return parameter_space_in_y(xcv, ind, Psy_2_curve_end_tag());
}
/*!
/*!
* Obtain the location of the given curve end in y.
* \param xcv The curve.
* \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::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Base::Point_2 Point_2;
typedef typename Base::Multiplicity Multiplicity;
// Categories.
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.
*/
class Compare_xy_2 {
typedef std::pair<Point_2, Multiplicity> Intersection_point;
typedef boost::variant<Intersection_point, X_monotone_curve_2>
Intersection_result;
public:
/*! Compare two points lexigoraphically: by x, then by y.
* \param p1 the first point.
@ -2360,7 +2367,7 @@ public:
Comparison_result operator()(const X_monotone_curve_2& c1,
const X_monotone_curve_2& c2) const
{
std::list<CGAL::Object> intersections;
std::list<Intersection_result> intersections;
return operator()(c1, c2, intersections,
Are_all_sides_oblivious_category());
}
@ -2586,7 +2593,7 @@ public:
Comparison_result
compare_remainder(const X_monotone_curve_2& c1,
const X_monotone_curve_2& c2,
std::list<CGAL::Object>& intersections) const
std::list<Intersection_result>& intersections) const
{
// Right-most sections are equal.
// Advance to the next respective sections:
@ -2597,9 +2604,9 @@ public:
}
// Verify the first intersection is an overlap, remove it, and
// recursively call.
CGAL::Object first = intersections.front();
X_monotone_curve_2 xcv;
if (!assign(xcv, first)) {
const X_monotone_curve_2* xcv =
boost::get<X_monotone_curve_2>(&(intersections.front()));
if (! xcv) {
CGAL_error_msg("The first intersection is not an overlap!");
return SMALLER;
}
@ -2611,10 +2618,9 @@ public:
typedef typename Self::Split_2 Split_2;
Split_2 split = m_self.split_2_object();
X_monotone_curve_2 c11, c12, c21, c22;
Construct_max_vertex_2 ctr_max =
m_self.construct_max_vertex_2_object();
const Point_2& p1 = ctr_max(xcv);
const Point_2& p2 = ctr_max(xcv);
Construct_max_vertex_2 ctr_max = m_self.construct_max_vertex_2_object();
const Point_2& p1 = ctr_max(*xcv);
const Point_2& p2 = ctr_max(*xcv);
split(c1, p1, c11, c12);
split(c2, p2, c21, c22);
return operator()(c12, c22, intersections,
@ -2625,7 +2631,7 @@ public:
*/
Comparison_result operator()(const X_monotone_curve_2& c1,
const X_monotone_curve_2& c2,
std::list<CGAL::Object>& intersections,
std::list<Intersection_result>& intersections,
Arr_all_sides_oblivious_tag) const
{
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,
const X_monotone_curve_2& c2,
std::list<CGAL::Object>& intersections,
std::list<Intersection_result>& intersections,
Arr_not_all_sides_oblivious_tag) const
{
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
//
//
// Author(s) : Ron Wein <wein@post.tau.ac.il>
// Baruch Zukerman <baruchzu@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Author(s): Ron Wein <wein@post.tau.ac.il>
// Baruch Zukerman <baruchzu@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
//
#ifndef 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_do_intersect_zone_visitor.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/Surface_sweep_2/Arr_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 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.
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);
// Break the input curve into x-monotone subcurves and isolated points.
std::list<CGAL::Object> 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;
arr.geometry_traits()->
make_x_monotone_2_object()(c, std::back_inserter(x_objects));
std::list<Make_x_monotone_result> x_objects;
const auto* traits = arr.geometry_traits();
traits->make_x_monotone_2_object()(c, std::back_inserter(x_objects));
// 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.
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) {
// Inserting an x-monotone 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
// completed.
arr_access.notify_after_global_change();
continue;
}
else {
iso_p = object_cast<typename Gt2::Point_2>(&(*obj_iter));
CGAL_assertion(iso_p != nullptr);
const auto* iso_p = boost::get<Point_2>(&x_obj);
CGAL_assertion(iso_p != nullptr);
// Inserting a point into the arrangement:
insert_point(arr, *iso_p, pl);
}
// Inserting a point into the arrangement:
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>
void insert(Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr,
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 TopologyTraits Tt;
@ -597,7 +598,8 @@ template <typename GeometryTraits_2, typename TopologyTraits>
CGAL_DEPRECATED void insert_x_monotone_curve
(Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr,
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);
}
@ -658,6 +660,7 @@ insert_non_intersecting_curve
Traits_adaptor_2;
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;
CGAL_USE_TYPE(Halfedge_const_handle);
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
// arrangement accordingly.
const Arr_parameter_space bx1 =
geom_traits->parameter_space_in_x_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;
auto bx1 = 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 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)) {
// We have a normal left endpoint with no boundary conditions:
// 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
// and existing vertex vh1.
CGAL_precondition_msg
(object_cast<Halfedge_const_handle>(&obj1) == nullptr,
"The curve must not intersect an existing edge.");
CGAL_precondition_msg(boost::get<Halfedge_const_handle>(&obj1) == nullptr,
"The curve must not intersect an existing edge.");
vh1 = object_cast<Vertex_const_handle>(&obj1);
}
else {
// We have a left end with boundary conditions. Use the accessor to locate
// the feature that contains it.
obj1 = arr_access.locate_curve_end(c, ARR_MIN_END, bx1, by1);
CGAL_precondition_msg
(object_cast<Halfedge_const_handle>(&obj1) == nullptr,
"The curve must not overlap an existing edge.");
vh1 = object_cast<Vertex_const_handle>(&obj1);
CGAL_precondition_msg(boost::get<Halfedge_const_handle>(&obj1) == nullptr,
"The curve must not overlap an existing edge.");
}
vh1 = Pl_result::template assign<Vertex_const_handle>(&obj1);
// Check whether the right end has boundary conditions, and locate it in the
// arrangement accordingly.
const Arr_parameter_space bx2 =
geom_traits->parameter_space_in_x_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;
auto bx2 = 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 Vertex_const_handle* vh2 = nullptr;
typename Pl_result::type obj2;
if ((bx2 == ARR_INTERIOR) && (by2 == ARR_INTERIOR)) {
// We have a normal right endpoint with no boundary conditions:
// 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
// and existing vertex vh2.
CGAL_precondition_msg
(object_cast<Halfedge_const_handle>(&obj2) == nullptr,
"The curve must not intersect an existing edge.");
vh2 = object_cast<Vertex_const_handle>(&obj2);
CGAL_precondition_msg(boost::get<Halfedge_const_handle>(&obj2) == nullptr,
"The curve must not intersect an existing edge.");
}
else {
// We have a right end with boundary conditions. Use the accessor to locate
@ -728,13 +721,10 @@ insert_non_intersecting_curve
// << ", by2: " << by2
// << std::endl;
obj2 = arr_access.locate_curve_end(c, ARR_MAX_END, bx2, by2);
CGAL_precondition_msg
(object_cast<Halfedge_const_handle>(&obj2) == nullptr,
"The curve must not overlap an existing edge.");
vh2 = object_cast<Vertex_const_handle>(&obj2);
CGAL_precondition_msg(boost::get<Halfedge_const_handle>(&obj2) == nullptr,
"The curve must not overlap an existing edge.");
}
vh2 = Pl_result::template assign<Vertex_const_handle>(&obj2);
// Notify the arrangement observers that a global operation is about to
// take place.
@ -776,10 +766,8 @@ insert_non_intersecting_curve
// we must insert the curve in the interior of a face.
// In this case insert_in_face_interior() already returns a halfedge
// directed from left to right.
const typename Arr::Face_const_handle* fh1 =
object_cast<typename Arr::Face_const_handle>(&obj1);
const typename Arr::Face_const_handle* fh2 =
object_cast<typename Arr::Face_const_handle>(&obj2);
const Face_const_handle* fh1 = boost::get<Face_const_handle>(&obj1);
const Face_const_handle* fh2 = boost::get<Face_const_handle>(&obj2);
// std::cout << arr << std::endl;
// 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 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.
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;
// 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
// take place.
Arr_accessor<Arr> arr_access (arr);
Arr_accessor<Arr> arr_access(arr);
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
// this face.
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 {
// In this case p lies on an existing vertex, so we just update this
// vertex.
vh = object_cast<typename Arr::Vertex_const_handle>(&obj);
CGAL_assertion (vh != nullptr);
const Halfedge_const_handle* hh = boost::get<Halfedge_const_handle>(&obj);
if (hh != 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;
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
@ -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
// check that this vertex is really contained in the proper face.
typename Gt2::Compare_y_at_x_right_2 comp_y_at_x_right =
traits->compare_y_at_x_right_2_object();
typename Gt2::Compare_y_at_x_left_2 comp_y_at_x_left =
traits->compare_y_at_x_left_2_object();
auto comp_y_at_x_right = traits->compare_y_at_x_right_2_object();
auto 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);
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;
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.
curr_v = vf_iter->first;
obj = def_pl.ray_shoot_down(curr_v->point());
Vertex_const_handle curr_v = vf_iter->first;
auto obj = def_pl.ray_shoot_down(curr_v->point());
if (CGAL::assign(he_below, obj)) {
// Hit an edge - take the incident face of the halfedge directed to the
// if (CGAL::assign(he_below, obj)) {
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.
if (he_below->direction() == ARR_RIGHT_TO_LEFT)
he_below = he_below->twin();
in_face = he_below->face();
auto he_below = *he_below_p;
in_face = (he_below->direction() == ARR_RIGHT_TO_LEFT) ?
he_below->twin()->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.
if (v_below->is_isolated()) in_face = v_below->face();
else {
// 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.
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_right; // A halfedge to the right of v_below.
do {
if (circ->direction() == ARR_LEFT_TO_RIGHT) {
he_left = circ;
}
if (circ->direction() == ARR_LEFT_TO_RIGHT) he_left = circ;
else {
he_right = circ;
if (he_left != invalid_he && he_right != invalid_he)
break;
if ((he_left != invalid_he) && (he_right != invalid_he)) 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) {
while (he_left->direction() == ARR_LEFT_TO_RIGHT)
@ -1460,26 +1435,24 @@ is_valid(const Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr)
else {
Comparison_result res;
Halfedge_const_handle he_curr = he_right;
do // as long as we have he_right halfedge which is below
{
do {
// as long as we have he_right halfedge which is below
he_right = he_curr;
he_curr = he_right->next()->twin();
res = comp_y_at_x_right (he_curr->curve(),
he_right->curve(),
v_below->point());
res = comp_y_at_x_right(he_curr->curve(),
he_right->curve(),
v_below->point());
} while(res == SMALLER);
in_face = he_right->face();
}
}
}
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).
assign_ok = CGAL::assign(in_face, obj);
CGAL_assertion (assign_ok && in_face->is_unbounded());
if (! assign_ok) return false;
CGAL_assertion(in_face->is_unbounded());
}
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.
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 =
static_cast<const Traits_adaptor_2*>(arr.geometry_traits());
std::list<CGAL::Object> 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;
std::list<Make_x_monotone_result> x_objects;
traits->make_x_monotone_2_object()(c, std::back_inserter(x_objects));
// 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.
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) {
// Check if the x-monotone subcurve intersects the arrangement.
if (do_intersect(arr, *x_curve, pl) == true)
return true;
if (do_intersect(arr, *x_curve, pl) == 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,
// it conincides with a vertex or an edge).
CGAL::Object obj = pl.locate (*iso_p);
const Point_2* iso_p = boost::get<Point_2>(&x_obj);
CGAL_assertion(iso_p != nullptr);
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.
@ -1651,8 +1623,8 @@ do_intersect(Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr,
template <typename GeometryTraits_2, typename TopologyTraits, typename Curve,
typename PointLocation>
bool
do_intersect (Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr,
const Curve& c, const PointLocation& pl)
do_intersect(Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr,
const Curve& c, const PointLocation& pl)
{
typedef GeometryTraits_2 Gt2;

View File

@ -7,16 +7,15 @@
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Eric Berberich <eric.berberich@cgal.org>
// (based on old version by: Iddo Hanniel,
// Eyal Flato,
// Oren Nechushtan,
// Ester Ezra,
// Shai Hirsch,
// and Eugene Lipovetsky)
// Author(s): Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Eric Berberich <eric.berberich@cgal.org>
// (based on old version by: Iddo Hanniel,
// Eyal Flato,
// Oren Nechushtan,
// Ester Ezra,
// Shai Hirsch,
// and Eugene Lipovetsky)
#ifndef CGAL_ARRANGEMENT_ON_SURFACE_2_IMPL_H
#define CGAL_ARRANGEMENT_ON_SURFACE_2_IMPL_H
@ -32,6 +31,8 @@
* class-template.
*/
#include <boost/variant.hpp>
#include <CGAL/function_objects.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
// given curve end.
CGAL::Object obj =
m_topol_traits.place_boundary_vertex(f, cv, ind, ps_x, ps_y);
DVertex* v;
DHalfedge* fict_he;
auto obj = m_topol_traits.place_boundary_vertex(f, cv, ind, ps_x, ps_y);
// 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
// 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.
// 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),
Halfedge_handle((*p_pred)->next()));
return v;
}
else if (CGAL::assign(v, obj)) {
// In this case we are given an existing vertex that represents the curve
// end. We now have to locate the predecessor edge for the insertion of cv
// around this vertex.
*p_pred =
m_topol_traits.locate_around_boundary_vertex(v, cv, ind, ps_x, ps_y);
}
else {
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.
DVertex** v_p = boost::get<DVertex*>(&*obj);
CGAL_assertion(v_p != nullptr);
DVertex* v = *v_p;
CGAL_assertion(v != nullptr);
// In this case we are given an existing vertex that represents the curve
// end. We now have to locate the predecessor edge for the insertion of cv
// around this vertex.
*p_pred = m_topol_traits.locate_around_boundary_vertex(v, cv, ind, ps_x, ps_y);
return v;
}

View File

@ -29,7 +29,7 @@ namespace CGAL {
//
template <typename Arrangement, typename 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
// 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).
const Vertex_const_handle* vh;
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);
// The left endpoint coincides with an existing vertex:
@ -119,7 +118,7 @@ void Arrangement_zone_2<Arrangement, ZoneVisitor>::compute_zone()
#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) {
// Obtain the right halfedge from the halfedge-pair containing m_left_pt
// in their interior.
@ -160,7 +159,7 @@ void Arrangement_zone_2<Arrangement, ZoneVisitor>::compute_zone()
}
else {
// 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,
"Invalid object returned by the point-location query.");

View File

@ -46,6 +46,8 @@
#include <CGAL/Iterator_project.h>
#include <CGAL/Iterator_transform.h>
#include <boost/pool/pool_alloc.hpp>
namespace CGAL {
/*! \class Arrangement_on_surface_2
@ -64,7 +66,7 @@ class Arrangement_on_surface_2 {
public:
typedef GeomTraits_ Geometry_traits_2;
typedef TopTraits_ Topology_traits;
typedef CGAL_ALLOCATOR(int) Allocator;
typedef boost::fast_pool_allocator<int> Allocator;
// first define adaptor ...
typedef Arr_traits_basic_adaptor_2<Geometry_traits_2> Traits_adaptor_2;
@ -308,6 +310,10 @@ public:
Base(iter, iend, pred)
{}
Edge_iterator(const Base& base) :
Base(base)
{}
// Casting to a halfedge iterator.
operator Halfedge_iterator() const
{
@ -342,6 +348,10 @@ public:
Base(iter, iend, pred)
{}
Edge_const_iterator(const Base& base) :
Base(base)
{}
// Casting to a halfedge iterator.
operator Halfedge_const_iterator() const
{
@ -432,6 +442,10 @@ public:
Base(iter, iend, is_unbounded)
{}
Unbounded_face_const_iterator(const Base& base) :
Base(base)
{}
// Casting to a face iterator.
operator Face_const_iterator() const
{
@ -2818,7 +2832,8 @@ void insert(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
template <typename GeomTraits, typename TopTraits>
void insert(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
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
@ -2934,16 +2949,16 @@ remove_vertex(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
template <typename GeomTraits, typename TopTraits>
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
* x-monotone curve intersects.
* \param arr The arrangement.
* \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 pi The point location strategy that is used to locate the starting
* point.
* \return The output iterator that the curves were inserted to.
* \param c the x-monotone curve that its zone is computed.
* \param oi the output iterator for the resulting zone elements. Its
* dereference type is a variant that wraps a \c Vertex_handle, a
* \c Halfedge_handle, or a \c Face_handle.
* \param pl the point location strategy used to locate the starting point.
* \return the past-the-end output iterator.
*/
template <typename GeomTraits, typename TopTraits,
typename OutputIterator, typename PointLocation>
@ -2957,9 +2972,11 @@ OutputIterator zone(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
* Overloaded version with no point location object - the walk point-location
* strategy is used as default.
* \param arr The arrangement.
* \param c The x-monotone curve that its zone was computed.
* \param oi Output iterator of CGAL::Object to insert the zone elements to.
* \return The output iterator that the curves were inserted to.
* \param c the x-monotone curve that its zone was computed.
* \param oi the output iterator for the resulting zone elements. Its
* 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>
OutputIterator zone(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,

View File

@ -28,6 +28,7 @@
#include <CGAL/Arr_tags.h>
#include <CGAL/Arr_accessor.h>
#include <CGAL/Arrangement_2/Arr_traits_adaptor_2.h>
#include <CGAL/Arr_point_location_result.h>
#include <list>
#include <map>
@ -113,6 +114,9 @@ protected:
typedef std::set<const X_monotone_curve_2*> Curves_set;
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:
Arrangement_2& m_arr; // The associated arrangement.
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
// 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_left_on_boundary; // Is the left point on the boundary.
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
* 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
* notifications for the visitor.

View File

@ -1410,9 +1410,9 @@ public:
* Functor that computes the intersections of two arcs
*/
template < class CurvedKernelViaAnalysis_2 >
class Intersect_2 : public
Curved_kernel_via_analysis_2_functor_base< CurvedKernelViaAnalysis_2 > {
class Intersect_2 :
public Curved_kernel_via_analysis_2_functor_base<CurvedKernelViaAnalysis_2>
{
public:
//! this instance' first template parameter
typedef CurvedKernelViaAnalysis_2 Curved_kernel_via_analysis_2;
@ -1420,13 +1420,17 @@ public:
//! the base type
typedef
Curved_kernel_via_analysis_2_functor_base< Curved_kernel_via_analysis_2 >
Base;
Base;
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
typedef CGAL::cpp98::iterator< std::output_iterator_tag, CGAL::Object >
result_type;
typedef CGAL::cpp98::iterator<std::output_iterator_tag, Intersection_result>
result_type;
//! the arity of the functor
@ -1458,11 +1462,6 @@ public:
template < class OutputIterator >
OutputIterator operator()(const Arc_2& cv1, const Arc_2& cv2,
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
<< ";\n cv2:" << cv2 << "");
@ -1860,100 +1859,110 @@ public:
/*!\brief
* 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
Curved_kernel_via_analysis_2_functor_base< CurvedKernelViaAnalysis_2 > {
Curved_kernel_via_analysis_2_functor_base<CurvedKernelViaAnalysis_2> {
public:
//! this instance' first template parameter
typedef CurvedKernelViaAnalysis_2 Curved_kernel_via_analysis_2;
//! this instance' first template parameter
typedef CurvedKernelViaAnalysis_2 Curved_kernel_via_analysis_2;
//! the base type
typedef
Curved_kernel_via_analysis_2_functor_base< Curved_kernel_via_analysis_2 >
//! the base type
typedef
Curved_kernel_via_analysis_2_functor_base< Curved_kernel_via_analysis_2>
Base;
CGAL_CKvA_2_GRAB_BASE_FUNCTOR_TYPES
CGAL_CKvA_2_GRAB_BASE_FUNCTOR_TYPES
//! the result type
typedef CGAL::cpp98::iterator< std::output_iterator_tag, CGAL::Object >
//! the result type
typedef CGAL::cpp98::iterator< std::output_iterator_tag, CGAL::Object>
result_type;
//! the arity of the functor
//! the arity of the functor
/*!\brief
* Standard constructor
*
* \param kernel The kernel
*/
Make_x_monotone_2(Curved_kernel_via_analysis_2 *kernel) :
Base(kernel) {
}
/*!\brief
* Standard constructor
*
* \param kernel The kernel
*/
Make_x_monotone_2(Curved_kernel_via_analysis_2* kernel) :
Base(kernel)
{}
/*!\brief
* Decomposes a given arc into list of x-monotone arcs
* (subcurves) and insert them to the output iterator. Since \c Arc_2
* is by definition x-monotone, an input arc is passed to the
* output iterator directly.
*
* \param cv The arc
* \param oi The output iterator, whose value-type is Object
* The returned objects are all wrappers Arc_2 objects
* \return The past-the-end iterator
*/
template < class OutputIterator >
OutputIterator operator()(const Arc_2& cv, OutputIterator oi) const {
/*!\brief
* Decomposes a given arc into list of x-monotone arcs
* (subcurves) and insert them to the output iterator. Since \c Arc_2
* is by definition x-monotone, an input arc is passed to the
* output iterator directly.
*
* \param cv The arc
* \param oi The output iterator, whose value-type is Object
* The returned objects are all wrappers Arc_2 objects
* \return The past-the-end iterator
*/
template <class OutputIterator>
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);
return oi;
}
/*!\brief
* 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
* 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 {
return make_x_monotone(cv, oi);
}
CGAL::internal::Make_x_monotone_2< Curved_kernel_via_analysis_2 >
make_x_monotone(Base::_ckva());
/*!\brief
* 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
* 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::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;
}
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 if (CGAL::assign(xcv, obj)) *oi++ = Make_x_monotone_result(xcv);
else if (CGAL::assign(p, obj)) *oi++ = Make_x_monotone_result(p);
else CGAL_error();
return oi;
}
};

View File

@ -169,12 +169,10 @@ public:
Coordinate_1 asym_info1, asym_info2;
CGAL::Arr_parameter_space ps1, ps2;
obj1 = cv1.curve().asymptotic_value_of_arc(
cv1.location(ce), cv1.arcno()
);
obj2 = cv2.curve().asymptotic_value_of_arc(
cv2.location(ce), cv2.arcno()
);
obj1 =
cv1.curve().asymptotic_value_of_arc(cv1.location(ce), cv1.arcno());
obj2 =
cv2.curve().asymptotic_value_of_arc(cv2.location(ce), cv2.arcno());
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.
*
* 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,
class ConstructArc_2 =
typename CurvedKernelViaAnalysis_2::Construct_arc_2 >
struct Make_x_monotone_2 :
public CGAL::cpp98::binary_function< typename CurvedKernelViaAnalysis_2::Curve_2,
CGAL::cpp98::iterator<std::output_iterator_tag, CGAL::Object>,
CGAL::cpp98::iterator<std::output_iterator_tag, CGAL::Object> > {
public CGAL::cpp98::binary_function<
typename CurvedKernelViaAnalysis_2::Curve_2,
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
//!@{
@ -87,242 +98,250 @@ struct Make_x_monotone_2 :
typedef typename Curved_kernel_via_analysis_2::Non_x_monotone_arc_2
Non_x_monotone_arc_2;
//!@}
//!@}
//!\name Constructors
//!@{
//!\name Constructors
//!@{
/*!\brief
* Standard constructor
*
* \param kernel The kernel instance to use
*/
Make_x_monotone_2(Curved_kernel_via_analysis_2 *kernel) :
_m_curved_kernel(kernel) {
CGAL_assertion(kernel != nullptr);
/*!\brief
* Standard constructor
*
* \param kernel The kernel instance to use
*/
Make_x_monotone_2(Curved_kernel_via_analysis_2 *kernel) :
_m_curved_kernel(kernel)
{
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
* Splits a curve into x-monotone arcs and isolated points
*
* \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) {
for (k = 0; k < evt_line1.number_of_events(); k++)
max_pts.push_back(construct_point(max_x, curve, k));
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;
}
//std::cout << "handling events over the 1st interval\n";
for (k = 0; k < int_line.number_of_events(); k++) {
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++ = CGAL::make_object(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();
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++ = Make_x_monotone_result(arc);
}
min_pts = max_pts;
max_pts.clear();
min_x = max_x;
typename Curved_kernel_via_analysis_2::Construct_point_2
construct_point =
_m_curved_kernel->construct_point_2_object();
// 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);
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();
n = evt_line2.number_of_events();
for (k = 0; k < n; k++)
max_pts.push_back(construct_point(max_x, curve, k));
for(k = 0; k < evt_line1.number_of_events(); k++)
max_pts.push_back(construct_point(max_x, curve, k));
//std::cout << "handling events over the 1st interval\n";
for(k = 0; k < int_line.number_of_events(); k++) {
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 ?
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);
if (info1.second != CGAL::ARR_INTERIOR) {
inf1_end = (info1.second == CGAL::ARR_BOTTOM_BOUNDARY ?
CGAL::ARR_MIN_END : CGAL::ARR_MAX_END);
if (info2.second != CGAL::ARR_INTERIOR) {
arc = construct_arc_2(min_x, inf1_end, max_x, inf2_end,
curve, k);
} else {
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;
if (info1.second != CGAL::ARR_INTERIOR) {
inf1_end = (info1.second == CGAL::ARR_BOTTOM_BOUNDARY ?
CGAL::ARR_MIN_END : CGAL::ARR_MAX_END);
if (info2.second != CGAL::ARR_INTERIOR) {
arc = construct_arc_2(min_x, inf1_end, max_x, inf2_end,
curve, k);
}
else {
arc = construct_arc_2(max_pts[info2.first], min_x,
inf1_end, curve, k, info2.first);
}
}
// 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++ = CGAL::make_object(arc);
else if (info2.second != CGAL::ARR_INTERIOR) {
arc = construct_arc_2(min_pts[info1.first], max_x,
inf2_end, curve, k, info1.first);
}
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:
//!\name Private members
//!@{
//!\name Private members
//!@{
/*!\brief
* Constructs vertical arcs and isolated points at event line
*
* \param cv_line The event line in focus
* \param x x-coordinate of event
* \param pts Points at event line
* \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 _handle_vertical_and_isolated(
Status_line_1 cv_line,
Coordinate_1 x, std::vector<Point_2> pts,
OutputIterator oi) const {
/*!\brief
* Constructs vertical arcs and isolated points at event line
*
* \param cv_line The event line in focus
* \param x x-coordinate of event
* \param pts Points at event line
* \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 <class OutputIterator>
OutputIterator
_handle_vertical_and_isolated(Status_line_1 cv_line,
Coordinate_1 x, std::vector<Point_2> pts,
OutputIterator oi) const
{
typedef boost::variant<Point_2, Arc_2> Make_x_monotone_result;
Construct_arc_2 construct_arc_2 =
_m_curved_kernel->construct_arc_2_object();
Construct_arc_2 construct_arc_2 =
_m_curved_kernel->construct_arc_2_object();
int n = cv_line.number_of_events(), j;
if(cv_line.covers_line()) { // look for vertical arcs
if(n > 0) {
// the first vertical ray
*oi++ = CGAL::make_object(
construct_arc_2(pts[0], CGAL::ARR_MIN_END, _m_curve)
);
for(j = 0; j < n-1; j++) // interior bounded arcs
*oi++ = CGAL::make_object(construct_arc_2(pts[j], pts[j+1],
_m_curve));
// the last vertical ray
*oi++ = CGAL::make_object(construct_arc_2(pts[n-1],
CGAL::ARR_MAX_END, _m_curve));
} else // unbounded vertical line
*oi++ = CGAL::make_object(construct_arc_2(x, _m_curve));
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++ = CGAL::make_object(construct_point(x, _m_curve, j));
}
}
return oi;
int n = cv_line.number_of_events(), j;
if (cv_line.covers_line()) { // look for vertical arcs
if (n > 0) {
// the first vertical ray
*oi++ =
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
*oi++ = Make_x_monotone_result(construct_arc_2(pts[j], pts[j+1],
_m_curve));
// the last vertical ray
*oi++ =
Make_x_monotone_result(construct_arc_2(pts[n-1], CGAL::ARR_MAX_END,
_m_curve));
}
else // unbounded vertical line
*oi++ = Make_x_monotone_result(construct_arc_2(x, _m_curve));
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
Curved_kernel_via_analysis_2 *_m_curved_kernel;
//!\name Private data
//!@{
//! to avoid passing curve as a parameter
Curve_analysis_2 _m_curve;
//! pointer to \c Curved_kernel_via_analysis_2
Curved_kernel_via_analysis_2 *_m_curved_kernel;
//!@}
}; // struct Make_x_monotone
//! to avoid passing curve as a parameter
Curve_analysis_2 _m_curve;
//!@}
}; // struct Make_x_monotone
} // namespace internal

View File

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

View File

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

View File

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

View File

@ -8,9 +8,9 @@
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
// Author(s): Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
#ifndef 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 <CGAL/Arr_tags.h>
#include <CGAL/Object.h>
namespace CGAL {

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