More bugs fixed. Additional test cases added

This commit is contained in:
Fernando Cacciola 2006-03-09 17:02:27 +00:00
parent 70ae2964dd
commit 176f4b23e3
47 changed files with 800 additions and 573 deletions

22
.gitattributes vendored
View File

@ -1482,6 +1482,7 @@ Straight_skeleton_2/demo/Straight_skeleton_2/data/square.poly -text
Straight_skeleton_2/demo/Straight_skeleton_2/data/triangle.poly -text Straight_skeleton_2/demo/Straight_skeleton_2/data/triangle.poly -text
Straight_skeleton_2/demo/Straight_skeleton_2/data/vertex_event_0.poly -text Straight_skeleton_2/demo/Straight_skeleton_2/data/vertex_event_0.poly -text
Straight_skeleton_2/demo/Straight_skeleton_2/data/vertex_event_9.poly -text Straight_skeleton_2/demo/Straight_skeleton_2/data/vertex_event_9.poly -text
Straight_skeleton_2/demo/Straight_skeleton_2/definitions.h -text
Straight_skeleton_2/doc_tex/Straight_skeleton_2/fig0.eps -text Straight_skeleton_2/doc_tex/Straight_skeleton_2/fig0.eps -text
Straight_skeleton_2/doc_tex/Straight_skeleton_2/fig0.pdf -text Straight_skeleton_2/doc_tex/Straight_skeleton_2/fig0.pdf -text
Straight_skeleton_2/doc_tex/Straight_skeleton_2/fig0.png -text Straight_skeleton_2/doc_tex/Straight_skeleton_2/fig0.png -text
@ -1517,14 +1518,34 @@ Straight_skeleton_2/test/Straight_skeleton_2/data/alley_2.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/alley_3.poly -text Straight_skeleton_2/test/Straight_skeleton_2/data/alley_3.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/closer_edge_event_0.poly -text Straight_skeleton_2/test/Straight_skeleton_2/data/closer_edge_event_0.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/closer_edge_event_1.poly -text Straight_skeleton_2/test/Straight_skeleton_2/data/closer_edge_event_1.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/degenerate0.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/degenerate1.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/degenerate10.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/degenerate11.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/degenerate12.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/degenerate2.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/degenerate3.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/degenerate4.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/degenerate5.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/degenerate6.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/degenerate7.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/degenerate8.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/degenerate9.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/degenerate_multinode0.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/double_edge.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/double_split.poly -text Straight_skeleton_2/test/Straight_skeleton_2/data/double_split.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/hole.poly -text Straight_skeleton_2/test/Straight_skeleton_2/data/hole.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/make_list -text
Straight_skeleton_2/test/Straight_skeleton_2/data/masked_double_split.poly -text Straight_skeleton_2/test/Straight_skeleton_2/data/masked_double_split.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/multinode1.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/parallels0.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/parallels0_b.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/rectangle.poly -text Straight_skeleton_2/test/Straight_skeleton_2/data/rectangle.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/region_4.poly -text Straight_skeleton_2/test/Straight_skeleton_2/data/region_4.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/sample_0.poly -text Straight_skeleton_2/test/Straight_skeleton_2/data/sample_0.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/sample_1.poly -text Straight_skeleton_2/test/Straight_skeleton_2/data/sample_1.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/sample_101.poly -text Straight_skeleton_2/test/Straight_skeleton_2/data/sample_101.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/sample_102.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/sample_147.poly -text Straight_skeleton_2/test/Straight_skeleton_2/data/sample_147.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/sample_2.poly -text Straight_skeleton_2/test/Straight_skeleton_2/data/sample_2.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/sample_235.poly -text Straight_skeleton_2/test/Straight_skeleton_2/data/sample_235.poly -text
@ -1542,6 +1563,7 @@ Straight_skeleton_2/test/Straight_skeleton_2/data/sample_698.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/sample_73.poly -text Straight_skeleton_2/test/Straight_skeleton_2/data/sample_73.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/sample_85.poly -text Straight_skeleton_2/test/Straight_skeleton_2/data/sample_85.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/single_split.poly -text Straight_skeleton_2/test/Straight_skeleton_2/data/single_split.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/split_at_zero_0.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/square.poly -text Straight_skeleton_2/test/Straight_skeleton_2/data/square.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/triangle.poly -text Straight_skeleton_2/test/Straight_skeleton_2/data/triangle.poly -text
Straight_skeleton_2/test/Straight_skeleton_2/data/vertex_event_0.poly -text Straight_skeleton_2/test/Straight_skeleton_2/data/vertex_event_0.poly -text

View File

@ -33,7 +33,7 @@
<prio>0</prio> <prio>0</prio>
<dontact>false</dontact> <dontact>false</dontact>
<makebin></makebin> <makebin></makebin>
<makeoptions>CGAL_MAKEFILE=/home/fcacciola/Programming/CGAL/make/makefile_i686_Linux-2.6_g++-3.3.5</makeoptions> <makeoptions>CGAL_MAKEFILE=/home/fcacciola/Programming/CGAL/make/makefile_i686_Linux-2.6_g++-4.0.2</makeoptions>
<selectedenvironment>default</selectedenvironment> <selectedenvironment>default</selectedenvironment>
<environments> <environments>
<default/> <default/>

View File

@ -33,12 +33,10 @@
<prio>0</prio> <prio>0</prio>
<dontact>false</dontact> <dontact>false</dontact>
<makebin/> <makebin/>
<makeoptions>DEBUGGING=yes</makeoptions> <makeoptions>CGAL_MAKEFILE=/home/fcacciola/Programming/CGAL/make/makefile_i686_Linux-2.6_g++-4.0.2 DEBUGGING=yes</makeoptions>
<selectedenvironment>default</selectedenvironment> <selectedenvironment>default</selectedenvironment>
<environments> <environments>
<default> <default/>
<envvar value="/home/fcacciola/Programming/CGAL/make/makefile_i686_Linux-2.6_g++-4.0.2" name="CGAL_MAKEFILE" />
</default>
</environments> </environments>
<defaulttarget/> <defaulttarget/>
</make> </make>

View File

@ -0,0 +1,2 @@
//#define SLS_DEMO_FAST
//#define SLS_DEMO_EXACT

View File

@ -5,7 +5,7 @@
# include platform specific settings # include platform specific settings
#---------------------------------------------------------------------# #---------------------------------------------------------------------#
# Choose the right include file from the <cgalroot>/make directory. # Choose the right include file from the <cgalroot>/make directory.
CGAL_MAKEFILE=c:/cgal/CGAL-3.2-I-361/make/makefile_i686_CYGWINNT-5.1_CL.EXE-1310 #CGAL_MAKEFILE=c:/cgal/CGAL-3.2-I-361/make/makefile_i686_CYGWINNT-5.1_CL.EXE-1310
include $(CGAL_MAKEFILE) include $(CGAL_MAKEFILE)
#---------------------------------------------------------------------# #---------------------------------------------------------------------#

View File

@ -23,19 +23,19 @@
namespace demo namespace demo
{ {
typedef CGAL::Straight_skeleton_2<K> Sls; typedef CGAL::Straight_skeleton_2<K> SSkel;
typedef CGAL::Straight_skeleton_builder_traits_2<K> SlsBuilderTraits; typedef CGAL::Straight_skeleton_builder_traits_2<K> SSkelBuilderTraits;
typedef CGAL::Straight_skeleton_builder_2<SlsBuilderTraits,Sls> SlsBuilder; typedef CGAL::Straight_skeleton_builder_2<SSkelBuilderTraits,SSkel> SSkelBuilder;
typedef CGAL::Polygon_offset_builder_traits_2<K> OffsetBuilderTraits; typedef CGAL::Polygon_offset_builder_traits_2<K> OffsetBuilderTraits;
typedef CGAL::Polygon_offset_builder_2<Sls,OffsetBuilderTraits,Polygon> OffsetBuilder; typedef CGAL::Polygon_offset_builder_2<SSkel,OffsetBuilderTraits,Polygon> OffsetBuilder;
typedef Sls::Halfedge_iterator Halfedge_iterator; typedef SSkel::Halfedge_iterator Halfedge_iterator;
typedef Sls::Vertex_handle Vertex_handle; typedef SSkel::Vertex_handle Vertex_handle;
typedef Sls::Face_const_iterator Face_const_iterator; typedef SSkel::Face_const_iterator Face_const_iterator;
typedef Sls::Halfedge_const_handle Halfedge_const_handle ; typedef SSkel::Halfedge_const_handle Halfedge_const_handle ;
typedef Sls::Vertex_const_handle Vertex_const_handle ; typedef SSkel::Vertex_const_handle Vertex_const_handle ;
typedef CGAL::HalfedgeDS_const_decorator<Sls> Sls_const_decorator ; typedef CGAL::HalfedgeDS_const_decorator<SSkel> SSkel_const_decorator ;
} }

View File

@ -217,6 +217,8 @@ private:
#define STATS #define STATS
//#define CGAL_SLS_PROFILING_ENABLED //#define CGAL_SLS_PROFILING_ENABLED
#define VERBOSE_VALIDATE false
#if defined(STATS) #if defined(STATS)
#define LOGSTATS(m) std::cout << m << std::endl ; #define LOGSTATS(m) std::cout << m << std::endl ;
#else #else
@ -325,8 +327,8 @@ const QString my_title_string("Straight_skeleton_2 Demo");
int current_state; int current_state;
Sls sls; SSkel sskel;
bool sls_valid ; bool sskel_valid ;
Regions input ; Regions input ;
Regions output ; Regions output ;
Doubles offsets ; Doubles offsets ;
@ -422,7 +424,7 @@ public:
// drawing menu // drawing menu
QPopupMenu * draw = new QPopupMenu( this ); QPopupMenu * draw = new QPopupMenu( this );
menuBar()->insertItem( "&Draw", draw ); menuBar()->insertItem( "&Draw", draw );
draw->insertItem("Generate Skeleton", this, SLOT(create_sls()), CTRL+Key_G ); draw->insertItem("Generate Skeleton", this, SLOT(create_skeleton()), CTRL+Key_G );
draw->insertItem("Generate Offset", this, SLOT(create_offset()), CTRL+Key_O ); draw->insertItem("Generate Offset", this, SLOT(create_offset()), CTRL+Key_O );
draw->insertItem("Set Offset Distance", this, SLOT(set_offset())); draw->insertItem("Set Offset Distance", this, SLOT(set_offset()));
@ -440,7 +442,7 @@ public:
newtoolbar = new Tools_toolbar(widget, this); newtoolbar = new Tools_toolbar(widget, this);
//the new scenes toolbar //the new scenes toolbar
vtoolbar = new Layers_toolbar(widget, this, input, sls, output); vtoolbar = new Layers_toolbar(widget, this, input, sskel, output);
resize(w,h); resize(w,h);
widget->set_window(-1, 1, -1, 1); widget->set_window(-1, 1, -1, 1);
@ -464,7 +466,7 @@ public slots:
widget->lock(); widget->lock();
widget->clear(); widget->clear();
input.clear(); input.clear();
sls.clear(); sskel.clear();
offsets.clear(); offsets.clear();
output.clear(); output.clear();
// set the Visible Area to the Interval // set the Visible Area to the Interval
@ -512,7 +514,7 @@ private slots:
}; };
void create_sls() void create_skeleton()
{ {
if ( input.size() > 0 ) if ( input.size() > 0 )
{ {
@ -521,15 +523,15 @@ private slots:
LOGSTATS("Creating Straight Skeleton..."); LOGSTATS("Creating Straight Skeleton...");
CGAL::Real_timer t ; CGAL::Real_timer t ;
t.start(); t.start();
SlsBuilder builder ; SSkelBuilder builder ;
for( Region::const_iterator bit = lRegion.begin(), ebit = lRegion.end() ; bit != ebit ; ++ bit ) for( Region::const_iterator bit = lRegion.begin(), ebit = lRegion.end() ; bit != ebit ; ++ bit )
{ {
builder.enter_contour((*bit)->vertices_begin(),(*bit)->vertices_end()); builder.enter_contour((*bit)->vertices_begin(),(*bit)->vertices_end());
} }
sls = builder.construct_skeleton() ; sskel = builder.construct_skeleton() ;
t.stop(); t.stop();
sls_valid = Sls_const_decorator(sls).is_valid(false,3); sskel_valid = SSkel_const_decorator(sskel).is_valid(VERBOSE_VALIDATE,3);
LOGSTATS( (sls_valid ? "Done" : "FAILED." ) << " Ellapsed time: " << t.time() << " seconds."); LOGSTATS( (sskel_valid ? "Done" : "FAILED." ) << " Ellapsed time: " << t.time() << " seconds.");
#ifdef CGAL_SLS_PROFILING_ENABLED #ifdef CGAL_SLS_PROFILING_ENABLED
LogProfilingResults(); LogProfilingResults();
#endif #endif
@ -540,7 +542,7 @@ private slots:
void create_offset() void create_offset()
{ {
if ( sls_valid ) if ( sskel_valid )
{ {
LOGSTATS("Creating Offsets..."); LOGSTATS("Creating Offsets...");
output.clear(); output.clear();
@ -553,7 +555,7 @@ private slots:
double offset = *i ; double offset = *i ;
LOGSTATS("Creating offsets at " << offset ); LOGSTATS("Creating offsets at " << offset );
RegionPtr lRegion( new Region ) ; RegionPtr lRegion( new Region ) ;
OffsetBuilder lOffsetBuilder(sls); OffsetBuilder lOffsetBuilder(sskel);
lOffsetBuilder.construct_offset_polygons(offset, std::back_inserter(*lRegion) ); lOffsetBuilder.construct_offset_polygons(offset, std::back_inserter(*lRegion) );
LOGSTATS("Done."); LOGSTATS("Done.");
if ( lRegion->size() > 0 ) if ( lRegion->size() > 0 )
@ -764,7 +766,7 @@ private slots:
} }
output.clear(); output.clear();
sls.clear(); sskel.clear();
widget->redraw(); widget->redraw();
something_changed(); something_changed();
} }

View File

@ -32,10 +32,12 @@ public:
void draw() void draw()
{ {
typename Sls::Rep::Construct_segment_2 construct_segment ; typename Sls::Traits::Construct_segment_2 construct_segment ;
widget->lock(); widget->lock();
int watchdog_limit = mSls.size_of_halfedges();
for ( Face_const_iterator fit = mSls.faces_begin(), efit = mSls.faces_end() for ( Face_const_iterator fit = mSls.faces_begin(), efit = mSls.faces_end()
; fit != efit ; fit != efit
; ++ fit ; ++ fit
@ -43,6 +45,9 @@ public:
{ {
Halfedge_const_handle hstart = fit->halfedge(); Halfedge_const_handle hstart = fit->halfedge();
Halfedge_const_handle he = hstart ; Halfedge_const_handle he = hstart ;
int watchdog = watchdog_limit ;
do do
{ {
if ( he == null_halfedge ) if ( he == null_halfedge )
@ -84,7 +89,7 @@ public:
} }
he = he->next(); he = he->next();
} }
while ( he != hstart ) ; while ( -- watchdog > 0 && he != hstart ) ;
} }
widget->unlock(); widget->unlock();

View File

@ -31,21 +31,21 @@
Layers_toolbar::Layers_toolbar(CGAL::Qt_widget* w Layers_toolbar::Layers_toolbar(CGAL::Qt_widget* w
,QMainWindow* mw ,QMainWindow* mw
,demo::Regions const& in ,demo::Regions const& in
,demo::Sls const& sls ,demo::SSkel const& sskel
,demo::Regions const& out ,demo::Regions const& out
) : QToolBar(mw, "LT"), ) : QToolBar(mw, "LT"),
nr_of_buttons(0) nr_of_buttons(0)
{ {
showI = new Qt_layer_show_regions <demo::Regions>(in,CGAL::RED); showI = new Qt_layer_show_regions <demo::Regions>(in,CGAL::RED);
showSLS = new Qt_layer_show_skeleton<demo::Sls> (sls); showSSkel = new Qt_layer_show_skeleton<demo::SSkel> (sskel);
showO = new Qt_layer_show_regions <demo::Regions>(out,CGAL::BLACK); showO = new Qt_layer_show_regions <demo::Regions>(out,CGAL::BLACK);
//set the widget //set the widget
widget = w; widget = w;
window = mw; window = mw;
widget->attach(showI); widget->attach(showI);
widget->attach(showSLS); widget->attach(showSSkel);
widget->attach(showO); widget->attach(showO);
@ -78,7 +78,7 @@ Layers_toolbar::Layers_toolbar(CGAL::Qt_widget* w
connect(but[0], SIGNAL(stateChanged(int)), connect(but[0], SIGNAL(stateChanged(int)),
showI, SLOT(stateChanged(int))); showI, SLOT(stateChanged(int)));
connect(but[1], SIGNAL(stateChanged(int)), connect(but[1], SIGNAL(stateChanged(int)),
showSLS, SLOT(stateChanged(int))); showSSkel, SLOT(stateChanged(int)));
connect(but[2], SIGNAL(stateChanged(int)), connect(but[2], SIGNAL(stateChanged(int)),
showO, SLOT(stateChanged(int))); showO, SLOT(stateChanged(int)));
} }
@ -86,7 +86,7 @@ Layers_toolbar::Layers_toolbar(CGAL::Qt_widget* w
Layers_toolbar::~Layers_toolbar() Layers_toolbar::~Layers_toolbar()
{ {
delete showI; delete showI;
delete showSLS; delete showSSkel;
delete showO; delete showO;
delete button_group; delete button_group;
}; };

View File

@ -41,7 +41,7 @@ public:
Layers_toolbar( CGAL::Qt_widget* w Layers_toolbar( CGAL::Qt_widget* w
, QMainWindow* mw , QMainWindow* mw
, demo::Regions const& in , demo::Regions const& in
, demo::Sls const& sls , demo::SSkel const& sskel
, demo::Regions const& out , demo::Regions const& out
); );
~Layers_toolbar(); ~Layers_toolbar();
@ -53,7 +53,7 @@ private:
int nr_of_buttons; int nr_of_buttons;
Qt_layer_show_regions <demo::Regions> *showI; Qt_layer_show_regions <demo::Regions> *showI;
Qt_layer_show_skeleton<demo::Sls> *showSLS; Qt_layer_show_skeleton<demo::SSkel> *showSSkel;
Qt_layer_show_regions <demo::Regions> *showO; Qt_layer_show_regions <demo::Regions> *showO;
};//end class };//end class

View File

@ -1,52 +0,0 @@
%% Copyright (c) 2006 SciSoft. All rights reserved.
%%
%% This file is part of CGAL (www.cgal.org); you may redistribute it under
%% the terms of the Q Public License version 1.0.
%% See the file LICENSE.QPL distributed with CGAL.
%%
%% Licensees holding a valid commercial license may use this file in
%% accordance with the commercial license agreement provided with the software.
%%
%% This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
%% WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
%%
%%
%%
%% Author(s) : Fernando Cacciola <fernando_cacciola@hotmail.com>
\ccRefPageBegin
%%RefPage: end of header, begin of main body
% +------------------------------------------------------------------------+
\begin{ccRefConcept}{StraightSkeleton_2}
\ccHeading{Introduction}
A model for the \ccRefName\ concept defines the underlying
combinatorial data structure (halfedge data structure) used to
represent the 2D straight skeleton of a simple polygon.
\ccRefines
\ccc{HalfedgeDS}
\ccTypes
\ccNestedType{Vertex}{
The vertex type. Should be a model of the
\ccc{StraightSkeletonVertex_2} concept.}
\ccNestedType{Halfedge}{
The halfedge type. Should be a model of the
\ccc{StraightSkeletonHalfedge_2} concept.}
\ccHasModels
There is no package-specific class serving as a model for this concept. Any model of the
\ccc{HalfedgeDS} concept whose \ccc{HalfedgeDSItems} match the \ccc{StraightSkeletonVertex_2} and \ccc{StraightSkeletonHalfedge_2} concepts (fore the Vertex and Halfedge resp.) can be used.
\end{ccRefConcept} % StraightSkeleton_2
% +------------------------------------------------------------------------+
%%RefPage: end of main body, begin of footer
\ccRefPageEnd
% EOF
% +------------------------------------------------------------------------+

View File

@ -11,6 +11,7 @@
\input{Straight_skeleton_2_ref/StraightSkeletonHalfedge_2.tex} \input{Straight_skeleton_2_ref/StraightSkeletonHalfedge_2.tex}
\input{Straight_skeleton_2_ref/StraightSkeletonBuilderTraits_2.tex} \input{Straight_skeleton_2_ref/StraightSkeletonBuilderTraits_2.tex}
\input{Straight_skeleton_2_ref/PolygonOffsetBuilderTraits_2.tex} \input{Straight_skeleton_2_ref/PolygonOffsetBuilderTraits_2.tex}
\input{Straight_skeleton_2_ref/Straight_skeleton_2.tex}
\input{Straight_skeleton_2_ref/Straight_skeleton_vertex_base_2.tex} \input{Straight_skeleton_2_ref/Straight_skeleton_vertex_base_2.tex}
\input{Straight_skeleton_2_ref/Straight_skeleton_halfedge_base_2.tex} \input{Straight_skeleton_2_ref/Straight_skeleton_halfedge_base_2.tex}
\input{Straight_skeleton_2_ref/Straight_skeleton_builder_traits_2.tex} \input{Straight_skeleton_2_ref/Straight_skeleton_builder_traits_2.tex}

View File

@ -35,7 +35,7 @@ Polygon_offset_builder_2<Sls,Gt,Cont>::Polygon_offset_builder_2( Sls const& aSls
if ( !lHE->is_bisector() && handle_assigned(lHE->face()) ) if ( !lHE->is_bisector() && handle_assigned(lHE->face()) )
{ {
CGAL_POLYOFFSET_SHOW (1, DrawBorder(lHE) ) ; CGAL_POLYOFFSET_SHOW ( DrawBorder(lHE) ) ;
mBorders.push_back(lHE); mBorders.push_back(lHE);
} }
} }
@ -112,8 +112,8 @@ void Polygon_offset_builder_2<Sls,Gt,Cont>::AddOffsetVertex( FT aTime, Halfedge_
Point_2 lP = Construct_offset_point(aTime,aHook); Point_2 lP = Construct_offset_point(aTime,aHook);
CGAL_POLYOFFSET_SHOW (1, DrawBisector(aHook) ) ; CGAL_POLYOFFSET_SHOW ( DrawBisector(aHook) ) ;
CGAL_POLYOFFSET_SHOW (1, DrawOffset(aPoly,lP) ) ; CGAL_POLYOFFSET_SHOW ( DrawOffset(aPoly,lP) ) ;
CGAL_POLYOFFSET_TRACE(3,"Constructing offset point along B" << aHook->id() ) ; CGAL_POLYOFFSET_TRACE(3,"Constructing offset point along B" << aHook->id() ) ;
aPoly->push_back(lP); aPoly->push_back(lP);
@ -150,7 +150,7 @@ OutputIterator Polygon_offset_builder_2<Sls,Gt,Cont>::TraceOffsetPolygon( FT aTi
break ; break ;
} }
CGAL_POLYOFFSET_SHOW (1, DrawOffset(lPoly,(*lPoly)[0]) ) ; CGAL_POLYOFFSET_SHOW ( DrawOffset(lPoly,(*lPoly)[0]) ) ;
if ( lPoly->size() >= 3 ) if ( lPoly->size() >= 3 )
{ {

View File

@ -36,35 +36,28 @@ class Straight_skeleton_2 : public CGAL_HALFEDGEDS_DEFAULT <Traits_,Items_,Alloc
{ {
public : public :
typedef Traits_ Rep ; typedef Traits_ Traits ;
typedef CGAL_HALFEDGEDS_DEFAULT <Traits_,Items_,Alloc_> Base ; typedef CGAL_HALFEDGEDS_DEFAULT <Traits_,Items_,Alloc_> Base ;
typedef typename Base::Vertex_base Vertex ; typedef typename Base::Vertex_base Vertex ;
typedef typename Base::Halfedge_base Halfedge ; typedef typename Base::Halfedge_base Halfedge ;
typedef typename Base::Face_base Face ; typedef typename Base::Face_base Face ;
typedef typename Base::Vertex_handle Vertex_handle ; typedef typename Base::Vertex_handle Vertex_handle ;
typedef typename Base::Halfedge_handle Halfedge_handle ; typedef typename Base::Halfedge_handle Halfedge_handle ;
typedef typename Base::Face_handle Face_handle ; typedef typename Base::Face_handle Face_handle ;
typedef typename Base::Vertex_iterator Vertex_iterator ; typedef typename Base::Vertex_iterator Vertex_iterator ;
typedef typename Base::Halfedge_iterator Halfedge_iterator ; typedef typename Base::Halfedge_iterator Halfedge_iterator ;
Straight_skeleton_2() {} Straight_skeleton_2() {}
/*
private:
Face_handle faces_push_back ( Face const& aF ) ;
Vertex_handle vertices_push_back ( Vertex const& aV ) ;
Halfedge_handle edges_push_back ( Halfedge const& aA, Halfedge const& aB ) ;
void vertices_erase ( Vertex_iterator first, Vertex_iterator last ) ;
void edges_erase ( Halfedge_handle h ) ;
*/
}; };
CGAL_END_NAMESPACE CGAL_END_NAMESPACE
#endif // CGAL_STRAIGHT_SKELETON_2_H // #endif // CGAL_STRAIGHT_SKELETON_2_H //
// EOF // // EOF //

View File

@ -48,9 +48,9 @@
#endif #endif
#ifdef CGAL_STRAIGHT_SKELETON_ENABLE_SHOW #ifdef CGAL_STRAIGHT_SKELETON_ENABLE_SHOW
# define CGAL_SSBUILDER_SHOW(l,code) if ( l <= CGAL_STRAIGHT_SKELETON_ENABLE_SHOW ) { code } # define CGAL_SSBUILDER_SHOW(code) { code }
#else #else
# define CGAL_SSBUILDER_SHOW(l,code) # define CGAL_SSBUILDER_SHOW(code)
#endif #endif
#ifdef CGAL_POLYGON_OFFSET_ENABLE_TRACE #ifdef CGAL_POLYGON_OFFSET_ENABLE_TRACE
@ -60,9 +60,9 @@
#endif #endif
#ifdef CGAL_POLYGON_OFFSET_ENABLE_SHOW #ifdef CGAL_POLYGON_OFFSET_ENABLE_SHOW
# define CGAL_POLYOFFSET_SHOW(l,code) if ( l <= CGAL_POLYGON_OFFSET_ENABLE_SHOW ) { code } # define CGAL_POLYOFFSET_SHOW(code) { code }
#else #else
# define CGAL_POLYOFFSET_SHOW(l,code) # define CGAL_POLYOFFSET_SHOW(code)
#endif #endif
CGAL_BEGIN_NAMESPACE CGAL_BEGIN_NAMESPACE

View File

@ -81,16 +81,10 @@ Straight_skeleton_builder_2<Gt,SS>::FindEdgeEvent( Vertex_handle aLNode, Vertex_
bool lAccepted = true ; bool lAccepted = true ;
if ( aLNode->is_skeleton() && IsNewEventInThePast(lBorderA,lBorderB,lBorderC,aLNode) ) if ( aLNode->is_skeleton() && IsNewEventInThePast(lBorderA,lBorderB,lBorderC,aLNode) )
{
CGAL_SSBUILDER_TRACE(1,"New edge event for Left seed N" << aLNode->id() << " is in the past. discarded." ) ;
lAccepted = false ; lAccepted = false ;
}
if ( aRNode->is_skeleton() && IsNewEventInThePast(lBorderA,lBorderB,lBorderC,aRNode) ) if ( aRNode->is_skeleton() && IsNewEventInThePast(lBorderA,lBorderB,lBorderC,aRNode) )
{
CGAL_SSBUILDER_TRACE(1,"New edge event for Right seed N" << aRNode->id() << " is in the past. discarded." ) ;
lAccepted = false ; lAccepted = false ;
}
if ( lAccepted ) if ( lAccepted )
{ {
@ -112,22 +106,9 @@ void Straight_skeleton_builder_2<Gt,SS>::CollectSplitEvent( Vertex_handle aNod
, Halfedge_handle aOppositeBorder , Halfedge_handle aOppositeBorder
) )
{ {
CGAL_SSBUILDER_TRACE(2,
"Computing potential split event between E" << aReflexLBorder->id()
<< ",E" <<aReflexRBorder->id() << " and E" << aOppositeBorder->id()
);
if ( ExistEvent(aReflexLBorder,aReflexRBorder,aOppositeBorder) ) if ( ExistEvent(aReflexLBorder,aReflexRBorder,aOppositeBorder) )
{ {
bool lAccepted = true ; if ( ! ( aNode->is_skeleton() && IsNewEventInThePast(aReflexLBorder,aReflexRBorder,aOppositeBorder,aNode) ) )
if ( aNode->is_skeleton() && IsNewEventInThePast(aReflexLBorder,aReflexRBorder,aOppositeBorder,aNode) )
{
CGAL_SSBUILDER_TRACE(1,"New split event for Seed N" << aNode->id() << " is in the past. discarded." ) ;
lAccepted = false ;
}
if ( lAccepted )
{ {
EventPtr lEvent( new SplitEvent( aReflexLBorder,aReflexRBorder,aOppositeBorder,aNode,aOppositeBorder) ) ; EventPtr lEvent( new SplitEvent( aReflexLBorder,aReflexRBorder,aOppositeBorder,aNode,aOppositeBorder) ) ;
#ifdef CGAL_STRAIGHT_SKELETON_ENABLE_TRACE #ifdef CGAL_STRAIGHT_SKELETON_ENABLE_TRACE
@ -141,6 +122,10 @@ void Straight_skeleton_builder_2<Gt,SS>::CollectSplitEvent( Vertex_handle aNod
EnqueEvent(lEvent); EnqueEvent(lEvent);
} }
} }
else
{
CGAL_SSBUILDER_TRACE(1,"Spit event for Seed N" << aNode->id() << " against E" << aOppositeBorder->id() << " does not exist." ) ;
}
} }
template<class Gt, class SS> template<class Gt, class SS>
@ -157,7 +142,7 @@ void Straight_skeleton_builder_2<Gt,SS>::CollectSplitEvents( Vertex_handle aNode
Halfedge_handle lRBorderP = lRBorder->opposite()->next()->opposite(); Halfedge_handle lRBorderP = lRBorder->opposite()->next()->opposite();
Halfedge_handle lRBorderN = lRBorder->opposite()->prev()->opposite(); Halfedge_handle lRBorderN = lRBorder->opposite()->prev()->opposite();
CGAL_SSBUILDER_TRACE(2 CGAL_SSBUILDER_TRACE(3
,"Finding SplitEvent for N" << aNode->id() ,"Finding SplitEvent for N" << aNode->id()
<< " LBorder: E" << lLBorder->id() << " RBorder: E" << lRBorder->id() << " LBorder: E" << lLBorder->id() << " RBorder: E" << lRBorder->id()
<< " LBorderP: E" << lLBorderP->id() << " LBorderN: E" << lLBorderN->id() << " LBorderP: E" << lLBorderP->id() << " LBorderN: E" << lLBorderN->id()
@ -187,52 +172,41 @@ void Straight_skeleton_builder_2<Gt,SS>::CollectNewEvents( Vertex_handle aNode )
Vertex_handle lNext = GetNextInLAV(aNode) ; Vertex_handle lNext = GetNextInLAV(aNode) ;
CGAL_SSBUILDER_TRACE CGAL_SSBUILDER_TRACE
( 1 ( 2
, "Collecting new events generated by N" << aNode->id() << " at " << aNode->point() << std::endl , "Collecting new events generated by N" << aNode->id() << " at " << aNode->point() << " (Prev: N" << lPrev->id() << " Next: N"
<< "Prev: N" << lPrev->id() << " Next: N" << lNext->id() << lNext->id() << ")"
) ; ) ;
EventPtr lLEdgeEvent = FindEdgeEvent( lPrev , aNode ) ;
EventPtr lREdgeEvent = FindEdgeEvent( aNode , lNext ) ;
if ( IsReflex(aNode) ) if ( IsReflex(aNode) )
CollectSplitEvents(aNode) ; CollectSplitEvents(aNode) ;
EventPtr lLEdgeEvent = FindEdgeEvent( lPrev , aNode ) ;
EventPtr lREdgeEvent = FindEdgeEvent( aNode , lNext ) ;
if ( lLEdgeEvent && !lREdgeEvent ) bool lAcceptL = !!lLEdgeEvent, lAcceptR = !!lREdgeEvent ;
{
EnqueEvent(lLEdgeEvent);
}
else if ( lREdgeEvent && !lLEdgeEvent )
{
EnqueEvent(lREdgeEvent);
}
else if ( lLEdgeEvent && lREdgeEvent )
{
CGAL_SSBUILDER_TRACE(2
,"Both Left and Right (candidate) EdgeEvents found:\n"
<< "L: " << *lLEdgeEvent << '\n'
<< "R: " << *lREdgeEvent
);
bool lPickLeft = true ;
if ( lLEdgeEvent && lREdgeEvent )
{
Comparison_result lRel = CompareEvents(lLEdgeEvent,lREdgeEvent) ; Comparison_result lRel = CompareEvents(lLEdgeEvent,lREdgeEvent) ;
if ( lRel == LARGER ) if ( lRel == EQUAL )
{
lPickLeft = false ;
}
else if ( lRel == EQUAL )
{ {
if ( CompareEventsDistanceToSeed(aNode,lLEdgeEvent,lREdgeEvent) == LARGER ) if ( CompareEventsDistanceToSeed(aNode,lLEdgeEvent,lREdgeEvent) == LARGER )
lPickLeft = false ; lAcceptL = false ;
else lAcceptR = false ;
CGAL_SSBUILDER_TRACE(3,"Both Left and Right Edge Events found with the same time:"
<< "LEvent:" << *lLEdgeEvent << '\n'
<< "REvent:" << *lREdgeEvent << '\n'
<< "Selecting the one closer to the seed: " << (lAcceptL ? "Left" : "Right")
);
} }
CGAL_SSBUILDER_TRACE(2,"Choosen: " << ( lPickLeft ? "Left" : "Right" ) ) ;
if ( lPickLeft )
EnqueEvent(lLEdgeEvent);
else EnqueEvent(lREdgeEvent);
} }
if ( lAcceptL )
EnqueEvent(lLEdgeEvent);
if ( lAcceptR )
EnqueEvent(lREdgeEvent);
} }
//! Handles the special case of two simultaneous edge events, that is, two edges //! Handles the special case of two simultaneous edge events, that is, two edges
@ -264,7 +238,7 @@ void Straight_skeleton_builder_2<Gt,SS>::HandleSimultaneousEdgeEvent( Vertex_han
mSLAV.remove(aA); mSLAV.remove(aA);
mSLAV.remove(aB); mSLAV.remove(aB);
CGAL_SSBUILDER_TRACE ( 2, 'N' << aA->id() << " processed\nN" << aB->id() << " processed" ) ; CGAL_SSBUILDER_TRACE ( 3, 'N' << aA->id() << " processed\nN" << aB->id() << " processed" ) ;
Halfedge_handle lOA_Prev = lOA->prev() ; Halfedge_handle lOA_Prev = lOA->prev() ;
Halfedge_handle lIA_Next = lIA->next() ; Halfedge_handle lIA_Next = lIA->next() ;
@ -286,9 +260,9 @@ void Straight_skeleton_builder_2<Gt,SS>::HandleSimultaneousEdgeEvent( Vertex_han
lOB->HBase::set_vertex (aA); lOB->HBase::set_vertex (aA);
CGAL_SSBUILDER_SHOW (1, DrawBisector(lOB) ) ; CGAL_SSBUILDER_SHOW ( DrawBisector(lOB) ; )
CGAL_SSBUILDER_TRACE ( 2, "B" << lOA->id() << " and B" << lIA->id() << " erased." ) ; CGAL_SSBUILDER_TRACE ( 3, "B" << lOA->id() << " and B" << lIA->id() << " erased." ) ;
mDanglingBisectors.push_back(lOA); mDanglingBisectors.push_back(lOA);
// //
@ -300,12 +274,12 @@ void Straight_skeleton_builder_2<Gt,SS>::HandleSimultaneousEdgeEvent( Vertex_han
if ( handle_assigned(lOA->vertex()) && lOA->vertex() != aA && lOA->vertex() != aB ) if ( handle_assigned(lOA->vertex()) && lOA->vertex() != aA && lOA->vertex() != aB )
{ {
lOA->vertex()->VBase::set_halfedge(lIB); lOA->vertex()->VBase::set_halfedge(lIB);
CGAL_SSBUILDER_TRACE ( 2, "N" << lOA->vertex()->id() << " has B" << lOA->id() << " as it's halfedge. Replacing it with B" << lIB->id() ) ; CGAL_SSBUILDER_TRACE ( 1, "N" << lOA->vertex()->id() << " has B" << lOA->id() << " as it's halfedge. Replacing it with B" << lIB->id() ) ;
} }
if ( handle_assigned(lIA->vertex()) && lIA->vertex() != aA && lIA->vertex() != aB ) if ( handle_assigned(lIA->vertex()) && lIA->vertex() != aA && lIA->vertex() != aB )
{ {
lIA->vertex()->VBase::set_halfedge(lOB); lIA->vertex()->VBase::set_halfedge(lOB);
CGAL_SSBUILDER_TRACE ( 2, "N" << lIA->vertex()->id() << " has B" << lIA->id() << " as it's halfedge. Replacing it with B" << lOB->id() ) ; CGAL_SSBUILDER_TRACE ( 1, "N" << lIA->vertex()->id() << " has B" << lIA->id() << " as it's halfedge. Replacing it with B" << lOB->id() ) ;
} }
CGAL_SSBUILDER_TRACE ( 2, "N" << aA->id() << " halfedge: B" << aA->halfedge()->id() ) ; CGAL_SSBUILDER_TRACE ( 2, "N" << aA->id() << " halfedge: B" << aA->halfedge()->id() ) ;
@ -317,7 +291,7 @@ void Straight_skeleton_builder_2<Gt,SS>::HandleSimultaneousEdgeEvent( Vertex_han
template<class Gt, class SS> template<class Gt, class SS>
bool Straight_skeleton_builder_2<Gt,SS>::AreBisectorsCoincident ( Halfedge_const_handle aA, Halfedge_const_handle aB ) const bool Straight_skeleton_builder_2<Gt,SS>::AreBisectorsCoincident ( Halfedge_const_handle aA, Halfedge_const_handle aB ) const
{ {
CGAL_SSBUILDER_TRACE ( 2, "Testing for simultaneous EdgeEvents between B" << aA->id() << " and B" << aB->id() ) ; CGAL_SSBUILDER_TRACE ( 3, "Testing for simultaneous EdgeEvents between B" << aA->id() << " and B" << aB->id() ) ;
Halfedge_const_handle lA_LBorder = aA->defining_contour_edge(); Halfedge_const_handle lA_LBorder = aA->defining_contour_edge();
Halfedge_const_handle lA_RBorder = aA->opposite()->defining_contour_edge(); Halfedge_const_handle lA_RBorder = aA->opposite()->defining_contour_edge();
@ -334,7 +308,7 @@ void Straight_skeleton_builder_2<Gt,SS>::UpdatePQ( Vertex_handle aNode )
Vertex_handle lPrev = GetPrevInLAV(aNode) ; Vertex_handle lPrev = GetPrevInLAV(aNode) ;
Vertex_handle lNext = GetNextInLAV(aNode) ; Vertex_handle lNext = GetNextInLAV(aNode) ;
CGAL_SSBUILDER_TRACE ( 2, "Updating PQ for N" << aNode->id() << " Prev N" << lPrev->id() << " Next N" << lNext->id() ) ; CGAL_SSBUILDER_TRACE ( 3, "Updating PQ for N" << aNode->id() << " Prev N" << lPrev->id() << " Next N" << lNext->id() ) ;
Halfedge_handle lOBisector_P = lPrev->primary_bisector() ; Halfedge_handle lOBisector_P = lPrev->primary_bisector() ;
Halfedge_handle lOBisector_C = aNode->primary_bisector() ; Halfedge_handle lOBisector_C = aNode->primary_bisector() ;
@ -352,7 +326,7 @@ template<class Gt, class SS>
void Straight_skeleton_builder_2<Gt,SS>::CreateInitialEvents() void Straight_skeleton_builder_2<Gt,SS>::CreateInitialEvents()
{ {
CGAL_SSBUILDER_TRACE(0, "Creating initial events..."); CGAL_SSBUILDER_TRACE(0, "Creating initial events...");
for ( Vertex_iterator v = mSS.vertices_begin(); v != mSS.vertices_end(); ++ v ) for ( Vertex_iterator v = mSSkel.vertices_begin(); v != mSSkel.vertices_end(); ++ v )
UpdatePQ(v); UpdatePQ(v);
} }
@ -391,7 +365,7 @@ Straight_skeleton_builder_2<Gt,SS>::FindVertexEvent( EventPtr aE0, Vertex_handle
boost::tie(lDistinct1, lDistinct2, lEqual1, lEqual2) = SortTwoDistinctAndTwoEqual(lBorderX,lBorderY); boost::tie(lDistinct1, lDistinct2, lEqual1, lEqual2) = SortTwoDistinctAndTwoEqual(lBorderX,lBorderY);
CGAL_SSBUILDER_TRACE ( 2 CGAL_SSBUILDER_TRACE ( 3
, "Distinct1 E" << lDistinct1->id() << " Distinct2 E" << lDistinct2->id() , "Distinct1 E" << lDistinct1->id() << " Distinct2 E" << lDistinct2->id()
<< " Equal1 E" << lEqual1->id() << " Equal2 E" << lEqual2->id() << " Equal1 E" << lEqual1->id() << " Equal2 E" << lEqual2->id()
) ; ) ;
@ -405,10 +379,10 @@ Straight_skeleton_builder_2<Gt,SS>::FindVertexEvent( EventPtr aE0, Vertex_handle
rResult = EventPtr( new VertexEvent( lDistinct1, lDistinct2, lEqual1 ,lEqual2, lSeedX, lSeedY ) ) ; rResult = EventPtr( new VertexEvent( lDistinct1, lDistinct2, lEqual1 ,lEqual2, lSeedX, lSeedY ) ) ;
#ifdef CGAL_STRAIGHT_SKELETON_ENABLE_TRACE #ifdef CGAL_STRAIGHT_SKELETON_ENABLE_TRACE
SetEventTimeAndPoint(*rResult); SetEventTimeAndPoint(*rResult);
#endif #endif
CGAL_SSBUILDER_SHOW (1, SS_IO_AUX::ScopedPointDrawing lDrawA(rResult->point(),CGAL::BLUE,"Event"); ) CGAL_SSBUILDER_SHOW ( SS_IO_AUX::ScopedPointDrawing lDrawA(rResult->point(),CGAL::BLUE,"Event"); )
} }
} }
} }
@ -437,114 +411,15 @@ Straight_skeleton_builder_2<Gt,SS>::FindVertexEvent( EventPtr aSplitEventPtr )
return rResult ; return rResult ;
} }
/*
template<class Gt, class SS>
void Straight_skeleton_builder_2<Gt,SS>::FindVertexEvents()
{
int c = 0 ;
int k = 0 ;
CGAL_SSBUILDER_TRACE(0, "Finding vertex events...");
for ( Vertex_iterator v0 = mSS.vertices_begin(), ev0 = mSS.vertices_end() ; v0 != ev0 ; ++ v0 )
{
if ( IsReflex(v0) )
{
// These are all the split events against a reflex vertex.
// That is, the event's opposite border is incident upon a reflex vertex which itself has split events,
// some possibly also against a reflex vertex.
EventPtr_Vector lV0ReflexSplits = GetReflexSplits(v0) ;
std::cout << "v" << v0->id() << " has " << lV0ReflexSplits.size() << " reflex splits" << std::endl ;
for ( event_iterator e0 = lV0ReflexSplits.begin(), ee0 = lV0ReflexSplits.end() ; e0 != ee0 ; ++ e0 )
{
++ k ;
EventPtr lE0 = *e0 ;
if ( !lE0->is_excluded() )
{
SplitEvent& lSE0 = dynamic_cast<SplitEvent&>(*lE0) ;
Vertex_handle lV1 = lSE0.opposite_border()->vertex();
CGAL_assertion(IsReflex(lV1));
EventPtr_Vector lV1ReflexSplits = GetReflexSplits(lV1) ;
for ( event_iterator e1 = lV1ReflexSplits.begin(), ee1 = lV1ReflexSplits.end() ; e1 != ee1 ; ++ e1 )
{
++ c ;
EventPtr lE1 = *e1 ;
if ( !lE1->is_excluded() && AreEventsSimultaneous(lE0,lE1) )
{
CGAL_SSBUILDER_TRACE(2, "Vertex Event found with\n" << *lE0 << "\n" << *lE1 );
lE0->Exclude();
lE1->Exclude();
Halfedge_handle lBorderX[3], lBorderY[3];
lBorderX[0] = lE0->border_a();
lBorderX[1] = lE0->border_b();
lBorderX[2] = lE0->border_c();
lBorderY[0] = lE1->border_a();
lBorderY[1] = lE1->border_b();
lBorderY[2] = lE1->border_c();
Halfedge_handle lDistinct1, lDistinct2, lEqual1, lEqual2 ;
boost::tie(lDistinct1, lDistinct2, lEqual1, lEqual2) = SortTwoDistinctAndTwoEqual(lBorderX,lBorderY);
CGAL_SSBUILDER_TRACE ( 2
, "Distinct1 E" << lDistinct1->id() << " Distinct2 E" << lDistinct2->id()
<< " Equal1 E" << lEqual1->id() << " Equal2 E" << lEqual2->id()
) ;
if ( ExistEvent(lDistinct1, lDistinct2, lEqual1 )
&& ExistEvent(lEqual1 , lEqual2 , lDistinct1)
)
{
Vertex_handle lSeedX = lE0->seed0();
Vertex_handle lSeedY = lE1->seed0();
EventPtr lVertexEvent = EventPtr( new VertexEvent( lDistinct1, lDistinct2, lEqual1 ,lEqual2, lSeedX, lSeedY ) ) ;
#ifdef CGAL_STRAIGHT_SKELETON_ENABLE_TRACE
SetEventTimeAndPoint(*lVertexEvent);
#endif
CGAL_SSBUILDER_SHOW (1, SS_IO_AUX::ScopedPointDrawing lDrawA(lVertexEvent->point(),CGAL::BLUE,"Event"); )
EnqueEvent(lVertexEvent);
break ;
}
}
}
}
if ( lE0->is_excluded() )
break ;
}
}
}
std::cout << "total reflex splits:" << k << ". Total innner iterations: " << c << std::endl ;
}
*/
template<class Gt, class SS> template<class Gt, class SS>
void Straight_skeleton_builder_2<Gt,SS>::CreateContourBisectors() void Straight_skeleton_builder_2<Gt,SS>::CreateContourBisectors()
{ {
CGAL_SSBUILDER_TRACE(0, "Creating contour bisectors..."); CGAL_SSBUILDER_TRACE(0, "Creating contour bisectors...");
for ( Vertex_iterator v = mSS.vertices_begin(); v != mSS.vertices_end(); ++ v ) for ( Vertex_iterator v = mSSkel.vertices_begin(); v != mSSkel.vertices_end(); ++ v )
{ {
// NOTE: Bisectors are always contructed with no geometric embedding. // NOTE: Bisectors are always contructed with no geometric embedding.
Halfedge lOB(mEdgeID++), lIB(mEdgeID++); Halfedge lOB(mEdgeID++), lIB(mEdgeID++);
Halfedge_handle lOBisector = mSS.SBase::edges_push_back (lOB, lIB); Halfedge_handle lOBisector = mSSkel.SBase::edges_push_back (lOB, lIB);
Halfedge_handle lIBisector = lOBisector->opposite(); Halfedge_handle lIBisector = lOBisector->opposite();
lOBisector->HBase::set_face(v->halfedge()->face()); lOBisector->HBase::set_face(v->halfedge()->face());
lIBisector->HBase::set_face(v->halfedge()->next()->face()); lIBisector->HBase::set_face(v->halfedge()->next()->face());
@ -556,7 +431,7 @@ void Straight_skeleton_builder_2<Gt,SS>::CreateContourBisectors()
lOBisector->HBase::set_prev(lIBorder); lOBisector->HBase::set_prev(lIBorder);
lOBorder ->HBase::set_prev(lIBisector); lOBorder ->HBase::set_prev(lIBisector);
lIBisector->HBase::set_next(lOBorder); lIBisector->HBase::set_next(lOBorder);
CGAL_SSBUILDER_TRACE(2 CGAL_SSBUILDER_TRACE(3
,"Adding Contour Bisector at N:" << v->id() << "\n B" << lOBisector->id() ,"Adding Contour Bisector at N:" << v->id() << "\n B" << lOBisector->id()
<< " (Out)\n B" << lIBisector->id() << " (In)" << " (Out)\n B" << lIBisector->id() << " (In)"
) ; ) ;
@ -582,7 +457,7 @@ Straight_skeleton_builder_2<Gt,SS>::ConstructEdgeEventNode( EdgeEvent& aEvent )
SetEventTimeAndPoint(aEvent); SetEventTimeAndPoint(aEvent);
Vertex_handle lNewNode = mSS.SBase::vertices_push_back( Vertex( mVertexID++, aEvent.point(), aEvent.time()) ) ; Vertex_handle lNewNode = mSSkel.SBase::vertices_push_back( Vertex( mVertexID++, aEvent.point(), aEvent.time()) ) ;
mSLAV.push_back(lNewNode); mSLAV.push_back(lNewNode);
mWrappedVertices.push_back( VertexWrapper(lNewNode) ) ; mWrappedVertices.push_back( VertexWrapper(lNewNode) ) ;
@ -599,10 +474,10 @@ Straight_skeleton_builder_2<Gt,SS>::ConstructEdgeEventNode( EdgeEvent& aEvent )
lLIBisector->HBase::set_prev( lROBisector ) ; lLIBisector->HBase::set_prev( lROBisector ) ;
lROBisector->HBase::set_next( lLIBisector ) ; lROBisector->HBase::set_next( lLIBisector ) ;
CGAL_SSBUILDER_SHOW(1, DrawBisector(lLOBisector); DrawBisector(lROBisector); ) ; CGAL_SSBUILDER_SHOW( DrawBisector(lLOBisector); DrawBisector(lROBisector); ) ;
CGAL_SSBUILDER_TRACE CGAL_SSBUILDER_TRACE
( 2 ( 3
, "LSeed: N" << lLSeed->id() << " proccesed\n" , "LSeed: N" << lLSeed->id() << " proccesed\n"
<< "RSeed: N" << lRSeed->id() << " proccesed" << "RSeed: N" << lRSeed->id() << " proccesed"
) ; ) ;
@ -642,13 +517,12 @@ Straight_skeleton_builder_2<Gt,SS>::LookupOnSLAV ( Halfedge_handle aBorder, Even
{ {
Vertex_handle rResult ; Vertex_handle rResult ;
CGAL_SSBUILDER_TRACE ( 2, "Looking up for E" << aBorder->id() << " on SLAV. P=" << aEvent.point() ) ; CGAL_SSBUILDER_TRACE ( 3, "Looking up for E" << aBorder->id() << " on SLAV. P=" << aEvent.point() ) ;
CGAL_SSBUILDER_SHOW ( 2
, SS_IO_AUX::ScopedSegmentDrawing draw_(aBorder->vertex()->point() #ifdef CGAL_STRAIGHT_SKELETON_ENABLE_TRACE
,aBorder->opposite()->vertex()->point() bool lFound = false ;
,CGAL::YELLOW,"OppBorder") ; #endif
)
for ( typename std::list<Vertex_handle>::const_iterator vi = mSLAV.begin(); vi != mSLAV.end(); ++ vi ) for ( typename std::list<Vertex_handle>::const_iterator vi = mSLAV.begin(); vi != mSLAV.end(); ++ vi )
{ {
@ -659,24 +533,43 @@ Straight_skeleton_builder_2<Gt,SS>::LookupOnSLAV ( Halfedge_handle aBorder, Even
&& GetDefiningBorderA(v) == aBorder && GetDefiningBorderA(v) == aBorder
) )
{ {
#ifdef CGAL_STRAIGHT_SKELETON_ENABLE_TRACE
lFound = true ;
#endif
Vertex_handle lPrev = GetPrevInLAV(v); Vertex_handle lPrev = GetPrevInLAV(v);
Halfedge_handle lPrevBorder = GetDefiningBorderA(lPrev); Halfedge_handle lPrevBorder = GetDefiningBorderA(lPrev);
Halfedge_handle lNextBorder = GetDefiningBorderB(v); Halfedge_handle lNextBorder = GetDefiningBorderB(v);
if ( IsEventInsideOffsetZone( aEvent.border_a()
, aEvent.border_b() CGAL_assertion(handle_assigned(lPrevBorder));
, aBorder CGAL_assertion(handle_assigned(lNextBorder));
, lPrevBorder
, lNextBorder if ( IsEventInsideOffsetZone( aEvent.border_a(), aEvent.border_b(), aBorder, lPrevBorder, lNextBorder ) )
)
)
{ {
rResult = v ; rResult = v ;
CGAL_SSBUILDER_TRACE ( 2, 'N' << rResult->id() << " found" ) ; CGAL_SSBUILDER_TRACE ( 2
, 'E' << aBorder->id() << " found in SLAV: N" << lPrev->id() << "->N" << v->id()
<< " (E" << lPrevBorder->id() << "->E" << aBorder->id() << "->E" << lNextBorder->id() << ")"
) ;
break ; break ;
} }
} }
} }
#ifdef CGAL_STRAIGHT_SKELETON_ENABLE_TRACE
if ( !handle_assigned(rResult) )
{
if ( !lFound )
{
CGAL_SSBUILDER_TRACE(1,"Split event is no longer valid. Opposite edge vanished.");
}
else
{
CGAL_SSBUILDER_TRACE(1,"Split event is no longer valid. Not inside the opposite edge offset zone.");
}
}
#endif
return rResult ; return rResult ;
} }
@ -693,8 +586,8 @@ Straight_skeleton_builder_2<Gt,SS>::ConstructSplitEventNodes( SplitEvent& aEvent
SetEventTimeAndPoint(aEvent); SetEventTimeAndPoint(aEvent);
Vertex_handle lNodeA = mSS.SBase::vertices_push_back( Vertex( mVertexID++, aEvent.point(), aEvent.time() ) ) ; Vertex_handle lNodeA = mSSkel.SBase::vertices_push_back( Vertex( mVertexID++, aEvent.point(), aEvent.time() ) ) ;
Vertex_handle lNodeB = mSS.SBase::vertices_push_back( Vertex( mVertexID++, aEvent.point(), aEvent.time() ) ) ; Vertex_handle lNodeB = mSSkel.SBase::vertices_push_back( Vertex( mVertexID++, aEvent.point(), aEvent.time() ) ) ;
mSLAV.push_back(lNodeA); mSLAV.push_back(lNodeA);
mSLAV.push_back(lNodeB); mSLAV.push_back(lNodeB);
@ -711,9 +604,9 @@ Straight_skeleton_builder_2<Gt,SS>::ConstructSplitEventNodes( SplitEvent& aEvent
lXOutBisector->HBase::set_vertex(lNodeA); lXOutBisector->HBase::set_vertex(lNodeA);
CGAL_SSBUILDER_SHOW(1, DrawBisector(lXOutBisector); ) ; CGAL_SSBUILDER_SHOW( DrawBisector(lXOutBisector); ) ;
CGAL_SSBUILDER_TRACE ( 2, "Seed: N" << lSeed->id() << " proccesed" ) ; CGAL_SSBUILDER_TRACE ( 3, "Seed: N" << lSeed->id() << " proccesed" ) ;
SetIsProcessed(lSeed) ; SetIsProcessed(lSeed) ;
mSLAV.remove(lSeed); mSLAV.remove(lSeed);
@ -763,8 +656,8 @@ Straight_skeleton_builder_2<Gt,SS>::ConstructVertexEventNodes( VertexEvent& aEve
SetEventTimeAndPoint(aEvent); SetEventTimeAndPoint(aEvent);
Vertex_handle lNewNodeA = mSS.SBase::vertices_push_back( Vertex( mVertexID++, aEvent.point(), aEvent.time()) ) ; Vertex_handle lNewNodeA = mSSkel.SBase::vertices_push_back( Vertex( mVertexID++, aEvent.point(), aEvent.time()) ) ;
Vertex_handle lNewNodeB = mSS.SBase::vertices_push_back( Vertex( mVertexID++, aEvent.point(), aEvent.time()) ) ; Vertex_handle lNewNodeB = mSSkel.SBase::vertices_push_back( Vertex( mVertexID++, aEvent.point(), aEvent.time()) ) ;
mSLAV.push_back(lNewNodeA); mSLAV.push_back(lNewNodeA);
mSLAV.push_back(lNewNodeB); mSLAV.push_back(lNewNodeB);
@ -788,11 +681,11 @@ Straight_skeleton_builder_2<Gt,SS>::ConstructVertexEventNodes( VertexEvent& aEve
lLOBisector->HBase::set_next( lRIBisector ) ; lLOBisector->HBase::set_next( lRIBisector ) ;
lRIBisector->HBase::set_prev( lLOBisector ) ; lRIBisector->HBase::set_prev( lLOBisector ) ;
CGAL_SSBUILDER_SHOW(1, DrawBisector(lLOBisector); DrawBisector(lROBisector); ) ; CGAL_SSBUILDER_SHOW( DrawBisector(lLOBisector); DrawBisector(lROBisector); ) ;
CGAL_SSBUILDER_TRACE CGAL_SSBUILDER_TRACE
( (
2 3
, "LSeed: N" << lLSeed->id() << " proccesed\n" , "LSeed: N" << lLSeed->id() << " proccesed\n"
<< "RSeed: N" << lRSeed->id() << " proccesed" << "RSeed: N" << lRSeed->id() << " proccesed"
) ; ) ;
@ -864,9 +757,9 @@ void Straight_skeleton_builder_2<Gt,SS>::HandleEdgeEvent( EventPtr aEvent )
if ( !handle_assigned(lLOBisector->next()) && !handle_assigned(lRIBisector->prev()) ) if ( !handle_assigned(lLOBisector->next()) && !handle_assigned(lRIBisector->prev()) )
{ {
CGAL_SSBUILDER_TRACE(2,"Creating new Edge Event's Bisector"); CGAL_SSBUILDER_TRACE(3,"Creating new Edge Event's Bisector");
Halfedge_handle lNOBisector = mSS.SBase::edges_push_back ( Halfedge(mEdgeID),Halfedge(mEdgeID+1) ); Halfedge_handle lNOBisector = mSSkel.SBase::edges_push_back ( Halfedge(mEdgeID),Halfedge(mEdgeID+1) );
Halfedge_handle lNIBisector = lNOBisector->opposite(); Halfedge_handle lNIBisector = lNOBisector->opposite();
mEdgeID += 2 ; mEdgeID += 2 ;
@ -909,7 +802,21 @@ void Straight_skeleton_builder_2<Gt,SS>::HandleEdgeEvent( EventPtr aEvent )
} }
else else
{ {
CGAL_SSBUILDER_TRACE(3, "N" << lNewNode->id() << " is a multiple node. Bisector not created"); Halfedge_handle lDefiningBorderA = lNewNode->halfedge()->face()->halfedge();
Halfedge_handle lDefiningBorderB = lNewNode->halfedge()->opposite()->prev()->opposite()->face()->halfedge();
Halfedge_handle lDefiningBorderC = lNewNode->halfedge()->opposite()->prev()->face()->halfedge();
SetDefiningBorderA(lNewNode, lDefiningBorderA) ;
SetDefiningBorderB(lNewNode, lDefiningBorderB) ;
SetDefiningBorderC(lNewNode, lDefiningBorderC) ;
CGAL_SSBUILDER_TRACE(2
, "NewNode N" << lNewNode->id() << " at " << lNewNode->point() << " defining borders:"
<< " E" << lDefiningBorderA->id()
<< ",E" << lDefiningBorderB->id()
<< ",E" << lDefiningBorderC->id()
<< ".\nThis is a multiple node (A node with these defining edges already exist in the LAV)"
);
} }
} }
@ -930,8 +837,8 @@ void Straight_skeleton_builder_2<Gt,SS>::HandleSplitEvent( EventPtr aEvent, Vert
Halfedge_handle lReflexLBorder = GetDefiningBorderA(lSeed); Halfedge_handle lReflexLBorder = GetDefiningBorderA(lSeed);
Halfedge_handle lReflexRBorder = GetDefiningBorderB(lSeed); Halfedge_handle lReflexRBorder = GetDefiningBorderB(lSeed);
Halfedge_handle lNOBisector_L = mSS.SBase::edges_push_back ( Halfedge(mEdgeID++),Halfedge(mEdgeID++) ); Halfedge_handle lNOBisector_L = mSSkel.SBase::edges_push_back ( Halfedge(mEdgeID++),Halfedge(mEdgeID++) );
Halfedge_handle lNOBisector_R = mSS.SBase::edges_push_back ( Halfedge(mEdgeID++),Halfedge(mEdgeID++) ); Halfedge_handle lNOBisector_R = mSSkel.SBase::edges_push_back ( Halfedge(mEdgeID++),Halfedge(mEdgeID++) );
Halfedge_handle lNIBisector_L = lNOBisector_L->opposite(); Halfedge_handle lNIBisector_L = lNOBisector_L->opposite();
Halfedge_handle lNIBisector_R = lNOBisector_R->opposite(); Halfedge_handle lNIBisector_R = lNOBisector_R->opposite();
@ -981,7 +888,7 @@ void Straight_skeleton_builder_2<Gt,SS>::HandleSplitEvent( EventPtr aEvent, Vert
<< ",E" << lNewNodeLDefiningBorderC->id() << '\n' << ",E" << lNewNodeLDefiningBorderC->id() << '\n'
<< "New Node R: N" << lNewNode_R->id() << " at " << lNewNode_R->point() << "New Node R: N" << lNewNode_R->id() << " at " << lNewNode_R->point()
<< " defining borders: E" << lNewNodeRDefiningBorderA->id() << " defining borders: E" << lNewNodeRDefiningBorderA->id()
<< ",E" << lNewNodeLDefiningBorderB->id() << '\n' << ",E" << lNewNodeRDefiningBorderB->id() << '\n'
<< ",E" << lNewNodeRDefiningBorderC->id() << '\n' << ",E" << lNewNodeRDefiningBorderC->id() << '\n'
<< "New Bisector OL:\nB" << lNOBisector_L->id() << "New Bisector OL:\nB" << lNOBisector_L->id()
<< "[E" << lNOBisector_L ->defining_contour_edge()->id() << "[E" << lNOBisector_L ->defining_contour_edge()->id()
@ -1027,7 +934,7 @@ bool Straight_skeleton_builder_2<Gt,SS>::SetupVertexEventNode( Vertex_handle a
{ {
rR = true ; rR = true ;
SetIsReflex(aNode); SetIsReflex(aNode);
CGAL_SSBUILDER_TRACE(2, ( lCollinear ? "COLLINEAR ":"Reflex " ) << "*NEW* vertex: N" << aNode->id() ); CGAL_SSBUILDER_TRACE(1, ( lCollinear ? "COLLINEAR ":"Reflex " ) << "*NEW* vertex: N" << aNode->id() );
} }
return rR ; return rR ;
@ -1044,8 +951,8 @@ void Straight_skeleton_builder_2<Gt,SS>::HandleVertexEvent( EventPtr aEvent )
Vertex_handle lNewNode_L, lNewNode_R ; Vertex_handle lNewNode_L, lNewNode_R ;
boost::tie(lNewNode_L,lNewNode_R) = ConstructVertexEventNodes(lEvent); boost::tie(lNewNode_L,lNewNode_R) = ConstructVertexEventNodes(lEvent);
Halfedge_handle lNBisector_LO = mSS.SBase::edges_push_back ( Halfedge(mEdgeID++),Halfedge(mEdgeID++) ); Halfedge_handle lNBisector_LO = mSSkel.SBase::edges_push_back ( Halfedge(mEdgeID++),Halfedge(mEdgeID++) );
Halfedge_handle lNBisector_RO = mSS.SBase::edges_push_back ( Halfedge(mEdgeID++),Halfedge(mEdgeID++) ); Halfedge_handle lNBisector_RO = mSSkel.SBase::edges_push_back ( Halfedge(mEdgeID++),Halfedge(mEdgeID++) );
Halfedge_handle lNBisector_LI = lNBisector_LO->opposite(); Halfedge_handle lNBisector_LI = lNBisector_LO->opposite();
Halfedge_handle lNBisector_RI = lNBisector_RO->opposite(); Halfedge_handle lNBisector_RI = lNBisector_RO->opposite();
@ -1145,10 +1052,6 @@ void Straight_skeleton_builder_2<Gt,SS>::HandlePotentialSplitEvent( EventPtr aEv
HandleSplitEvent (aEvent,lOppVertex); HandleSplitEvent (aEvent,lOppVertex);
else HandleVertexEvent(lVertexEvent); else HandleVertexEvent(lVertexEvent);
} }
else
{
CGAL_SSBUILDER_TRACE(3,"Split event is no longer valid. Opposite edge vanished.");
}
} }
template<class Gt, class SS> template<class Gt, class SS>
@ -1163,12 +1066,13 @@ void Straight_skeleton_builder_2<Gt,SS>::Propagate()
if ( !lEvent->is_excluded() && !IsProcessed(lEvent) ) if ( !lEvent->is_excluded() && !IsProcessed(lEvent) )
{ {
CGAL_SSBUILDER_TRACE (0,"\nStep: " << mStepID << " Event: " << *lEvent ) ; CGAL_SSBUILDER_TRACE (0,"\nStep: " << mStepID << " Event: " << *lEvent ) ;
CGAL_SSBUILDER_SHOW (1, SS_IO_AUX::ScopedPointDrawing lDraw(lEvent->point(),CGAL::BLUE,"Event"); ) CGAL_SSBUILDER_SHOW ( SS_IO_AUX::ScopedPointDrawing lDraw(lEvent->point(),CGAL::BLUE,"Event"); )
switch ( lEvent->type() ) switch ( lEvent->type() )
{ {
case Event::cEdgeEvent : HandleEdgeEvent (lEvent) ; break ; case Event::cEdgeEvent : HandleEdgeEvent (lEvent) ; break ;
case Event::cSplitEvent: HandlePotentialSplitEvent(lEvent) ; break ; case Event::cSplitEvent : HandlePotentialSplitEvent(lEvent) ; break ;
case Event::cVertexEvent: break ; // Avoids warning about unused enum value in switch
} }
++ mStepID ; ++ mStepID ;
@ -1211,7 +1115,7 @@ void Straight_skeleton_builder_2<Gt,SS>::MergeSplitNodes ( Vertex_handle_pair aS
<< 'B' << lIBisectorR2->id() << " now linked to N" << lIBisectorR2->vertex()->id() << 'B' << lIBisectorR2->id() << " now linked to N" << lIBisectorR2->vertex()->id()
); );
mSS.SBase::vertices_erase(lRNode); mSSkel.SBase::vertices_erase(lRNode);
} }
template<class Gt, class SS> template<class Gt, class SS>
@ -1238,10 +1142,10 @@ void Straight_skeleton_builder_2<Gt,SS>::Run()
} }
template<class Gt, class SS> template<class Gt, class SS>
typename Straight_skeleton_builder_2<Gt,SS>::Ssds Straight_skeleton_builder_2<Gt,SS>::construct_skeleton() typename Straight_skeleton_builder_2<Gt,SS>::SSkel Straight_skeleton_builder_2<Gt,SS>::construct_skeleton()
{ {
Run(); Run();
return mSS ; return mSSkel ;
} }
CGAL_END_NAMESPACE CGAL_END_NAMESPACE

View File

@ -33,47 +33,47 @@
CGAL_BEGIN_NAMESPACE CGAL_BEGIN_NAMESPACE
template<class Traits_, class Ssds_> template<class Traits_, class SSkel_>
class Straight_skeleton_builder_2 class Straight_skeleton_builder_2
{ {
public: public:
typedef Traits_ Traits ; typedef Traits_ Traits ;
typedef Ssds_ Ssds ; typedef SSkel_ SSkel ;
typedef typename Ssds::Traits::Segment_2 Segment_2 ; typedef typename SSkel::Traits::Segment_2 Segment_2 ;
private : private :
typedef typename Traits::FT FT ; typedef typename Traits::FT FT ;
typedef typename Traits::Point_2 Point_2 ; typedef typename Traits::Point_2 Point_2 ;
typedef typename Ssds::Vertex Vertex ; typedef typename SSkel::Vertex Vertex ;
typedef typename Ssds::Halfedge Halfedge ; typedef typename SSkel::Halfedge Halfedge ;
typedef typename Ssds::Face Face ; typedef typename SSkel::Face Face ;
typedef typename Ssds::Vertex_const_handle Vertex_const_handle ; typedef typename SSkel::Vertex_const_handle Vertex_const_handle ;
typedef typename Ssds::Halfedge_const_handle Halfedge_const_handle ; typedef typename SSkel::Halfedge_const_handle Halfedge_const_handle ;
typedef typename Ssds::Face_const_handle Face_const_handle ; typedef typename SSkel::Face_const_handle Face_const_handle ;
typedef typename Ssds::Vertex_const_iterator Vertex_const_iterator ; typedef typename SSkel::Vertex_const_iterator Vertex_const_iterator ;
typedef typename Ssds::Halfedge_const_iterator Halfedge_const_iterator ; typedef typename SSkel::Halfedge_const_iterator Halfedge_const_iterator ;
typedef typename Ssds::Face_const_iterator Face_const_iterator ; typedef typename SSkel::Face_const_iterator Face_const_iterator ;
typedef typename Ssds::Vertex_handle Vertex_handle ; typedef typename SSkel::Vertex_handle Vertex_handle ;
typedef typename Ssds::Halfedge_handle Halfedge_handle ; typedef typename SSkel::Halfedge_handle Halfedge_handle ;
typedef typename Ssds::Face_handle Face_handle ; typedef typename SSkel::Face_handle Face_handle ;
typedef typename Ssds::Vertex_iterator Vertex_iterator ; typedef typename SSkel::Vertex_iterator Vertex_iterator ;
typedef typename Ssds::Halfedge_iterator Halfedge_iterator ; typedef typename SSkel::Halfedge_iterator Halfedge_iterator ;
typedef typename Ssds::Face_iterator Face_iterator ; typedef typename SSkel::Face_iterator Face_iterator ;
typedef typename Ssds::size_type size_type ; typedef typename SSkel::size_type size_type ;
typedef Straight_skeleton_builder_event_2<Ssds> Event ; typedef Straight_skeleton_builder_event_2<SSkel> Event ;
typedef Straight_skeleton_builder_edge_event_2<Ssds> EdgeEvent ; typedef Straight_skeleton_builder_edge_event_2<SSkel> EdgeEvent ;
typedef Straight_skeleton_builder_split_event_2<Ssds> SplitEvent ; typedef Straight_skeleton_builder_split_event_2<SSkel> SplitEvent ;
typedef Straight_skeleton_builder_vertex_event_2<Ssds> VertexEvent ; typedef Straight_skeleton_builder_vertex_event_2<SSkel> VertexEvent ;
typedef boost::intrusive_ptr<Event> EventPtr ; typedef boost::intrusive_ptr<Event> EventPtr ;
@ -89,13 +89,12 @@ private :
typedef CGAL_SLS_i::Edge <FT> iEdge ; typedef CGAL_SLS_i::Edge <FT> iEdge ;
typedef CGAL_SLS_i::Triedge<FT> iTriedge ; typedef CGAL_SLS_i::Triedge<FT> iTriedge ;
typedef typename Halfedge::SSBase SSBase; typedef typename Halfedge::Base HBase;
typedef typename Halfedge::Base HBase; typedef typename Vertex::Base VBase;
typedef typename Vertex::Base VBase; typedef typename Face::Base FBase;
typedef typename Face::Base FBase; typedef typename SSkel::Base SBase ;
typedef typename Ssds::Base SBase ;
typedef Straight_skeleton_builder_2<Traits,Ssds> Self ; typedef Straight_skeleton_builder_2<Traits,SSkel> Self ;
public: public:
@ -107,7 +106,7 @@ public:
// template<class InputPointIterator> Straight_skeleton_builder_2& enter_contour ( InputPointIterator aBegin, InputPointIterator aEnd ) ; // template<class InputPointIterator> Straight_skeleton_builder_2& enter_contour ( InputPointIterator aBegin, InputPointIterator aEnd ) ;
Ssds construct_skeleton() ; SSkel construct_skeleton() ;
private : private :
@ -426,8 +425,7 @@ private :
} }
else return EQUAL ; else return EQUAL ;
} }
bool AreEventsSimultaneous( EventPtr const& aX, EventPtr const& aY ) const bool AreEventsSimultaneous( EventPtr const& aX, EventPtr const& aY ) const
{ {
Halfedge_handle xa = aX->border_a() ; Halfedge_handle xa = aX->border_a() ;
@ -460,7 +458,18 @@ private :
, CreateTriedge(lSeedBorderA,lSeedBorderB,lSeedBorderC) , CreateTriedge(lSeedBorderA,lSeedBorderB,lSeedBorderC)
) == SMALLER ) == SMALLER
) )
{
#ifdef CGAL_STRAIGHT_SKELETON_ENABLE_TRACE
FT lTime1, lTime2 ;
Point_2 lP1, lP2 ;
boost::tie(lTime1,lP1) = ConstructEventTimeAndPoint(CreateTriedge(aBorderA,aBorderB,aBorderC));
boost::tie(lTime2,lP2) = ConstructEventTimeAndPoint(CreateTriedge(lSeedBorderA,lSeedBorderB,lSeedBorderC));
CGAL_SSBUILDER_TRACE(1,"New event for N" << aSeedNode->id() << ", with t=" << lTime1 << ", is in the past (current t="
<< lTime2 << "). discarded."
) ;
#endif
rResult = true ; rResult = true ;
}
} }
return rResult ; return rResult ;
@ -480,7 +489,7 @@ private :
void EraseBisector( Halfedge_handle aB ) void EraseBisector( Halfedge_handle aB )
{ {
mSS.SBase::edges_erase(aB); mSSkel.SBase::edges_erase(aB);
} }
BorderTriple GetDefiningBorders( Vertex_handle aA, Vertex_handle aB ) ; BorderTriple GetDefiningBorders( Vertex_handle aA, Vertex_handle aB ) ;
@ -578,7 +587,7 @@ private:
PQ mPQ ; PQ mPQ ;
//Output //Output
Ssds mSS ; SSkel mSSkel ;
public: public:
@ -598,17 +607,17 @@ public:
InputPointIterator lCurr = aBegin ; InputPointIterator lCurr = aBegin ;
while ( lCurr != aEnd ) while ( lCurr != aEnd )
{ {
Halfedge_handle lCCWBorder = mSS.SBase::edges_push_back ( Halfedge(mEdgeID),Halfedge(mEdgeID+1) ); Halfedge_handle lCCWBorder = mSSkel.SBase::edges_push_back ( Halfedge(mEdgeID),Halfedge(mEdgeID+1) );
Halfedge_handle lCWBorder = lCCWBorder->opposite(); Halfedge_handle lCWBorder = lCCWBorder->opposite();
mEdgeID += 2 ; mEdgeID += 2 ;
mContourHalfedges.push_back(lCCWBorder); mContourHalfedges.push_back(lCCWBorder);
Vertex_handle lVertex = mSS.SBase::vertices_push_back( Vertex(mVertexID++,*lCurr) ) ; Vertex_handle lVertex = mSSkel.SBase::vertices_push_back( Vertex(mVertexID++,*lCurr) ) ;
CGAL_SSBUILDER_TRACE(2,"Vertex: V" << lVertex->id() << " at " << lVertex->point() ); CGAL_SSBUILDER_TRACE(2,"Vertex: V" << lVertex->id() << " at " << lVertex->point() );
mWrappedVertices.push_back( VertexWrapper(lVertex) ) ; mWrappedVertices.push_back( VertexWrapper(lVertex) ) ;
Face_handle lFace = mSS.SBase::faces_push_back( Face() ) ; Face_handle lFace = mSSkel.SBase::faces_push_back( Face() ) ;
lCCWBorder->HBase::set_face (lFace); lCCWBorder->HBase::set_face (lFace);
lFace ->FBase::set_halfedge(lCCWBorder); lFace ->FBase::set_halfedge(lCCWBorder);
@ -641,8 +650,8 @@ public:
CGAL_SSBUILDER_TRACE(2,"CW Border: E" << lCWBorder ->id() << ' ' << lVertex ->point() << " -> " << lPrevVertex->point() ); CGAL_SSBUILDER_TRACE(2,"CW Border: E" << lCWBorder ->id() << ' ' << lVertex ->point() << " -> " << lPrevVertex->point() );
CGAL_SSBUILDER_SHOW CGAL_SSBUILDER_SHOW
( 2 (
, SS_IO_AUX::ScopedSegmentDrawing draw_(lPrevVertex->point(),lVertex->point(), CGAL::RED, "Border" ) ; SS_IO_AUX::ScopedSegmentDrawing draw_(lPrevVertex->point(),lVertex->point(), CGAL::RED, "Border" ) ;
draw_.Release(); draw_.Release();
) )
} }
@ -663,8 +672,7 @@ public:
lFirstCCWBorder->opposite()->HBase::set_vertex(lPrevVertex); lFirstCCWBorder->opposite()->HBase::set_vertex(lPrevVertex);
CGAL_SSBUILDER_SHOW CGAL_SSBUILDER_SHOW
( 2 ( SS_IO_AUX::ScopedSegmentDrawing draw_(lPrevVertex->point(),lFirstVertex->point(), CGAL::RED, "Border" ) ;
, SS_IO_AUX::ScopedSegmentDrawing draw_(lPrevVertex->point(),lFirstVertex->point(), CGAL::RED, "Border" ) ;
draw_.Release(); draw_.Release();
) )
@ -682,7 +690,7 @@ public:
); );
} }
for ( Vertex_iterator v = mSS.SBase::vertices_begin(); v != mSS.SBase::vertices_end(); ++ v ) for ( Vertex_iterator v = mSSkel.SBase::vertices_begin(); v != mSSkel.SBase::vertices_end(); ++ v )
{ {
mSLAV.push_back(static_cast<Vertex_handle>(v)); mSLAV.push_back(static_cast<Vertex_handle>(v));
Vertex_handle lPrev = GetPrevInLAV(v) ; Vertex_handle lPrev = GetPrevInLAV(v) ;

View File

@ -22,22 +22,22 @@
CGAL_BEGIN_NAMESPACE CGAL_BEGIN_NAMESPACE
template<class R> template<class SSkel>
class Straight_skeleton_builder_event_2 : public Ref_counted_base class Straight_skeleton_builder_event_2 : public Ref_counted_base
{ {
public: public:
typedef Straight_skeleton_builder_event_2<R> Self ; typedef Straight_skeleton_builder_event_2<SSkel> Self ;
typedef boost::intrusive_ptr<Self> SelfPtr ; typedef boost::intrusive_ptr<Self> SelfPtr ;
typedef typename R::Rep Rep ; typedef typename SSkel::Traits Traits ;
typedef typename Rep::Point_2 Point_2 ; typedef typename Traits::Point_2 Point_2 ;
typedef typename Rep::FT FT ; typedef typename Traits::FT FT ;
typedef typename R::Halfedge_handle Halfedge_handle ; typedef typename SSkel::Halfedge_handle Halfedge_handle ;
typedef typename R::Vertex_handle Vertex_handle ; typedef typename SSkel::Vertex_handle Vertex_handle ;
enum Type { cEdgeEvent, cSplitEvent, cVertexEvent } ; enum Type { cEdgeEvent, cSplitEvent, cVertexEvent } ;
@ -73,7 +73,7 @@ public:
void SetTimeAndPoint( FT aTime, Point_2 const& aP ) { mTime = aTime ; mP = aP ; } void SetTimeAndPoint( FT aTime, Point_2 const& aP ) { mTime = aTime ; mP = aP ; }
friend std::ostream& operator<< ( std::ostream& ss friend std::ostream& operator<< ( std::ostream& ss
,Straight_skeleton_builder_event_2<R> const& e ,Straight_skeleton_builder_event_2<SSkel> const& e
) )
{ {
ss << "[" ; ss << "[" ;
@ -99,19 +99,19 @@ private :
bool mExcluded ; bool mExcluded ;
} ; } ;
template<class R> template<class SSkel>
class Straight_skeleton_builder_edge_event_2 : public Straight_skeleton_builder_event_2<R> class Straight_skeleton_builder_edge_event_2 : public Straight_skeleton_builder_event_2<SSkel>
{ {
typedef Straight_skeleton_builder_event_2<R> Base ; typedef Straight_skeleton_builder_event_2<SSkel> Base ;
typedef typename R::Rep Rep ; typedef typename SSkel::Traits Traits ;
typedef typename Rep::Point_2 Point_2 ; typedef typename Traits::Point_2 Point_2 ;
typedef typename Rep::FT FT ; typedef typename Traits::FT FT ;
typedef typename R::Halfedge_handle Halfedge_handle ; typedef typename SSkel::Halfedge_handle Halfedge_handle ;
typedef typename R::Vertex_handle Vertex_handle ; typedef typename SSkel::Vertex_handle Vertex_handle ;
typedef typename Base::Type Type ; typedef typename Base::Type Type ;
@ -129,7 +129,7 @@ public:
, mRSeed(aRSeed) , mRSeed(aRSeed)
{} {}
virtual Type type() const { return Base::cEdgeEvent ; } virtual Type type() const { return this->cEdgeEvent ; }
virtual Vertex_handle seed0() const { return mLSeed ; } virtual Vertex_handle seed0() const { return mLSeed ; }
virtual Vertex_handle seed1() const { return mRSeed ; } virtual Vertex_handle seed1() const { return mRSeed ; }
@ -148,19 +148,19 @@ private :
Vertex_handle mRSeed ; Vertex_handle mRSeed ;
} ; } ;
template<class R> template<class SSkel>
class Straight_skeleton_builder_split_event_2 : public Straight_skeleton_builder_event_2<R> class Straight_skeleton_builder_split_event_2 : public Straight_skeleton_builder_event_2<SSkel>
{ {
typedef Straight_skeleton_builder_event_2<R> Base ; typedef Straight_skeleton_builder_event_2<SSkel> Base ;
typedef typename R::Rep Rep ; typedef typename SSkel::Traits Traits ;
typedef typename Rep::Point_2 Point_2 ; typedef typename Traits::Point_2 Point_2 ;
typedef typename Rep::FT FT ; typedef typename Traits::FT FT ;
typedef typename R::Halfedge_handle Halfedge_handle ; typedef typename SSkel::Halfedge_handle Halfedge_handle ;
typedef typename R::Vertex_handle Vertex_handle ; typedef typename SSkel::Vertex_handle Vertex_handle ;
typedef typename Base::Type Type ; typedef typename Base::Type Type ;
public: public:
@ -176,7 +176,7 @@ public:
, mOppositeBorder(aOppositeBorder) , mOppositeBorder(aOppositeBorder)
{} {}
virtual Type type() const { return Base::cSplitEvent ; } virtual Type type() const { return this->cSplitEvent ; }
virtual Vertex_handle seed0() const { return mSeed ; } virtual Vertex_handle seed0() const { return mSeed ; }
virtual Vertex_handle seed1() const { return mSeed ; } virtual Vertex_handle seed1() const { return mSeed ; }
@ -198,19 +198,19 @@ private :
Halfedge_handle mOppositeBorder ; Halfedge_handle mOppositeBorder ;
} ; } ;
template<class R> template<class SSkel>
class Straight_skeleton_builder_vertex_event_2 : public Straight_skeleton_builder_event_2<R> class Straight_skeleton_builder_vertex_event_2 : public Straight_skeleton_builder_event_2<SSkel>
{ {
typedef Straight_skeleton_builder_event_2<R> Base ; typedef Straight_skeleton_builder_event_2<SSkel> Base ;
typedef typename R::Rep Rep ; typedef typename SSkel::Traits Traits ;
typedef typename Rep::Point_2 Point_2 ; typedef typename Traits::Point_2 Point_2 ;
typedef typename Rep::FT FT ; typedef typename Traits::FT FT ;
typedef typename R::Halfedge_handle Halfedge_handle ; typedef typename SSkel::Halfedge_handle Halfedge_handle ;
typedef typename R::Vertex_handle Vertex_handle ; typedef typename SSkel::Vertex_handle Vertex_handle ;
typedef typename Base::Type Type ; typedef typename Base::Type Type ;
@ -230,7 +230,7 @@ public:
, mRSeed(aRSeed) , mRSeed(aRSeed)
{} {}
virtual Type type() const { return Base::cVertexEvent ; } virtual Type type() const { return this->cVertexEvent ; }
Halfedge_handle border_d() const { return mBorderD ; } Halfedge_handle border_d() const { return mBorderD ; }

View File

@ -49,6 +49,34 @@ struct Exist_sls_event_2 : Sls_functor_base_2<K>
} }
}; };
template<class K>
struct Compare_sls_event_distance_to_seed_2 : Sls_functor_base_2<K>
{
typedef Sls_functor_base_2<K> Base ;
typedef typename Base::Point_2 Point_2 ;
typedef typename Base::Triedge Triedge ;
typedef Uncertain<Comparison_result> result_type ;
typedef Arity_tag<3> Arity ;
Uncertain<Comparison_result> operator() ( Point_2 const& aP
, Triedge const& aL
, Triedge const& aR
) const
{
return compare_offset_lines_isec_dist_to_pointC2(toVertex(aP),aL,aR) ;
}
Uncertain<Comparison_result> operator() ( Triedge const& aS
, Triedge const& aL
, Triedge const& aR
) const
{
return compare_offset_lines_isec_dist_to_pointC2(aS,aL,aR) ;
}
};
template<class K> template<class K>
struct Compare_sls_event_times_2 : Sls_functor_base_2<K> struct Compare_sls_event_times_2 : Sls_functor_base_2<K>
@ -70,43 +98,6 @@ struct Compare_sls_event_times_2 : Sls_functor_base_2<K>
} }
}; };
template<class K>
struct Compare_sls_event_distance_to_seed_2 : Sls_functor_base_2<K>
{
typedef Sls_functor_base_2<K> Base ;
typedef typename Base::Point_2 Point_2 ;
typedef typename Base::Triedge Triedge ;
typedef Uncertain<Comparison_result> result_type ;
typedef Arity_tag<3> Arity ;
Uncertain<Comparison_result> operator() ( Point_2 const& aP
, Triedge const& aL
, Triedge const& aR
) const
{
Uncertain<Comparison_result> rResult = compare_offset_lines_isec_dist_to_pointC2(toVertex(aP),aL,aR) ;
CGAL_SLS_ASSERT_PREDICATE_RESULT(rResult,K,"Compapre_dist_to_point:","P=" << aP << "\nL=" << aL << "\nR=" << aR);
return rResult ;
}
Uncertain<Comparison_result> operator() ( Triedge const& aS
, Triedge const& aL
, Triedge const& aR
) const
{
Uncertain<Comparison_result> rResult = compare_offset_lines_isec_dist_to_pointC2(aS,aL,aR) ;
CGAL_SLS_ASSERT_PREDICATE_RESULT(rResult,K,"Compapre_dist_to_point:","S=" << aS << "\nL=" << aL << "\nR=" << aR);
return rResult ;
}
};
template<class K> template<class K>
struct Is_sls_event_inside_offset_zone_2 : Sls_functor_base_2<K> struct Is_sls_event_inside_offset_zone_2 : Sls_functor_base_2<K>
{ {
@ -223,7 +214,7 @@ public:
typedef Unfiltered_predicate_adaptor<typename Unfiltering::Compare_sls_event_distance_to_seed_2> typedef Unfiltered_predicate_adaptor<typename Unfiltering::Compare_sls_event_distance_to_seed_2>
Compare_sls_event_distance_to_seed_2 ; Compare_sls_event_distance_to_seed_2 ;
typedef Unfiltered_predicate_adaptor<typename Unfiltering::Is_sls_event_inside_offset_zone_2> typedef Unfiltered_predicate_adaptor<typename Unfiltering::Is_sls_event_inside_offset_zone_2>
Is_sls_event_inside_offset_zone_2 ; Is_sls_event_inside_offset_zone_2 ;
@ -270,8 +261,7 @@ public:
, C2F , C2F
> >
Compare_sls_event_distance_to_seed_2 ; Compare_sls_event_distance_to_seed_2 ;
typedef Filtered_predicate< typename Exact ::Is_sls_event_inside_offset_zone_2 typedef Filtered_predicate< typename Exact ::Is_sls_event_inside_offset_zone_2
, typename Filtering::Is_sls_event_inside_offset_zone_2 , typename Filtering::Is_sls_event_inside_offset_zone_2
, C2E , C2E

View File

@ -35,7 +35,6 @@
# include<sstream> # include<sstream>
# include<iomanip> # include<iomanip>
# define CGAL_SSTRAITS_TRACE(m) \ # define CGAL_SSTRAITS_TRACE(m) \
if ( l <= CGAL_STRAIGHT_SKELETON_TRAITS_ENABLE_TRACE ) \
{ \ { \
std::ostringstream ss ; \ std::ostringstream ss ; \
ss << std::setprecision(19) << m << std::ends ; \ ss << std::setprecision(19) << m << std::ends ; \

View File

@ -49,18 +49,18 @@ public:
bool is_bisector() const bool is_bisector() const
{ {
return !HBase::is_border() && !HBase::opposite()->is_border() ; return !this->is_border() && !this->opposite()->is_border() ;
} }
bool is_inner_bisector() const bool is_inner_bisector() const
{ {
return !HBase::vertex()->is_contour() && !HBase::opposite()->HBase::vertex()->is_contour(); return !this->vertex()->is_contour() && !this->opposite()->vertex()->is_contour();
} }
Halfedge_const_handle defining_contour_edge() const { return HBase::face()->halfedge() ; } Halfedge_const_handle defining_contour_edge() const { return this->face()->halfedge() ; }
Halfedge_handle defining_contour_edge() { return HBase::face()->halfedge() ; } Halfedge_handle defining_contour_edge() { return this->face()->halfedge() ; }
void set_opposite( Halfedge_handle h) { HBase::set_opposite(h);} //void set_opposite( Halfedge_handle h) { this->set_opposite(h);}
private: private:
@ -73,13 +73,13 @@ class Straight_skeleton_halfedge_base_2
{ {
public: public:
typedef Straight_skeleton_halfedge_base_base_2 < Refs, S > SSBase ; typedef Straight_skeleton_halfedge_base_base_2 < Refs, S > SBase ;
typedef typename SSBase::HBase_base HBase_base ; typedef typename SBase::HBase_base HBase_base ;
typedef typename SBase::Base HBase ;
typedef typename SSBase::Base HBase ; typedef typename SBase::Segment_2 Segment_2;
typedef typename SSBase::Segment_2 Segment_2;
typedef typename HBase::Halfedge_handle Halfedge_handle ; typedef typename HBase::Halfedge_handle Halfedge_handle ;
typedef typename HBase::Vertex_handle Vertex_handle ; typedef typename HBase::Vertex_handle Vertex_handle ;
typedef typename HBase::Face_handle Face_handle ; typedef typename HBase::Face_handle Face_handle ;
@ -87,15 +87,15 @@ public:
public: public:
Straight_skeleton_halfedge_base_2() {} Straight_skeleton_halfedge_base_2() {}
Straight_skeleton_halfedge_base_2( int aID ) : SSBase(aID) {} Straight_skeleton_halfedge_base_2( int aID ) : SBase(aID) {}
void set_opposite( Halfedge_handle h) { HBase_base::set_opposite(h);} //void set_opposite( Halfedge_handle h) { this->set_opposite(h);}
protected: protected:
void set_prev ( Halfedge_handle h ) { HBase_base::set_prev(h) ; } //void set_prev ( Halfedge_handle h ) { this->set_prev(h) ; }
void set_vertex( Vertex_handle w ) { HBase_base::set_vertex(w); } //void set_vertex( Vertex_handle w ) { this->set_vertex(w); }
void set_face ( Face_handle g ) { HBase_base::set_face(g) ; } //void set_face ( Face_handle g ) { this->set_face(g) ; }
}; };
CGAL_END_NAMESPACE CGAL_END_NAMESPACE

View File

@ -159,31 +159,31 @@ public:
FT time() const { return mTime ; } FT time() const { return mTime ; }
Halfedge_const_handle primary_bisector() const { return Base::halfedge()->next(); } Halfedge_const_handle primary_bisector() const { return this->halfedge()->next(); }
Halfedge_handle primary_bisector() { return Base::halfedge()->next(); } Halfedge_handle primary_bisector() { return this->halfedge()->next(); }
Halfedge_around_vertex_const_circulator incident_edges_begin() const Halfedge_around_vertex_const_circulator incident_edges_begin() const
{ {
return Halfedge_around_vertex_const_circulator(Base::halfedge()); return Halfedge_around_vertex_const_circulator(this->halfedge());
} }
Halfedge_around_vertex_circulator incident_edges_begin() Halfedge_around_vertex_circulator incident_edges_begin()
{ {
return Halfedge_around_vertex_circulator(Base::halfedge()); return Halfedge_around_vertex_circulator(this->halfedge());
} }
Halfedge_across_incident_faces_const_circulator defining_contour_edges_begin() const Halfedge_across_incident_faces_const_circulator defining_contour_edges_begin() const
{ {
return Halfedge_across_incident_faces_const_circulator(Base::halfedge()); return Halfedge_across_incident_faces_const_circulator(this->halfedge());
} }
Halfedge_across_incident_faces_circulator defining_contour_edges_begin() Halfedge_across_incident_faces_circulator defining_contour_edges_begin()
{ {
return Halfedge_across_incident_faces_circulator(Base::halfedge()); return Halfedge_across_incident_faces_circulator(this->halfedge());
} }
bool is_skeleton() const { return Base::halfedge()->is_bisector() ; } bool is_skeleton() const { return this->halfedge()->is_bisector() ; }
bool is_contour () const { return !Base::halfedge()->is_bisector() ; } bool is_contour () const { return !this->halfedge()->is_bisector() ; }
private: private:
@ -218,7 +218,7 @@ public:
Base(aID,aP,aTime) Base(aID,aP,aTime)
{} {}
protected: protected:
void set_halfedge( Halfedge_handle h ) { Base_base::set_halfedge(h) ; } // void set_halfedge( Halfedge_handle h ) { this->set_halfedge(h) ; }
}; };
CGAL_END_NAMESPACE CGAL_END_NAMESPACE

View File

@ -128,6 +128,15 @@ inline Uncertain<bool> certified_is_larger_or_equal(const NT1& n1, const NT2& n2
return certified_is_larger_or_equal(certified_compare(n1,n2)) ; return certified_is_larger_or_equal(certified_compare(n1,n2)) ;
} }
template <class NT>
inline Uncertain<Sign> certified_sign_of_determinant2x2( const NT& a00
, const NT& a01
, const NT& a10
, const NT& a11
)
{
return enum_cast<Sign>(certified_compare(a00*a11, a10*a01)) ;
}
CGAL_END_NAMESPACE CGAL_END_NAMESPACE

View File

@ -232,16 +232,19 @@ Rational<FT> compute_degenerate_offset_lines_isec_timeC2 ( SortedTriedge<FT> con
num = (l2.a() * l0.b() - l0.a() * l2.b() ) * qx + l0.b() * l2.c() - l2.b() * l0.c() ; num = (l2.a() * l0.b() - l0.a() * l2.b() ) * qx + l0.b() * l2.c() - l2.b() * l0.c() ;
den = (l0.a() * l0.a() - 1) * l2.b() + ( 1 - l2.a() * l0.a() ) * l0.b() ; den = (l0.a() * l0.a() - 1) * l2.b() + ( 1 - l2.a() * l0.a() ) * l0.b() ;
CGAL_SSTRAITS_TRACE("Non-vertical Degenerate Event:\nn=" << num << "\nd=" << den )
} }
else else
{ {
FT qy = ( triedge.e0().t().y() + triedge.e1().s().y() ) / static_cast<FT>(2.0); FT qy = ( triedge.e0().t().y() + triedge.e1().s().y() ) / static_cast<FT>(2.0);
num = (l2.a() * l0.b() - l0.a() * l2.b() ) * qy + l0.a() * l2.c() - l2.a() * l0.c() ; num = (l2.a() * l0.b() - l0.a() * l2.b() ) * qy - l0.a() * l2.c() + l2.a() * l0.c() ;
den = l0.a() * l0.b() * l2.b() - l0.b() * l0.b() * l2.a() + l2.a() - l0.a() ; den = l0.a() * l0.b() * l2.b() - l0.b() * l0.b() * l2.a() + l2.a() - l0.a() ;
CGAL_SSTRAITS_TRACE("Vertical Degenerate Event:\nn=" << num << "\nd=" << den )
} }
CGAL_SSTRAITS_TRACE("Degenerate Event:\nn=" << num << "\nd=" << den )
return Rational<FT>(num,den) ; return Rational<FT>(num,den) ;
} }
@ -312,7 +315,7 @@ Vertex<FT> construct_degenerate_offset_lines_isecC2 ( SortedTriedge<FT> const& t
} }
else else
{ {
num = (l2.a() * l0.b() - l0.a() * l2.b() ) * qy + l0.a() * l2.c() - l2.a() * l0.c() ; num = (l2.a() * l0.b() - l0.a() * l2.b() ) * qy - l0.a() * l2.c() + l2.a() * l0.c() ;
den = l0.a() * l0.b() * l2.b() - l0.b() * l0.b() * l2.a() + l2.a() - l0.a() ; den = l0.a() * l0.b() * l2.b() - l0.b() * l0.b() * l2.a() + l2.a() - l0.a() ;
} }

View File

@ -44,6 +44,18 @@ Uncertain<bool> are_edges_collinear( Edge<FT> const& e0, Edge<FT> const& e1 )
) ; ) ;
} }
template<class FT>
Uncertain<bool> are_edges_parallel( Edge<FT> const& e0, Edge<FT> const& e1 )
{
Uncertain<Sign> s = certified_sign_of_determinant2x2(e0.t().x() - e0.s().x()
,e0.t().y() - e0.s().y()
,e1.t().x() - e1.s().x()
,e1.t().y() - e1.s().y()
) ;
return s == Uncertain<Sign>(ZERO);
}
template<class FT> template<class FT>
SortedTriedge<FT> collinear_sort ( Triedge<FT> const& triedge ) SortedTriedge<FT> collinear_sort ( Triedge<FT> const& triedge )
{ {
@ -55,10 +67,10 @@ SortedTriedge<FT> collinear_sort ( Triedge<FT> const& triedge )
if ( !CGAL_NTS is_indeterminate(is_01) ) if ( !CGAL_NTS is_indeterminate(is_01) )
{ {
Uncertain<bool> is_02 = are_edges_collinear(triedge.e0(),triedge.e2()); Uncertain<bool> is_02 = are_edges_collinear(triedge.e0(),triedge.e2());
if ( !CGAL_NTS is_indeterminate(is_01) ) if ( !CGAL_NTS is_indeterminate(is_02) )
{ {
Uncertain<bool> is_12 = are_edges_collinear(triedge.e1(),triedge.e2()); Uncertain<bool> is_12 = are_edges_collinear(triedge.e1(),triedge.e2());
if ( !CGAL_NTS is_indeterminate(is_01) ) if ( !CGAL_NTS is_indeterminate(is_12) )
{ {
if ( CGAL_NTS logical_and(is_01 , !is_02 , !is_12 ) ) if ( CGAL_NTS logical_and(is_01 , !is_02 , !is_12 ) )
{ {
@ -98,6 +110,32 @@ SortedTriedge<FT> collinear_sort ( Triedge<FT> const& triedge )
} }
// Given some input edge E1, there is a sequence of offset polygons, in some time range (possibly including time 0),
// such that E1 has E0 and E2 as adjacent edges.
// At time 0, E0 and E2 are the edges adjacent to E1 in the input polygon, but later, E0 and E2 can be any edges.
// There is some time range were E0->E1->E2 are consecutive in each offset polygon. For each specific t
// in the range, the vertices (E0,E1) and (E1,E2) move along the bisectors (E0,E1) and (E1,E2). Thus, the actual length
// and position of each E1 offset varies along the time period.
// The set of all the E1 offsets which have E0 and E2 as inmediate neighbors is called the "Offset Zone" for E1 w.r.t to E0 and E2.
//
// Such offset zone is the part of the halfplane to the left of E1 (were _all_ offsets to E1 are) bounded between the bisectors
// (E0,E1) and (E1,E2)
//
// If E0 and/or E2 are parallel to E1, then there is just 1 E1 offset, located at the medial bisector of the E2 and its parallel(s).
//
// But E0 and E2 are the inmediate neighbors of E1 in the offset polygon (at some t), so if E0 and/or E2 are parallel to E1,
// it means that such an offset polygon has degenerated to an innermost segment. Thus, E1 can't be split further by any
// other reflex wavefront.
// Therefore, is E0 or E2 are parallel to E1, the offset zone for E1 w.r.t to E0,E2 is said to be "degenerate".
template<class FT>
Uncertain<bool> is_offset_zone_degenerate ( Triedge<FT> const& zone )
{
Uncertain<bool> is_01 = are_edges_parallel(zone.e0(),zone.e1());
Uncertain<bool> is_12 = are_edges_parallel(zone.e1(),zone.e2());
return CGAL_NTS logical_or(is_01,is_12);
}
// Given 3 oriented straight line segments: l0, l1, l2 [each segment is passed as (sx,sy,tx,ty)] // Given 3 oriented straight line segments: l0, l1, l2 [each segment is passed as (sx,sy,tx,ty)]
// returns true if there exist some positive offset distance 't' for which the // returns true if there exist some positive offset distance 't' for which the
// leftward-offsets of their supporting lines intersect at a single point. // leftward-offsets of their supporting lines intersect at a single point.
@ -114,7 +152,7 @@ Uncertain<bool> exist_offset_lines_isec2 ( Triedge<FT> const& triedge )
{ {
if ( sorted.collinear_count() < 3 ) // If the 3 edges are collinear thre is no event. if ( sorted.collinear_count() < 3 ) // If the 3 edges are collinear thre is no event.
{ {
CGAL_SSTRAITS_TRACE( ( sorted.is_normal() ? " normal edges" : " collinear edges" ) ) ; CGAL_SSTRAITS_TRACE( ( sorted.collinear_count() == 0 ? " normal edges" : " collinear edges" ) ) ;
Rational<FT> t = compute_offset_lines_isec_timeC2(sorted) ; Rational<FT> t = compute_offset_lines_isec_timeC2(sorted) ;
@ -233,8 +271,9 @@ compare_offset_lines_isec_dist_to_pointC2 ( Triedge<FT> const& s
} }
// Given a triple of oriented lines in _normalized_ implicit form: (e0,e1,e2) such that their offsets // Given a triple of oriented lines in _normalized_ implicit form: (e0,e1,e2) such that their offsets
// at a distance 't intersects in a point (x,y); and another triple of oriented lines in _normalized_ implicit form: // at somne distance intersects in a point (x,y); and another triple of oriented lines in _normalized_ implicit form:
// (el,ec,er); returns true if the intersection point (x,y) is inside the offset zone of 'ec' w.r.t 'el' and 'er'; // (el,ec,er); returns true if the intersection point (x,y) is inside the offset zone of 'ec' w.r.t 'el' and 'er';
// that is, the locus of points to the left of 'ec', to the right of the bisector (el,ec) and to the left of the bisector // that is, the locus of points to the left of 'ec', to the right of the bisector (el,ec) and to the left of the bisector
// (ec,er). // (ec,er).
@ -245,92 +284,101 @@ compare_offset_lines_isec_dist_to_pointC2 ( Triedge<FT> const& s
// //
template<class FT> template<class FT>
Uncertain<bool> Uncertain<bool>
is_offset_lines_isec_inside_offset_zoneC2 ( Triedge<FT> const& triedge, Triedge<FT> const& zone ) is_offset_lines_isec_inside_offset_zoneC2 ( Triedge<FT> const& event, Triedge<FT> const& zone )
{ {
Uncertain<bool> r = Uncertain<bool>::indeterminate(); Uncertain<bool> r = Uncertain<bool>::indeterminate();
SortedTriedge<FT> sorted = collinear_sort(triedge); SortedTriedge<FT> e_sorted = collinear_sort(event);
if ( !sorted.is_indeterminate() )
Uncertain<bool> degenerate_zone = is_offset_zone_degenerate(zone);
if ( !(e_sorted.is_indeterminate() || is_indeterminate(degenerate_zone)) )
{ {
CGAL_assertion ( sorted.collinear_count() < 3 ) ; CGAL_assertion ( e_sorted.collinear_count() < 3 ) ;
Line<FT> zl = compute_normalized_line_ceoffC2(zone.e0()) ; if ( !degenerate_zone )
Line<FT> zc = compute_normalized_line_ceoffC2(zone.e1()) ;
Line<FT> zr = compute_normalized_line_ceoffC2(zone.e2()) ;
// Construct intersection point (x,y)
Vertex<FT> i = construct_offset_lines_isecC2(sorted);
// Calculate scaled (signed) distance from (x,y) to 'zc'
FT sdc = zc.a() * i.x() + zc.b() * i.y() + zc.c() ;
CGAL_SSTRAITS_TRACE("\nsdc=" << sdc ) ;
// NOTE:
// if (x,y) is not on the positive side of 'ec' it isn't on it's offset zone.
// Also, if (x,y) is over 'ec' (its signed distance to ec is not certainly positive) then by definition is not on its _offset_
// zone either.
Uncertain<bool> cok = CGAL_NTS certified_is_positive(sdc);
if ( ! CGAL_NTS is_indeterminate(cok) )
{ {
if ( cok == true ) Line<FT> zl = compute_normalized_line_ceoffC2(zone.e0()) ;
Line<FT> zc = compute_normalized_line_ceoffC2(zone.e1()) ;
Line<FT> zr = compute_normalized_line_ceoffC2(zone.e2()) ;
// Construct intersection point (x,y)
Vertex<FT> i = construct_offset_lines_isecC2(e_sorted);
// Calculate scaled (signed) distance from (x,y) to 'zc'
FT sdc = zc.a() * i.x() + zc.b() * i.y() + zc.c() ;
CGAL_SSTRAITS_TRACE("\nsdc=" << sdc ) ;
// NOTE:
// if (x,y) is not on the positive side of 'ec' it isn't on it's offset zone.
// Also, if (x,y) is over 'ec' (its signed distance to ec is not certainly positive) then by definition is not on its _offset_
// zone either.
Uncertain<bool> cok = CGAL_NTS certified_is_positive(sdc);
if ( ! CGAL_NTS is_indeterminate(cok) )
{ {
CGAL_SSTRAITS_TRACE("\nright side of ec." ) ; if ( cok == true )
// Calculate scaled (signed) distances from (x,y) to 'el' and 'er'
FT sdl = zl.a() * i.x() + zl.b() * i.y() + zl.c() ;
FT sdr = zr.a() * i.x() + zr.b() * i.y() + zr.c() ;
CGAL_SSTRAITS_TRACE("\nsdl=" << sdl ) ;
CGAL_SSTRAITS_TRACE("\nsdr=" << sdr ) ;
// Determine if the vertices (el,ec) and (ec,er) are reflex.
Uncertain<bool> lcx = CGAL_NTS certified_is_smaller(zl.a()*zc.b(),zc.a()*zl.b());
Uncertain<bool> crx = CGAL_NTS certified_is_smaller(zc.a()*zr.b(),zr.a()*zc.b());
if ( ! CGAL_NTS is_indeterminate(lcx) && ! CGAL_NTS is_indeterminate(crx) )
{ {
CGAL_SSTRAITS_TRACE("\n(el,ec) reflex:" << lcx ) ; CGAL_SSTRAITS_TRACE("\nright side of ec." ) ;
CGAL_SSTRAITS_TRACE("\n(ec,er) reflex:" << crx ) ;
// Calculate scaled (signed) distances from (x,y) to 'el' and 'er'
// Is (x,y) to the right|left of the bisectors (el,ec) and (ec,er)? FT sdl = zl.a() * i.x() + zl.b() * i.y() + zl.c() ;
// It depends on whether the vertex ((el,ec) and (ec,er)) is relfex or not. FT sdr = zr.a() * i.x() + zr.b() * i.y() + zr.c() ;
// If it is reflex, then (x,y) is to the right|left of the bisector if sdl|sdr <= sdc; otherwise, if sdc <= sdl|srd
CGAL_SSTRAITS_TRACE("\nsdl=" << sdl ) ;
Uncertain<bool> lok = lcx ? CGAL_NTS certified_is_smaller_or_equal(sdl,sdc) CGAL_SSTRAITS_TRACE("\nsdr=" << sdr ) ;
: CGAL_NTS certified_is_smaller_or_equal(sdc,sdl) ;
// Determine if the vertices (el,ec) and (ec,er) are reflex.
Uncertain<bool> rok = crx ? CGAL_NTS certified_is_smaller_or_equal(sdr,sdc) Uncertain<bool> lcx = CGAL_NTS certified_is_smaller(zl.a()*zc.b(),zc.a()*zl.b());
: CGAL_NTS certified_is_smaller_or_equal(sdc,sdr) ; Uncertain<bool> crx = CGAL_NTS certified_is_smaller(zc.a()*zr.b(),zr.a()*zc.b());
CGAL_SSTRAITS_TRACE("\nlok:" << lok) ; if ( ! CGAL_NTS is_indeterminate(lcx) && ! CGAL_NTS is_indeterminate(crx) )
CGAL_SSTRAITS_TRACE("\nrok:" << rok) ; {
CGAL_SSTRAITS_TRACE("\n(el,ec) reflex:" << lcx ) ;
r = CGAL_NTS logical_and(lok , rok) ; CGAL_SSTRAITS_TRACE("\n(ec,er) reflex:" << crx ) ;
// Is (x,y) to the right|left of the bisectors (el,ec) and (ec,er)?
// It depends on whether the vertex ((el,ec) and (ec,er)) is relfex or not.
// If it is reflex, then (x,y) is to the right|left of the bisector if sdl|sdr <= sdc; otherwise, if sdc <= sdl|srd
Uncertain<bool> lok = lcx ? CGAL_NTS certified_is_smaller_or_equal(sdl,sdc)
: CGAL_NTS certified_is_smaller_or_equal(sdc,sdl) ;
Uncertain<bool> rok = crx ? CGAL_NTS certified_is_smaller_or_equal(sdr,sdc)
: CGAL_NTS certified_is_smaller_or_equal(sdc,sdr) ;
CGAL_SSTRAITS_TRACE("\nlok:" << lok) ;
CGAL_SSTRAITS_TRACE("\nrok:" << rok) ;
r = CGAL_NTS logical_and(lok , rok) ;
}
else
{
CGAL_SSTRAITS_TRACE("\nUnable to reliably determine side-of-line." ) ;
}
} }
else else
{ {
CGAL_SSTRAITS_TRACE("\nUnable to reliably determine side-of-line." ) ; CGAL_SSTRAITS_TRACE("\nWRONG side of ec." ) ;
r = make_uncertain(false);
} }
} }
else else
{ {
CGAL_SSTRAITS_TRACE("\nWRONG side of ec." ) ; CGAL_SSTRAITS_TRACE("\nUnable to reliably determine side-of-line." ) ;
r = make_uncertain(false);
} }
} }
else else
{ {
CGAL_SSTRAITS_TRACE("\nUnable to reliably determine side-of-line." ) ; CGAL_SSTRAITS_TRACE("\nDegenerate offset zone. Edge collapsed." ) ;
r = make_uncertain(false);
} }
} }
else else
{ {
CGAL_SSTRAITS_TRACE("\nUnable to determine collinearity of event triedge." ) ; CGAL_SSTRAITS_TRACE("\nUnable to determine collinearity of event triedge or parallelity of zone triedge." ) ;
} }
return r ; return r ;
} }

View File

@ -0,0 +1,7 @@
1
5
0 0
4 0
8 0
8 2
0 2

View File

@ -0,0 +1,8 @@
1
6
0 0
4 0
8 0
8 2
4 2
0 2

View File

@ -0,0 +1,14 @@
1
11
0 2
1 2
5 2
5 0
9 0
9 2
12 2
13 2
13 3
13 5
0 5

View File

@ -0,0 +1,14 @@
1
12
0 0
1 0
3 0
4 0
4 1
4 3
4 4
3 4
1 4
0 4
0 3
0 1

View File

@ -0,0 +1,12 @@
1
10
0 2
3 2
5 0
6 1
8 1
8 2
6 2
5 1
3 3
0 3

View File

@ -0,0 +1,7 @@
1
5
0 0
8 0
8 1
8 2
0 2

View File

@ -0,0 +1,9 @@
1
7
0 0
4 0
8 0
8 1
8 2
4 2
0 2

View File

@ -0,0 +1,10 @@
1
8
0 0
4 0
8 0
8 1
8 2
4 2
0 2
0 1

View File

@ -0,0 +1,8 @@
1
6
0 0
3 0
5 0
8 0
8 2
0 2

View File

@ -0,0 +1,8 @@
1
6
0 0
1 0
7 0
8 0
8 2
0 2

View File

@ -0,0 +1,9 @@
1
7
0 0
3 0
5 0
8 0
8 2
4 2
0 2

View File

@ -0,0 +1,14 @@
1
12
0 0
1 0
4 0
7 0
8 0
8 1
8 2
7 2
4 2
1 2
0 2
0 1

View File

@ -0,0 +1,12 @@
1
9
0 2
2 2
5 2
5 0
9 0
9 2
13 2
13 5
0 5

View File

@ -0,0 +1,31 @@
1
28
3 0
4 0
4 1
5 1
6 1
6 2
6 3
7 3
7 4
6 4
6 5
6 6
5 6
4 6
4 7
3 7
3 6
2 6
1 6
1 5
1 4
0 4
0 3
1 3
1 2
1 1
2 1
3 1

View File

@ -0,0 +1,8 @@
1
5
0 0
2 1
2 6
-2 6
-2 1

View File

@ -0,0 +1 @@
ls --format=single-column -S -r

View File

@ -0,0 +1,23 @@
1
20
0 0
2 0
2 1
3 1
3 0
5 0
5 2
4 2
4 3
5 3
5 5
3 5
3 4
2 4
2 5
0 5
0 3
1 3
1 2
0 2

View File

@ -0,0 +1,33 @@
1
29
2 1
5 3
5 1
6 0
7 3
7 0
9 3
10 0
15 0
12 2
14 2
12 5
14 8
13 8
13 9
12 9
12 8
10 10
9 9
8 6
5 9
2 7
1 7
1 6
0 6
0 5
2 5
0 4
3 2

View File

@ -0,0 +1,32 @@
1
28
2 1
5 3
5 1
6 0
7 3
7 0
9 3
10 0
15 0
12 2
14 2
12 5
14 8
13 8
13 9
12 9
12 8
10 10
9 9
8 6
5 9
2 7
1 7
1 6
0 6
0 5
2 5
0 4

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,14 @@
1
11
0 0
3 0
4 1
5 0
9 0
9 1
5 1
5 2
3 2
3 1
0 1

View File

@ -1,36 +1,55 @@
./data ./data
sample_85.poly degenerate2.poly
sample_298.poly degenerate0.poly
sample_147.poly double_edge.poly
sample_698.poly degenerate6.poly
sample_235.poly degenerate5.poly
sample_73.poly degenerate1.poly
sample_101.poly
sample_638.poly
sample_333.poly
sample_319.poly
sample_325.poly
sample_46.poly
sample_4.poly
sample_2.poly
sample_0.poly
vertex_event_9.poly
sample_5.poly
alley_3.poly
sample_1.poly
alley_2.poly
sample_6.poly
sample_3.poly
hole.poly
closer_edge_event_0.poly
closer_edge_event_1.poly
double_split.poly
masked_double_split.poly
alley_0.poly
alley_1.poly
region_4.poly
single_split.poly
vertex_event_0.poly
rectangle.poly
square.poly
triangle.poly triangle.poly
degenerate7.poly
degenerate3.poly
degenerate4.poly
square.poly
rectangle.poly
degenerate9.poly
degenerate12.poly
vertex_event_0.poly
split_at_zero_0.poly
single_split.poly
degenerate8.poly
region_4.poly
degenerate10.poly
alley_1.poly
alley_0.poly
masked_double_split.poly
double_split.poly
closer_edge_event_1.poly
closer_edge_event_0.poly
hole.poly
multinode1.poly
degenerate_multinode0.poly
parallels0_b.poly
parallels0.poly
sample_3.poly
sample_6.poly
alley_2.poly
sample_1.poly
alley_3.poly
sample_5.poly
vertex_event_9.poly
sample_0.poly
sample_2.poly
sample_4.poly
sample_46.poly
sample_325.poly
sample_319.poly
sample_333.poly
sample_638.poly
sample_101.poly
sample_73.poly
sample_235.poly
sample_698.poly
sample_147.poly
sample_298.poly
sample_85.poly
sample_102.poly