diff --git a/.gitattributes b/.gitattributes index 43534b33c86..760cbe5c474 100644 --- a/.gitattributes +++ b/.gitattributes @@ -328,6 +328,7 @@ Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementSegmentInputCa Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementTypes.h -text Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Callback.cpp -text Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Callback.h -text +Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Conic_reader.h -text Arrangement_on_surface_2/demo/Arrangement_on_surface_2/CurveGraphicsItem.h -text Arrangement_on_surface_2/demo/Arrangement_on_surface_2/DeleteCurveCallback.h -text Arrangement_on_surface_2/demo/Arrangement_on_surface_2/EnvelopeCallback.cpp -text diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementCurveInputCallback.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementCurveInputCallback.h index a994a877b82..bb958e93c5c 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementCurveInputCallback.h +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementCurveInputCallback.h @@ -52,6 +52,11 @@ public: this->snapToGridStrategy.setScene( scene ); } + void setArrangement( Arrangement* newArr ) + { + this->arrangement = newArr; + } + protected: Point_2 snapPoint( QGraphicsSceneMouseEvent* event ) { 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 06def5143e5..03f6110d92c 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 @@ -43,7 +43,7 @@ protected: QGraphicsScene* scene; QGridLayout* layout; - CGAL::Qt::GraphicsItem* arrangementGraphicsItem; + CGAL::Qt::ArrangementGraphicsItemBase* arrangementGraphicsItem; CGAL::Qt::GraphicsViewCurveInputBase* curveInputCallback; CGAL::Qt::Callback* deleteCurveCallback; CGAL::Qt::Callback* pointLocationCallback; @@ -76,6 +76,7 @@ public: this->envelopeCallback = new EnvelopeCallback< Arrangement >( this->arrangement, this ); this->scene->addItem( this->arrangementGraphicsItem ); + this->arrangementGraphicsItem->setScene( this->scene ); this->curveInputCallback->setScene( this->scene ); this->deleteCurveCallback->setScene( this->scene ); this->pointLocationCallback->setScene( this->scene ); @@ -92,6 +93,49 @@ public: QObject::connect( this, SIGNAL( modelChanged( ) ), this->envelopeCallback, SLOT( slotModelChanged( ) ) ); } + void setArrangement( Arrangement* newArr ) + { + this->scene->removeItem( this->arrangementGraphicsItem ); + delete this->arrangementGraphicsItem; + delete this->curveInputCallback; + delete this->deleteCurveCallback; + delete this->pointLocationCallback; + delete this->verticalRayShootCallback; + delete this->mergeEdgeCallback; + delete this->splitEdgeCallback; + delete this->envelopeCallback; + + this->arrangement = newArr; + + this->arrangementGraphicsItem = new CGAL::Qt::ArrangementGraphicsItem< Arrangement >( this->arrangement ); + + this->curveInputCallback = new ArrangementCurveInputCallback< Arrangement >( this->arrangement, this ); + this->deleteCurveCallback = new DeleteCurveCallback< Arrangement >( this->arrangement, this ); + this->pointLocationCallback = new PointLocationCallback< Arrangement >( this->arrangement, this ); + this->verticalRayShootCallback = new VerticalRayShootCallback< Arrangement >( this->arrangement, this ); + this->mergeEdgeCallback = new MergeEdgeCallback< Arrangement >( this->arrangement, this ); + this->splitEdgeCallback = new SplitEdgeCallback< Arrangement >( this->arrangement, this ); + this->envelopeCallback = new EnvelopeCallback< Arrangement >( this->arrangement, this ); + + this->scene->addItem( this->arrangementGraphicsItem ); + this->arrangementGraphicsItem->setScene( this->scene ); + this->curveInputCallback->setScene( this->scene ); + this->deleteCurveCallback->setScene( this->scene ); + this->pointLocationCallback->setScene( this->scene ); + this->verticalRayShootCallback->setScene( this->scene ); + this->mergeEdgeCallback->setScene( this->scene ); + this->splitEdgeCallback->setScene( this->scene ); + this->envelopeCallback->setScene( this->scene ); + + this->scene->installEventFilter( this->curveInputCallback ); + QObject::connect( this->curveInputCallback, SIGNAL( modelChanged( ) ), this, SIGNAL( modelChanged( ) ) ); + QObject::connect( this->deleteCurveCallback, SIGNAL( modelChanged( ) ), this, SIGNAL( modelChanged( ) ) ); + QObject::connect( this, SIGNAL( modelChanged( ) ), this->arrangementGraphicsItem, SLOT( modelChanged( ) ) ); + QObject::connect( this, SIGNAL( modelChanged( ) ), this->envelopeCallback, SLOT( slotModelChanged( ) ) ); + + emit modelChanged( ); + } + protected: Arrangement* arrangement; 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 2e564bff51a..b8726a1b1d1 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 @@ -1,7 +1,14 @@ #include "ArrangementDemoWindow.h" #include +#include +#include #include "NewTabDialog.h" #include "OverlayDialog.h" +#include "Conic_reader.h" + +#include +#include +#include ArrangementDemoWindow:: ArrangementDemoWindow(QWidget* parent) : @@ -76,6 +83,7 @@ makeTab( TraitsType tt ) this->addNavigation( view ); this->ui->tabWidget->addTab( demoTab, tabLabel ); this->lastTabIndex = this->ui->tabWidget->currentIndex( ); + this->ui->tabWidget->setCurrentWidget( demoTab ); return demoTab; } @@ -147,6 +155,7 @@ updateMode( QAction* newMode ) //QWidget* widget = this->ui->tabWidget->currentWidget( ); //ArrangementDemoTabBase* demoTab = static_cast< ArrangementDemoTabBase* >( widget ); const int TabIndex = this->ui->tabWidget->currentIndex( ); + if ( TabIndex == -1 ) return; ArrangementDemoTabBase* activeTab = this->tabs[ TabIndex ]; QGraphicsScene* activeScene = activeTab->getScene( ); QGraphicsView* activeView = activeTab->getView( ); @@ -296,6 +305,7 @@ void ArrangementDemoWindow:: updateEnvelope( QAction* newMode ) { + if ( this->ui->tabWidget->currentIndex( ) == -1 ) return; ArrangementDemoTabBase* activeTab = this->tabs[ this->ui->tabWidget->currentIndex( ) ]; QGraphicsScene* activeScene = activeTab->getScene( ); QGraphicsView* activeView = activeTab->getView( ); @@ -386,6 +396,155 @@ updateConicType( QAction* newType ) } } +void +ArrangementDemoWindow:: +on_actionSaveAs_triggered( ) +{ + int index = this->ui->tabWidget->currentIndex( ); + if ( index == -1 ) + return; + QString filename = + QFileDialog::getSaveFileName( this, tr( "Save file" ), + "", "Arrangement (*.arr)" ); + if ( filename.isNull( ) ) + return; + + std::ofstream ofs( filename.toStdString( ).c_str( ) ); + CGAL::Object arr = this->arrangements[ index ]; + Seg_arr* seg; + Pol_arr* pol; + Conic_arr* conic; + if ( CGAL::assign( seg, arr ) ) + { + typedef CGAL::Arr_with_history_text_formatter< CGAL::Arr_text_formatter< Seg_arr > > ArrFormatter; + ArrFormatter arrFormatter; + CGAL::write( *seg, ofs, arrFormatter ); + } + else if ( CGAL::assign( pol, arr ) ) + { + typedef CGAL::Arr_with_history_text_formatter< CGAL::Arr_text_formatter< Pol_arr > > ArrFormatter; + ArrFormatter arrFormatter; + CGAL::write( *pol, ofs, arrFormatter ); + } + else if ( CGAL::assign( conic, arr ) ) + { +#if 0 + typedef CGAL::Arr_with_history_text_formatter< CGAL::Arr_text_formatter< Conic_arr > > ArrFormatter; + ArrFormatter arrFormatter; + CGAL::write( *conic, ofs, arrFormatter ); +#endif + ofs << conic->number_of_curves( ) << std::endl; + for ( typename Conic_arr::Curve_iterator it = conic->curves_begin( ); it != conic->curves_end( ); ++it ) + { + if ( it->is_full_conic( ) ) + { + ofs << "F "; + ofs << it->r( ) << " "; + ofs << it->s( ) << " "; + ofs << it->t( ) << " "; + ofs << it->u( ) << " "; + ofs << it->v( ) << " "; + ofs << it->w( ) << " "; + ofs << std::endl; + } + else if ( it->orientation( ) == CGAL::COLLINEAR ) + { + ofs << "S "; + ofs << it->source( ) << " "; + ofs << it->target( ) << " "; + ofs << std::endl; + } + else + { + ofs << "A "; + ofs << it->r( ) << " "; + ofs << it->s( ) << " "; + ofs << it->t( ) << " "; + ofs << it->u( ) << " "; + ofs << it->v( ) << " "; + ofs << it->w( ) << " "; + if ( it->orientation( ) == CGAL::COUNTERCLOCKWISE ) + ofs << "1 "; + else if ( it->orientation( ) == CGAL::CLOCKWISE ) + ofs << "-1 "; + else + ofs << "0 "; + ofs << it->source( ) << " "; + ofs << it->target( ) << " "; + ofs << std::endl; + } + } + } + ofs.close( ); +} + +void +ArrangementDemoWindow:: +on_actionOpen_triggered( ) +{ + int index = this->ui->tabWidget->currentIndex( ); + if ( index == -1 ) + { + QMessageBox::information( this, "Oops", "Create a new tab first" ); + return; + } + QString filename = + QFileDialog::getOpenFileName( this, tr( "Open file" ), + "", "Arrangement file - *.arr (*.arr);;All files (*.*)" ); + if ( filename.isNull( ) ) + return; + std::ifstream ifs( filename.toStdString( ).c_str( ) ); + CGAL::Object arr = this->arrangements[ index ]; + Seg_arr* seg; + Pol_arr* pol; + Conic_arr* conic; + if ( CGAL::assign( seg, arr ) ) + { + typedef CGAL::Arr_with_history_text_formatter< CGAL::Arr_text_formatter< Seg_arr > > ArrFormatter; + typedef ArrangementDemoTab< Seg_arr > TabType; + + ArrFormatter arrFormatter; + CGAL::read( *seg, ifs, arrFormatter ); + this->arrangements[ index ] = CGAL::make_object( seg ); + TabType* tab = static_cast< TabType* >( this->tabs[ index ] ); + tab->setArrangement( seg ); + } + else if ( CGAL::assign( pol, arr ) ) + { + typedef CGAL::Arr_with_history_text_formatter< CGAL::Arr_text_formatter< Pol_arr > > ArrFormatter; + typedef ArrangementDemoTab< Pol_arr > TabType; + + ArrFormatter arrFormatter; + CGAL::read( *pol, ifs, arrFormatter ); + this->arrangements[ index ] = CGAL::make_object( pol ); + TabType* tab = static_cast< TabType* >( this->tabs[ index ] ); + tab->setArrangement( pol ); + } + else if ( CGAL::assign( conic, arr ) ) + { +#if 0 + typedef CGAL::Arr_with_history_text_formatter< CGAL::Arr_text_formatter< Conic_arr > > ArrFormatter; + ArrFormatter arrFormatter; + CGAL::read( *conic, ifs, arrFormatter ); + this->arrangements[ index ] = CGAL::make_object( conic ); + tab->setArrangement( conic ); +#endif + typedef ArrangementDemoTab< Conic_arr > TabType; + Conic_reader< typename Conic_arr::Geometry_traits_2 > conicReader; + std::vector< typename Conic_arr::Curve_2 > curve_list; + CGAL::Bbox_2 bbox; + conicReader.read_data( filename.toStdString( ).c_str( ), + std::back_inserter( curve_list ), bbox ); + this->arrangements[ index ] = CGAL::make_object( conic ); + TabType* tab = static_cast< TabType* >( this->tabs[ index ] ); + tab->setArrangement( conic ); + + CGAL::insert( *conic, curve_list.begin(), curve_list.end() ); + //QMessageBox::information( this, "Oops", "Reading conic arrangement not supported" ); + } + ifs.close( ); +} + void ArrangementDemoWindow:: on_actionQuit_triggered( ) @@ -433,7 +592,9 @@ on_tabWidget_currentChanged( ) this->updateMode( this->modeGroup->checkedAction( ) ); - CGAL::Object arr = this->arrangements[ this->ui->tabWidget->currentIndex( ) ]; + 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; @@ -496,3 +657,76 @@ on_actionOverlay_triggered( ) delete overlayDialog; } +void +ArrangementDemoWindow:: +on_actionCloseTab_triggered( ) +{ + int currentTabIndex = this->ui->tabWidget->currentIndex( ); + if ( ! this->ui->tabWidget->count( ) || currentTabIndex == -1 ) + { + return; + } + + // delete the tab + this->ui->tabWidget->removeTab( currentTabIndex ); + this->tabs.erase( this->tabs.begin( ) + currentTabIndex ); + + // delete the arrangement + this->arrangements.erase( this->arrangements.begin( ) + currentTabIndex ); +} + +void +ArrangementDemoWindow:: +on_actionPrintConicCurves_triggered( ) +{ + int currentTabIndex = this->ui->tabWidget->currentIndex( ); + Conic_arr* arr; + if ( currentTabIndex == -1 ) + return; + CGAL::Object o = this->arrangements[ currentTabIndex ]; + if ( ! CGAL::assign( arr, o ) ) + return; + typedef typename Conic_arr::Curve_iterator Curve_iterator; + std::cout << arr->number_of_curves( ) << std::endl; + for ( Curve_iterator it = arr->curves_begin( ); it != arr->curves_end( ); ++it ) + { + std::cout << *it << std::endl; + if ( it->is_full_conic( ) ) + { + std::cout << "F "; + std::cout << it->r( ) << " "; + std::cout << it->s( ) << " "; + std::cout << it->t( ) << " "; + std::cout << it->u( ) << " "; + std::cout << it->v( ) << " "; + std::cout << it->w( ) << " "; + std::cout << std::endl; + } + else if ( it->orientation( ) == CGAL::COLLINEAR ) + { + std::cout << "S "; + std::cout << it->source( ) << " "; + std::cout << it->target( ) << " "; + std::cout << std::endl; + } + else + { + std::cout << "A "; + std::cout << it->r( ) << " "; + std::cout << it->s( ) << " "; + std::cout << it->t( ) << " "; + std::cout << it->u( ) << " "; + std::cout << it->v( ) << " "; + std::cout << it->w( ) << " "; + if ( it->orientation( ) == CGAL::COUNTERCLOCKWISE ) + std::cout << "1 "; + else if ( it->orientation( ) == CGAL::CLOCKWISE ) + std::cout << "-1 "; + else + std::cout << "0 "; + std::cout << it->source( ) << " "; + std::cout << it->target( ) << " "; + std::cout << std::endl; + } + } +} 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 d8e47d1e0c2..d675a247215 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 @@ -27,8 +27,10 @@ class ArrangementDemoWindow : public CGAL::Qt::DemosMainWindow { Q_OBJECT public: +#if 0 typedef Seg_traits::Point_2 Point; typedef Seg_traits::Segment_2 Segment; +#endif typedef enum TraitsType { SEGMENT_TRAITS, POLYLINE_TRAITS, @@ -43,8 +45,8 @@ public: std::vector< QString > getTabLabels( ) const; std::vector< CGAL::Object > getArrangements( ) const; - template < class Arr1 > - void makeOverlayTab( Arr1* arr1, Arr1* arr2 ); + template < class ArrType > + void makeOverlayTab( ArrType* arr1, ArrType* arr2 ); public slots: void updateMode( QAction* a ); @@ -52,9 +54,13 @@ public slots: void updateSnapping( QAction* a ); void updateConicType( QAction* a ); void on_actionNewTab_triggered( ); + void on_actionSaveAs_triggered( ); + void on_actionOpen_triggered( ); void on_actionQuit_triggered( ); void on_tabWidget_currentChanged( ); void on_actionOverlay_triggered( ); + void on_actionCloseTab_triggered( ); + void on_actionPrintConicCurves_triggered( ); signals: void modelChanged( ); @@ -76,20 +82,20 @@ protected: QActionGroup* conicTypeGroup; }; -template < class Arr1 > +template < class ArrType > void ArrangementDemoWindow:: -makeOverlayTab( Arr1* arr1, Arr1* arr2 ) +makeOverlayTab( ArrType* arr1, ArrType* arr2 ) { QString tabLabel = QString( "Overlay Tab" ); ArrangementDemoTabBase* demoTab; - Arr1* overlayArr = new Arr1; - CGAL::Arr_default_overlay_traits< Arr1 > defaultTraits; + ArrType* overlayArr = new ArrType; + CGAL::Arr_default_overlay_traits< ArrType > defaultTraits; CGAL::overlay( *arr1, *arr2, *overlayArr, defaultTraits ); - demoTab = new ArrangementDemoTab< Arr1 >( overlayArr, 0 ); + demoTab = new ArrangementDemoTab< ArrType >( overlayArr, 0 ); this->arrangements.push_back( CGAL::make_object( overlayArr ) ); this->tabs.push_back( demoTab ); 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 944b853b299..5c637902249 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 @@ -38,6 +38,10 @@ &File + + + + @@ -80,11 +84,18 @@ + + + Testing + + + + @@ -270,6 +281,9 @@ New tab + + Ctrl+N + @@ -373,6 +387,35 @@ Five Point Conic + + + Close Tab + + + Ctrl+W + + + + + Save As... + + + Ctrl+S + + + + + Open... + + + Ctrl+O + + + + + Print conic curves + + 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 475b8c8d1aa..05da91f961b 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 @@ -10,7 +10,8 @@ ArrangementGraphicsItemBase( ): visible_edges( true ), visible_vertices( true ), verticesPen( QPen( ::Qt::black, 3. ) ), - edgesPen( QPen( ::Qt::black, 1. ) ) + edgesPen( QPen( ::Qt::black, 1. ) ), + scene( NULL ) { } const QPen& @@ -71,5 +72,12 @@ setVisibleEdges( const bool b ) this->update( ); } +void +ArrangementGraphicsItemBase:: +setScene( QGraphicsScene* scene_ ) +{ + this->scene = scene_; +} + } // 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 074996ddc15..570cc4b5879 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 @@ -44,6 +44,7 @@ public: void setVisibleVertices( const bool b ); bool visibleEdges( ) const; void setVisibleEdges( const bool b ); + void setScene( QGraphicsScene* scene_ ); protected: CGAL::Bbox_2 bb; @@ -53,6 +54,9 @@ protected: QPen edgesPen; bool visible_edges; bool visible_vertices; + + QGraphicsScene* scene; + }; // class ArrangementGraphicsItemBase template < class Arr_ > @@ -116,6 +120,8 @@ ArrangementGraphicsItem< Arr_ >::paint(QPainter *painter, 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( ); 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 d3ec26c43ec..356d6ec94cc 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 @@ -32,7 +32,8 @@ public: ArrangementPainterOstreamBase( QPainter* p, QRectF clippingRectangle = QRectF( ) ): painterOstream( p, clippingRectangle ), qp( p ), - convert( clippingRectangle ) + convert( clippingRectangle ), + scene( NULL ) { } template < class T > @@ -41,11 +42,16 @@ public: this->painterOstream << t; return *this; } + void setScene( QGraphicsScene* scene_ ) + { + this->scene = scene_; + } protected: PainterOstream< Kernel > painterOstream; QPainter* qp; Converter< Kernel > convert; + QGraphicsScene* scene; }; // class ArrangementPainterOstreamBase template < class ArrTraits > @@ -170,7 +176,23 @@ public: { std::cout << "ArrangementPainterOstream< Conic_traits >::paint curve" << std::endl; - int n = 100; // TODO: get an adaptive approximation + int n; + if ( this->scene == NULL ) + n = 100; // TODO: get an adaptive approximation + else + { + QGraphicsView* view = this->scene->views( ).first( ); + CGAL::Bbox_2 bb = curve.bbox( ); + int xmin, xmax; + xmin = view->mapFromScene( bb.xmin( ), bb.ymin( ) ).x( ); + xmax = view->mapFromScene( bb.xmax( ), bb.ymin( ) ).x( ); + n = xmax - xmin; + } + if ( n == 0 ) + { + return *this; + } + std::pair< double, double >* app_pts = new std::pair< double, double >[ n + 1 ]; std::pair< double, double >* end_pts = curve.polyline_approximation( n, app_pts ); std::pair< double, double >* p_curr = app_pts; diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Conic_reader.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Conic_reader.h new file mode 100644 index 00000000000..c4ccdbc3ba3 --- /dev/null +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Conic_reader.h @@ -0,0 +1,227 @@ +#ifndef CGAL_CONIC_READER_H +#define CGAL_CONIC_READER_H + +#include +#include +#include +#include +#include + +template +class Conic_reader +{ +public: + typedef typename Traits::Curve_2 Curve_2; + typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; + typedef typename Traits::Point_2 Point_2; + + typedef typename Traits::Rational Rational; + typedef typename Traits::Algebraic Algebraic; + typedef typename Traits::Rat_point_2 Rat_point_2; + typedef typename Traits::Rat_segment_2 Rat_segment_2; + typedef typename Traits::Rat_circle_2 Rat_circle_2; + + template + int read_data(const char * filename, OutputIterator curves_out, + CGAL::Bbox_2 & bbox) + { + + Curve_2 cv; + char dummy[256]; + + std::ifstream inp(filename); + if (!inp.is_open()) { + std::cerr << "Cannot open file " << filename << "!" << std::endl; + return -1; + } + int count; + inp >> count; + inp.getline(dummy, sizeof(dummy)); + for (int i = 0; i < count; i++) { + if (read_curve(inp, cv)) { + ++curves_out = cv; + CGAL::Bbox_2 curve_bbox = cv.bbox(); + if (i == 0) bbox = curve_bbox; + else bbox = bbox + curve_bbox; + } + } + inp.close(); + return 0; + } + + /*! */ + bool read_curve(std::ifstream & is, Curve_2 & cv) + { + // Read a line from the input file. + char one_line[128]; + + skip_comments (is, one_line); + std::istringstream str_line (one_line); + + // Read the arc type and act accordingly. + char type; + + str_line >> type; + + if (type == 's' || type == 'S') + { + // Construct a line segment. The line should have the format: + // s + // where (x1, y1), (x2, y2) are the endpoints of a segment. + Rational x1, y1, x2, y2; + std::string buf; + + //str_line >> x1 >> y1 >> x2 >> y2; + str_line >> buf; + x1 = Algebraic( buf ).BigRatValue( ); + str_line >> buf; + y1 = Algebraic( buf ).BigRatValue( ); + str_line >> buf; + x2 = Algebraic( buf ).BigRatValue( ); + str_line >> buf; + y2 = Algebraic( buf ).BigRatValue( ); + + Rat_point_2 p1(x1, y1), p2(x2, y2); + Rat_segment_2 seg (p1, p2); + + cv = Curve_2 (seg); + } + else if (type == 'c' || type == 'C') + { + // Construct a full circle. The line should have the format: + // c + // where (x0, y0) is the center of the circle and R_sq is its squared + // radius. + Rational x0, y0, R_sq; + + str_line >> x0 >> y0 >> R_sq; + + Rat_point_2 p0(x0, y0); + Rat_circle_2 circ(p0, R_sq); + + cv = Curve_2 (circ); + } + else if (type == 't' || type == 'T') + { + // Construct a circular arc. The line should have the format: + // t + // where (x1, y1), (x2, y2) and (x3, y3) define the arc. + Rational x1, y1, x2, y2, x3, y3; + + str_line >> x1 >> y1 >> x2 >> y2 >> x3 >> y3; + + Rat_point_2 p1(x1, y1), p2(x2, y2), p3(x3, y3); + + cv = Curve_2 (p1, p2, p3); + } + else if (type == 'f' || type == 'F') + { + // Construct a full conic curve. The line should have the format: + // c + // where r, s, t, u, v, w define the conic equation. + Rational r, s, t, u, v, w; + + str_line >> r >> s >> t >> u >> v >> w; + + cv = Curve_2 (r, s, t, u, v, w); + } + else if (type == 'a' || type == 'A') + { + // Construct a conic arc. The line should have the format: + // c + // where r, s, t, u, v, w define the conic equation, while (x1, y1) + // and (x2, y2) are the arc's endpoints. + Rational r, s, t, u, v, w; + + str_line >> r >> s >> t >> u >> v >> w; + + // Read the orientation. + int i_orient; + CGAL::Orientation orient; + + str_line >> i_orient; + if (i_orient > 0) + orient = CGAL::COUNTERCLOCKWISE; + else if (i_orient < 0) + orient = CGAL::CLOCKWISE; + else + orient = CGAL::COLLINEAR; + + // Read the end points of the arc and create it. + // Notice we read the coordinates as strings, then we convert them to + // the Algebraic type, as we do not want to initialize Algebraic from a double. + char num[50]; + Algebraic x1, y1, x2, y2; + + str_line >> num; + x1 = Algebraic(num); + str_line >> num; + y1 = Algebraic(num); + + str_line >> num; + x2 = Algebraic(num); + str_line >> num; + y2 = Algebraic(num); + + Point_2 ps (x1, y1); + Point_2 pt (x2, y2); + + cv = Curve_2 (r, s, t, u, v, w, orient, ps ,pt); + } + else if (type == 'q' || type == 'Q') + { + // Construct a circular arc. The line should have the format: + // t + // where (x1, y1), (x2, y2), (x3, y3), (x4, y4) and (x5, y5) define the + // arc. + Rational x1, y1, x2, y2, x3, y3, x4, y4, x5, y5; + + str_line >> x1 >> y1 >> x2 >> y2 >> x3 >> y3 >> x4 >> y4 >> x5 >> y5; + + Rat_point_2 p1(x1, y1), p2(x2, y2), p3(x3, y3), p4(x4, y4), p5(x5, y5); + + cv = Curve_2 (p1, p2, p3, p4, p5); + } + else if(type == 'e' || type == 'E') + { + // Construct a full ellipse. The line should have the format: + // e // raddi and center of ellipse + + int x0, y0, r1, r2; + Rational sqr_r1, sqr_r2; + Rational R, S, T, U, V, W; + + str_line >> r1 >> r2 >> x0 >> y0; + + sqr_r1 = Rational (r1*r1); + sqr_r2 = Rational (r2*r2); + R = sqr_r2; + S = sqr_r1; + T = 0; + U = -2 * sqr_r2 * x0; + V = -2 * sqr_r1 * y0; + W = sqr_r2*x0*x0 + sqr_r1*y0*y0 - sqr_r1*sqr_r2; + + cv = Curve_2 (R, S, T, U, V, W); + } + else + { + std::cerr << "Illegal conic type specification: " << type << "." + << std::endl; + return false; + } + + return true; + } + + /*! */ + void skip_comments( std::ifstream& is, char* one_line ) + { + while (!is.eof()) { + is.getline(one_line, 128); + if (one_line[0] != '#') break; + } + } +}; + +#endif