diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoTab.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoTab.h index 9d4f78786ac..7117df439e3 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoTab.h +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoTab.h @@ -62,10 +62,11 @@ public: typedef ArrangementDemoTabBase Superclass; typedef Arr_ Arrangement; - ArrangementDemoTab( Arrangement* arrangement_, QWidget* parent ): + ArrangementDemoTab( Arrangement* arrangement_, QWidget* parent = 0 ): Superclass( parent ), arrangement( arrangement_ ) { + std::cout << this->scene->views( ).size( ) << std::endl; // set up demo components this->arrangementGraphicsItem = new CGAL::Qt::ArrangementGraphicsItem< Arrangement >( this->arrangement ); this->curveInputCallback = new ArrangementCurveInputCallback< Arrangement >( this->arrangement, this ); diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoWindow.cpp b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoWindow.cpp index 52ec2684fd7..b42622a6a83 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoWindow.cpp +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoWindow.cpp @@ -15,7 +15,6 @@ #include #include - ArrangementDemoWindow:: ArrangementDemoWindow(QWidget* parent) : CGAL::Qt::DemosMainWindow( parent ), @@ -57,6 +56,7 @@ makeTab( TraitsType tt ) Seg_arr* seg_arr; Pol_arr* pol_arr; Conic_arr* conic_arr; + Lin_arr* lin_arr; CGAL::Object arr; switch ( tt ) @@ -80,6 +80,12 @@ makeTab( TraitsType tt ) arr = CGAL::make_object( conic_arr ); tabLabel = QString( "%1 - Conic" ).arg( tabLabelCounter++ ); break; + case LINEAR_TRAITS: + lin_arr = new Lin_arr; + demoTab = new ArrangementDemoTab< Lin_arr >( lin_arr, 0 ); + arr = CGAL::make_object( lin_arr ); + tabLabel = QString( "%1 - Linear" ).arg( tabLabelCounter++ ); + break; } this->arrangements.push_back( arr ); @@ -177,6 +183,8 @@ setupUi( ) this->conicTypeGroup->addAction( this->ui->actionConicEllipse ); this->conicTypeGroup->addAction( this->ui->actionConicThreePoint ); this->conicTypeGroup->addAction( this->ui->actionConicFivePoint ); + this->conicTypeGroup->addAction( this->ui->actionCurveRay ); + this->conicTypeGroup->addAction( this->ui->actionCurveLine ); } void @@ -394,7 +402,9 @@ updateConicType( QAction* newType ) QGraphicsScene* activeScene = activeTab->getScene( ); ArrangementDemoGraphicsView* activeView = activeTab->getView( ); Conic_arr* conic_arr; + Lin_arr* lin_arr; bool isConicArr = CGAL::assign( conic_arr, this->arrangements[ this->ui->tabWidget->currentIndex( ) ] ); + bool isLinearArr = CGAL::assign( lin_arr, this->arrangements[ this->ui->tabWidget->currentIndex( ) ] ); if ( isConicArr ) { std::cout << "do something conic arr related" << std::endl; @@ -421,8 +431,22 @@ updateConicType( QAction* newType ) curveInputCallback->setConicType( ConicCurveInputCallback::CONIC_FIVE_POINT ); } } - else + else if ( isLinearArr ) { + typedef CGAL::Qt::GraphicsViewCurveInput< typename Lin_arr::Geometry_traits_2 > LinearCurveInputCallback; + LinearCurveInputCallback* curveInputCallback = ( LinearCurveInputCallback* ) activeTab->getCurveInputCallback( ); + if ( newType == this->ui->actionConicSegment ) + { + curveInputCallback->setCurveType( LinearCurveInputCallback::SEGMENT ); + } + else if ( newType == this->ui->actionCurveRay ) + { + curveInputCallback->setCurveType( LinearCurveInputCallback::RAY ); + } + else if ( newType == this->ui->actionCurveLine ) + { + curveInputCallback->setCurveType( LinearCurveInputCallback::LINE ); + } //std::cout << "do nothing" << std::endl; } } @@ -614,6 +638,10 @@ on_actionNewTab_triggered( ) { this->makeTab( CONIC_TRAITS ); } + else if ( id == LINEAR_TRAITS ) + { + this->makeTab( LINEAR_TRAITS ); + } else { std::cout << "Sorry, this trait is not yet supported" << std::endl; @@ -637,16 +665,52 @@ on_tabWidget_currentChanged( ) CGAL::Object arr; if ( this->ui->tabWidget->currentIndex( ) != -1 ) arr = this->arrangements[ this->ui->tabWidget->currentIndex( ) ]; + Seg_arr* seg; Pol_arr* pol; Conic_arr* conic; + Lin_arr* lin; if ( CGAL::assign( conic, arr ) ) { + this->ui->actionConicSegment->setChecked( true ); + + this->ui->actionCurveRay->setVisible( false ); + this->ui->actionCurveLine->setVisible( false ); + + this->ui->actionConicCircle->setVisible( true ); + this->ui->actionConicEllipse->setVisible( true ); + this->ui->actionConicThreePoint->setVisible( true ); + this->ui->actionConicFivePoint->setVisible( true ); + + this->conicTypeGroup->setEnabled( true ); + } + else if ( CGAL::assign( lin, arr ) ) + { + this->ui->actionConicSegment->setChecked( true ); + + this->ui->actionCurveRay->setVisible( true ); + this->ui->actionCurveLine->setVisible( true ); + + this->ui->actionConicCircle->setVisible( false ); + this->ui->actionConicEllipse->setVisible( false ); + this->ui->actionConicThreePoint->setVisible( false ); + this->ui->actionConicFivePoint->setVisible( false ); + this->conicTypeGroup->setEnabled( true ); } else - { - this->conicTypeGroup->setEnabled( false ); + { // segment or polyline + this->ui->actionConicSegment->setChecked( true ); + + this->ui->actionCurveRay->setVisible( false ); + this->ui->actionCurveLine->setVisible( false ); + + this->ui->actionConicCircle->setVisible( false ); + this->ui->actionConicEllipse->setVisible( false ); + this->ui->actionConicThreePoint->setVisible( false ); + this->ui->actionConicFivePoint->setVisible( false ); + + this->conicTypeGroup->setEnabled( true ); } } diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoWindow.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoWindow.h index 8a13e76a725..927c037d858 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoWindow.h +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoWindow.h @@ -43,7 +43,8 @@ public: typedef enum TraitsType { SEGMENT_TRAITS, POLYLINE_TRAITS, - CONIC_TRAITS + CONIC_TRAITS, + LINEAR_TRAITS } TraitsType; ArrangementDemoWindow(QWidget* parent = 0); diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoWindow.qrc b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoWindow.qrc index 0d2dfb176ac..088355f9a3b 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoWindow.qrc +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoWindow.qrc @@ -1,5 +1,6 @@ + icons/demo_conic_line.xpm icons/demo_zoomin.xpm icons/demo_zoomout.xpm icons/yellow_icon.xpm @@ -11,6 +12,7 @@ icons/demo_conic_segment.xpm icons/demo_conic_3points.xpm icons/demo_snapvertex.xpm + icons/demo_conic_ray.xpm icons/lower_env_xpm.xpm icons/upper_env_xpm.xpm icons/demo_snapgrid.xpm diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoWindow.ui b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoWindow.ui index 478f93a966e..6ccba51ad22 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoWindow.ui +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoWindow.ui @@ -6,7 +6,7 @@ 0 0 - 800 + 829 600 @@ -29,7 +29,7 @@ 0 0 - 800 + 829 25 @@ -127,6 +127,8 @@ + + @@ -437,6 +439,30 @@ Zoom Out + + + true + + + + :/icons/demo_conic_ray.xpm:/icons/demo_conic_ray.xpm + + + Ray + + + + + true + + + + :/icons/demo_conic_line.xpm:/icons/demo_conic_line.xpm + + + Line + + diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementGraphicsItem.cpp b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementGraphicsItem.cpp index ec05d6e912c..284305296fe 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementGraphicsItem.cpp +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementGraphicsItem.cpp @@ -83,5 +83,23 @@ setScene( QGraphicsScene* scene_ ) this->scene = scene_; } +QRectF +ArrangementGraphicsItemBase:: +getViewportRect( ) const +{ + QRectF clipRect; + if ( this->scene == NULL || this->scene->views( ).size( ) == 0 ) + { + return clipRect; + } + + QGraphicsView* view = this->scene->views( ).first( ); + QPointF p1 = view->mapToScene( 0, 0 ); + QPointF p2 = view->mapToScene( view->width( ), view->height( ) ); + clipRect = QRectF( p1, p2 ); + + return clipRect; +} + } // namespace Qt } // namespace CGAL diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementGraphicsItem.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementGraphicsItem.h index 5c67fdeabb2..f500baadfad 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementGraphicsItem.h +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementGraphicsItem.h @@ -51,6 +51,8 @@ public: void setScene( QGraphicsScene* scene_ ); protected: + QRectF getViewportRect( ) const; + CGAL::Bbox_2 bb; bool bb_initialized; @@ -63,7 +65,7 @@ protected: }; // class ArrangementGraphicsItemBase -template < class Arr_ > +template < class Arr_, class ArrTraits = typename Arr_::Geometry_traits_2 > class ArrangementGraphicsItem : public ArrangementGraphicsItemBase { typedef Arr_ Arrangement; @@ -78,10 +80,9 @@ class ArrangementGraphicsItem : public ArrangementGraphicsItemBase public: ArrangementGraphicsItem( Arrangement* t_ ); - void modelChanged( ); public: - // QGraphicsItem overrides + void modelChanged( ); QRectF boundingRect( ) const; virtual void paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget ); @@ -95,8 +96,8 @@ protected: std::map< Curve_iterator, CGAL::Bbox_2 > curveBboxMap; }; // class ArrangementGraphicsItem -template < class Arr_ > -ArrangementGraphicsItem< Arr_ >:: +template < class Arr_, class ArrTraits > +ArrangementGraphicsItem< Arr_, ArrTraits >:: ArrangementGraphicsItem( Arrangement* arr_ ): arr( arr_ ), painterostream( 0 ) @@ -108,32 +109,22 @@ ArrangementGraphicsItem( Arrangement* arr_ ): this->setZValue( 3 ); } -template < class Arr_ > +template < class Arr_, class ArrTraits > QRectF -ArrangementGraphicsItem< Arr_ >:: +ArrangementGraphicsItem< Arr_, ArrTraits >:: boundingRect( ) const { QRectF rect = this->convert( this->bb ); return rect; } -template < class Arr_ > +template < class Arr_, class ArrTraits > void -ArrangementGraphicsItem< Arr_ >::paint(QPainter *painter, +ArrangementGraphicsItem< Arr_, ArrTraits >::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget * /*widget*/) { - //painter->setClipping( true ); - //painter->drawRect( this->boundingRect( ) ); -#if 0 - QTransform transform = painter->worldTransform( ); - if ( transform.isScaling( ) ) - { - std::cout << "Cool, we're scaling." << std::endl; - std::cout << transform.m11( ) << std::endl; - } -#endif painter->setPen( this->verticesPen ); this->painterostream = ArrangementPainterOstream< Traits >( painter, this->boundingRect( ) ); this->painterostream.setScene( this->scene ); @@ -146,12 +137,6 @@ ArrangementGraphicsItem< Arr_ >::paint(QPainter *painter, painter->setPen( this->edgesPen ); for ( Edge_iterator it = this->arr->edges_begin( ); it != this->arr->edges_end( ); ++it ) { -#if 0 - Point_2 p1 = it->source( )->point( ); - Point_2 p2 = it->target( )->point( ); - Segment_2 edge( p1, p2 ); - this->painterostream << edge; -#endif X_monotone_curve_2 curve = it->curve( ); this->painterostream << curve; } @@ -159,9 +144,9 @@ ArrangementGraphicsItem< Arr_ >::paint(QPainter *painter, // We let the bounding box only grow, so that when vertices get removed // the maximal bbox gets refreshed in the GraphicsView -template < class Arr_ > +template < class Arr_, class ArrTraits > void -ArrangementGraphicsItem< Arr_ >::updateBoundingBox( ) +ArrangementGraphicsItem< Arr_, ArrTraits >::updateBoundingBox( ) { this->prepareGeometryChange( ); if ( this->arr->number_of_vertices( ) == 0 ) @@ -188,9 +173,9 @@ ArrangementGraphicsItem< Arr_ >::updateBoundingBox( ) } } -template < class Arr_ > +template < class Arr_, class ArrTraits > void -ArrangementGraphicsItem< Arr_ >::modelChanged( ) +ArrangementGraphicsItem< Arr_, ArrTraits >::modelChanged( ) { if ( this->arr->is_empty( ) ) { @@ -204,6 +189,129 @@ ArrangementGraphicsItem< Arr_ >::modelChanged( ) this->update( ); } +/** + * Why is this not being used? +Specialized methods: + updateBoundingBox +*/ +template < class Arr_, class Kernel_ > +class ArrangementGraphicsItem< Arr_, CGAL::Arr_linear_traits_2< Kernel_ > > : public ArrangementGraphicsItemBase +{ + typedef Arr_ Arrangement; + typedef ArrangementGraphicsItemBase Superclass; + typedef typename Arrangement::Geometry_traits_2 Traits; + typedef typename Arrangement::Vertex_iterator Vertex_iterator; + typedef typename Arrangement::Curve_iterator Curve_iterator; + typedef typename Arrangement::Edge_iterator Edge_iterator; + typedef typename ArrTraitsAdaptor< Traits >::Kernel Kernel; + typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; + typedef typename Kernel::Point_2 Point_2; + typedef typename Kernel::Segment_2 Segment_2; + +public: + ArrangementGraphicsItem( Arrangement* arr_ ): + arr( arr_ ), + painterostream( 0 ) + { + if ( this->arr->number_of_vertices( ) == 0 ) { + this->hide( ); + } + this->updateBoundingBox( ); + this->setZValue( 3 ); + } + + void modelChanged( ) + { + if ( this->arr->is_empty( ) ) + { + this->hide( ); + } + else + { + this->show( ); + } + this->updateBoundingBox( ); + this->update( ); + } + + +public: // methods + // @override QGraphicsItem::boundingRect + QRectF boundingRect( ) const + { + QRectF rect = this->convert( this->bb ); + return rect; + } + + // @override QGraphicsItem::paint + virtual void paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget ) + { + this->updateBoundingBox( ); + painter->setPen( this->verticesPen ); + this->painterostream = ArrangementPainterOstream< Traits >( painter, this->boundingRect( ) ); + this->painterostream.setScene( this->scene ); + + for ( Vertex_iterator it = this->arr->vertices_begin( ); it != this->arr->vertices_end( ); ++it ) + { + Point_2 pt = it->point( ); + this->painterostream << pt; + } + painter->setPen( this->edgesPen ); + for ( Edge_iterator it = this->arr->edges_begin( ); it != this->arr->edges_end( ); ++it ) + { + X_monotone_curve_2 curve = it->curve( ); + this->painterostream << curve; + } + } + +protected: // methods + void updateBoundingBox( ) + { + this->prepareGeometryChange( ); + QRectF clipRect = this->getViewportRect( ); + this->convert = Converter( clipRect ); + + if ( ! clipRect.isValid( ) /*|| this->arr->number_of_vertices( ) == 0*/ ) + { + this->bb = Bbox_2( 0, 0, 0, 0 ); + this->bb_initialized = false; + return; + } + else + { + this->bb = this->convert( clipRect ).bbox( ); + this->bb_initialized = true; + } + + for ( Curve_iterator it = this->arr->curves_begin( ); + it != this->arr->curves_end( ); + ++it ) + { + if ( it->is_segment( ) ) + { + this->bb = this->bb + it->segment( ).bbox( ); + } + else if ( it->is_ray( ) ) + { + QLineF qclippedRay = this->convert( it->ray( ) ); + Segment_2 clippedRay = this->convert( qclippedRay ); + this->bb = this->bb + clippedRay.bbox( ); + } + else // ( it->is_line( ) ) + { + QLineF qclippedLine = this->convert( it->line( ) ); + Segment_2 clippedLine = this->convert( qclippedLine ); + this->bb = this->bb + clippedLine.bbox( ); + } + } + } + +protected: // fields + Arrangement* arr; + ArrangementPainterOstream< Traits > painterostream; + CGAL::Qt::Converter< Kernel > convert; +}; // class ArrangementGraphicsItem + } // namespace Qt } // namespace CGAL diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementPainterOstream.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementPainterOstream.h index 4bef673b1a5..2beba1d2203 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementPainterOstream.h +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementPainterOstream.h @@ -8,6 +8,7 @@ #include #include #include +#include #include "Utils.h" #include @@ -74,18 +75,6 @@ protected: // methods QPointF p1 = view->mapToScene( 0, 0 ); QPointF p2 = view->mapToScene( view->width( ), view->height( ) ); QRectF clipRect = QRectF( p1, p2 ); -#if 0 - std::cout << "(" - << p1.x( ) - << " " - << p1.y( ) - << " " - << p2.x( ) - << " " - << p2.y( ) - << ")" - << std::endl; -#endif return clipRect; } @@ -608,6 +597,101 @@ protected: // members Construct_x_monotone_curve_2 construct_x_monotone_curve_2; }; +template < class Kernel_ > +class ArrangementPainterOstream< CGAL::Arr_linear_traits_2< Kernel_ > >: + public ArrangementPainterOstreamBase< CGAL::Arr_linear_traits_2< Kernel_ > > +{ +public: // typedefs + typedef Kernel_ Kernel; + typedef CGAL::Arr_linear_traits_2< Kernel > Traits; + typedef ArrangementPainterOstreamBase< Traits > Superclass; + typedef typename Superclass::Point_2 Point_2; + typedef typename Superclass::Segment_2 Segment_2; + typedef typename Superclass::Ray_2 Ray_2; + typedef typename Superclass::Line_2 Line_2; + typedef typename Superclass::Triangle_2 Triangle_2; + typedef typename Superclass::Iso_rectangle_2 Iso_rectangle_2; + typedef typename Superclass::Circle_2 Circle_2; + typedef typename Traits::Curve_2 Curve_2; + typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; + +public: // constructors + ArrangementPainterOstream( QPainter* p, QRectF clippingRectangle = QRectF( ) ): + Superclass( p, clippingRectangle ) + { } + +public: // methods + ArrangementPainterOstream& operator<<( const X_monotone_curve_2& curve ) + { + if ( curve.is_segment( ) ) + { + Segment_2 seg = curve.segment( ); + + // skip segments outside our view + QRectF seg_bb = this->convert( seg.bbox( ) ); + if ( this->clippingRect.isValid( ) && + ! this->clippingRect.intersects( seg_bb ) ) + { + return *this; + } + + this->painterOstream << seg; + } + else if ( curve.is_ray( ) ) + { + Ray_2 ray = curve.ray( ); + QLineF qseg = this->convert( ray ); + if ( qseg.isNull( ) ) + { // it's out of view + return *this; + } + Segment_2 seg = this->convert( qseg ); + this-> painterOstream << seg; + } + else // curve.is_line( ) + { + Line_2 line = curve.line( ); + QLineF qseg = this->convert( line ); + if ( qseg.isNull( ) ) + { // it's out of view + return *this; + } + Segment_2 seg = this->convert( qseg ); + this-> painterOstream << seg; + } + return *this; + } + + ArrangementPainterOstream& operator<<( const Point_2& p ) + { + QPointF qpt = this->convert( p ); + // clip the point if possible + if ( this->clippingRect.isValid( ) && + ! this->clippingRect.contains( qpt ) ) + { + return *this; + } + + QPen savePen = this->qp->pen( ); + this->qp->setBrush( QBrush( savePen.color( ) ) ); + double radius = savePen.width( ) / 2.0; + radius /= this->scale; + + this->qp->drawEllipse( qpt, radius, radius ); + + this->qp->setBrush( QBrush( ) ); + this->qp->setPen( savePen ); + return *this; + } + + template < class T > + ArrangementPainterOstream& operator<<( const T& p ) + { + (*(static_cast< Superclass* >(this)) << p); + return *this; + } +}; + } // namespace Qt } // namespace CGAL #endif // CGAL_QT_ARRANGEMENT_PAINTER_OSTREAM_H diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementTypes.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementTypes.h index 36398ad26ce..f18eaedc687 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementTypes.h +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementTypes.h @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -238,6 +239,35 @@ typedef CGAL::Arr_landmarks_point_location #endif +// Linear: +typedef CGAL::Arr_linear_traits_2 Lin_traits; +typedef Lin_traits::Curve_2 Arr_lin_2; +typedef Lin_traits::X_monotone_curve_2 Arr_xlin_2; +typedef Lin_traits::Point_2 Arr_lin_point_2; +typedef Dcel Lin_dcel; +typedef CGAL::Arrangement_with_history_2 Lin_arr; +typedef Lin_arr::Halfedge Lin_halfedge; +typedef Lin_arr::Halfedge_handle Lin_halfedge_handle; +typedef Lin_arr::Face_handle Lin_face_handle; +typedef Lin_arr::Ccb_halfedge_circulator Lin_ccb_halfedge_circulator; +typedef Lin_arr::Hole_iterator Lin_holes_iterator; +typedef Lin_arr::Face_iterator Lin_face_iterator; +typedef std::list Arr_lin_list; +typedef Arr_lin_list::const_iterator Arr_lin_const_iter; +typedef Arr_lin_list::iterator Arr_lin_iter; + +//point location +typedef CGAL::Arr_trapezoid_ric_point_location + Lin_trap_point_location; +typedef CGAL::Arr_simple_point_location + Lin_simple_point_location; +typedef CGAL::Arr_walk_along_line_point_location + Lin_walk_point_location; +typedef CGAL::Arr_landmarks_point_location + Lin_landmarks_point_location; + + template diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/CurveGraphicsItem.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/CurveGraphicsItem.h index 5a22d80f073..01edf827b28 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/CurveGraphicsItem.h +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/CurveGraphicsItem.h @@ -3,6 +3,8 @@ #include "ArrangementPainterOstream.h" #include #include +#include + namespace CGAL { namespace Qt { @@ -16,23 +18,30 @@ public: typedef typename Traits::Curve_2 Curve_2; typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; +public: // ctors CurveGraphicsItem( ); +public: // methods virtual void paint( QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget ); - void updateBoundingBox( ); + virtual QRectF boundingRect( ) const; void insert( const X_monotone_curve_2& curve ); void clear( ); - QRectF boundingRect( ) const; + void setScene( QGraphicsScene* scene_ ); public slots: void modelChanged( ); -protected: +protected: // methods + void updateBoundingBox( ); + QRectF viewportRect( ) const; + +protected: // fields CGAL::Qt::Converter< Kernel > convert; - ArrangementPainterOstream< ArrTraits > painterOstream; + ArrangementPainterOstream< Traits > painterOstream; std::vector< X_monotone_curve_2 > curves; CGAL::Bbox_2 boundingBox; bool boundingBoxInitialized; + QGraphicsScene* scene; }; // class CurveGraphicsItem template < class ArrTraits > @@ -40,7 +49,8 @@ CurveGraphicsItem< ArrTraits >:: CurveGraphicsItem( ): painterOstream( 0 ), boundingBox( 0, 0, 0, 0 ), - boundingBoxInitialized( false ) + boundingBoxInitialized( false ), + scene( 0 ) { this->setZValue( 4 ); } @@ -51,7 +61,8 @@ CurveGraphicsItem< ArrTraits >:: paint( QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget ) { painter->setPen( QPen( ::Qt::red, 0. ) ); - this->painterOstream = ArrangementPainterOstream< ArrTraits >( painter/*, clippingRectangle */ ); + QRectF clippingRectangle = this->viewportRect( ); + this->painterOstream = ArrangementPainterOstream< Traits >( painter, clippingRectangle ); for ( int i = 0; i < this->curves.size( ); ++i ) { X_monotone_curve_2 curve = this->curves[ i ]; @@ -59,6 +70,15 @@ paint( QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widge } } +template < class ArrTraits > +QRectF +CurveGraphicsItem< ArrTraits >:: +boundingRect( ) const +{ + QRectF boundingRectangle = this->convert( this->boundingBox ); + return boundingRectangle; +} + template < class ArrTraits > void CurveGraphicsItem< ArrTraits >:: @@ -116,15 +136,214 @@ clear( ) this->curves.clear( ); } + + template < class ArrTraits > -QRectF +void CurveGraphicsItem< ArrTraits >:: -boundingRect( ) const +setScene( QGraphicsScene* scene_ ) { - QRectF boundingRectangle = this->convert( this->boundingBox ); - return boundingRectangle; + this->scene = scene_; } +template < class ArrTraits > +QRectF +CurveGraphicsItem< ArrTraits >:: +viewportRect( ) const +{ + QRectF res; + if ( ! this->scene ) + return res; + if ( this->scene->views( ).size( ) == 0 ) + return res; + + QGraphicsView* view = this->scene->views( ).first( ); + QPointF p1 = view->mapToScene( 0, 0 ); + QPointF p2 = view->mapToScene( view->width( ), view->height( ) ); + res = QRectF( p1, p2 ); + return res; +} + +/** +Specialization of the base template CurveGraphicsItem: + + updateBoundingBox +*/ +template < class Kernel_ > +class CurveGraphicsItem< CGAL::Arr_linear_traits_2< Kernel_ > > : public GraphicsItem +{ +public: // typedefs + // known curve types + typedef CGAL::Arr_linear_traits_2< Kernel_ > Traits; + typedef Kernel_ Kernel; + typedef typename Traits::Curve_2 Curve_2; + typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; + typedef typename Kernel::Segment_2 Segment_2; + typedef typename Kernel::Line_2 Line_2; + typedef typename Kernel::Ray_2 Ray_2; + +public: // ctors + CurveGraphicsItem( ): + painterOstream( 0 ), + boundingBox( 0, 0, 0, 0 ), + boundingBoxInitialized( false ), + scene( 0 ) + { + this->setZValue( 4 ); + } + +public: // methods + virtual void paint( QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget ) + { + QRectF clippingRectangle = this->viewportRect( ); + painter->setPen( QPen( ::Qt::red, 0. ) ); + this->painterOstream = ArrangementPainterOstream< Traits >( painter, clippingRectangle ); + for ( int i = 0; i < this->curves.size( ); ++i ) + { + X_monotone_curve_2 curve = this->curves[ i ]; + this->painterOstream << curve; + } + } + + void insert( const X_monotone_curve_2& curve ) + { + this->curves.push_back( curve ); + } + + void clear( ) + { + this->curves.clear( ); + } + + QRectF boundingRect( ) const + { + QRectF res; + if ( ! this->scene ) + { + return res; + } + + } + + void setScene( QGraphicsScene* scene_ ) + { + this->scene = scene_; + if ( this->scene ) + { + QRectF clipRect = this->viewportRect( ); + this->convert = CGAL::Qt::Converter< Kernel >( clipRect ); + } + } + +public slots: + void modelChanged( ) + { + if ( this->curves.size( ) == 0 ) + { + this->hide( ); + } + else + { + this->show( ); + } + this->updateBoundingBox( ); + this->update( ); + } + +protected: // methods + void updateBoundingBox( ) + { + this->boundingBoxInitialized = 0; + this->boundingBox = CGAL::Bbox_2( 0, 0, 0, 0 ); + QRectF clipRect = this->viewportRect( ); + if ( !clipRect.isValid( ) ) + { + return; + } + this->convert = CGAL::Qt::Converter< Kernel >( clipRect ); + + bool first = 1; + for ( int i = 0; i < curves.size( ); ++i ) + { + X_monotone_curve_2 curve = curves[ i ]; + if ( curve.is_segment( ) ) + { + Segment_2 seg = curve.segment( ); + CGAL::Bbox_2 seg_bbox = seg.bbox( ); + if ( first ) + { + first = 0; + this->boundingBoxInitialized = 1; + this->boundingBox = seg_bbox; + } + else + { + this->boundingBox = this->boundingBox + seg_bbox; + } + } + else if ( curve.is_ray( ) ) + { + Ray_2 ray = curve.ray( ); + QLineF qclippedRay = this->convert( ray ); + if ( qclippedRay.isNull( ) ) + continue; + Segment_2 clippedRay = this->convert( qclippedRay ); + if ( first ) + { + first = 0; + this->boundingBoxInitialized = 1; + this->boundingBox = clippedRay.bbox( ); + } + else + { + this->boundingBox = this->boundingBox + clippedRay.bbox( ); + } + } + else // curve.is_line( ) + { + Line_2 line = curve.line( ); + QLineF qclippedLine = this->convert( line ); + if ( qclippedLine.isNull( ) ) + continue; + Segment_2 clippedLine = this->convert( qclippedLine ); + if ( first ) + { + first = 0; + this->boundingBoxInitialized = 1; + this->boundingBox = clippedLine.bbox( ); + } + else + { + this->boundingBox = this->boundingBox + clippedLine.bbox( ); + } + } + } + } + + QRectF viewportRect( ) const + { + QRectF res; + if ( ! this->scene ) + return res; + if ( this->scene->views( ).size( ) == 0 ) + return res; + + QGraphicsView* view = this->scene->views( ).first( ); + QPointF p1 = view->mapToScene( 0, 0 ); + QPointF p2 = view->mapToScene( view->width( ), view->height( ) ); + res = QRectF( p1, p2 ); + return res; + } + +protected: // fields + CGAL::Qt::Converter< Kernel > convert; + ArrangementPainterOstream< Traits > painterOstream; + std::vector< X_monotone_curve_2 > curves; + CGAL::Bbox_2 boundingBox; + bool boundingBoxInitialized; + QGraphicsScene* scene; +}; // class CurveGraphicsItem + } // namespace Qt } // namespace CGAL diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/DeleteCurveCallback.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/DeleteCurveCallback.h index 58523921689..742c57e9d1c 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/DeleteCurveCallback.h +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/DeleteCurveCallback.h @@ -70,6 +70,7 @@ DeleteCurveCallback< Arr_ >:: setScene( QGraphicsScene* scene_ ) { this->scene = scene_; + this->highlightedCurve->setScene( scene_ ); if ( this->scene ) { this->scene->addItem( this->highlightedCurve ); @@ -162,6 +163,7 @@ highlightNearestCurve( QGraphicsSceneMouseEvent* event ) } #endif Find_nearest_edge< Arr_ > findNearestEdge( this->arr ); + findNearestEdge.setScene( this->scene ); Halfedge_const_handle nearestEdge = findNearestEdge( p ); this->removableHalfedge = this->arr->non_const_handle( nearestEdge ); @@ -170,6 +172,7 @@ highlightNearestCurve( QGraphicsSceneMouseEvent* event ) //if ( isFirst ) if ( this->removableHalfedge == Halfedge_handle( ) ) { + std::cout << "no curve found" << std::endl; return; } diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/EnvelopeCallback.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/EnvelopeCallback.h index 88e9c86e35d..864b56b3377 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/EnvelopeCallback.h +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/EnvelopeCallback.h @@ -33,6 +33,9 @@ public: typedef typename Traits::Construct_x_monotone_curve_2 Construct_x_monotone_curve_2; typedef typename ArrTraitsAdaptor< Traits >::Kernel Kernel; typedef typename Kernel::Point_2 Point_2; + typedef typename Kernel::Segment_2 Segment_2; + typedef typename Kernel::Ray_2 Ray_2; + typedef typename Kernel::Line_2 Line_2; typedef CGAL::Envelope_diagram_1< Traits > Diagram_1; /** @@ -136,6 +139,8 @@ updateEnvelope( bool lower ) typename Diagram_1::Edge_const_handle e = diagram.leftmost( ); typename Diagram_1::Vertex_const_handle v; + QRectF clipRect = this->viewportRect( ); + CGAL::Qt::Converter< Kernel > convert( clipRect ); while ( e != diagram.rightmost( ) ) { if ( ! e->is_empty( ) ) @@ -147,8 +152,27 @@ updateEnvelope( bool lower ) // TODO: generate a subcurve instead of just making a segment - Point_2 leftPoint = e->left( )->point( ); - Point_2 rightPoint = e->right( )->point( ); + Point_2 leftPoint, rightPoint; + if ( e->left( ) != NULL ) + { + leftPoint = e->left( )->point( ); + } + else + { + std::cout << "handle unbounded curve" << std::endl; + v = e->right( ); + e = v->right( ); + continue; + } + + if ( e->right( ) != NULL ) + { + rightPoint = e->right( )->point( ); + } + else + { + std::cout << "pRight is null; should never get here..." << std::endl; + } X_monotone_curve_2 curve = this->construct_x_monotone_subcurve_2( e->curve( ), leftPoint, rightPoint ); envelopeToUpdate->insert( curve ); diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/GraphicsViewCurveInput.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/GraphicsViewCurveInput.h index 19b73fbd6a2..93532f91483 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/GraphicsViewCurveInput.h +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/GraphicsViewCurveInput.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -21,7 +22,7 @@ class GraphicsViewCurveInputBase: { public: virtual void setScene( QGraphicsScene* scene_ ); - QGraphicsScene* getScene( ) const; + virtual QGraphicsScene* getScene( ) const; void setSnappingEnabled( bool b ); void setSnapToGridEnabled( bool b ); @@ -493,6 +494,142 @@ protected: ConicType conicType; }; // class GraphicsViewCurveInput< CGAL::Arr_conic_traits_2< RatKernel, AlgKernel, NtTraits > > +/** +Specialization of GraphicsViewCurveInput for Arr_linear_traits_2; handles +user-guided generation of line segment curves. +*/ +template < class Kernel_ > +class GraphicsViewCurveInput< CGAL::Arr_linear_traits_2< Kernel_ > >: + public GraphicsViewCurveInputBase +{ +public: // typedefs + typedef Kernel_ Kernel; + typedef GraphicsViewCurveInputBase Superclass; + typedef CGAL::Arr_linear_traits_2< Kernel > Traits; + typedef typename Traits::Curve_2 Curve_2; + typedef typename Kernel::Point_2 Point_2; + typedef typename Kernel::Segment_2 Segment_2; + typedef typename Kernel::Ray_2 Ray_2; + typedef typename Kernel::Line_2 Line_2; + enum CurveType + { + SEGMENT, RAY, LINE + }; + +public: // constructors + GraphicsViewCurveInput( QObject* parent ): + GraphicsViewCurveInputBase( parent ), + second( false ), + curveType( SEGMENT ) + { } + +public: // methods + void setCurveType( CurveType type ) + { + this->curveType = type; + } + +protected: // methods + virtual bool eventFilter( QObject* obj, QEvent* event ) + { + // before we do anything, update the clipping rect + // TODO: somehow only update this when the view changes + QRectF clippingRect = this->viewportRect( ); + this->convert = Converter< Kernel >( clippingRect ); + + // now handle the event + return Superclass::eventFilter( obj, event ); + } + + void mouseMoveEvent( QGraphicsSceneMouseEvent* event ) + { + if ( this->second ) + { + Point_2 hoverPoint = this->snapPoint( event ); + if ( p1 == hoverPoint ) + return; + QLineF qSegment; + if ( this->curveType == SEGMENT ) + { + Segment_2 segment( this->p1, hoverPoint ); + qSegment = this->convert( segment ); + } + else if ( this->curveType == RAY ) + { + Ray_2 ray( this->p1, hoverPoint ); + qSegment = this->convert( ray ); + } + else // this->curveType == LINE + { + Line_2 line( this->p1, hoverPoint ); + qSegment = this->convert( line ); + } + this->segmentGuide.setLine( qSegment ); + } + } + + void mousePressEvent( QGraphicsSceneMouseEvent* event ) + { + if ( !this->second ) + { // fix our first point + this->second = true; + this->p1 = this->snapPoint( event ); + QPointF pt = this->convert( this->p1 ); + this->segmentGuide.setLine( pt.x( ), pt.y( ), pt.x( ), pt.y( ) ); + if ( this->scene != NULL ) + { + this->scene->addItem( &( this->segmentGuide ) ); + } + } + else // this->second == true + { + this->second = false; + this->p2 = this->snapPoint( event ); + + // skip if degenerate + if ( this->p1 == this->p2 ) + return; + + if ( this->scene != NULL ) + { + this->scene->removeItem( &( this->segmentGuide ) ); + } + + Curve_2 res; + if ( this->curveType == SEGMENT ) + { + res = Curve_2( Segment_2( this->p1, this->p2 ) ); + } + else if ( this->curveType == RAY ) + { + res = Curve_2( Ray_2( this->p1, this->p2 ) ); + } + else // this->curveType == LINE + { + res = Curve_2( Line_2( this->p1, this->p2 ) ); + } + + emit generate( CGAL::make_object( res ) ); + } + } + + // override this to snap to the points you like + virtual Point_2 snapPoint( QGraphicsSceneMouseEvent* event ) + { + Point_2 clickedPoint = this->convert( event->scenePos( ) ); + return clickedPoint; + } + +protected: // fields + Converter< Kernel > convert; + Point_2 p1; + Point_2 p2; + bool second; + + QGraphicsLineItem segmentGuide; + CurveType curveType; +}; // class GraphicsViewCurveInput< CGAL::Arr_linear_traits_2< Kernel_ > > + } // namespace Qt } // namespace CGAL #endif // CGAL_QT_GRAPHICS_VIEW_SEGMENT_INPUT_H diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/MergeEdgeCallback.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/MergeEdgeCallback.h index bd6da8ed9e9..4f52591a9da 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/MergeEdgeCallback.h +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/MergeEdgeCallback.h @@ -75,6 +75,8 @@ MergeEdgeCallback< Arr_ >:: setScene( QGraphicsScene* scene_ ) { this->scene = scene_; + this->highlightedCurve->setScene( scene_ ); + this->highlightedCurve2->setScene( scene_ ); if ( this->scene ) { this->scene->addItem( this->highlightedCurve ); diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/NewTabDialog.cpp b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/NewTabDialog.cpp index a8742f2e48a..9c64251baf0 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/NewTabDialog.cpp +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/NewTabDialog.cpp @@ -14,6 +14,7 @@ NewTabDialog( QWidget* parent, Qt::WindowFlags f ): this->buttonGroup->addButton( this->ui->segmentRadioButton, ArrangementDemoWindow::SEGMENT_TRAITS ); this->buttonGroup->addButton( this->ui->polylineRadioButton, ArrangementDemoWindow::POLYLINE_TRAITS ); this->buttonGroup->addButton( this->ui->conicRadioButton, ArrangementDemoWindow::CONIC_TRAITS ); + this->buttonGroup->addButton( this->ui->linearRadioButton, ArrangementDemoWindow::LINEAR_TRAITS ); } int diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/NewTabDialog.ui b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/NewTabDialog.ui index 837946a923b..2d648fa5d74 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/NewTabDialog.ui +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/NewTabDialog.ui @@ -7,7 +7,7 @@ 0 0 400 - 133 + 165 @@ -19,7 +19,7 @@ 10 10 381 - 113 + 141 @@ -50,7 +50,7 @@ - + Qt::Horizontal @@ -60,6 +60,13 @@ + + + + Linear + + + diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/SplitEdgeCallback.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/SplitEdgeCallback.h index ba6a7cf912d..c3d32171fac 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/SplitEdgeCallback.h +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/SplitEdgeCallback.h @@ -153,8 +153,8 @@ mousePressEvent( QGraphicsSceneMouseEvent* event ) if ( CGAL::assign( pair, res ) ) { Point_2 splitPoint = pair.first; - if ( this->areEqual( hei->source( )->point( ), splitPoint ) || - this->areEqual( hei->target( )->point( ), splitPoint ) ) + if ( ( ! hei->source( )->is_at_open_boundary( ) && this->areEqual( hei->source( )->point( ), splitPoint ) ) || + ( ! hei->target( )->is_at_open_boundary( ) && this->areEqual( hei->target( )->point( ), splitPoint ) ) ) { continue; } diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Utils.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Utils.h index c91ffead24e..d3bd1ec94d9 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Utils.h +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Utils.h @@ -26,6 +26,15 @@ public: typedef typename ArrTraits::Point_2 Point_2; }; +template < class Kernel_ > +class ArrTraitsAdaptor< CGAL::Arr_linear_traits_2< Kernel_ > > +{ +public: + typedef Kernel_ Kernel; + typedef CGAL::Arr_linear_traits_2< Kernel > ArrTraits; + typedef typename ArrTraits::Point_2 Point_2; +}; + template < class SegmentTraits > class ArrTraitsAdaptor< CGAL::Arr_polyline_traits_2< SegmentTraits > > { @@ -51,6 +60,12 @@ public: typedef typename ArrTraitsAdaptor< ArrTraits >::Kernel Kernel; typedef typename Kernel::FT FT; +public: // ctors + Compute_squared_distance_2_base( ): + scene( 0 ) + { } + +public: // methods template < class T1, class T2 > FT operator() ( const T1& t1, const T2& t2 ) const @@ -58,8 +73,36 @@ public: return this->squared_distance( t1, t2 ); } -protected: + void setScene( QGraphicsScene* scene_ ) + { + this->scene = scene_; + } + + QRectF viewportRect( ) const + { + QRectF res; + if ( this->scene == NULL ) + { + return res; + } + + QList< QGraphicsView* > views = this->scene->views( ); + if ( views.size( ) == 0 ) + { + return res; + } + // assumes the first view is the right one + QGraphicsView* viewport = views.first( ); + QPointF p1 = viewport->mapToScene( 0, 0 ); + QPointF p2 = viewport->mapToScene( viewport->width( ), viewport->height( ) ); + res = QRectF( p1, p2 ); + + return res; + } + +protected: // fields typename Kernel::Compute_squared_distance_2 squared_distance; + QGraphicsScene* scene; }; template < class ArrTraits > @@ -89,6 +132,44 @@ public: } }; +template < class Kernel_ > +class Compute_squared_distance_2< CGAL::Arr_linear_traits_2< Kernel_ > > : + public Compute_squared_distance_2_base< CGAL::Arr_linear_traits_2< Kernel_ > > +{ +public: + typedef Kernel_ Kernel; + typedef CGAL::Arr_linear_traits_2< Kernel > Traits; + typedef Compute_squared_distance_2_base< Traits > Superclass; + typedef typename Kernel::FT FT; + typedef typename Kernel::Point_2 Point_2; + typedef typename Kernel::Segment_2 Segment_2; + typedef typename Kernel::Ray_2 Ray_2; + typedef typename Kernel::Line_2 Line_2; + typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; + + FT operator() ( const Point_2& p, const X_monotone_curve_2& c ) const + { + Segment_2 seg; + Ray_2 ray; + Line_2 line; + if ( c.is_segment( ) ) + { + seg = c.segment( ); + return this->squared_distance( p, seg ); + } + else if ( c.is_ray( ) ) + { + ray = c.ray( ); + return this->squared_distance( p, ray ); + } + else // ( c.is_line( ) ) + { + line = c.line( ); + return this->squared_distance( p, line ); + } + } +}; + template < class Kernel_ > class Compute_squared_distance_2< CGAL::Arr_polyline_traits_2< Kernel_ > > : public Compute_squared_distance_2_base< CGAL::Arr_polyline_traits_2< Kernel_ > > @@ -145,6 +226,7 @@ public: typedef typename Traits::Curve_2 Curve_2; typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; +public: // methods FT operator() ( const Point_2& p, const X_monotone_curve_2& c ) const { // Get the co-ordinates of the curve's source and target. @@ -178,7 +260,20 @@ public: FT min_dist( 100000000 ); AlgKernel ker; - int n = 100; // TODO: get an adaptive approximation + int n = 100; + if ( this->scene != NULL && this->scene->views( ).size( ) != 0 ) + { // use the scene to approximate the resolution of the curve + QGraphicsView* view = this->scene->views( ).first( ); + CGAL::Bbox_2 bb = c.bbox( ); // assumes bounded curve + int xmin = view->mapFromScene( bb.xmin( ), bb.ymin( ) ).x( ); + int xmax = view->mapFromScene( bb.xmax( ), bb.ymin( ) ).x( ); + n = xmax - xmin; + if ( n < 2 ) + { + n = 2; + } + } + std::pair< double, double >* app_pts = new std::pair< double, double >[ n + 1 ]; std::pair< double, double >* end_pts = c.polyline_approximation( n, app_pts ); std::pair< double, double >* p_curr = app_pts; @@ -192,7 +287,7 @@ public: FT dist = CGAL::squared_distance( p, seg ); if ( first || dist < min_dist ) { - first = true; + first = false; min_dist = dist; } @@ -249,6 +344,7 @@ public: if ( this->compare_x_2( pLeft, pMin ) == CGAL::LARGER ) { // FIXME: handle vertical lines properly + // FIXME: handle unbounded lines properly CGAL::Bbox_2 c_bbox = curve.bbox( ); FT splitLineYMin( c_bbox.ymin( ) - 1.0 ); FT splitLineYMax( c_bbox.ymax( ) + 1.0 ); @@ -346,6 +442,36 @@ public: } }; // class Construct_x_monotone_subcurve_2 for Arr_conic_traits_2 +template < class Kernel_ > +class Construct_x_monotone_subcurve_2< CGAL::Arr_linear_traits_2< Kernel_ > > +{ +public: // typedefs + typedef CGAL::Arr_linear_traits_2< Kernel_ > ArrTraits; + typedef typename ArrTraits::X_monotone_curve_2 X_monotone_curve_2; + typedef Kernel_ Kernel; + typedef typename Kernel::Point_2 Point_2; + typedef typename Kernel::Segment_2 Segment_2; + +public: // methods + // curve can be unbounded. if curve is unbounded to the left, pLeft is a point on the left edge of viewport. + X_monotone_curve_2 operator() ( const X_monotone_curve_2& curve, const Point_2& pLeft, const Point_2& pRight ) + { + if ( curve.is_segment( ) ) + { + Segment_2 subsegment = this->constructSubsegment( curve.segment( ), pLeft, pRight ); + return X_monotone_curve_2( subsegment ); + } + else if ( curve.is_ray( ) ) + { + + } + return curve; + } + +protected: + Construct_x_monotone_subcurve_2< CGAL::Arr_segment_traits_2< Kernel_ > > constructSubsegment; +}; + template < class K_ > class SnapStrategy @@ -536,12 +662,51 @@ protected: CGAL::Qt::Converter< Kernel > convert; }; // class SnapToArrangementVertexStrategy -template < class Arr_ > -class Find_nearest_edge +class Find_nearest_edge_base +{ +public: + Find_nearest_edge_base( ): + scene( 0 ) + { } + +public: + virtual void setScene( QGraphicsScene* scene_ ) + { + this->scene = scene_; + } + + QRectF viewportRect( ) const + { + QRectF res; + if ( this->scene == NULL ) + { + return res; + } + + QList< QGraphicsView* > views = this->scene->views( ); + if ( views.size( ) == 0 ) + { + return res; + } + // assumes the first view is the right one + QGraphicsView* viewport = views.first( ); + QPointF p1 = viewport->mapToScene( 0, 0 ); + QPointF p2 = viewport->mapToScene( viewport->width( ), viewport->height( ) ); + res = QRectF( p1, p2 ); + + return res; + } + +protected: + QGraphicsScene* scene; +}; + +template < class Arr_, class ArrTraits = typename Arr_::Geometry_traits_2 > +class Find_nearest_edge : public Find_nearest_edge_base { public: // typedefs typedef Arr_ Arrangement; - typedef typename Arrangement::Geometry_traits_2 ArrTraits; + //typedef typename Arrangement::Geometry_traits_2 ArrTraits; typedef Compute_squared_distance_2< ArrTraits > Point_curve_distance; typedef typename ArrTraits::X_monotone_curve_2 X_monotone_curve_2; typedef CGAL::Arr_walk_along_line_point_location< Arrangement > Point_location_strategy; @@ -557,6 +722,7 @@ public: // typedefs public: // constructors Find_nearest_edge( Arrangement* arr_ ): + Find_nearest_edge_base( ), arr( arr_ ), pointLocationStrategy( Point_location_strategy( *arr_ ) ) { } @@ -587,6 +753,159 @@ public: // member methods } while ( ++cc != face->outer_ccb( ) ); } +#if 0 // we can't do this with bounded arrangements + else + { + Ccb_halfedge_const_circulator cc = face->outer_ccb( ); + do + { + if ( cc->is_fictitious( ) ) + { + continue; + } + + X_monotone_curve_2 curve = cc->curve( ); + FT dist = this->pointCurveDistance( queryPt, curve ); + if ( first || dist < minDist ) + { + first = 0; + minDist = dist; + closestEdge = cc; + } + } + while ( ++cc != face->outer_ccb( ) ); + } +#endif + Hole_const_iterator hit; + Hole_const_iterator eit = face->holes_end( ); + int counter = 0; + for ( hit = face->holes_begin( ); hit != eit; ++hit ) + { // check any holes inside this face + Ccb_halfedge_const_circulator cc = *hit; + do + { + X_monotone_curve_2 curve = cc->curve( ); + FT dist = this->pointCurveDistance( queryPt, curve ); + if ( first || dist < minDist ) + { + first = 0; + minDist = dist; + closestEdge = cc; + } + cc++; + } + while ( cc != *hit ); + } + + return closestEdge; + } + + virtual void setScene( QGraphicsScene* scene_ ) + { + this->pointCurveDistance.setScene( scene_ ); + Find_nearest_edge_base::setScene( scene_ ); + } + +protected: // member methods + Face_const_handle getFace( const CGAL::Object& obj ) + { + Face_const_handle f; + if ( CGAL::assign( f, obj ) ) + return f; + + Halfedge_const_handle he; + if (CGAL::assign( he, obj )) + return (he->face( )); + + Vertex_const_handle v; + CGAL_assertion(CGAL::assign( v, obj )); + CGAL::assign( v, obj ); + if ( v->is_isolated( ) ) + return v->face( ); + Halfedge_around_vertex_const_circulator eit = v->incident_halfedges( ); + return (eit->face( )); + } + +protected: // member fields + Arrangement* arr; + Point_curve_distance pointCurveDistance; + Point_location_strategy pointLocationStrategy; + +}; // class Find_nearest_edge + +template < class Arr_, class Kernel_ > +class Find_nearest_edge< Arr_, CGAL::Arr_linear_traits_2< Kernel_ > >: public Find_nearest_edge_base +{ +public: // typedefs + typedef Arr_ Arrangement; + typedef typename Arrangement::Geometry_traits_2 ArrTraits; + typedef Compute_squared_distance_2< ArrTraits > Point_curve_distance; + typedef typename ArrTraits::X_monotone_curve_2 X_monotone_curve_2; + typedef CGAL::Arr_walk_along_line_point_location< Arrangement > Point_location_strategy; + typedef typename ArrTraitsAdaptor< ArrTraits >::Kernel Kernel; + typedef typename Kernel::Point_2 Point_2; + typedef typename Arrangement::Face_const_handle Face_const_handle; + typedef typename Arrangement::Halfedge_const_handle Halfedge_const_handle; + typedef typename Arrangement::Vertex_const_handle Vertex_const_handle; + typedef typename Arrangement::Ccb_halfedge_const_circulator Ccb_halfedge_const_circulator; + typedef typename Point_curve_distance::FT FT; + typedef typename Arrangement::Hole_const_iterator Hole_const_iterator; + typedef typename Arrangement::Halfedge_around_vertex_const_circulator Halfedge_around_vertex_const_circulator; + +public: // constructors + Find_nearest_edge( Arrangement* arr_ ): + Find_nearest_edge_base( ), + arr( arr_ ), + pointLocationStrategy( Point_location_strategy( *arr_ ) ) + { } + +public: // member methods + Halfedge_const_handle operator()( const Point_2& queryPt ) + { + CGAL::Object pointLocationResult = this->pointLocationStrategy.locate( queryPt ); + Face_const_handle face = this->getFace( pointLocationResult ); + bool first = 1; + X_monotone_curve_2 closestCurve; + Halfedge_const_handle closestEdge; + FT minDist( 0 ); + + if ( ! face->is_unbounded( ) ) + { // it is an interior face so it has a ccb + Ccb_halfedge_const_circulator cc = face->outer_ccb( ); + do + { + X_monotone_curve_2 curve = cc->curve( ); + FT dist = this->pointCurveDistance( queryPt, curve ); + if ( first || dist < minDist ) + { + first = 0; + minDist = dist; + closestEdge = cc; + } + } + while ( ++cc != face->outer_ccb( ) ); + } + else + { + Ccb_halfedge_const_circulator cc = face->outer_ccb( ); + do + { + if ( cc->is_fictitious( ) ) + { + continue; + } + + X_monotone_curve_2 curve = cc->curve( ); + FT dist = this->pointCurveDistance( queryPt, curve ); + if ( first || dist < minDist ) + { + first = 0; + minDist = dist; + closestEdge = cc; + } + } + while ( ++cc != face->outer_ccb( ) ); + } Hole_const_iterator hit; Hole_const_iterator eit = face->holes_end( ); for ( hit = face->holes_begin( ); hit != eit; ++hit ) @@ -634,7 +953,7 @@ protected: // member fields Arrangement* arr; Point_curve_distance pointCurveDistance; Point_location_strategy pointLocationStrategy; - }; // class Find_nearest_edge + #endif // CGAL_ARRANGEMENTS_DEMO_UTILS_H diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/VerticalRayShootCallback.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/VerticalRayShootCallback.h index 9f1f784ad9f..d773db19e79 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/VerticalRayShootCallback.h +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/VerticalRayShootCallback.h @@ -115,6 +115,7 @@ VerticalRayShootCallback< Arr_ >:: setScene( QGraphicsScene* scene_ ) { this->scene = scene_; + this->highlightedCurves->setScene( scene_ ); if ( this->scene ) { this->scene->addItem( this->highlightedCurves );