Back to index

salome-gui  6.5.0
GLViewer_Context.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_Context.cxx
00025 // Created:   November, 2004
00026 //
00032 #include "GLViewer_Context.h"
00033 
00034 #include "GLViewer_Group.h"
00035 #include "GLViewer_Object.h"
00036 #include "GLViewer_Viewer2d.h"
00037 #include "GLViewer_ViewPort2d.h"
00038 #include "GLViewer_ViewFrame.h"
00039 
00040 //QT includes
00041 #include <QRect>
00042 
00043 #include <TColStd_SequenceOfInteger.hxx>
00044 
00045 #define TOLERANCE  12
00046 
00050 GLViewer_Context::GLViewer_Context( GLViewer_Viewer2d* v ) :
00051        myGLViewer2d( v ),
00052        myHighlightColor( Quantity_NOC_CYAN1 ),
00053        mySelectionColor( Quantity_NOC_RED ),
00054        myTolerance( TOLERANCE )
00055 {
00056   myUpdateAll = true;
00057 
00058   myLastPicked = 0;
00059   myLastPickedChanged = false;
00060 
00061   myHFlag = GL_TRUE;
00062   mySFlag = GL_TRUE;
00063 
00064   mySelCurIndex = 0;
00065 }
00066 
00070 GLViewer_Context::~GLViewer_Context()
00071 {
00072     myActiveObjects.clear();
00073     myInactiveObjects.clear();
00074     mySelectedObjects.clear();
00075 }
00076 
00084 int GLViewer_Context::MoveTo( int xi, int yi, bool byCircle )
00085 {
00086     GLfloat x = (GLfloat)xi;
00087     GLfloat y = (GLfloat)yi;
00088     myGLViewer2d->transPoint( x, y );
00089 
00090     myXhigh = x;
00091     myYhigh = y;  
00092 
00093     GLboolean isHigh = GL_FALSE;
00094     GLboolean onObject = GL_FALSE;
00095 
00096     GLViewer_Object* aPrevLastPicked = myLastPicked;
00097     GLViewer_Object* lastPicked = 0;
00098 
00099     ObjList anUpdatedObjects;
00100   
00101     if( myActiveObjects.isEmpty() )
00102         return -1;
00103 
00104     ObjList::iterator it = myActiveObjects.end();
00105     ObjList::iterator itEnd = myActiveObjects.begin();
00106     for( it--; ; --it )
00107     {
00108         GLViewer_Object* object = *it;
00109 
00110         GLViewer_Rect* rect = object->getUpdateRect();
00111         if( rect->contains( GLViewer_Pnt( x, y ) ) )
00112         {
00113             onObject = GL_TRUE;
00114             object->highlight( x, y, myTolerance, GL_FALSE );
00115             isHigh = object->isHighlighted();
00116         }
00117 
00118         if( isHigh )
00119         {
00120             lastPicked = object;
00121             break;
00122         }
00123 
00124         if( it == itEnd )
00125             break;
00126     }
00127 
00128     if( !myHFlag )
00129     {
00130         myLastPicked = lastPicked;
00131         return -1;
00132     }
00133 
00134     if ( !onObject )
00135     {
00136         //cout << 0 << endl;
00137         it = myActiveObjects.begin();
00138         itEnd = myActiveObjects.end();
00139 
00140         for( ; it != itEnd; ++it )
00141             (*it)->unhighlight();
00142 
00143         anUpdatedObjects.append( (*it) );
00144 
00145         myLastPicked = 0;
00146         myLastPickedChanged = aPrevLastPicked != myLastPicked;
00147 
00148         if( myLastPickedChanged )
00149             myGLViewer2d->updateAll();  
00150 
00151         return 0;
00152     }
00153 
00154     if( !myLastPicked && isHigh )
00155     {
00156         //cout << 1 << endl;
00157         myLastPicked = lastPicked;
00158         anUpdatedObjects.append( myLastPicked );
00159     }
00160     else if( myLastPicked && !isHigh )
00161     {
00162         //cout << 2 << endl;
00163         myLastPicked->unhighlight();
00164         anUpdatedObjects.append( myLastPicked );
00165         myLastPicked = 0;
00166     }
00167     else if( myLastPicked && isHigh )
00168     {
00169         //cout << 3 << endl;
00170         myLastPicked->highlight( x, y, myTolerance, byCircle );
00171         anUpdatedObjects.append( myLastPicked );
00172         if( myLastPicked != lastPicked )
00173         {
00174             myLastPicked->unhighlight();
00175             myLastPicked = lastPicked;
00176             anUpdatedObjects.append( myLastPicked );
00177         }
00178     }
00179 
00180     myLastPickedChanged = ( aPrevLastPicked != myLastPicked );
00181 
00182     if( myLastPickedChanged || myUpdateAll )
00183         myGLViewer2d->updateAll();
00184     else
00185         myGLViewer2d->activateDrawers( anUpdatedObjects, TRUE, TRUE );
00186 
00187     return 0;
00188 }
00189 
00194 int GLViewer_Context::Select( bool Append, bool byCircle )
00195 {
00196     ObjList::Iterator it, itEnd, oit, oitEnd;
00197     SelectionStatus status = SS_Invalid;
00198 
00199     bool updateAll = false;
00200 
00201     ObjList aList;
00202 
00203     if ( !mySFlag )
00204         return status;//invalid
00205 
00206     if( myHFlag && myLastPicked )
00207     {
00208         if( mySelectedObjects.count() == 1 && mySelectedObjects.first() == myLastPicked )
00209             status = SS_LocalChanged;
00210 
00211         if ( !Append )
00212         {
00213             for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end() ; it != itEnd; ++it )
00214                     if( myLastPicked != *it )
00215                 {
00216                         updateAll = (*it)->unselect() || updateAll;
00217                         aList.append( *it );
00218                 }
00219 
00220             if( updateAll || myUpdateAll )
00221                 myGLViewer2d->updateAll();
00222             else
00223                 myGLViewer2d->activateDrawers( aList, TRUE, TRUE );
00224 
00225             if( mySelectedObjects.count() != 0 && status == SS_Invalid )
00226                 status = SS_GlobalChanged;
00227             mySelectedObjects.clear();
00228         } 
00229         else if( myLastPicked->isSelected() && status != SS_LocalChanged )
00230         {
00231             mySelectedObjects.removeAll( myLastPicked );
00232             myLastPicked->unselect();
00233             myGLViewer2d->updateAll();
00234 
00235             if( mySelectedObjects.count() != 0 && status == SS_Invalid )
00236               status = SS_GlobalChanged;
00237 
00238             return status;
00239         }
00240 
00241         if ( myLastPicked->select( myXhigh, myYhigh, myTolerance, GLViewer_Rect(), false, byCircle, Append )
00242              && mySelectedObjects.indexOf( myLastPicked ) == -1 )
00243         {
00244             mySelectedObjects.append( myLastPicked );
00245             myGLViewer2d->activateDrawer( myLastPicked, TRUE, TRUE );
00246 
00247             if( status == SS_Invalid )
00248                 status = SS_GlobalChanged;
00249         }
00250         else if( status == SS_LocalChanged )
00251             status = SS_GlobalChanged;
00252 
00253         return status;
00254     }
00255 
00256     if( myHFlag && !myLastPicked )
00257     {
00258         if ( !Append )
00259         {
00260             for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end() ; it != itEnd; ++it )
00261                     if ( myLastPicked != *it )
00262                 {
00263                         updateAll = (*it)->unselect() || updateAll;
00264                         aList.append( *it );
00265                 }
00266 
00267             if( updateAll || myUpdateAll )
00268                 myGLViewer2d->updateAll();
00269             else
00270                 myGLViewer2d->activateDrawers( aList, TRUE, TRUE );
00271 
00272             if( mySelectedObjects.count() != 0 )
00273                 status = SS_GlobalChanged;
00274 
00275             mySelectedObjects.clear();
00276         }
00277         return status;
00278     }
00279 
00280     if( !myHFlag )
00281     {
00282         bool isSel = false;
00283         GLfloat aXScale;
00284         GLfloat aYScale;
00285         GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )myGLViewer2d->getActiveView()->getViewPort();
00286         vp->getScale( aXScale, aYScale );
00287 
00288         if ( !Append )
00289         {
00290             for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end() ; it != itEnd; ++it )
00291                 if( myLastPicked != *it )
00292                 {
00293                     updateAll = (*it)->unselect() || updateAll;
00294                     aList.append( *it );
00295                 }
00296 
00297             if( updateAll || myUpdateAll )
00298                 myGLViewer2d->updateAll();
00299             else
00300                 myGLViewer2d->activateDrawers( aList, TRUE, TRUE );
00301 
00302             if( mySelectedObjects.count() != 0 )
00303                 status = SS_GlobalChanged;
00304 
00305             mySelectedObjects.clear();
00306         }        
00307 
00308         for( oit = myActiveObjects.begin(), oitEnd = myActiveObjects.end(); oit != oitEnd; ++oit )
00309         {
00310             (*oit)->setScale( aXScale, aYScale );
00311             GLViewer_Rect* rect = (*oit)->getUpdateRect();
00312 
00313             if( rect->contains( GLViewer_Pnt( myXhigh, myXhigh ) ) )
00314             {
00315                 (*oit)->select( myXhigh, myYhigh, myTolerance, GLViewer_Rect(), false, byCircle, Append );
00316                 isSel = (*oit)->isSelected();
00317             }
00318             if( isSel )
00319             {
00320                 myLastPicked = *oit;
00321                 mySelectedObjects.append( myLastPicked );
00322                 myGLViewer2d->activateDrawer( myLastPicked, TRUE, TRUE );
00323                 status = SS_GlobalChanged;
00324                 return status;
00325             }
00326         }
00327     }
00328         
00329     return SS_NoChanged;
00330 }
00331 
00337 int GLViewer_Context::SelectByRect( const QRect& theRect, bool Append )
00338 {
00339     GLfloat aXScale;
00340     GLfloat aYScale;
00341     GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )myGLViewer2d->getActiveView()->getViewPort();
00342     vp->getScale( aXScale, aYScale );
00343 
00344     SelectionStatus status = SS_NoChanged;
00345 
00346     ObjList aList;
00347     ObjList::Iterator it, itEnd;
00348 
00349     if ( !mySFlag || myActiveObjects.empty() )
00350         return SS_Invalid;
00351 
00352     bool updateAll = false;
00353     if( !Append )
00354     {
00355         if( mySelectedObjects.count() != 0 )
00356             status = SS_GlobalChanged;
00357 
00358         for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end(); it != itEnd; ++it )
00359         {
00360             updateAll = (*it)->unselect() || updateAll;
00361             aList.append( *it );
00362         }
00363         mySelectedObjects.clear();
00364     }
00365 
00366     for( it = myActiveObjects.begin(), itEnd = myActiveObjects.end(); it != itEnd; ++it )
00367     {
00368         bool isSel = false;
00369         (*it)->setScale( aXScale, aYScale );
00370         QRect rect = myGLViewer2d->getQRect( *( (*it)->getRect() ) );
00371 
00372         if( rect.intersects( theRect ) )
00373         {
00374             GLViewer_Rect aRect = myGLViewer2d->getGLVRect( theRect );
00375             (*it)->select( myXhigh, myYhigh, myTolerance, aRect, false, false, Append );
00376             isSel = (*it)->isSelected();
00377         }
00378 
00379         if( isSel && mySelectedObjects.indexOf( *it ) == -1 )
00380         {
00381             aList.append( *it );
00382             mySelectedObjects.append( *it );
00383             status = SS_GlobalChanged;
00384         }
00385     }
00386 
00387     if( updateAll || myUpdateAll )
00388         myGLViewer2d->updateAll();
00389     else
00390         myGLViewer2d->activateDrawers( aList, TRUE, TRUE );
00391 
00392     return status;
00393 }
00394 
00399 void GLViewer_Context::SetHighlightColor( Quantity_NameOfColor aCol )
00400 {
00401   myHighlightColor = aCol;
00402   
00403   Quantity_Color colorH( aCol );
00404   int redH = 255 * (int)colorH.Red();
00405   int greenH = 255 * (int)colorH.Green();
00406   int blueH = 255 * (int)colorH.Blue();
00407   QColor colH = QColor( redH, greenH, blueH );
00408 
00409   Quantity_Color colorS( mySelectionColor );
00410   int redS = 255 * (int)colorS.Red();
00411   int greenS = 255 * (int)colorS.Green();
00412   int blueS = 255 * (int)colorS.Blue();
00413   QColor colS = QColor( redS, greenS, blueS );
00414 
00415   myGLViewer2d->updateColors( colH, colS);
00416 }
00417 
00422 void GLViewer_Context::SetSelectionColor( Quantity_NameOfColor aCol )
00423 {
00424   mySelectionColor = aCol;
00425   
00426   Quantity_Color colorH( myHighlightColor );
00427   int redH = 255 * (int)colorH.Red();
00428   int greenH = 255 * (int)colorH.Green();
00429   int blueH = 255 * (int)colorH.Blue();
00430   QColor colH = QColor( redH, greenH, blueH );
00431 
00432   Quantity_Color colorS( aCol );
00433   int redS = 255 * (int)colorS.Red();
00434   int greenS = 255 * (int)colorS.Green();
00435   int blueS = 255 * (int)colorS.Blue();
00436   QColor colS = QColor( redS, greenS, blueS );
00437 
00438   myGLViewer2d->updateColors( colH, colS);
00439 }
00440 
00444 int GLViewer_Context::NbSelected()
00445 {
00446   return mySelectedObjects.count();
00447 }
00448 
00452 void GLViewer_Context::InitSelected()
00453 {
00454   mySelCurIndex = 0;
00455 }
00456 
00460 bool GLViewer_Context::MoreSelected()
00461 {
00462   return ( mySelCurIndex < NbSelected() );
00463 }
00464 
00468 bool GLViewer_Context::NextSelected()
00469 {
00470   if ( mySelCurIndex >= 0 && mySelCurIndex < NbSelected() )
00471   {
00472     mySelCurIndex++;
00473     return TRUE;
00474   }
00475 
00476   return FALSE;
00477 }
00478 
00482 GLViewer_Object* GLViewer_Context::SelectedObject()
00483 {
00484     return mySelectedObjects[ mySelCurIndex ];
00485 }
00486 
00491 bool  GLViewer_Context::isSelected( GLViewer_Object* theObj )
00492 {
00493     return mySelectedObjects.contains( theObj );
00494 }
00495 
00501 int GLViewer_Context::insertObject( GLViewer_Object* object, bool display, bool isActive )
00502 {
00503 //  cout << "GLViewer_Context::insertObject" << endl;
00504 
00505     if( !object )
00506         return -1;
00507 
00508     if( isActive )
00509     {
00510         myActiveObjects.append( object );
00511         if( display )
00512         {
00513             //QRect* rect = object->getRect()->toQRect();
00514             //myGLViewer2d->updateBorders( *rect );
00515             myGLViewer2d->activateDrawer( object, FALSE );
00516         }
00517     }
00518     else
00519         myInactiveObjects.append( object );
00520 
00521     return myActiveObjects.count() + myInactiveObjects.count();
00522 }
00523 
00529 bool GLViewer_Context::replaceObject( GLViewer_Object* oldObject, GLViewer_Object* newObject )
00530 {
00531     if( !oldObject || !newObject )
00532         return false;
00533 
00534   if( myActiveObjects.contains( oldObject ) )
00535   {
00536     myActiveObjects.removeAll( oldObject );
00537     myActiveObjects.append( newObject );
00538     return true;
00539   }
00540 
00541   if( myInactiveObjects.contains( oldObject ) )
00542   {
00543     myInactiveObjects.removeAll( oldObject );
00544     myInactiveObjects.append( newObject );
00545     return true;
00546   }
00547 
00548   return false;
00549 }
00550 
00554 void GLViewer_Context::updateScales( GLfloat scX, GLfloat scY )
00555 {
00556   if( scX <= 0 || scY <= 0 )
00557       return;
00558 
00559   ObjList::iterator it, itEnd;
00560 
00561   for( it = myActiveObjects.begin(), itEnd = myActiveObjects.end(); it != itEnd; ++it )
00562       (*it)->setScale( scX, scY );
00563 
00564   for( it = myInactiveObjects.begin(), itEnd = myInactiveObjects.end(); it != itEnd; ++it )
00565       (*it)->setScale( scX, scY );
00566 }
00567 
00572 void GLViewer_Context::clearHighlighted( bool updateViewer )
00573 {
00574   if( myHFlag && myLastPicked )
00575   {
00576     myLastPicked->unhighlight();
00577     myLastPicked = 0;
00578     
00579     if( updateViewer )
00580       myGLViewer2d->updateAll();
00581   }
00582 }
00583 
00588 void GLViewer_Context::clearSelected( bool updateViewer )
00589 {
00590   if( !mySFlag )
00591     return;
00592 
00593   ObjList::Iterator it, itEnd;
00594   ObjList aList;
00595 
00596   for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end(); it != itEnd; ++it )
00597   {
00598     (*it)->unselect();
00599     aList.append( *it );
00600   }          
00601         
00602   if( updateViewer )
00603     myGLViewer2d->activateDrawers( aList, TRUE );
00604   mySelectedObjects.clear();    
00605 }
00606 
00611 void GLViewer_Context::setSelected( GLViewer_Object* object, bool updateViewer )
00612 {
00613   if( !object )
00614     return;
00615 
00616   if( myActiveObjects.contains( object ) && !mySelectedObjects.contains( object ) )
00617   {
00618     object->setSelected( TRUE );
00619     mySelectedObjects.append( object );
00620   }
00621      
00622   if( updateViewer )
00623     myGLViewer2d->activateDrawer( object, TRUE, TRUE );
00624 }
00625 
00630 void GLViewer_Context::remSelected( GLViewer_Object* object, bool updateViewer )
00631 {
00632   if( !object || !mySelectedObjects.contains( object ) )
00633     return;
00634   
00635   mySelectedObjects.removeAll( object );
00636   object->unselect();
00637   
00638   if( updateViewer )
00639     myGLViewer2d->activateDrawer( object, TRUE, TRUE );
00640 }
00641 
00646 void GLViewer_Context::eraseObject( GLViewer_Object* theObject, bool theUpdateViewer )
00647 {
00648     if( !theObject || !myActiveObjects.contains( theObject ) )
00649         return;
00650 
00651     theObject->unhighlight();
00652     theObject->unselect();
00653     theObject->setVisible( false );
00654 
00655     if( theUpdateViewer )
00656         myGLViewer2d->updateAll();
00657 }
00658 
00663 void GLViewer_Context::deleteObject( GLViewer_Object* theObject, bool updateViewer )
00664 {
00665     if( !theObject ||
00666         ( !myActiveObjects.contains( theObject ) && !myInactiveObjects.contains( theObject ) ) )
00667         return;
00668 
00669     if( myActiveObjects.contains( theObject ) )      
00670         myActiveObjects.removeAll( theObject );
00671     else if( myInactiveObjects.contains( theObject ) )
00672         myInactiveObjects.removeAll( theObject );
00673     else 
00674         return;
00675      
00676     if( mySelectedObjects.contains( theObject ) )
00677         mySelectedObjects.removeAll( theObject );
00678 
00679     GLViewer_Group* aGroup = theObject->getGroup();
00680     if( aGroup )
00681         aGroup->removeObject( theObject );
00682 
00683     if( myLastPicked == theObject )
00684         myLastPicked = 0;
00685 
00686     if ( updateViewer )
00687       myGLViewer2d->updateAll();
00688 }
00689 
00694 bool GLViewer_Context::setActive( GLViewer_Object* theObject )
00695 {
00696   if( !theObject || !myInactiveObjects.contains( theObject ) )
00697     return false;
00698 
00699   myInactiveObjects.removeAll( theObject );
00700   myActiveObjects.append( theObject );
00701   return true;
00702 }
00703 
00708 bool GLViewer_Context::setInactive( GLViewer_Object* theObject )
00709 {
00710   if( !theObject || !myActiveObjects.contains( theObject ) )
00711     return false;
00712 
00713   myActiveObjects.removeAll( theObject );
00714   myInactiveObjects.append( theObject );
00715   return true;
00716 }