Back to index

salome-gui  6.5.0
GLViewer_Viewer2d.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 //  Author : OPEN CASCADE
00024 // File:      GLViewer_Viewer2d.cxx
00025 // Created:   November, 2004
00026 //#include <GLViewerAfx.h>
00027 //
00028 #include "GLViewer_Viewer2d.h"
00029 #include "GLViewer_Object.h"
00030 #include "GLViewer_ViewFrame.h"
00031 #include "GLViewer_BaseObjects.h"
00032 #include "GLViewer_CoordSystem.h"
00033 #include "GLViewer_Context.h"
00034 #include "GLViewer_Drawer.h"
00035 #include "GLViewer_Selector2d.h"
00036 #include "GLViewer_ViewPort2d.h"
00037 
00038 #include "SUIT_Desktop.h"
00039 #include "SUIT_ViewWindow.h"
00040 #include "SUIT_ViewManager.h"
00041 
00042 #include <QMenu>
00043 #include <QRect>
00044 #include <QFile>
00045 #include <QPolygon>
00046 #include <QMouseEvent>
00047 #include <QColorDialog>
00048 
00053 GLViewer_Viewer2d::GLViewer_Viewer2d( const QString& title) :
00054 GLViewer_Viewer( title )
00055 {
00056   myGLContext = new GLViewer_Context( this );
00057 
00058   createSelector();
00059 
00060   mySelMode = GLViewer_Viewer::Multiple;
00061 
00062   myDrawers.clear();
00063 }
00064 
00068 GLViewer_Viewer2d::~GLViewer_Viewer2d()
00069 {    
00070     //myGLSketcher = 0;
00071     //delete myGLSketcher;
00072   GLViewer_TexFont::clearTextBases();
00073 }
00074 
00078 SUIT_ViewWindow* GLViewer_Viewer2d::createView( SUIT_Desktop* theDesktop )
00079 {
00080     return new GLViewer_ViewFrame( theDesktop, this );
00081 }
00082 
00087 void GLViewer_Viewer2d::addPopupItems( QMenu* thePopup )
00088 {
00089   // CTH8434. "Change background color" menu item is available if there are no selected objects
00090   if ( getSelector() == 0 || getSelector()->numSelected() == 0 )
00091   {
00092     if( thePopup->actions().count() > 0 )
00093         thePopup->addSeparator();
00094     thePopup->addAction( tr( "CHANGE_BGCOLOR" ), this, SLOT( onChangeBgColor() ) );
00095   }
00096 }
00097 
00101 void GLViewer_Viewer2d::onChangeBgColor()
00102 {
00103   if( !getActiveView() )
00104     return;
00105   GLViewer_ViewPort2d* vp = ( ( GLViewer_ViewPort2d* )getActiveView()->getViewPort() );
00106 
00107   QColor selColor = QColorDialog::getColor( vp->backgroundColor(), vp );        
00108   if ( selColor.isValid() ) {
00109     vp->setBackgroundColor( selColor );
00110   }
00111 }
00112 
00116 void GLViewer_Viewer2d::updateColors( QColor colorH, QColor colorS )
00117 {
00118 //  cout << "GLViewer_Viewer2d::updateColors" << endl;
00119 
00120 /*
00121     for ( DrawerMap::Iterator it = myDrawers.begin(); it != myDrawers.end(); ++it )
00122     {
00123         it.key()->setHColor( colorH );
00124         it.key()->setSColor( colorS );
00125     }
00126 */
00127     /*
00128     ObjList anObjects = myGLContext->getObjects();
00129     ObjList::Iterator beginIt = anObjects.begin();
00130     ObjList::Iterator endIt = anObjects.end();
00131     for ( ObjList::Iterator it = beginIt; it != endIt; ++it )
00132     {
00133         //GLViewer_Drawer* aDrawer = (*it)->getDrawer();
00134         //aDrawer->setHColor( colorH );
00135         //aDrawer->setSColor( colorS );
00136     }
00137     */
00138 
00139 
00140   activateAllDrawers( TRUE );
00141 }
00142 
00147 void GLViewer_Viewer2d::updateBorders( GLViewer_Rect* theRect )
00148 {
00149   QVector<SUIT_ViewWindow*> views = getViewManager()->getViews();
00150   for ( int i = 0, n = views.count(); i < n; i++ )
00151   {
00152     GLViewer_Rect* border = ( ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)views[i])->getViewPort() )->getBorder();
00153 
00154     border->setLeft( qMin( border->left(), theRect->left() ) );
00155     border->setRight( qMax( border->right(), theRect->right() ) );
00156     border->setBottom( qMin( border->bottom(), theRect->bottom() ) );
00157     border->setTop( qMax( border->top(), theRect->top() ) );
00158   }
00159 }
00160 
00164 void GLViewer_Viewer2d::updateBorders()
00165 {
00166     QVector<SUIT_ViewWindow*> views = getViewManager()->getViews();
00167 
00168     ObjList anObjects = myGLContext->getObjects();
00169     ObjList::Iterator beginIt = anObjects.begin();
00170     ObjList::Iterator endIt = anObjects.end();
00171     for ( int i = 0, n = views.count(); i < n; i++ )
00172     {
00173         GLViewer_Rect* border = ( ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)views[i])->getViewPort() )->getBorder();
00174         if ( !border )
00175           continue;
00176         border->setIsEmpty( true );
00177         // initialise border by default values to avoid old values
00178         border->setCoords( 0, 0, 0, 0 );
00179         for ( ObjList::Iterator it = beginIt; it != endIt; ++it )
00180         {
00181             GLViewer_Object* anObject = *it;
00182             GLViewer_Rect* aRect = anObject->getRect();
00183             if( !anObject->isSelectable() || !anObject->getVisible() )
00184                 continue;
00185 
00186             if( border->isEmpty() )
00187             {
00188                 border->setIsEmpty( false );
00189                 border->setCoords( aRect->left(), aRect->right(), aRect->bottom(), aRect->top() );
00190             }
00191             else
00192             {
00193                 border->setLeft( qMin( border->left(), aRect->left() ) );
00194                 border->setRight( qMax( border->right(), aRect->right() ) );
00195                 border->setBottom( qMin( border->bottom(), aRect->bottom() ) );
00196                 border->setTop( qMax( border->top(), aRect->top() ) );
00197             }
00198         }
00199     }
00200 }
00201 
00205 void GLViewer_Viewer2d::updateAll()
00206 {
00207   if ( !getActiveView() )
00208     return;
00209 
00210   QVector<SUIT_ViewWindow*> views = getViewManager()->getViews();
00211   for ( int i = 0, n = views.count(); i < n; i++ )
00212     ( ( GLViewer_ViewPort2d* )( ( GLViewer_ViewFrame* )views[i] )->getViewPort() )->getGLWidget()->updateGL();
00213 }
00214 
00218 void GLViewer_Viewer2d::updateDrawers( GLboolean update, GLfloat scX, GLfloat scY )
00219 {
00220 //  cout << "GLViewer_Viewer2d::updateDrawers" << endl;
00221 
00222     //myGLContext->updateScales( scX, scY );
00223     //myGLSketcher->drawContour();
00224     activateAllDrawers( update );
00225 }
00226 
00230 void GLViewer_Viewer2d::activateDrawers( QList<GLViewer_Object*>& theObjects, bool onlyUpdate, GLboolean swap )
00231 {
00232     //cout << "GLViewer_Viewer2d::activateDrawers " << (int)onlyUpdate << " " << (int)swap << endl;
00233     QList<GLViewer_Drawer*>::Iterator anIt = myDrawers.begin();
00234     QList<GLViewer_Drawer*>::Iterator endDIt = myDrawers.end();
00235     for( ; anIt != endDIt; anIt++ )
00236         (*anIt)->clear();
00237 
00238     QList<GLViewer_Drawer*> anActiveDrawers;
00239     QList<GLViewer_Object*>::Iterator endOIt = theObjects.end();
00240 
00241     for( QList<GLViewer_Object*>::Iterator oit = theObjects.begin(); oit != endOIt; ++oit )
00242     {
00243         GLViewer_Drawer* aDrawer = (*oit)->getDrawer();
00244         if( !aDrawer )
00245         {
00246             anIt = myDrawers.begin();
00247             endDIt = myDrawers.end();
00248 
00249             for( ; anIt != endDIt; anIt++ )
00250                 if( (*anIt)->getObjectType() == (*oit)->getObjectType() )
00251                 {
00252                     (*oit)->setDrawer( *anIt );
00253                     aDrawer = *anIt;
00254                     break;
00255                 }
00256 
00257             if( !aDrawer )
00258             {
00259                 myDrawers.append( (*oit)->createDrawer() );
00260                 aDrawer = (*oit)->getDrawer();
00261             }
00262         }
00263         if ( !aDrawer )
00264           continue;
00265         aDrawer->addObject( (*oit) );
00266 
00267         int aPriority = aDrawer->getPriority();
00268 
00269         if( anActiveDrawers.indexOf( aDrawer ) != -1 )
00270             continue;
00271 
00272         QList<GLViewer_Drawer*>::Iterator aDIt = anActiveDrawers.begin();
00273         QList<GLViewer_Drawer*>::Iterator aDEndIt = anActiveDrawers.end();
00274         for( ; aDIt != aDEndIt; ++aDIt )
00275             if( (*aDIt)->getPriority() > aPriority )
00276                 break;
00277 
00278         anActiveDrawers.insert( aDIt, aDrawer );
00279     } 
00280 
00281     QList<GLViewer_Drawer*>::Iterator aDIt = anActiveDrawers.begin();
00282     QList<GLViewer_Drawer*>::Iterator aDEndIt = anActiveDrawers.end();
00283 
00284     QVector<SUIT_ViewWindow*> views = getViewManager()->getViews();
00285     for ( int i = 0, n = views.count(); i < n; i++ )
00286     {
00287         float xScale, yScale;
00288         GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)views[i])->getViewPort();
00289         vp->getScale( xScale, yScale );
00290         vp->getGLWidget()->makeCurrent();
00291 
00292         for( ; aDIt != aDEndIt; aDIt++ )
00293         {
00294             GLViewer_Drawer* aDrawer = *aDIt;
00295             if( aDrawer )
00296                 aDrawer->create( xScale, yScale, onlyUpdate );
00297         }
00298 /*
00299         // draw border
00300         GLViewer_Rect* border = ( ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)views[i])->getViewPort() )->getBorder();
00301         (*aDIt)->drawRectangle( border, Qt::blue );
00302 
00303         QString coords = QString::number( border->left() ) + " " + QString::number( border->right() ) + " " +
00304                          QString::number( border->bottom() ) + " " + QString::number( border->top() );
00305         (*aDIt)->drawText( "Border : " + coords, border->left(), border->top() + 10 / yScale,
00306                            Qt::blue, &QFont( "Courier", 8, QFont::Normal ), 2 );
00307 */
00308         if ( swap )
00309            vp->getGLWidget()->swapBuffers();
00310     }
00311 
00312     ( ( GLViewer_ViewPort2d* )getActiveView()->getViewPort() )->getGLWidget()->makeCurrent();
00313 }
00314 
00318 void GLViewer_Viewer2d::activateDrawer( GLViewer_Object* theObject, bool onlyUpdate, GLboolean swap )
00319 {
00320   ObjList aList;
00321   aList.append( theObject );
00322   activateDrawers( aList, onlyUpdate, swap );
00323 }
00324 
00328 void GLViewer_Viewer2d::activateAllDrawers( bool onlyUpdate, GLboolean swap )
00329 {
00330     if ( !getActiveView() )
00331       return;
00332 
00333     ObjList anActiveObjs;
00334     const ObjList& objs = myGLContext->getObjects();
00335     for( ObjList::const_iterator it = objs.begin(); it != objs.end(); ++it )
00336     {
00337       GLViewer_Object* obj = (GLViewer_Object*)(*it);
00338       if( obj->getVisible() )
00339           anActiveObjs.append( obj );
00340     }
00341 
00342     activateDrawers( anActiveObjs, onlyUpdate, swap );
00343 }
00344 
00350 void GLViewer_Viewer2d::onCreateGLMarkers( int theMarkersNum, int theMarkersRad )
00351 {
00352     if ( !getActiveView() )
00353       return;
00354 
00355     GLViewer_MarkerSet* aMarkerSet = new GLViewer_MarkerSet( theMarkersNum, theMarkersRad );
00356     getGLContext()->insertObject( aMarkerSet );
00357 
00358     GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
00359     int vpWidth = vp->getWidth();
00360     int vpHeight = vp->getHeight();
00361 
00362     float* aXCoord = new float[ theMarkersNum ];
00363     float* anYCoord = new float[ theMarkersNum ];
00364 
00365     srand( 1 );
00366     for ( long i = 0; i < theMarkersNum; i++ )  
00367     {
00368         aXCoord[i] = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpWidth / 2.);
00369         anYCoord[i] = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpHeight / 2.);
00370     }
00371 
00372     aMarkerSet->setXCoord( aXCoord, theMarkersNum );
00373     aMarkerSet->setYCoord( anYCoord, theMarkersNum );
00374     aMarkerSet->compute();
00375 
00376     updateBorders( aMarkerSet->getRect() );
00377     
00378     activateAllDrawers( false );
00379     activateTransform( GLViewer_Viewer::FitAll );
00380 
00381     delete[] aXCoord;
00382     delete[] anYCoord;
00383 }
00384 
00391 void GLViewer_Viewer2d::onCreateGLPolyline( int theAnglesNum, int theRadius, int thePolylineNumber )
00392 {
00393     if ( !getActiveView() )
00394       return;
00395 
00396     GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
00397     int vpWidth = vp->getWidth();
00398     int vpHeight = vp->getHeight();
00399 
00400     float* aXCoord = new float[ theAnglesNum ];
00401     float* anYCoord = new float[ theAnglesNum ];
00402 
00403     //srand( ( unsigned )time( NULL ) );
00404     srand( 1 );
00405     for( int j = 0; j < thePolylineNumber; j++)
00406     {
00407         GLViewer_Polyline* aPolyline = new GLViewer_Polyline( theAnglesNum, theRadius );
00408         getGLContext()->insertObject( aPolyline );
00409 
00410         float aXOffset = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpWidth / 2.);
00411         float anYOffset = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpHeight / 2.);
00412         for( int i = 0; i < theAnglesNum; i++ )  
00413         {
00414             aXCoord[i] = cos( 2. * PI * i / theAnglesNum ) * theRadius + aXOffset;
00415             anYCoord[i] = sin( 2. * PI * i / theAnglesNum ) * theRadius + anYOffset;
00416         }
00417 
00418         aPolyline->setHighSelAll( true );
00419         aPolyline->setClosed( true );
00420         aPolyline->setXCoord( aXCoord, theAnglesNum );
00421         aPolyline->setYCoord( anYCoord, theAnglesNum );
00422         aPolyline->compute();
00423 
00424         updateBorders( aPolyline->getRect() );
00425     }
00426     
00427     activateAllDrawers( false );
00428     activateTransform( GLViewer_Viewer::FitAll );
00429 
00430     delete[] aXCoord;
00431     delete[] anYCoord;
00432 }
00433 
00439 void GLViewer_Viewer2d::onCreateGLText( QString theStr, int theTextNumber )
00440 {
00441     if ( !getActiveView() )
00442       return;
00443 
00444     if( theTextNumber <= 0 )
00445         return;
00446     
00447     GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
00448     int vpWidth = vp->getWidth();
00449     int vpHeight = vp->getHeight();
00450 
00451     //srand( ( unsigned )time( NULL ) );
00452     srand( 1 );
00453     for( int j = 0; j < theTextNumber; j++)
00454     {
00455         float aXPos = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpWidth / 2.);
00456         float anYPos = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpHeight / 2.);
00457         QColor aColor( 255, 0, 255 );
00458 
00459         GLViewer_TextObject* aText = new GLViewer_TextObject( theStr, aXPos, anYPos, aColor  );
00460         aText->compute();
00461         getGLContext()->insertObject( aText );
00462 
00463         updateBorders( aText->getRect() );
00464     }
00465 
00466     activateAllDrawers( false );
00467 }
00468 
00473 void GLViewer_Viewer2d::transPoint( GLfloat& x, GLfloat& y )
00474 {
00475     if ( !getActiveView() )
00476       return;
00477 
00478     GLfloat xScale, yScale;
00479     GLfloat xPan, yPan;
00480 
00481     GLViewer_ViewPort2d* curvp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
00482 
00483     curvp->getScale( xScale, yScale );
00484     curvp->getPan( xPan, yPan );
00485 
00486     GLfloat a = curvp->getGLWidget()->getRotationAngle() * PI / 180.;
00487     
00488     x = (  x - ( GLfloat )curvp->getWidth()  / 2 ) / xScale;
00489     y = ( -y + ( GLfloat )curvp->getHeight() / 2 ) / yScale;
00490 
00491     GLfloat x1 = x;
00492     GLfloat y1 = y;
00493 
00494     x = x1 * cos(a) + y1 * sin(a);
00495     y = -x1 * sin(a) + y1 * cos(a);
00496 
00497     x -= xPan;
00498     y -= yPan;
00499 }
00500 
00505 QRect* GLViewer_Viewer2d::getWinObjectRect( GLViewer_Object* theObject )
00506 {
00507     if ( !getActiveView() )
00508       return 0;
00509 
00510     GLfloat xScale, yScale;
00511     GLfloat xPan, yPan;
00512 
00513     GLViewer_ViewPort2d* curvp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
00514     GLfloat aWidth = curvp->getWidth();
00515     GLfloat aHeight = curvp->getHeight();
00516 
00517 
00518     curvp->getScale( xScale, yScale );
00519     curvp->getPan( xPan, yPan );
00520 
00521     QRect aObjRect = theObject->getRect()->toQRect();
00522     float aLeft = aObjRect.left() + xPan, aRight = aObjRect.right() + xPan;
00523     float aTop = aObjRect.top() + yPan, aBot = aObjRect.bottom() + yPan;
00524 
00525     GLfloat anAngle = curvp->getGLWidget()->getRotationAngle() * PI / 180.;
00526 
00527     QPolygon aPointArray(4);
00528     aPointArray[0] = QPoint( (int)(aLeft*cos(anAngle) - aTop*sin(anAngle)),
00529                              (int)(aLeft*sin(anAngle) + aTop*cos(anAngle)) );
00530     aPointArray[1] = QPoint( (int)(aRight*cos(anAngle) - aTop*sin(anAngle)),
00531                              (int)(aRight*sin(anAngle) + aTop*cos(anAngle)) );
00532     aPointArray[2] = QPoint( (int)(aRight*cos(anAngle) - aBot*sin(anAngle)),
00533                              (int)(aRight*sin(anAngle) + aBot*cos(anAngle)) );
00534     aPointArray[3] = QPoint( (int)(aLeft*cos(anAngle) - aBot*sin(anAngle)),
00535                              (int)(aLeft*sin(anAngle) + aBot*cos(anAngle)) );
00536 
00537     int aMinLeft = aPointArray[0].x(), aMaxRight = aPointArray[0].x(), 
00538         aMinTop = aPointArray[0].y(), aMaxBottom = aPointArray[0].y();
00539     for( int i = 1; i < 4; i++ )
00540     {
00541         int x = aPointArray[i].x();
00542         int y = aPointArray[i].y();
00543         aMinLeft = qMin( aMinLeft,x );
00544         aMaxRight = qMax( aMaxRight, x );
00545         aMinTop = qMin( aMinTop, y );
00546         aMaxBottom = qMax( aMaxBottom, y );
00547     }
00548 
00549     aLeft = (aMinLeft/* + xPan*/)*xScale + aWidth / 2;
00550     aRight = (aMaxRight/* + xPan*/)*xScale + aWidth / 2;
00551 
00552     aTop = -( (aMaxBottom/* + yPan*/)*yScale - aHeight / 2 );
00553     aBot = -( (aMinTop/* + yPan*/)*yScale - aHeight / 2 );    
00554 
00555     QRect* newRect = new QRect( (int)aLeft, (int)aTop, (int)(aRight-aLeft), (int)(aBot-aTop) );
00556     
00557     return newRect;
00558 }
00559 
00565 GLViewer_Rect GLViewer_Viewer2d::getGLVRect( const QRect& theRect ) const
00566 {
00567   if ( !getActiveView() )
00568       return GLViewer_Rect();
00569 
00570   GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
00571 
00572   if( !vp )
00573     return GLViewer_Rect();
00574 
00575   return vp->win2GLV( theRect );
00576 }
00577 
00583 QRect GLViewer_Viewer2d::getQRect( const GLViewer_Rect& theRect ) const
00584 {
00585   if ( !getActiveView() )
00586       return QRect();
00587 
00588   GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
00589 
00590   if( !vp )
00591     return QRect();
00592 
00593   return vp->GLV2win( theRect );
00594 }
00595 
00599 GLViewer_Selector* GLViewer_Viewer2d::createSelector()
00600 {
00601   return new GLViewer_Selector2d( this, getGLContext() );
00602 }
00603 
00608 GLViewer_ViewTransformer* GLViewer_Viewer2d::createTransformer( int type )
00609 {
00610     return new GLViewer_View2dTransformer( this, type );
00611 }
00612 
00616 void GLViewer_Viewer2d::onMouseEvent( SUIT_ViewWindow*, QMouseEvent* e )
00617 {
00618     if ( !getActiveView() )
00619         return;
00620 
00621     //if ( testRotation( e ) )
00622     //    return;
00623 
00624     switch( e->type() )
00625     {
00626         case QEvent::MouseButtonPress :
00627         case QEvent::MouseMove :
00628         case QEvent::MouseButtonRelease :
00629             //if( myGLSketcher->getType() != None )
00630             //    myGLSketcher->sketch( e );
00631         default: break;
00632     }
00633 
00634     GLViewer_Viewer::onMouseEvent( 0, e );
00635 }
00636 
00640 bool GLViewer_Viewer2d::testRotation( QMouseEvent* e )
00641 {
00642     if ( ( e->button() == GLViewer_View2dTransformer::rotateButton() ) &&
00643          ( e->type() == QEvent::MouseButtonPress ) &&
00644          ( e->modifiers() & GLViewer_ViewTransformer::accelKey() ) )
00645     {
00646         activateTransform( GLViewer_Viewer::Rotate );
00647         return true;
00648     }
00649     return false;
00650 }
00651 
00657 void GLViewer_Viewer2d::insertHeader( VectorFileType aType, QFile& hFile )
00658 {
00659     if( aType == POST_SCRIPT )
00660     {
00661         QString header = "%!PS-Adobe-3.0\n";
00662         header += "%%Creator: OpenCascade 2004\n";
00663         header += "%%Title: Our document\n";        
00664         header += "%%PageOrder: Ascend\n";      
00665         header += "%%Orientation: Portrait\n";
00666         header += "%%LanguageLevel: 2\n";
00667 
00668         header += "%%Pages: 1\n";
00669         header += "%%Page: 1\n\n";
00670         
00671         hFile.write( header.toAscii() );
00672     }
00673     else if( aType == HPGL )
00674     {
00675         QString header = "[Esc].(;\n";
00676         header += "[Esc].I81;;17:\n";
00677         header += "[Esc].N;19:\n";
00678         header += "IN;\n";
00679         header += "SC;\n";
00680         header += "PU;\n";
00681         header += "SP1;\n";
00682         header += "LT;\n";
00683         header += "VS36;\n";
00684         
00685         hFile.write( header.toAscii() );
00686     }
00687 }
00688 
00694 void GLViewer_Viewer2d::insertEnding( VectorFileType aType, QFile& hFile )
00695 {
00696     if( aType == POST_SCRIPT )
00697     {
00698         QString ending = "showpage\n\n%%EOF";
00699         hFile.write( ending.toAscii() );
00700     }
00701     else if( aType == HPGL )
00702     {
00703         QString ending = "PU;PA0,0;SP;EC;PG1;EC1;OE\n"; 
00704         hFile.write( ending.toAscii() );
00705     }
00706 }
00707 
00708 inline void mm2custom( GLViewer_Viewer2d::VectorFileType aType, double& value )
00709 {
00710     if( aType==GLViewer_Viewer2d::POST_SCRIPT )
00711         value*=2.8346; //mm to pt
00712 
00713     else if( aType==GLViewer_Viewer2d::HPGL )
00714         value*=40;     //mm to plu (there are 40 plues in mm)
00715 #ifdef WIN32
00716     else if( aType==GLViewer_Viewer2d::ENH_METAFILE )
00717         value*=100;    //this unit is 1/100 mm
00718 #endif 
00719 }
00720 
00728 bool GLViewer_Viewer2d::translateTo( VectorFileType aType, QString FileName, PaperType aPType, 
00729                                   double mmLeft, double mmRight, double mmTop, double mmBottom )
00730 {
00731     if ( !getActiveView() )
00732       return false;
00733 
00734         QFile hFile( FileName.toAscii() );
00735 
00736 #ifdef WIN32
00737     HDC hMetaFileDC;
00738 #endif
00739 
00740     GLViewer_ViewPort2d* aCurVP = (GLViewer_ViewPort2d*) getActiveView()->getViewPort();
00741 
00742     GLfloat xPan, yPan;
00743     aCurVP->getPan( xPan, yPan );
00744     GLfloat aRotation = aCurVP->getGLWidget()->getRotationAngle() * 3.14159265 / 180.0;
00745 
00746     GLViewer_CoordSystem aViewerCS( GLViewer_CoordSystem::Cartesian, xPan, yPan, 1.0, 1.0, aRotation );
00747 
00748     double AW = Sizes[2*int(aPType)], 
00749            AH = Sizes[2*int(aPType)+1]; //size of Axx paper in mm
00750 
00751     mm2custom( aType, mmLeft ); //we translate mm to custom units
00752     mm2custom( aType, mmRight );
00753     mm2custom( aType, mmTop );
00754     mm2custom( aType, mmBottom );
00755     mm2custom( aType, AW );
00756     mm2custom( aType, AH );
00757 
00758     float xScale, yScale;
00759     aCurVP->getScale( xScale, yScale );
00760 
00761     double VPWidth = aCurVP->getWidth()/xScale,   //the width in reference units
00762            VPHeight = aCurVP->getHeight()/yScale;
00763 
00764     double k1 = ( AW-mmLeft-mmRight ) / VPWidth,
00765            k2 = ( AH-mmTop-mmBottom ) / VPHeight;
00766 
00767     if( k1>k2 )
00768         k1 = k2; //We select the minimum
00769 
00770     double hdelta = ( AW-mmLeft-mmRight - VPWidth * k1 )/2.0, //addition in horizontal
00771            vdelta = ( AH-mmTop-mmBottom - VPHeight * k1 )/2.0; //addition in vertical
00772 
00773     mmLeft   += hdelta; //The real free space on the left and right borders
00774     mmRight  += hdelta;
00775     mmTop    += vdelta;
00776     mmBottom += vdelta;
00777 
00778     GLViewer_CoordSystem aPaperCS( GLViewer_CoordSystem::Cartesian, 
00779         -(mmLeft/k1+VPWidth/2.0), -(mmBottom/k1+VPHeight/2.0), 1/k1, 1/k1 );
00780 
00781     if( aType==POST_SCRIPT || aType==HPGL )
00782     {
00783         hFile.open( QIODevice::ReadWrite | QIODevice::Truncate );
00784         hFile.seek( 0 );
00785         insertHeader( aType, hFile );
00786     }
00787 #ifdef WIN32
00788     else if( aType==ENH_METAFILE )
00789     {
00790         RECT r; 
00791         r.left = 0; r.right = AW; 
00792         r.top = 0; r.bottom = AH; 
00793         HDC screen_dc = GetDC( 0 ); //The screen device context
00794         HDC bitDC = CreateCompatibleDC ( screen_dc ); //The context compatible with screen
00795 
00796         hMetaFileDC = CreateEnhMetaFile( bitDC, FileName.toAscii(), &r, "" );
00797         SetMapMode( hMetaFileDC, MM_HIMETRIC );
00798         SetWindowOrgEx( hMetaFileDC, 0, r.bottom, NULL );
00799         HRGN ClipRgn = CreateRectRgn( 0, 0, AW, AH );
00800         SelectClipRgn( hMetaFileDC, ClipRgn );
00801 
00802         LOGBRUSH aBrushData;
00803         aBrushData.lbColor = RGB( 255, 255, 255 );      
00804         aBrushData.lbStyle = BS_SOLID;
00805 
00806         FillRect( hMetaFileDC, &r, CreateBrushIndirect( &aBrushData ) );
00807 
00808         ReleaseDC( 0, screen_dc );
00809         DeleteDC( bitDC );
00810 
00811         aCurVP->getGLWidget()->translateBackgroundToEMF( hMetaFileDC, &aViewerCS, &aPaperCS );
00812     }
00813 #endif
00814 
00815     if( aType==POST_SCRIPT )
00816     {
00817         QString temp = "%1 %2 %3 %4 rectclip\n\n",
00818                 aBuffer = temp.arg( mmLeft ).arg( mmBottom ).
00819                                arg( AW-mmLeft-mmRight ).arg( AH-mmBottom-mmTop );
00820         //It is set clipping path
00821 
00822         hFile.write( aBuffer.toAscii() );
00823 
00824         aCurVP->getGLWidget()->translateBackgroundToPS( hFile, &aViewerCS, &aPaperCS );
00825     }
00826 
00827     bool result = true;
00828     for( int i=0, n=myDrawers.count(); i<n; i++ )
00829         if( aType==POST_SCRIPT )
00830             result &= myDrawers[ i ]->translateToPS( hFile, &aViewerCS, &aPaperCS );
00831         else if( aType==HPGL )
00832             result &= myDrawers[ i ]->translateToHPGL( hFile, &aViewerCS, &aPaperCS );
00833 #ifdef WIN32
00834         else if( aType==ENH_METAFILE )
00835             result &= myDrawers[ i ]->translateToEMF( hMetaFileDC, &aViewerCS, &aPaperCS );
00836 #endif
00837 
00838     if( aType==POST_SCRIPT || aType==HPGL )
00839     {
00840         insertEnding( aType, hFile);
00841         hFile.close();
00842     }
00843 #ifdef WIN32
00844     else if( aType==ENH_METAFILE )  
00845         DeleteEnhMetaFile( CloseEnhMetaFile( hMetaFileDC ) );
00846 #endif
00847 
00848     return true;
00849 }
00850 
00855 void GLViewer_Viewer2d::repaintView( GLViewer_ViewFrame* theView, bool makeCurrent )
00856 {
00857     GLViewer_ViewFrame* aCurView;
00858     if( !theView )
00859         aCurView = (GLViewer_ViewFrame*)getActiveView();
00860     else
00861         aCurView = theView;
00862     
00863     if ( !aCurView )
00864       return;
00865 
00866     ObjList anActiveObjs;
00867     const ObjList& objs = myGLContext->getObjects();
00868     for( ObjList::const_iterator it = objs.begin(); it != objs.end(); ++it )
00869     {
00870       GLViewer_Object* obj = (GLViewer_Object*)(*it);
00871       if( obj->getVisible() )
00872           anActiveObjs.append( obj );
00873     }
00874 
00875     float xScale;
00876     float yScale;
00877 
00878     QList<GLViewer_Drawer*>::Iterator anIt = myDrawers.begin();
00879     QList<GLViewer_Drawer*>::Iterator endDIt = myDrawers.end();
00880     for( ; anIt != endDIt; anIt++ )
00881             (*anIt)->clear();
00882 
00883     QList<GLViewer_Drawer*> anActiveDrawers;
00884     QList<GLViewer_Object*>::Iterator endOIt = anActiveObjs.end();
00885 
00886     for( QList<GLViewer_Object*>::Iterator oit = anActiveObjs.begin(); oit != endOIt; ++oit )
00887     {
00888         GLViewer_Drawer* aDrawer = (*oit)->getDrawer();
00889         if( !aDrawer )
00890         {
00891             anIt = myDrawers.begin();            
00892 
00893             for( ; anIt != endDIt; anIt++ )
00894                 if( (*anIt)->getObjectType() == (*oit)->getObjectType() )
00895                 {
00896                     (*oit)->setDrawer( *anIt );
00897                     aDrawer = *anIt;
00898                     break;
00899                 }
00900 
00901             if( !aDrawer ) //are not exists
00902             {
00903                 myDrawers.append( (*oit)->createDrawer() );
00904                 aDrawer = (*oit)->getDrawer();
00905             }
00906         }
00907         aDrawer->addObject( (*oit) );
00908         if( anActiveDrawers.indexOf( aDrawer ) == -1 )
00909             anActiveDrawers.append( aDrawer );
00910     } 
00911 
00912     QList<GLViewer_Drawer*>::Iterator aDIt = anActiveDrawers.begin();
00913     QList<GLViewer_Drawer*>::Iterator aDEndIt = anActiveDrawers.end();
00914 
00915     GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )aCurView->getViewPort();
00916     vp->getScale( xScale, yScale );
00917 
00918     if( makeCurrent )
00919         vp->getGLWidget()->makeCurrent();
00920 
00921     for( ; aDIt != aDEndIt; aDIt++ )
00922         (*aDIt)->create( xScale, yScale, false );
00923     
00924 //    if ( swap )
00925     vp->getGLWidget()->swapBuffers();
00926 
00927 //    ( ( GLViewer_ViewPort2d* )getActiveView()->getViewPort() )->getGLWidget()->makeCurrent();
00928 }
00929 
00933 void GLViewer_Viewer2d::startOperations( QMouseEvent* e )
00934 {
00935     GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)getActiveView())->getViewPort();
00936 
00937     float x = e->pos().x();
00938     float y = e->pos().y();
00939     transPoint( x, y );
00940     GLViewer_Pnt point( x, y );
00941 
00942     if( e->button() == Qt::LeftButton && !myGLContext->getCurrentObject() && vp->startPulling( point ) )
00943         return;
00944 
00945     if( e->button() == Qt::LeftButton && !(vp->currentBlock() & BS_Selection) && !myGLContext->getCurrentObject() )
00946         vp->startSelectByRect( e->x(), e->y() );
00947 }
00948 
00952 bool GLViewer_Viewer2d::updateOperations( QMouseEvent* e )
00953 {
00954     GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)getActiveView())->getViewPort();
00955 
00956     if( vp->isPulling() )
00957     {
00958         float x = e->pos().x();
00959         float y = e->pos().y();
00960         transPoint( x, y );
00961 
00962         vp->drawPulling( GLViewer_Pnt( x, y ) );
00963         updateAll();
00964         return true;
00965     }
00966 
00967     if( !myGLContext->getCurrentObject() )
00968     {
00969         vp->drawSelectByRect( e->x(), e->y() );
00970         return true;
00971     }
00972     return false;
00973 }
00974 
00978 void GLViewer_Viewer2d::finishOperations( QMouseEvent* e )
00979 {
00980     GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)getActiveView())->getViewPort();
00981 
00982     if( vp->isPulling() )
00983     {
00984         vp->finishPulling();
00985         updateAll();
00986         return;
00987     }
00988 
00989     if( !myGLContext->getCurrentObject() )
00990     {
00991         QRect aSelRect = vp->selectionRect();
00992         vp->finishSelectByRect();
00993         if ( getSelector() && !aSelRect.isNull() )
00994         {            
00995             bool append = bool ( e->modifiers() & GLViewer_Selector::appendKey() );
00996             getSelector()->select( aSelRect, append );
00997         }
00998     }
00999 }
01000 
01004 void GLViewer_Viewer2d::startOperations( QWheelEvent* e )
01005 {
01006     bool zoomIn = e->delta() > 0;
01007     bool update = false;
01008     for( myGLContext->InitSelected(); myGLContext->MoreSelected(); myGLContext->NextSelected() )
01009     {
01010         GLViewer_Object* anObject = myGLContext->SelectedObject();
01011         update = anObject->updateZoom( zoomIn ) || update;
01012     }
01013 
01014     emit wheelZoomChange( zoomIn );
01015 
01016     if( update )
01017         updateAll();
01018 }
01019 
01020 
01021 int GLViewer_View2dTransformer::rotateBtn = Qt::RightButton;
01022 
01026 GLViewer_View2dTransformer::GLViewer_View2dTransformer( GLViewer_Viewer* viewer, int typ )
01027 : GLViewer_ViewTransformer( viewer, typ )
01028 {
01029     if ( type() == GLViewer_Viewer::Rotate )
01030         initTransform( true );
01031 }
01032 
01036 GLViewer_View2dTransformer::~GLViewer_View2dTransformer()
01037 {
01038     if ( type() == GLViewer_Viewer::Rotate )
01039         initTransform( false );
01040 }
01041 
01045 void GLViewer_View2dTransformer::exec()
01046 {
01047     if ( !myViewer->getActiveView() )
01048       return;
01049 
01050     /* additional transforms */
01051     GLViewer_ViewPort* vp = myViewer->getActiveView()->getViewPort();
01052     GLViewer_ViewPort2d* avp = (GLViewer_ViewPort2d*)vp;
01053     switch ( myType )
01054     {
01055         case GLViewer_Viewer::Rotate:
01056             myMajorBtn = rotateButton();
01057             avp->setCursor( *avp->getRotCursor() );
01058             break;
01059         default:
01060             GLViewer_ViewTransformer::exec();
01061     }
01062 }
01063 
01067 void GLViewer_View2dTransformer::onTransform( TransformState state )
01068 {
01069     if ( !myViewer->getActiveView() )
01070       return;
01071 
01072     GLViewer_ViewPort* vp = myViewer->getActiveView()->getViewPort();
01073     GLViewer_ViewPort2d* avp = (GLViewer_ViewPort2d*)vp;
01074     if ( type() == GLViewer_Viewer::Rotate )
01075     {
01076         switch ( state )
01077         {
01078             case Debut:
01079                 if ( myButtonState & myMajorBtn )
01080                     avp->startRotation( myStart.x(), myStart.y() );
01081                 break;
01082             case EnTrain:
01083                 if ( myButtonState & myMajorBtn )
01084                     avp->rotate( myCurr.x(), myCurr.y() );
01085                 break;
01086             case Fin:
01087                 avp->endRotation();
01088                 break;
01089             default: break;
01090         }
01091     }
01092     GLViewer_ViewTransformer::onTransform( state );
01093 }