mirror of https://github.com/CGAL/cgal
191 lines
5.4 KiB
C
Executable File
191 lines
5.4 KiB
C
Executable File
// Copyright (c) 2005, 2006 Fernando Luis Cacciola Carballal. 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.
|
|
//
|
|
// $URL$
|
|
// $Id$
|
|
//
|
|
// Author(s) : Fernando Cacciola <fernando_cacciola@ciudad.com.ar>
|
|
//
|
|
#ifndef CGAL_POLYGON_OFFSET_BUILDER_2_C
|
|
#define CGAL_POLYGON_OFFSET_BUILDER_2_C 1
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
template<class Sls, class Gt, class Cont>
|
|
Polygon_offset_builder_2<Sls,Gt,Cont>::Polygon_offset_builder_2( Sls const& aSls, Traits const& aTraits )
|
|
:
|
|
mTraits(aTraits)
|
|
{
|
|
|
|
int lMaxID = -1 ;
|
|
|
|
for ( Halfedge_const_handle lHE = aSls.halfedges_begin() ; lHE != aSls.halfedges_end() ; ++ lHE )
|
|
{
|
|
if ( lHE->id() > lMaxID )
|
|
lMaxID = lHE->id() ;
|
|
|
|
if ( !lHE->is_bisector() && handle_assigned(lHE->face()) )
|
|
{
|
|
CGAL_POLYOFFSET_SHOW ( DrawBorder(lHE) ) ;
|
|
mBorders.push_back(lHE);
|
|
}
|
|
}
|
|
|
|
CGAL_POLYOFFSET_TRACE("Border count: " << mBorders.size() ) ;
|
|
|
|
CGAL_POLYOFFSET_TRACE("Highest Bisector ID: " << lMaxID ) ;
|
|
|
|
mVisitedBisectors.resize(lMaxID+1);
|
|
|
|
ResetVisitedBisectorsMap();
|
|
}
|
|
|
|
template<class Sls, class Gt, class Cont>
|
|
typename Polygon_offset_builder_2<Sls,Gt,Cont>::Halfedge_const_handle
|
|
Polygon_offset_builder_2<Sls,Gt,Cont>::LocateHook( FT aTime, Halfedge_const_handle aBisector )
|
|
{
|
|
CGAL_POLYOFFSET_TRACE("Searching for hook at " << aTime ) ;
|
|
|
|
Halfedge_const_handle rHook ;
|
|
|
|
while ( aBisector->is_bisector() )
|
|
{
|
|
CGAL_POLYOFFSET_TRACE("Testing hook on B" << aBisector->id() ) ;
|
|
|
|
Halfedge_const_handle lPrev = aBisector->prev();
|
|
Halfedge_const_handle lNext = aBisector->next();
|
|
|
|
if ( !IsVisited(aBisector) )
|
|
{
|
|
Comparison_result lCNext = lNext->is_bisector() ? Compare_offset_against_event_time(aTime,aBisector,lNext)
|
|
: SMALLER ;
|
|
|
|
Comparison_result lCPrev = lPrev->is_bisector() ? Compare_offset_against_event_time(aTime,lPrev,aBisector)
|
|
: SMALLER ;
|
|
|
|
CGAL_POLYOFFSET_TRACE("CPrev: " << lCPrev << " CNext: " << lCNext ) ;
|
|
|
|
if ( lCNext != lCPrev )
|
|
{
|
|
CGAL_POLYOFFSET_TRACE( "Hook found on B" << aBisector->id() ) ;
|
|
rHook = aBisector ;
|
|
break ;
|
|
}
|
|
}
|
|
aBisector = lNext ;
|
|
}
|
|
|
|
return rHook;
|
|
}
|
|
|
|
template<class Sls, class Gt, class Cont>
|
|
typename Polygon_offset_builder_2<Sls,Gt,Cont>::Halfedge_const_handle
|
|
Polygon_offset_builder_2<Sls,Gt,Cont>::LocateSeed( FT aTime )
|
|
{
|
|
Halfedge_const_handle rSeed ;
|
|
|
|
for ( typename Halfedge_vector::const_iterator f = mBorders.begin()
|
|
; f != mBorders.end() && !handle_assigned(rSeed)
|
|
; ++ f
|
|
)
|
|
{
|
|
CGAL_POLYOFFSET_TRACE("Locating hook for face E" << (*f)->id() ) ;
|
|
rSeed = LocateHook(aTime,(*f)->next());
|
|
}
|
|
CGAL_POLYOFFSET_TRACE("Seed found on B" << ( handle_assigned(rSeed) ? rSeed->id() : -1 ) ) ;
|
|
return rSeed;
|
|
}
|
|
|
|
template<class Sls, class Gt, class Cont>
|
|
void Polygon_offset_builder_2<Sls,Gt,Cont>::AddOffsetVertex( FT aTime, Halfedge_const_handle aHook, ContainerPtr aPoly )
|
|
{
|
|
Visit(aHook);
|
|
|
|
Point_2 lP = Construct_offset_point(aTime,aHook);
|
|
|
|
CGAL_POLYOFFSET_SHOW ( DrawBisector(aHook) ) ;
|
|
CGAL_POLYOFFSET_SHOW ( DrawOffset(aPoly,lP) ) ;
|
|
CGAL_POLYOFFSET_TRACE("Constructing offset point along B" << aHook->id() ) ;
|
|
|
|
aPoly->push_back(lP);
|
|
}
|
|
|
|
template<class Sls, class Gt, class Cont>
|
|
template<class OutputIterator>
|
|
OutputIterator Polygon_offset_builder_2<Sls,Gt,Cont>::TraceOffsetPolygon( FT aTime, Halfedge_const_handle aSeed, OutputIterator aOut )
|
|
{
|
|
CGAL_POLYOFFSET_TRACE("Tracing new offset polygon" ) ;
|
|
|
|
ContainerPtr lPoly( new Container() ) ;
|
|
|
|
Halfedge_const_handle lHook = aSeed ;
|
|
|
|
AddOffsetVertex(aTime,lHook,lPoly);
|
|
|
|
while ( true )
|
|
{
|
|
lHook = LocateHook(aTime,lHook->next()) ;
|
|
|
|
if ( handle_assigned(lHook) )
|
|
{
|
|
AddOffsetVertex(aTime,lHook,lPoly);
|
|
|
|
Halfedge_const_handle lNextBisector = lHook->opposite();
|
|
|
|
if ( lNextBisector != aSeed && !IsVisited(lNextBisector) )
|
|
{
|
|
lHook = lNextBisector;
|
|
continue;
|
|
}
|
|
}
|
|
break ;
|
|
}
|
|
|
|
CGAL_POLYOFFSET_SHOW ( DrawOffset(lPoly,(*lPoly)[0]) ) ;
|
|
|
|
if ( lPoly->size() >= 3 )
|
|
{
|
|
CGAL_POLYOFFSET_TRACE("Offset polygon of " << lPoly->size() << " vertices traced." ) ;
|
|
*aOut++ = lPoly ;
|
|
}
|
|
|
|
// ResetVisitedBisectorsMap();
|
|
|
|
return aOut ;
|
|
}
|
|
|
|
template<class Sls, class Gt, class Cont>
|
|
void Polygon_offset_builder_2<Sls,Gt,Cont>::ResetVisitedBisectorsMap()
|
|
{
|
|
std::fill(mVisitedBisectors.begin(),mVisitedBisectors.end(),0);
|
|
}
|
|
|
|
template<class Sls, class Gt, class Cont>
|
|
template<class OutputIterator>
|
|
OutputIterator Polygon_offset_builder_2<Sls,Gt,Cont>::construct_offset_polygons( FT aTime, OutputIterator aOut )
|
|
{
|
|
CGAL_precondition( aTime > static_cast<FT>(0.0) ) ;
|
|
|
|
ResetVisitedBisectorsMap();
|
|
|
|
CGAL_POLYOFFSET_TRACE("Constructing offset polygons for offset: " << aTime ) ;
|
|
for ( Halfedge_const_handle lSeed = LocateSeed(aTime); handle_assigned(lSeed); lSeed = LocateSeed(aTime) )
|
|
aOut = TraceOffsetPolygon(aTime,lSeed,aOut);
|
|
|
|
return aOut ;
|
|
}
|
|
|
|
CGAL_END_NAMESPACE
|
|
|
|
#endif // CGAL_POLYGON_OFFSET_BUILDER_2_C //
|
|
// EOF //
|