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 qDeleteAll(myActiveObjects);
73 myActiveObjects.clear();
75 qDeleteAll(myInactiveObjects);
76 myInactiveObjects.clear();
78 mySelectedObjects.clear();
82 Hiilights objects under cursor
83 \param x - X coord of mouse cursor
84 \param y - Y coord of mouse cursor
85 \param byCircle - true if needs round sensitive area around mouse cursor, else rectangle
86 function search object rectangle which intersect with sensitive area and call object highlight method
88 int GLViewer_Context::MoveTo( int xi, int yi, bool byCircle )
90 GLfloat x = (GLfloat)xi;
91 GLfloat y = (GLfloat)yi;
92 myGLViewer2d->transPoint( x, y );
97 GLboolean isHigh = GL_FALSE;
98 GLboolean onObject = GL_FALSE;
100 GLViewer_Object* aPrevLastPicked = myLastPicked;
101 GLViewer_Object* lastPicked = 0;
103 ObjList anUpdatedObjects;
105 if( myActiveObjects.isEmpty() )
108 ObjList::iterator it = myActiveObjects.end();
109 ObjList::iterator itEnd = myActiveObjects.begin();
112 GLViewer_Object* object = *it;
114 GLViewer_Rect* rect = object->getUpdateRect();
115 if( object->isSelectable() &&
116 rect->contains( GLViewer_Pnt( x, y ) ) )
119 object->highlight( x, y, myTolerance, GL_FALSE );
120 isHigh = object->isHighlighted();
137 myLastPicked = lastPicked;
144 it = myActiveObjects.begin();
145 itEnd = myActiveObjects.end();
147 for( ; it != itEnd; ++it )
148 (*it)->unhighlight();
150 anUpdatedObjects.append( (*it) );
153 myLastPickedChanged = aPrevLastPicked != myLastPicked;
155 if( myLastPickedChanged )
156 myGLViewer2d->updateAll();
161 if( !myLastPicked && isHigh )
164 myLastPicked = lastPicked;
165 anUpdatedObjects.append( myLastPicked );
167 else if( myLastPicked && !isHigh )
170 myLastPicked->unhighlight();
171 anUpdatedObjects.append( myLastPicked );
174 else if( myLastPicked && isHigh )
177 myLastPicked->highlight( x, y, myTolerance, byCircle );
178 anUpdatedObjects.append( myLastPicked );
179 if( myLastPicked != lastPicked )
181 myLastPicked->unhighlight();
182 myLastPicked = lastPicked;
183 anUpdatedObjects.append( myLastPicked );
187 myLastPickedChanged = ( aPrevLastPicked != myLastPicked );
189 if( myLastPickedChanged || myUpdateAll )
190 myGLViewer2d->updateAll();
192 myGLViewer2d->activateDrawers( anUpdatedObjects, true, true );
197 /*! Selects already highlighting object by calling object method select
198 \param Append - true if new selection will be append to existing selection, false - another
199 \param byCircle - true if needs round selection area in complex object
201 int GLViewer_Context::Select( bool Append, bool byCircle )
203 ObjList::Iterator it, itEnd, oit, oitEnd;
204 SelectionStatus status = SS_Invalid;
206 bool updateAll = false;
211 return status;//invalid
213 if( myHFlag && myLastPicked )
215 if( mySelectedObjects.count() == 1 && mySelectedObjects.first() == myLastPicked )
216 status = SS_LocalChanged;
220 for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end() ; it != itEnd; ++it )
221 if( myLastPicked != *it )
223 updateAll = (*it)->unselect() || updateAll;
227 if( updateAll || myUpdateAll )
228 myGLViewer2d->updateAll();
230 myGLViewer2d->activateDrawers( aList, true, true );
232 if( mySelectedObjects.count() != 0 && status == SS_Invalid )
233 status = SS_GlobalChanged;
234 mySelectedObjects.clear();
236 else if( myLastPicked->isSelected() && status != SS_LocalChanged )
238 mySelectedObjects.removeAll( myLastPicked );
239 myLastPicked->unselect();
240 myGLViewer2d->updateAll();
242 if( mySelectedObjects.count() != 0 && status == SS_Invalid )
243 status = SS_GlobalChanged;
248 if ( myLastPicked->select( myXhigh, myYhigh, myTolerance, GLViewer_Rect(), false, byCircle, Append )
249 && mySelectedObjects.indexOf( myLastPicked ) == -1 )
251 mySelectedObjects.append( myLastPicked );
252 myGLViewer2d->activateDrawer( myLastPicked, true, true );
254 if( status == SS_Invalid )
255 status = SS_GlobalChanged;
257 else if( status == SS_LocalChanged )
258 status = SS_GlobalChanged;
263 if( myHFlag && !myLastPicked )
267 for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end() ; it != itEnd; ++it )
268 if ( myLastPicked != *it )
270 updateAll = (*it)->unselect() || updateAll;
274 if( updateAll || myUpdateAll )
275 myGLViewer2d->updateAll();
277 myGLViewer2d->activateDrawers( aList, true, true );
279 if( mySelectedObjects.count() != 0 )
280 status = SS_GlobalChanged;
282 mySelectedObjects.clear();
292 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )myGLViewer2d->getActiveView()->getViewPort();
293 vp->getScale( aXScale, aYScale );
297 for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end() ; it != itEnd; ++it )
298 if( myLastPicked != *it )
300 updateAll = (*it)->unselect() || updateAll;
304 if( updateAll || myUpdateAll )
305 myGLViewer2d->updateAll();
307 myGLViewer2d->activateDrawers( aList, true, true );
309 if( mySelectedObjects.count() != 0 )
310 status = SS_GlobalChanged;
312 mySelectedObjects.clear();
315 for( oit = myActiveObjects.begin(), oitEnd = myActiveObjects.end(); oit != oitEnd; ++oit )
317 (*oit)->setScale( aXScale, aYScale );
318 GLViewer_Rect* rect = (*oit)->getUpdateRect();
320 if( rect->contains( GLViewer_Pnt( myXhigh, myXhigh ) ) )
322 (*oit)->select( myXhigh, myYhigh, myTolerance, GLViewer_Rect(), false, byCircle, Append );
323 isSel = (*oit)->isSelected();
328 mySelectedObjects.append( myLastPicked );
329 myGLViewer2d->activateDrawer( myLastPicked, true, true );
330 status = SS_GlobalChanged;
339 /*! Selects objects on scene by rectangle
340 \param theRect - rectangle of selection
341 \param Append - true if new selection will be append to existing selection, false - another
342 function search object rectangle which intersect with theRect and call object select method
344 int GLViewer_Context::SelectByRect( const QRect& theRect, bool Append )
348 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )myGLViewer2d->getActiveView()->getViewPort();
349 vp->getScale( aXScale, aYScale );
351 SelectionStatus status = SS_NoChanged;
354 ObjList::Iterator it, itEnd;
356 if ( !mySFlag || myActiveObjects.empty() )
359 bool updateAll = false;
362 if( mySelectedObjects.count() != 0 )
363 status = SS_GlobalChanged;
365 for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end(); it != itEnd; ++it )
367 updateAll = (*it)->unselect() || updateAll;
370 mySelectedObjects.clear();
373 for( it = myActiveObjects.begin(), itEnd = myActiveObjects.end(); it != itEnd; ++it )
376 (*it)->setScale( aXScale, aYScale );
377 QRect rect = myGLViewer2d->getQRect( *( (*it)->getRect() ) );
379 if( rect.intersects( theRect ) )
381 GLViewer_Rect aRect = myGLViewer2d->getGLVRect( theRect );
382 (*it)->select( myXhigh, myYhigh, myTolerance, aRect, false, false, Append );
383 isSel = (*it)->isSelected();
386 if( isSel && mySelectedObjects.indexOf( *it ) == -1 )
389 mySelectedObjects.append( *it );
390 status = SS_GlobalChanged;
394 if( updateAll || myUpdateAll )
395 myGLViewer2d->updateAll();
397 myGLViewer2d->activateDrawers( aList, true, true );
403 Sets color of hilighting
404 \param aCol - new color of highlighting
406 void GLViewer_Context::SetHighlightColor( Quantity_NameOfColor aCol )
408 myHighlightColor = aCol;
410 Quantity_Color colorH( aCol );
411 int redH = 255 * (int)colorH.Red();
412 int greenH = 255 * (int)colorH.Green();
413 int blueH = 255 * (int)colorH.Blue();
414 QColor colH = QColor( redH, greenH, blueH );
416 Quantity_Color colorS( mySelectionColor );
417 int redS = 255 * (int)colorS.Red();
418 int greenS = 255 * (int)colorS.Green();
419 int blueS = 255 * (int)colorS.Blue();
420 QColor colS = QColor( redS, greenS, blueS );
422 myGLViewer2d->updateColors( colH, colS);
426 Sets color of selection
427 \param aCol - new color of selection
429 void GLViewer_Context::SetSelectionColor( Quantity_NameOfColor aCol )
431 mySelectionColor = aCol;
433 Quantity_Color colorH( myHighlightColor );
434 int redH = 255 * (int)colorH.Red();
435 int greenH = 255 * (int)colorH.Green();
436 int blueH = 255 * (int)colorH.Blue();
437 QColor colH = QColor( redH, greenH, blueH );
439 Quantity_Color colorS( aCol );
440 int redS = 255 * (int)colorS.Red();
441 int greenS = 255 * (int)colorS.Green();
442 int blueS = 255 * (int)colorS.Blue();
443 QColor colS = QColor( redS, greenS, blueS );
445 myGLViewer2d->updateColors( colH, colS);
449 \return number of selected objects
451 int GLViewer_Context::NbSelected()
453 return mySelectedObjects.count();
457 Inits iteration through selected objects
459 void GLViewer_Context::InitSelected()
465 Checks if iteration through selected objects may be continued
467 bool GLViewer_Context::MoreSelected()
469 return ( mySelCurIndex < NbSelected() );
473 Iterates to next selected object
475 bool GLViewer_Context::NextSelected()
477 if ( mySelCurIndex >= 0 && mySelCurIndex < NbSelected() )
487 \return current selected object (must be used only in cycle as "for( InitSelected(); MoreSelected(); NextSelected() ) {...}" )
489 GLViewer_Object* GLViewer_Context::SelectedObject()
491 return mySelectedObjects[ mySelCurIndex ];
495 \return true if object is selected
496 \param theObj - object to be checked
498 bool GLViewer_Context::isSelected( GLViewer_Object* theObj )
500 return mySelectedObjects.contains( theObj );
503 /*! Inserts new object in context
504 \param theObject - object to be inserted
505 \param display - true if needs display object immediatly after inserting, else false
506 \param isActive - true if needs inserting object in active list
508 int GLViewer_Context::insertObject( GLViewer_Object* object, bool display, bool isActive )
510 // cout << "GLViewer_Context::insertObject" << endl;
517 myActiveObjects.append( object );
520 //QRect* rect = object->getRect()->toQRect();
521 //myGLViewer2d->updateBorders( *rect );
522 myGLViewer2d->activateDrawer( object, false );
526 myInactiveObjects.append( object );
528 return myActiveObjects.count() + myInactiveObjects.count();
532 Replaces object in context
533 \param oldObject - object to be replaced
534 \param newObject - object for replacing
536 bool GLViewer_Context::replaceObject( GLViewer_Object* oldObject, GLViewer_Object* newObject )
538 if( !oldObject || !newObject )
541 if( myActiveObjects.contains( oldObject ) )
543 myActiveObjects.removeAll( oldObject );
544 myActiveObjects.append( newObject );
548 if( myInactiveObjects.contains( oldObject ) )
550 myInactiveObjects.removeAll( oldObject );
551 myInactiveObjects.append( newObject );
559 Updates scales of all objects in context
561 void GLViewer_Context::updateScales( GLfloat scX, GLfloat scY )
563 if( scX <= 0 || scY <= 0 )
566 ObjList::iterator it, itEnd;
568 for( it = myActiveObjects.begin(), itEnd = myActiveObjects.end(); it != itEnd; ++it )
569 (*it)->setScale( scX, scY );
571 for( it = myInactiveObjects.begin(), itEnd = myInactiveObjects.end(); it != itEnd; ++it )
572 (*it)->setScale( scX, scY );
576 Clears hilighting of objects
577 \param updateViewer - if it is true, viewer must be updated
579 void GLViewer_Context::clearHighlighted( bool updateViewer )
581 if( myHFlag && myLastPicked )
583 myLastPicked->unhighlight();
587 myGLViewer2d->updateAll();
592 Clears selection of objects
593 \param updateViewer - if it is true, viewer must be updated
595 void GLViewer_Context::clearSelected( bool updateViewer )
600 ObjList::Iterator it, itEnd;
603 for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end(); it != itEnd; ++it )
610 myGLViewer2d->activateDrawers( aList, true );
611 mySelectedObjects.clear();
615 Selects object, other selected objects are left as selected
616 \param updateViewer - if it is true, viewer must be updated
618 void GLViewer_Context::setSelected( GLViewer_Object* object, bool updateViewer )
623 if( myActiveObjects.contains( object ) && !mySelectedObjects.contains( object ) )
625 object->setSelected( true );
626 mySelectedObjects.append( object );
630 myGLViewer2d->activateDrawer( object, true, true );
634 Unselects object, other selected objects are left as selected
635 \param updateViewer - if it is true, viewer must be updated
637 void GLViewer_Context::remSelected( GLViewer_Object* object, bool updateViewer )
639 if( !object || !mySelectedObjects.contains( object ) )
642 mySelectedObjects.removeAll( object );
646 myGLViewer2d->activateDrawer( object, true, true );
650 Erases object in viewer
651 \param theUpdateViewer - if it is true, viewer must be updated
653 void GLViewer_Context::eraseObject( GLViewer_Object* theObject, bool theUpdateViewer )
655 if( !theObject || !myActiveObjects.contains( theObject ) )
658 theObject->unhighlight();
659 theObject->unselect();
660 theObject->setVisible( false );
662 if( theUpdateViewer )
663 myGLViewer2d->updateAll();
668 \param updateViewer - if it is true, viewer must be updated
670 void GLViewer_Context::deleteObject( GLViewer_Object* theObject, bool updateViewer )
673 ( !myActiveObjects.contains( theObject ) && !myInactiveObjects.contains( theObject ) ) )
676 if( myActiveObjects.contains( theObject ) )
677 myActiveObjects.removeAll( theObject );
678 else if( myInactiveObjects.contains( theObject ) )
679 myInactiveObjects.removeAll( theObject );
683 if( mySelectedObjects.contains( theObject ) )
684 mySelectedObjects.removeAll( theObject );
686 GLViewer_Group* aGroup = theObject->getGroup();
688 aGroup->removeObject( theObject );
690 if( myLastPicked == theObject )
694 myGLViewer2d->updateAll();
698 Installs active status to object
701 bool GLViewer_Context::setActive( GLViewer_Object* theObject )
703 if( !theObject || !myInactiveObjects.contains( theObject ) )
706 myInactiveObjects.removeAll( theObject );
707 myActiveObjects.append( theObject );
712 Installs inactive status to object
715 bool GLViewer_Context::setInactive( GLViewer_Object* theObject )
717 if( !theObject || !myActiveObjects.contains( theObject ) )
720 myActiveObjects.removeAll( theObject );
721 myInactiveObjects.append( theObject );