1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // Author : OPEN CASCADE
24 // File: GLViewer_Viewer2d.cxx
25 // Created: November, 2004
26 //#include <GLViewerAfx.h>
28 #include "GLViewer_Viewer2d.h"
29 #include "GLViewer_Object.h"
30 #include "GLViewer_ViewFrame.h"
31 #include "GLViewer_BaseObjects.h"
32 #include "GLViewer_CoordSystem.h"
33 #include "GLViewer_Context.h"
34 #include "GLViewer_Drawer.h"
35 #include "GLViewer_Selector2d.h"
36 #include "GLViewer_ViewPort2d.h"
38 #include "SUIT_Desktop.h"
39 #include "SUIT_ViewWindow.h"
40 #include "SUIT_ViewManager.h"
46 #include <QMouseEvent>
47 #include <QColorDialog>
51 \param title - viewer title
53 GLViewer_Viewer2d::GLViewer_Viewer2d( const QString& title) :
54 GLViewer_Viewer( title )
56 myGLContext = new GLViewer_Context( this );
60 mySelMode = GLViewer_Viewer::Multiple;
68 GLViewer_Viewer2d::~GLViewer_Viewer2d()
71 //delete myGLSketcher;
72 GLViewer_TexFont::clearTextBases();
75 /*!Create new instance of view window on desktop \a theDesktop.
76 *\retval SUIT_ViewWindow* - created view window pointer.
78 SUIT_ViewWindow* GLViewer_Viewer2d::createView( SUIT_Desktop* theDesktop )
80 return new GLViewer_ViewFrame( theDesktop, this );
84 Adds item for change background color
85 \param thePopup - menu
87 void GLViewer_Viewer2d::addPopupItems( QMenu* thePopup )
89 // CTH8434. "Change background color" menu item is available if there are no selected objects
90 if ( getSelector() == 0 || getSelector()->numSelected() == 0 )
92 if( thePopup->actions().count() > 0 )
93 thePopup->addSeparator();
94 thePopup->addAction( tr( "CHANGE_BGCOLOR" ), this, SLOT( onChangeBgColor() ) );
99 Changes background color
101 void GLViewer_Viewer2d::onChangeBgColor()
103 if( !getActiveView() )
105 GLViewer_ViewPort2d* vp = ( ( GLViewer_ViewPort2d* )getActiveView()->getViewPort() );
107 QColor selColor = QColorDialog::getColor( vp->backgroundColor(), vp );
108 if ( selColor.isValid() ) {
109 vp->setBackgroundColor( selColor );
114 Updates colors for all drawers (does not work)
116 void GLViewer_Viewer2d::updateColors( QColor colorH, QColor colorS )
118 // cout << "GLViewer_Viewer2d::updateColors" << endl;
121 for ( DrawerMap::Iterator it = myDrawers.begin(); it != myDrawers.end(); ++it )
123 it.key()->setHColor( colorH );
124 it.key()->setSColor( colorS );
128 ObjList anObjects = myGLContext->getObjects();
129 ObjList::Iterator beginIt = anObjects.begin();
130 ObjList::Iterator endIt = anObjects.end();
131 for ( ObjList::Iterator it = beginIt; it != endIt; ++it )
133 //GLViewer_Drawer* aDrawer = (*it)->getDrawer();
134 //aDrawer->setHColor( colorH );
135 //aDrawer->setSColor( colorS );
140 activateAllDrawers( TRUE );
144 Updates rect of global scene by adding new rectangle
145 \param theRect - rectangle
147 void GLViewer_Viewer2d::updateBorders( GLViewer_Rect* theRect )
149 QVector<SUIT_ViewWindow*> views = getViewManager()->getViews();
150 for ( int i = 0, n = views.count(); i < n; i++ )
152 GLViewer_Rect* border = ( ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)views[i])->getViewPort() )->getBorder();
154 border->setLeft( qMin( border->left(), theRect->left() ) );
155 border->setRight( qMax( border->right(), theRect->right() ) );
156 border->setBottom( qMin( border->bottom(), theRect->bottom() ) );
157 border->setTop( qMax( border->top(), theRect->top() ) );
162 Recomputes global scene rect
164 void GLViewer_Viewer2d::updateBorders()
166 QVector<SUIT_ViewWindow*> views = getViewManager()->getViews();
168 ObjList anObjects = myGLContext->getObjects();
169 ObjList::Iterator beginIt = anObjects.begin();
170 ObjList::Iterator endIt = anObjects.end();
171 for ( int i = 0, n = views.count(); i < n; i++ )
173 GLViewer_Rect* border = ( ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)views[i])->getViewPort() )->getBorder();
176 border->setIsEmpty( true );
177 // initialise border by default values to avoid old values
178 border->setCoords( 0, 0, 0, 0 );
179 for ( ObjList::Iterator it = beginIt; it != endIt; ++it )
181 GLViewer_Object* anObject = *it;
182 GLViewer_Rect* aRect = anObject->getRect();
183 if( !anObject->isSelectable() || !anObject->getVisible() )
186 if( border->isEmpty() )
188 border->setIsEmpty( false );
189 border->setCoords( aRect->left(), aRect->right(), aRect->bottom(), aRect->top() );
193 border->setLeft( qMin( border->left(), aRect->left() ) );
194 border->setRight( qMax( border->right(), aRect->right() ) );
195 border->setBottom( qMin( border->bottom(), aRect->bottom() ) );
196 border->setTop( qMax( border->top(), aRect->top() ) );
203 Redraws all active objects by updating all drawers in all views
205 void GLViewer_Viewer2d::updateAll()
207 if ( !getActiveView() )
210 QVector<SUIT_ViewWindow*> views = getViewManager()->getViews();
211 for ( int i = 0, n = views.count(); i < n; i++ )
212 ( ( GLViewer_ViewPort2d* )( ( GLViewer_ViewFrame* )views[i] )->getViewPort() )->getGLWidget()->updateGL();
216 \param onlyUpdate is passed to method activateAllDrawers drawers
218 void GLViewer_Viewer2d::updateDrawers( GLboolean update, GLfloat scX, GLfloat scY )
220 // cout << "GLViewer_Viewer2d::updateDrawers" << endl;
222 //myGLContext->updateScales( scX, scY );
223 //myGLSketcher->drawContour();
224 activateAllDrawers( update );
228 Activates drawers for objects from list \param theObjects only
230 void GLViewer_Viewer2d::activateDrawers( QList<GLViewer_Object*>& theObjects, bool onlyUpdate, GLboolean swap )
232 //cout << "GLViewer_Viewer2d::activateDrawers " << (int)onlyUpdate << " " << (int)swap << endl;
233 QList<GLViewer_Drawer*>::Iterator anIt = myDrawers.begin();
234 QList<GLViewer_Drawer*>::Iterator endDIt = myDrawers.end();
235 for( ; anIt != endDIt; anIt++ )
238 QList<GLViewer_Drawer*> anActiveDrawers;
239 QList<GLViewer_Object*>::Iterator endOIt = theObjects.end();
241 for( QList<GLViewer_Object*>::Iterator oit = theObjects.begin(); oit != endOIt; ++oit )
243 GLViewer_Drawer* aDrawer = (*oit)->getDrawer();
246 anIt = myDrawers.begin();
247 endDIt = myDrawers.end();
249 for( ; anIt != endDIt; anIt++ )
250 if( (*anIt)->getObjectType() == (*oit)->getObjectType() )
252 (*oit)->setDrawer( *anIt );
259 myDrawers.append( (*oit)->createDrawer() );
260 aDrawer = (*oit)->getDrawer();
265 aDrawer->addObject( (*oit) );
267 int aPriority = aDrawer->getPriority();
269 if( anActiveDrawers.indexOf( aDrawer ) != -1 )
272 QList<GLViewer_Drawer*>::Iterator aDIt = anActiveDrawers.begin();
273 QList<GLViewer_Drawer*>::Iterator aDEndIt = anActiveDrawers.end();
274 for( ; aDIt != aDEndIt; ++aDIt )
275 if( (*aDIt)->getPriority() > aPriority )
278 anActiveDrawers.insert( aDIt, aDrawer );
281 QList<GLViewer_Drawer*>::Iterator aDIt = anActiveDrawers.begin();
282 QList<GLViewer_Drawer*>::Iterator aDEndIt = anActiveDrawers.end();
284 QVector<SUIT_ViewWindow*> views = getViewManager()->getViews();
285 for ( int i = 0, n = views.count(); i < n; i++ )
287 float xScale, yScale;
288 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)views[i])->getViewPort();
289 vp->getScale( xScale, yScale );
290 vp->getGLWidget()->makeCurrent();
292 for( ; aDIt != aDEndIt; aDIt++ )
294 GLViewer_Drawer* aDrawer = *aDIt;
296 aDrawer->create( xScale, yScale, onlyUpdate );
300 GLViewer_Rect* border = ( ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)views[i])->getViewPort() )->getBorder();
301 (*aDIt)->drawRectangle( border, Qt::blue );
303 QString coords = QString::number( border->left() ) + " " + QString::number( border->right() ) + " " +
304 QString::number( border->bottom() ) + " " + QString::number( border->top() );
305 (*aDIt)->drawText( "Border : " + coords, border->left(), border->top() + 10 / yScale,
306 Qt::blue, &QFont( "Courier", 8, QFont::Normal ), 2 );
309 vp->getGLWidget()->swapBuffers();
312 ( ( GLViewer_ViewPort2d* )getActiveView()->getViewPort() )->getGLWidget()->makeCurrent();
316 Activates drawer for \param theObject
318 void GLViewer_Viewer2d::activateDrawer( GLViewer_Object* theObject, bool onlyUpdate, GLboolean swap )
321 aList.append( theObject );
322 activateDrawers( aList, onlyUpdate, swap );
326 \param onlyUpdate is passed to drawers
328 void GLViewer_Viewer2d::activateAllDrawers( bool onlyUpdate, GLboolean swap )
330 if ( !getActiveView() )
333 ObjList anActiveObjs;
334 const ObjList& objs = myGLContext->getObjects();
335 for( ObjList::const_iterator it = objs.begin(); it != objs.end(); ++it )
337 GLViewer_Object* obj = (GLViewer_Object*)(*it);
338 if( obj->getVisible() )
339 anActiveObjs.append( obj );
342 activateDrawers( anActiveObjs, onlyUpdate, swap );
346 Creates set of marker
347 \param theMarkersNum - number of markers
348 \param theMarkersRad - radius of markers
350 void GLViewer_Viewer2d::onCreateGLMarkers( int theMarkersNum, int theMarkersRad )
352 if ( !getActiveView() )
355 GLViewer_MarkerSet* aMarkerSet = new GLViewer_MarkerSet( theMarkersNum, theMarkersRad );
356 getGLContext()->insertObject( aMarkerSet );
358 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
359 int vpWidth = vp->getWidth();
360 int vpHeight = vp->getHeight();
362 float* aXCoord = new float[ theMarkersNum ];
363 float* anYCoord = new float[ theMarkersNum ];
366 for ( long i = 0; i < theMarkersNum; i++ )
368 aXCoord[i] = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpWidth / 2.);
369 anYCoord[i] = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpHeight / 2.);
372 aMarkerSet->setXCoord( aXCoord, theMarkersNum );
373 aMarkerSet->setYCoord( anYCoord, theMarkersNum );
374 aMarkerSet->compute();
376 updateBorders( aMarkerSet->getRect() );
378 activateAllDrawers( false );
379 activateTransform( GLViewer_Viewer::FitAll );
387 \param theAnglesNum - number of angles
388 \param theRadius - radius
389 \param thePolylineNumber - number
391 void GLViewer_Viewer2d::onCreateGLPolyline( int theAnglesNum, int theRadius, int thePolylineNumber )
393 if ( !getActiveView() )
396 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
397 int vpWidth = vp->getWidth();
398 int vpHeight = vp->getHeight();
400 float* aXCoord = new float[ theAnglesNum ];
401 float* anYCoord = new float[ theAnglesNum ];
403 //srand( ( unsigned )time( NULL ) );
405 for( int j = 0; j < thePolylineNumber; j++)
407 GLViewer_Polyline* aPolyline = new GLViewer_Polyline( theAnglesNum, theRadius );
408 getGLContext()->insertObject( aPolyline );
410 float aXOffset = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpWidth / 2.);
411 float anYOffset = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpHeight / 2.);
412 for( int i = 0; i < theAnglesNum; i++ )
414 aXCoord[i] = cos( 2. * PI * i / theAnglesNum ) * theRadius + aXOffset;
415 anYCoord[i] = sin( 2. * PI * i / theAnglesNum ) * theRadius + anYOffset;
418 aPolyline->setHighSelAll( true );
419 aPolyline->setClosed( true );
420 aPolyline->setXCoord( aXCoord, theAnglesNum );
421 aPolyline->setYCoord( anYCoord, theAnglesNum );
422 aPolyline->compute();
424 updateBorders( aPolyline->getRect() );
427 activateAllDrawers( false );
428 activateTransform( GLViewer_Viewer::FitAll );
436 \param theStr - text string
437 \param theTextNumber - number
439 void GLViewer_Viewer2d::onCreateGLText( QString theStr, int theTextNumber )
441 if ( !getActiveView() )
444 if( theTextNumber <= 0 )
447 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
448 int vpWidth = vp->getWidth();
449 int vpHeight = vp->getHeight();
451 //srand( ( unsigned )time( NULL ) );
453 for( int j = 0; j < theTextNumber; j++)
455 float aXPos = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpWidth / 2.);
456 float anYPos = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpHeight / 2.);
457 QColor aColor( 255, 0, 255 );
459 GLViewer_TextObject* aText = new GLViewer_TextObject( theStr, aXPos, anYPos, aColor );
461 getGLContext()->insertObject( aText );
463 updateBorders( aText->getRect() );
466 activateAllDrawers( false );
470 Translates point from global CS to curreent viewer CS
471 \param x, y - co-ordinates to be translated
473 void GLViewer_Viewer2d::transPoint( GLfloat& x, GLfloat& y )
475 if ( !getActiveView() )
478 GLfloat xScale, yScale;
481 GLViewer_ViewPort2d* curvp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
483 curvp->getScale( xScale, yScale );
484 curvp->getPan( xPan, yPan );
486 GLfloat a = curvp->getGLWidget()->getRotationAngle() * PI / 180.;
488 x = ( x - ( GLfloat )curvp->getWidth() / 2 ) / xScale;
489 y = ( -y + ( GLfloat )curvp->getHeight() / 2 ) / yScale;
494 x = x1 * cos(a) + y1 * sin(a);
495 y = -x1 * sin(a) + y1 * cos(a);
502 \return object rect in window CS
503 \param theObject - object
505 QRect* GLViewer_Viewer2d::getWinObjectRect( GLViewer_Object* theObject )
507 if ( !getActiveView() )
510 GLfloat xScale, yScale;
513 GLViewer_ViewPort2d* curvp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
514 GLfloat aWidth = curvp->getWidth();
515 GLfloat aHeight = curvp->getHeight();
518 curvp->getScale( xScale, yScale );
519 curvp->getPan( xPan, yPan );
521 QRect aObjRect = theObject->getRect()->toQRect();
522 float aLeft = aObjRect.left() + xPan, aRight = aObjRect.right() + xPan;
523 float aTop = aObjRect.top() + yPan, aBot = aObjRect.bottom() + yPan;
525 GLfloat anAngle = curvp->getGLWidget()->getRotationAngle() * PI / 180.;
527 QPolygon aPointArray(4);
528 aPointArray[0] = QPoint( (int)(aLeft*cos(anAngle) - aTop*sin(anAngle)),
529 (int)(aLeft*sin(anAngle) + aTop*cos(anAngle)) );
530 aPointArray[1] = QPoint( (int)(aRight*cos(anAngle) - aTop*sin(anAngle)),
531 (int)(aRight*sin(anAngle) + aTop*cos(anAngle)) );
532 aPointArray[2] = QPoint( (int)(aRight*cos(anAngle) - aBot*sin(anAngle)),
533 (int)(aRight*sin(anAngle) + aBot*cos(anAngle)) );
534 aPointArray[3] = QPoint( (int)(aLeft*cos(anAngle) - aBot*sin(anAngle)),
535 (int)(aLeft*sin(anAngle) + aBot*cos(anAngle)) );
537 int aMinLeft = aPointArray[0].x(), aMaxRight = aPointArray[0].x(),
538 aMinTop = aPointArray[0].y(), aMaxBottom = aPointArray[0].y();
539 for( int i = 1; i < 4; i++ )
541 int x = aPointArray[i].x();
542 int y = aPointArray[i].y();
543 aMinLeft = qMin( aMinLeft,x );
544 aMaxRight = qMax( aMaxRight, x );
545 aMinTop = qMin( aMinTop, y );
546 aMaxBottom = qMax( aMaxBottom, y );
549 aLeft = (aMinLeft/* + xPan*/)*xScale + aWidth / 2;
550 aRight = (aMaxRight/* + xPan*/)*xScale + aWidth / 2;
552 aTop = -( (aMaxBottom/* + yPan*/)*yScale - aHeight / 2 );
553 aBot = -( (aMinTop/* + yPan*/)*yScale - aHeight / 2 );
555 QRect* newRect = new QRect( (int)aLeft, (int)aTop, (int)(aRight-aLeft), (int)(aBot-aTop) );
561 Translates rect in window CS to rect in global CS
562 \param theRect - rectangle to be translated
563 \return transformed rect
565 GLViewer_Rect GLViewer_Viewer2d::getGLVRect( const QRect& theRect ) const
567 if ( !getActiveView() )
568 return GLViewer_Rect();
570 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
573 return GLViewer_Rect();
575 return vp->win2GLV( theRect );
579 Translates rect in global CS to rect in window CS
580 \param theRect - rectangle to be translated
581 \return transformed rect
583 QRect GLViewer_Viewer2d::getQRect( const GLViewer_Rect& theRect ) const
585 if ( !getActiveView() )
588 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
593 return vp->GLV2win( theRect );
599 GLViewer_Selector* GLViewer_Viewer2d::createSelector()
601 return new GLViewer_Selector2d( this, getGLContext() );
605 \return new Transformer
606 \param type - type of new transformer
608 GLViewer_ViewTransformer* GLViewer_Viewer2d::createTransformer( int type )
610 return new GLViewer_View2dTransformer( this, type );
614 Custom mouse event handler
616 void GLViewer_Viewer2d::onMouseEvent( SUIT_ViewWindow*, QMouseEvent* e )
618 if ( !getActiveView() )
621 //if ( testRotation( e ) )
626 case QEvent::MouseButtonPress :
627 case QEvent::MouseMove :
628 case QEvent::MouseButtonRelease :
629 //if( myGLSketcher->getType() != None )
630 // myGLSketcher->sketch( e );
634 GLViewer_Viewer::onMouseEvent( 0, e );
638 Rotation transformation
640 bool GLViewer_Viewer2d::testRotation( QMouseEvent* e )
642 if ( ( e->button() == GLViewer_View2dTransformer::rotateButton() ) &&
643 ( e->type() == QEvent::MouseButtonPress ) &&
644 ( e->modifiers() & GLViewer_ViewTransformer::accelKey() ) )
646 activateTransform( GLViewer_Viewer::Rotate );
653 Inserts text lines as header for file
654 \param aType - file type
655 \param hFile - file instance
657 void GLViewer_Viewer2d::insertHeader( VectorFileType aType, QFile& hFile )
659 if( aType == POST_SCRIPT )
661 QString header = "%!PS-Adobe-3.0\n";
662 header += "%%Creator: OpenCascade 2004\n";
663 header += "%%Title: Our document\n";
664 header += "%%PageOrder: Ascend\n";
665 header += "%%Orientation: Portrait\n";
666 header += "%%LanguageLevel: 2\n";
668 header += "%%Pages: 1\n";
669 header += "%%Page: 1\n\n";
671 hFile.write( header.toAscii() );
673 else if( aType == HPGL )
675 QString header = "[Esc].(;\n";
676 header += "[Esc].I81;;17:\n";
677 header += "[Esc].N;19:\n";
685 hFile.write( header.toAscii() );
690 Inserts text lines as ending for file
691 \param aType - file type
692 \param hFile - file instance
694 void GLViewer_Viewer2d::insertEnding( VectorFileType aType, QFile& hFile )
696 if( aType == POST_SCRIPT )
698 QString ending = "showpage\n\n%%EOF";
699 hFile.write( ending.toAscii() );
701 else if( aType == HPGL )
703 QString ending = "PU;PA0,0;SP;EC;PG1;EC1;OE\n";
704 hFile.write( ending.toAscii() );
708 inline void mm2custom( GLViewer_Viewer2d::VectorFileType aType, double& value )
710 if( aType==GLViewer_Viewer2d::POST_SCRIPT )
711 value*=2.8346; //mm to pt
713 else if( aType==GLViewer_Viewer2d::HPGL )
714 value*=40; //mm to plu (there are 40 plues in mm)
716 else if( aType==GLViewer_Viewer2d::ENH_METAFILE )
717 value*=100; //this unit is 1/100 mm
722 Translates current view content to vector file
723 \param aType - type of file
724 \param FileName - name of file,
725 \param aPType - paper size type
726 \param mmLeft, mmRight, mmTop, mmBottom - margins
728 bool GLViewer_Viewer2d::translateTo( VectorFileType aType, QString FileName, PaperType aPType,
729 double mmLeft, double mmRight, double mmTop, double mmBottom )
731 if ( !getActiveView() )
734 QFile hFile( FileName.toAscii() );
740 GLViewer_ViewPort2d* aCurVP = (GLViewer_ViewPort2d*) getActiveView()->getViewPort();
743 aCurVP->getPan( xPan, yPan );
744 GLfloat aRotation = aCurVP->getGLWidget()->getRotationAngle() * 3.14159265 / 180.0;
746 GLViewer_CoordSystem aViewerCS( GLViewer_CoordSystem::Cartesian, xPan, yPan, 1.0, 1.0, aRotation );
748 double AW = Sizes[2*int(aPType)],
749 AH = Sizes[2*int(aPType)+1]; //size of Axx paper in mm
751 mm2custom( aType, mmLeft ); //we translate mm to custom units
752 mm2custom( aType, mmRight );
753 mm2custom( aType, mmTop );
754 mm2custom( aType, mmBottom );
755 mm2custom( aType, AW );
756 mm2custom( aType, AH );
758 float xScale, yScale;
759 aCurVP->getScale( xScale, yScale );
761 double VPWidth = aCurVP->getWidth()/xScale, //the width in reference units
762 VPHeight = aCurVP->getHeight()/yScale;
764 double k1 = ( AW-mmLeft-mmRight ) / VPWidth,
765 k2 = ( AH-mmTop-mmBottom ) / VPHeight;
768 k1 = k2; //We select the minimum
770 double hdelta = ( AW-mmLeft-mmRight - VPWidth * k1 )/2.0, //addition in horizontal
771 vdelta = ( AH-mmTop-mmBottom - VPHeight * k1 )/2.0; //addition in vertical
773 mmLeft += hdelta; //The real free space on the left and right borders
778 GLViewer_CoordSystem aPaperCS( GLViewer_CoordSystem::Cartesian,
779 -(mmLeft/k1+VPWidth/2.0), -(mmBottom/k1+VPHeight/2.0), 1/k1, 1/k1 );
781 if( aType==POST_SCRIPT || aType==HPGL )
783 hFile.open( QIODevice::ReadWrite | QIODevice::Truncate );
785 insertHeader( aType, hFile );
788 else if( aType==ENH_METAFILE )
791 r.left = 0; r.right = AW;
792 r.top = 0; r.bottom = AH;
793 HDC screen_dc = GetDC( 0 ); //The screen device context
794 HDC bitDC = CreateCompatibleDC ( screen_dc ); //The context compatible with screen
796 hMetaFileDC = CreateEnhMetaFile( bitDC, FileName.toAscii(), &r, "" );
797 SetMapMode( hMetaFileDC, MM_HIMETRIC );
798 SetWindowOrgEx( hMetaFileDC, 0, r.bottom, NULL );
799 HRGN ClipRgn = CreateRectRgn( 0, 0, AW, AH );
800 SelectClipRgn( hMetaFileDC, ClipRgn );
803 aBrushData.lbColor = RGB( 255, 255, 255 );
804 aBrushData.lbStyle = BS_SOLID;
806 FillRect( hMetaFileDC, &r, CreateBrushIndirect( &aBrushData ) );
808 ReleaseDC( 0, screen_dc );
811 aCurVP->getGLWidget()->translateBackgroundToEMF( hMetaFileDC, &aViewerCS, &aPaperCS );
815 if( aType==POST_SCRIPT )
817 QString temp = "%1 %2 %3 %4 rectclip\n\n",
818 aBuffer = temp.arg( mmLeft ).arg( mmBottom ).
819 arg( AW-mmLeft-mmRight ).arg( AH-mmBottom-mmTop );
820 //It is set clipping path
822 hFile.write( aBuffer.toAscii() );
824 aCurVP->getGLWidget()->translateBackgroundToPS( hFile, &aViewerCS, &aPaperCS );
828 for( int i=0, n=myDrawers.count(); i<n; i++ )
829 if( aType==POST_SCRIPT )
830 result &= myDrawers[ i ]->translateToPS( hFile, &aViewerCS, &aPaperCS );
831 else if( aType==HPGL )
832 result &= myDrawers[ i ]->translateToHPGL( hFile, &aViewerCS, &aPaperCS );
834 else if( aType==ENH_METAFILE )
835 result &= myDrawers[ i ]->translateToEMF( hMetaFileDC, &aViewerCS, &aPaperCS );
838 if( aType==POST_SCRIPT || aType==HPGL )
840 insertEnding( aType, hFile);
844 else if( aType==ENH_METAFILE )
845 DeleteEnhMetaFile( CloseEnhMetaFile( hMetaFileDC ) );
853 \param theView - view to be repainted. If it is NULL then all views will be repainted
855 void GLViewer_Viewer2d::repaintView( GLViewer_ViewFrame* theView, bool makeCurrent )
857 GLViewer_ViewFrame* aCurView;
859 aCurView = (GLViewer_ViewFrame*)getActiveView();
866 ObjList anActiveObjs;
867 const ObjList& objs = myGLContext->getObjects();
868 for( ObjList::const_iterator it = objs.begin(); it != objs.end(); ++it )
870 GLViewer_Object* obj = (GLViewer_Object*)(*it);
871 if( obj->getVisible() )
872 anActiveObjs.append( obj );
878 QList<GLViewer_Drawer*>::Iterator anIt = myDrawers.begin();
879 QList<GLViewer_Drawer*>::Iterator endDIt = myDrawers.end();
880 for( ; anIt != endDIt; anIt++ )
883 QList<GLViewer_Drawer*> anActiveDrawers;
884 QList<GLViewer_Object*>::Iterator endOIt = anActiveObjs.end();
886 for( QList<GLViewer_Object*>::Iterator oit = anActiveObjs.begin(); oit != endOIt; ++oit )
888 GLViewer_Drawer* aDrawer = (*oit)->getDrawer();
891 anIt = myDrawers.begin();
893 for( ; anIt != endDIt; anIt++ )
894 if( (*anIt)->getObjectType() == (*oit)->getObjectType() )
896 (*oit)->setDrawer( *anIt );
901 if( !aDrawer ) //are not exists
903 myDrawers.append( (*oit)->createDrawer() );
904 aDrawer = (*oit)->getDrawer();
907 aDrawer->addObject( (*oit) );
908 if( anActiveDrawers.indexOf( aDrawer ) == -1 )
909 anActiveDrawers.append( aDrawer );
912 QList<GLViewer_Drawer*>::Iterator aDIt = anActiveDrawers.begin();
913 QList<GLViewer_Drawer*>::Iterator aDEndIt = anActiveDrawers.end();
915 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )aCurView->getViewPort();
916 vp->getScale( xScale, yScale );
919 vp->getGLWidget()->makeCurrent();
921 for( ; aDIt != aDEndIt; aDIt++ )
922 (*aDIt)->create( xScale, yScale, false );
925 vp->getGLWidget()->swapBuffers();
927 // ( ( GLViewer_ViewPort2d* )getActiveView()->getViewPort() )->getGLWidget()->makeCurrent();
931 Starts some operation on mouse event
933 void GLViewer_Viewer2d::startOperations( QMouseEvent* e )
935 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)getActiveView())->getViewPort();
937 float x = e->pos().x();
938 float y = e->pos().y();
940 GLViewer_Pnt point( x, y );
942 if( e->button() == Qt::LeftButton && !myGLContext->getCurrentObject() && vp->startPulling( point ) )
945 if( e->button() == Qt::LeftButton && !(vp->currentBlock() & BS_Selection) && !myGLContext->getCurrentObject() )
946 vp->startSelectByRect( e->x(), e->y() );
950 Updates started operation on mouse event
952 bool GLViewer_Viewer2d::updateOperations( QMouseEvent* e )
954 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)getActiveView())->getViewPort();
956 if( vp->isPulling() )
958 float x = e->pos().x();
959 float y = e->pos().y();
962 vp->drawPulling( GLViewer_Pnt( x, y ) );
967 if( !myGLContext->getCurrentObject() )
969 vp->drawSelectByRect( e->x(), e->y() );
976 Completes started operation on mouse event
978 void GLViewer_Viewer2d::finishOperations( QMouseEvent* e )
980 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)getActiveView())->getViewPort();
982 if( vp->isPulling() )
989 if( !myGLContext->getCurrentObject() )
991 QRect aSelRect = vp->selectionRect();
992 vp->finishSelectByRect();
993 if ( getSelector() && !aSelRect.isNull() )
995 bool append = bool ( e->modifiers() & GLViewer_Selector::appendKey() );
996 getSelector()->select( aSelRect, append );
1002 Starts some operation on mouse wheel event
1004 void GLViewer_Viewer2d::startOperations( QWheelEvent* e )
1006 bool zoomIn = e->delta() > 0;
1007 bool update = false;
1008 for( myGLContext->InitSelected(); myGLContext->MoreSelected(); myGLContext->NextSelected() )
1010 GLViewer_Object* anObject = myGLContext->SelectedObject();
1011 update = anObject->updateZoom( zoomIn ) || update;
1014 emit wheelZoomChange( zoomIn );
1021 int GLViewer_View2dTransformer::rotateBtn = Qt::RightButton;
1026 GLViewer_View2dTransformer::GLViewer_View2dTransformer( GLViewer_Viewer* viewer, int typ )
1027 : GLViewer_ViewTransformer( viewer, typ )
1029 if ( type() == GLViewer_Viewer::Rotate )
1030 initTransform( true );
1036 GLViewer_View2dTransformer::~GLViewer_View2dTransformer()
1038 if ( type() == GLViewer_Viewer::Rotate )
1039 initTransform( false );
1043 Redefined to provide specific 3D transfomations. [ virtual public ]
1045 void GLViewer_View2dTransformer::exec()
1047 if ( !myViewer->getActiveView() )
1050 /* additional transforms */
1051 GLViewer_ViewPort* vp = myViewer->getActiveView()->getViewPort();
1052 GLViewer_ViewPort2d* avp = (GLViewer_ViewPort2d*)vp;
1055 case GLViewer_Viewer::Rotate:
1056 myMajorBtn = rotateButton();
1057 avp->setCursor( *avp->getRotCursor() );
1060 GLViewer_ViewTransformer::exec();
1065 Handles rotation. [ protected virtual ]
1067 void GLViewer_View2dTransformer::onTransform( TransformState state )
1069 if ( !myViewer->getActiveView() )
1072 GLViewer_ViewPort* vp = myViewer->getActiveView()->getViewPort();
1073 GLViewer_ViewPort2d* avp = (GLViewer_ViewPort2d*)vp;
1074 if ( type() == GLViewer_Viewer::Rotate )
1079 if ( myButtonState & myMajorBtn )
1080 avp->startRotation( myStart.x(), myStart.y() );
1083 if ( myButtonState & myMajorBtn )
1084 avp->rotate( myCurr.x(), myCurr.y() );
1092 GLViewer_ViewTransformer::onTransform( state );