1 // Copyright (C) 2007-2024 CEA, EDF, 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_Context.cxx
25 // Created: November, 2004
28 \class GLViewer_AspectLine
29 \brief Class for manage of presentations in GLViewer
32 #include "GLViewer_Context.h"
34 #include "GLViewer_Group.h"
35 #include "GLViewer_Object.h"
36 #include "GLViewer_Viewer2d.h"
37 #include "GLViewer_ViewPort2d.h"
38 #include "GLViewer_ViewFrame.h"
43 #include <TColStd_SequenceOfInteger.hxx>
50 GLViewer_Context::GLViewer_Context( GLViewer_Viewer2d* v ) :
52 myHighlightColor( Quantity_NOC_CYAN1 ),
53 mySelectionColor( Quantity_NOC_RED ),
54 myTolerance( TOLERANCE )
59 myLastPickedChanged = false;
70 GLViewer_Context::~GLViewer_Context()
72 myActiveObjects.clear();
73 myInactiveObjects.clear();
74 mySelectedObjects.clear();
78 Hiilights objects under cursor
79 \param x - X coord of mouse cursor
80 \param y - Y coord of mouse cursor
81 \param byCircle - true if needs round sensitive area around mouse cursor, else rectangle
82 function search object rectangle which intersect with sensitive area and call object highlight method
84 int GLViewer_Context::MoveTo( int xi, int yi, bool byCircle )
86 GLfloat x = (GLfloat)xi;
87 GLfloat y = (GLfloat)yi;
88 myGLViewer2d->transPoint( x, y );
93 GLboolean isHigh = GL_FALSE;
94 GLboolean onObject = GL_FALSE;
96 GLViewer_Object* aPrevLastPicked = myLastPicked;
97 GLViewer_Object* lastPicked = 0;
99 ObjList anUpdatedObjects;
101 if( myActiveObjects.isEmpty() )
104 ObjList::iterator it = myActiveObjects.end();
105 ObjList::iterator itEnd = myActiveObjects.begin();
108 GLViewer_Object* object = *it;
110 GLViewer_Rect* rect = object->getUpdateRect();
111 if( object->isSelectable() &&
112 rect->contains( GLViewer_Pnt( x, y ) ) )
115 object->highlight( x, y, myTolerance, GL_FALSE );
116 isHigh = object->isHighlighted();
131 myLastPicked = lastPicked;
138 it = myActiveObjects.begin();
139 itEnd = myActiveObjects.end();
141 for( ; it != itEnd; ++it )
142 (*it)->unhighlight();
144 anUpdatedObjects.append( (*it) );
147 myLastPickedChanged = aPrevLastPicked != myLastPicked;
149 if( myLastPickedChanged )
150 myGLViewer2d->updateAll();
155 if( !myLastPicked && isHigh )
158 myLastPicked = lastPicked;
159 anUpdatedObjects.append( myLastPicked );
161 else if( myLastPicked && !isHigh )
164 myLastPicked->unhighlight();
165 anUpdatedObjects.append( myLastPicked );
168 else if( myLastPicked && isHigh )
171 myLastPicked->highlight( x, y, myTolerance, byCircle );
172 anUpdatedObjects.append( myLastPicked );
173 if( myLastPicked != lastPicked )
175 myLastPicked->unhighlight();
176 myLastPicked = lastPicked;
177 anUpdatedObjects.append( myLastPicked );
181 myLastPickedChanged = ( aPrevLastPicked != myLastPicked );
183 if( myLastPickedChanged || myUpdateAll )
184 myGLViewer2d->updateAll();
186 myGLViewer2d->activateDrawers( anUpdatedObjects, true, true );
191 /*! Selects already highlighting object by calling object method select
192 \param Append - true if new selection will be append to existing selection, false - another
193 \param byCircle - true if needs round selection area in complex object
195 int GLViewer_Context::Select( bool Append, bool byCircle )
197 ObjList::Iterator it, itEnd, oit, oitEnd;
198 SelectionStatus status = SS_Invalid;
200 bool updateAll = false;
205 return status;//invalid
207 if( myHFlag && myLastPicked )
209 if( mySelectedObjects.count() == 1 && mySelectedObjects.first() == myLastPicked )
210 status = SS_LocalChanged;
214 for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end() ; it != itEnd; ++it )
215 if( myLastPicked != *it )
217 updateAll = (*it)->unselect() || updateAll;
221 if( updateAll || myUpdateAll )
222 myGLViewer2d->updateAll();
224 myGLViewer2d->activateDrawers( aList, true, true );
226 if( mySelectedObjects.count() != 0 && status == SS_Invalid )
227 status = SS_GlobalChanged;
228 mySelectedObjects.clear();
230 else if( myLastPicked->isSelected() && status != SS_LocalChanged )
232 mySelectedObjects.removeAll( myLastPicked );
233 myLastPicked->unselect();
234 myGLViewer2d->updateAll();
236 if( mySelectedObjects.count() != 0 && status == SS_Invalid )
237 status = SS_GlobalChanged;
242 if ( myLastPicked->select( myXhigh, myYhigh, myTolerance, GLViewer_Rect(), false, byCircle, Append )
243 && mySelectedObjects.indexOf( myLastPicked ) == -1 )
245 mySelectedObjects.append( myLastPicked );
246 myGLViewer2d->activateDrawer( myLastPicked, true, true );
248 if( status == SS_Invalid )
249 status = SS_GlobalChanged;
251 else if( status == SS_LocalChanged )
252 status = SS_GlobalChanged;
257 if( myHFlag && !myLastPicked )
261 for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end() ; it != itEnd; ++it )
262 if ( myLastPicked != *it )
264 updateAll = (*it)->unselect() || updateAll;
268 if( updateAll || myUpdateAll )
269 myGLViewer2d->updateAll();
271 myGLViewer2d->activateDrawers( aList, true, true );
273 if( mySelectedObjects.count() != 0 )
274 status = SS_GlobalChanged;
276 mySelectedObjects.clear();
286 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )myGLViewer2d->getActiveView()->getViewPort();
287 vp->getScale( aXScale, aYScale );
291 for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end() ; it != itEnd; ++it )
292 if( myLastPicked != *it )
294 updateAll = (*it)->unselect() || updateAll;
298 if( updateAll || myUpdateAll )
299 myGLViewer2d->updateAll();
301 myGLViewer2d->activateDrawers( aList, true, true );
303 if( mySelectedObjects.count() != 0 )
304 status = SS_GlobalChanged;
306 mySelectedObjects.clear();
309 for( oit = myActiveObjects.begin(), oitEnd = myActiveObjects.end(); oit != oitEnd; ++oit )
311 (*oit)->setScale( aXScale, aYScale );
312 GLViewer_Rect* rect = (*oit)->getUpdateRect();
314 if( rect->contains( GLViewer_Pnt( myXhigh, myXhigh ) ) )
316 (*oit)->select( myXhigh, myYhigh, myTolerance, GLViewer_Rect(), false, byCircle, Append );
317 isSel = (*oit)->isSelected();
322 mySelectedObjects.append( myLastPicked );
323 myGLViewer2d->activateDrawer( myLastPicked, true, true );
324 status = SS_GlobalChanged;
333 /*! Selects objects on scene by rectangle
334 \param theRect - rectangle of selection
335 \param Append - true if new selection will be append to existing selection, false - another
336 function search object rectangle which intersect with theRect and call object select method
338 int GLViewer_Context::SelectByRect( const QRect& theRect, bool Append )
342 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )myGLViewer2d->getActiveView()->getViewPort();
343 vp->getScale( aXScale, aYScale );
345 SelectionStatus status = SS_NoChanged;
348 ObjList::Iterator it, itEnd;
350 if ( !mySFlag || myActiveObjects.empty() )
353 bool updateAll = false;
356 if( mySelectedObjects.count() != 0 )
357 status = SS_GlobalChanged;
359 for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end(); it != itEnd; ++it )
361 updateAll = (*it)->unselect() || updateAll;
364 mySelectedObjects.clear();
367 for( it = myActiveObjects.begin(), itEnd = myActiveObjects.end(); it != itEnd; ++it )
370 (*it)->setScale( aXScale, aYScale );
371 QRect rect = myGLViewer2d->getQRect( *( (*it)->getRect() ) );
373 if( rect.intersects( theRect ) )
375 GLViewer_Rect aRect = myGLViewer2d->getGLVRect( theRect );
376 (*it)->select( myXhigh, myYhigh, myTolerance, aRect, false, false, Append );
377 isSel = (*it)->isSelected();
380 if( isSel && mySelectedObjects.indexOf( *it ) == -1 )
383 mySelectedObjects.append( *it );
384 status = SS_GlobalChanged;
388 if( updateAll || myUpdateAll )
389 myGLViewer2d->updateAll();
391 myGLViewer2d->activateDrawers( aList, true, true );
397 Sets color of hilighting
398 \param aCol - new color of highlighting
400 void GLViewer_Context::SetHighlightColor( Quantity_NameOfColor aCol )
402 myHighlightColor = aCol;
404 Quantity_Color colorH( aCol );
405 int redH = 255 * (int)colorH.Red();
406 int greenH = 255 * (int)colorH.Green();
407 int blueH = 255 * (int)colorH.Blue();
408 QColor colH = QColor( redH, greenH, blueH );
410 Quantity_Color colorS( mySelectionColor );
411 int redS = 255 * (int)colorS.Red();
412 int greenS = 255 * (int)colorS.Green();
413 int blueS = 255 * (int)colorS.Blue();
414 QColor colS = QColor( redS, greenS, blueS );
416 myGLViewer2d->updateColors( colH, colS);
420 Sets color of selection
421 \param aCol - new color of selection
423 void GLViewer_Context::SetSelectionColor( Quantity_NameOfColor aCol )
425 mySelectionColor = aCol;
427 Quantity_Color colorH( myHighlightColor );
428 int redH = 255 * (int)colorH.Red();
429 int greenH = 255 * (int)colorH.Green();
430 int blueH = 255 * (int)colorH.Blue();
431 QColor colH = QColor( redH, greenH, blueH );
433 Quantity_Color colorS( aCol );
434 int redS = 255 * (int)colorS.Red();
435 int greenS = 255 * (int)colorS.Green();
436 int blueS = 255 * (int)colorS.Blue();
437 QColor colS = QColor( redS, greenS, blueS );
439 myGLViewer2d->updateColors( colH, colS);
443 \return number of selected objects
445 int GLViewer_Context::NbSelected()
447 return mySelectedObjects.count();
451 Inits iteration through selected objects
453 void GLViewer_Context::InitSelected()
459 Checks if iteration through selected objects may be continued
461 bool GLViewer_Context::MoreSelected()
463 return ( mySelCurIndex < NbSelected() );
467 Iterates to next selected object
469 bool GLViewer_Context::NextSelected()
471 if ( mySelCurIndex >= 0 && mySelCurIndex < NbSelected() )
481 \return current selected object (must be used only in cycle as "for( InitSelected(); MoreSelected(); NextSelected() ) {...}" )
483 GLViewer_Object* GLViewer_Context::SelectedObject()
485 return mySelectedObjects[ mySelCurIndex ];
489 \return true if object is selected
490 \param theObj - object to be checked
492 bool GLViewer_Context::isSelected( GLViewer_Object* theObj )
494 return mySelectedObjects.contains( theObj );
497 /*! Inserts new object in context
498 \param theObject - object to be inserted
499 \param display - true if needs display object immediatly after inserting, else false
500 \param isActive - true if needs inserting object in active list
502 int GLViewer_Context::insertObject( GLViewer_Object* object, bool display, bool isActive )
504 // cout << "GLViewer_Context::insertObject" << endl;
511 myActiveObjects.append( object );
514 //QRect* rect = object->getRect()->toQRect();
515 //myGLViewer2d->updateBorders( *rect );
516 myGLViewer2d->activateDrawer( object, false );
520 myInactiveObjects.append( object );
522 return myActiveObjects.count() + myInactiveObjects.count();
526 Replaces object in context
527 \param oldObject - object to be replaced
528 \param newObject - object for replacing
530 bool GLViewer_Context::replaceObject( GLViewer_Object* oldObject, GLViewer_Object* newObject )
532 if( !oldObject || !newObject )
535 if( myActiveObjects.contains( oldObject ) )
537 myActiveObjects.removeAll( oldObject );
538 myActiveObjects.append( newObject );
542 if( myInactiveObjects.contains( oldObject ) )
544 myInactiveObjects.removeAll( oldObject );
545 myInactiveObjects.append( newObject );
553 Updates scales of all objects in context
555 void GLViewer_Context::updateScales( GLfloat scX, GLfloat scY )
557 if( scX <= 0 || scY <= 0 )
560 ObjList::iterator it, itEnd;
562 for( it = myActiveObjects.begin(), itEnd = myActiveObjects.end(); it != itEnd; ++it )
563 (*it)->setScale( scX, scY );
565 for( it = myInactiveObjects.begin(), itEnd = myInactiveObjects.end(); it != itEnd; ++it )
566 (*it)->setScale( scX, scY );
570 Clears hilighting of objects
571 \param updateViewer - if it is true, viewer must be updated
573 void GLViewer_Context::clearHighlighted( bool updateViewer )
575 if( myHFlag && myLastPicked )
577 myLastPicked->unhighlight();
581 myGLViewer2d->updateAll();
586 Clears selection of objects
587 \param updateViewer - if it is true, viewer must be updated
589 void GLViewer_Context::clearSelected( bool updateViewer )
594 ObjList::Iterator it, itEnd;
597 for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end(); it != itEnd; ++it )
604 myGLViewer2d->activateDrawers( aList, true );
605 mySelectedObjects.clear();
609 Selects object, other selected objects are left as selected
610 \param updateViewer - if it is true, viewer must be updated
612 void GLViewer_Context::setSelected( GLViewer_Object* object, bool updateViewer )
617 if( myActiveObjects.contains( object ) && !mySelectedObjects.contains( object ) )
619 object->setSelected( true );
620 mySelectedObjects.append( object );
624 myGLViewer2d->activateDrawer( object, true, true );
628 Unselects object, other selected objects are left as selected
629 \param updateViewer - if it is true, viewer must be updated
631 void GLViewer_Context::remSelected( GLViewer_Object* object, bool updateViewer )
633 if( !object || !mySelectedObjects.contains( object ) )
636 mySelectedObjects.removeAll( object );
640 myGLViewer2d->activateDrawer( object, true, true );
644 Erases object in viewer
645 \param theUpdateViewer - if it is true, viewer must be updated
647 void GLViewer_Context::eraseObject( GLViewer_Object* theObject, bool theUpdateViewer )
649 if( !theObject || !myActiveObjects.contains( theObject ) )
652 theObject->unhighlight();
653 theObject->unselect();
654 theObject->setVisible( false );
656 if( theUpdateViewer )
657 myGLViewer2d->updateAll();
662 \param updateViewer - if it is true, viewer must be updated
664 void GLViewer_Context::deleteObject( GLViewer_Object* theObject, bool updateViewer )
667 ( !myActiveObjects.contains( theObject ) && !myInactiveObjects.contains( theObject ) ) )
670 if( myActiveObjects.contains( theObject ) )
671 myActiveObjects.removeAll( theObject );
672 else if( myInactiveObjects.contains( theObject ) )
673 myInactiveObjects.removeAll( theObject );
677 if( mySelectedObjects.contains( theObject ) )
678 mySelectedObjects.removeAll( theObject );
680 GLViewer_Group* aGroup = theObject->getGroup();
682 aGroup->removeObject( theObject );
684 if( myLastPicked == theObject )
688 myGLViewer2d->updateAll();
692 Installs active status to object
695 bool GLViewer_Context::setActive( GLViewer_Object* theObject )
697 if( !theObject || !myInactiveObjects.contains( theObject ) )
700 myInactiveObjects.removeAll( theObject );
701 myActiveObjects.append( theObject );
706 Installs inactive status to object
709 bool GLViewer_Context::setInactive( GLViewer_Object* theObject )
711 if( !theObject || !myActiveObjects.contains( theObject ) )
714 myActiveObjects.removeAll( theObject );
715 myInactiveObjects.append( theObject );