1 // Copyright (C) 2007-2008 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.
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
22 // Author : OPEN CASCADE
23 // File: GLViewer_Context.cxx
24 // Created: November, 2004
27 \class GLViewer_AspectLine
28 \brief Class for manage of presentations in GLViewer
31 #include "GLViewer_Context.h"
33 #include "GLViewer_Group.h"
34 #include "GLViewer_Object.h"
35 #include "GLViewer_Viewer2d.h"
36 #include "GLViewer_ViewPort2d.h"
37 #include "GLViewer_ViewFrame.h"
42 #include <TColStd_SequenceOfInteger.hxx>
49 GLViewer_Context::GLViewer_Context( GLViewer_Viewer2d* v ) :
51 myHighlightColor( Quantity_NOC_CYAN1 ),
52 mySelectionColor( Quantity_NOC_RED ),
53 myTolerance( TOLERANCE )
58 myLastPickedChanged = false;
69 GLViewer_Context::~GLViewer_Context()
71 myActiveObjects.clear();
72 myInactiveObjects.clear();
73 mySelectedObjects.clear();
77 Hiilights objects under cursor
78 \param x - X coord of mouse cursor
79 \param y - Y coord of mouse cursor
80 \param byCircle - true if needs round sensitive area around mouse cursor, else rectangle
81 function search object rectangle which intersect with sensitive area and call object highlight method
83 int GLViewer_Context::MoveTo( int xi, int yi, bool byCircle )
85 GLfloat x = (GLfloat)xi;
86 GLfloat y = (GLfloat)yi;
87 myGLViewer2d->transPoint( x, y );
92 GLboolean isHigh = GL_FALSE;
93 GLboolean onObject = GL_FALSE;
95 GLViewer_Object* aPrevLastPicked = myLastPicked;
96 GLViewer_Object* lastPicked = 0;
98 ObjList anUpdatedObjects;
100 if( myActiveObjects.isEmpty() )
103 ObjList::iterator it = myActiveObjects.end();
104 ObjList::iterator itEnd = myActiveObjects.begin();
107 GLViewer_Object* object = *it;
109 GLViewer_Rect* rect = object->getUpdateRect();
110 if( rect->contains( GLViewer_Pnt( x, y ) ) )
113 object->highlight( x, y, myTolerance, GL_FALSE );
114 isHigh = object->isHighlighted();
129 myLastPicked = lastPicked;
136 it = myActiveObjects.begin();
137 itEnd = myActiveObjects.end();
139 for( ; it != itEnd; ++it )
140 (*it)->unhighlight();
142 anUpdatedObjects.append( (*it) );
145 myLastPickedChanged = aPrevLastPicked != myLastPicked;
147 if( myLastPickedChanged )
148 myGLViewer2d->updateAll();
153 if( !myLastPicked && isHigh )
156 myLastPicked = lastPicked;
157 anUpdatedObjects.append( myLastPicked );
159 else if( myLastPicked && !isHigh )
162 myLastPicked->unhighlight();
163 anUpdatedObjects.append( myLastPicked );
166 else if( myLastPicked && isHigh )
169 myLastPicked->highlight( x, y, myTolerance, byCircle );
170 anUpdatedObjects.append( myLastPicked );
171 if( myLastPicked != lastPicked )
173 myLastPicked->unhighlight();
174 myLastPicked = lastPicked;
175 anUpdatedObjects.append( myLastPicked );
179 myLastPickedChanged = ( aPrevLastPicked != myLastPicked );
181 if( myLastPickedChanged || myUpdateAll )
182 myGLViewer2d->updateAll();
184 myGLViewer2d->activateDrawers( anUpdatedObjects, TRUE, TRUE );
189 /*! Selects already highlighting object by calling object method select
190 \param Append - true if new selection will be append to existing selection, false - another
191 \param byCircle - true if needs round selection area in complex object
193 int GLViewer_Context::Select( bool Append, bool byCircle )
195 ObjList::Iterator it, itEnd, oit, oitEnd;
196 SelectionStatus status = SS_Invalid;
198 bool updateAll = false;
203 return status;//invalid
205 if( myHFlag && myLastPicked )
207 if( mySelectedObjects.count() == 1 && mySelectedObjects.first() == myLastPicked )
208 status = SS_LocalChanged;
212 for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end() ; it != itEnd; ++it )
213 if( myLastPicked != *it )
215 updateAll = (*it)->unselect() || updateAll;
219 if( updateAll || myUpdateAll )
220 myGLViewer2d->updateAll();
222 myGLViewer2d->activateDrawers( aList, TRUE, TRUE );
224 if( mySelectedObjects.count() != 0 && status == SS_Invalid )
225 status = SS_GlobalChanged;
226 mySelectedObjects.clear();
228 else if( myLastPicked->isSelected() && status != SS_LocalChanged )
230 mySelectedObjects.removeAll( myLastPicked );
231 myLastPicked->unselect();
232 myGLViewer2d->updateAll();
234 if( mySelectedObjects.count() != 0 && status == SS_Invalid )
235 status = SS_GlobalChanged;
240 if ( myLastPicked->select( myXhigh, myYhigh, myTolerance, GLViewer_Rect(), false, byCircle, Append )
241 && mySelectedObjects.indexOf( myLastPicked ) == -1 )
243 mySelectedObjects.append( myLastPicked );
244 myGLViewer2d->activateDrawer( myLastPicked, TRUE, TRUE );
246 if( status == SS_Invalid )
247 status = SS_GlobalChanged;
249 else if( status == SS_LocalChanged )
250 status = SS_GlobalChanged;
255 if( myHFlag && !myLastPicked )
259 for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end() ; it != itEnd; ++it )
260 if ( myLastPicked != *it )
262 updateAll = (*it)->unselect() || updateAll;
266 if( updateAll || myUpdateAll )
267 myGLViewer2d->updateAll();
269 myGLViewer2d->activateDrawers( aList, TRUE, TRUE );
271 if( mySelectedObjects.count() != 0 )
272 status = SS_GlobalChanged;
274 mySelectedObjects.clear();
284 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )myGLViewer2d->getActiveView()->getViewPort();
285 vp->getScale( aXScale, aYScale );
289 for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end() ; it != itEnd; ++it )
290 if( myLastPicked != *it )
292 updateAll = (*it)->unselect() || updateAll;
296 if( updateAll || myUpdateAll )
297 myGLViewer2d->updateAll();
299 myGLViewer2d->activateDrawers( aList, TRUE, TRUE );
301 if( mySelectedObjects.count() != 0 )
302 status = SS_GlobalChanged;
304 mySelectedObjects.clear();
307 for( oit = myActiveObjects.begin(), oitEnd = myActiveObjects.end(); oit != oitEnd; ++oit )
309 (*oit)->setScale( aXScale, aYScale );
310 GLViewer_Rect* rect = (*oit)->getUpdateRect();
312 if( rect->contains( GLViewer_Pnt( myXhigh, myXhigh ) ) )
314 (*oit)->select( myXhigh, myYhigh, myTolerance, GLViewer_Rect(), false, byCircle, Append );
315 isSel = (*oit)->isSelected();
320 mySelectedObjects.append( myLastPicked );
321 myGLViewer2d->activateDrawer( myLastPicked, TRUE, TRUE );
322 status = SS_GlobalChanged;
331 /*! Selects objects on scene by rectangle
332 \param theRect - rectangle of selection
333 \param Append - true if new selection will be append to existing selection, false - another
334 function search object rectangle which intersect with theRect and call object select method
336 int GLViewer_Context::SelectByRect( const QRect& theRect, bool Append )
340 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )myGLViewer2d->getActiveView()->getViewPort();
341 vp->getScale( aXScale, aYScale );
343 SelectionStatus status = SS_NoChanged;
346 ObjList::Iterator it, itEnd;
348 if ( !mySFlag || myActiveObjects.empty() )
351 bool updateAll = false;
354 if( mySelectedObjects.count() != 0 )
355 status = SS_GlobalChanged;
357 for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end(); it != itEnd; ++it )
359 updateAll = (*it)->unselect() || updateAll;
362 mySelectedObjects.clear();
365 for( it = myActiveObjects.begin(), itEnd = myActiveObjects.end(); it != itEnd; ++it )
368 (*it)->setScale( aXScale, aYScale );
369 QRect rect = myGLViewer2d->getQRect( *( (*it)->getRect() ) );
371 if( rect.intersects( theRect ) )
373 GLViewer_Rect aRect = myGLViewer2d->getGLVRect( theRect );
374 (*it)->select( myXhigh, myYhigh, myTolerance, aRect, false, false, Append );
375 isSel = (*it)->isSelected();
378 if( isSel && mySelectedObjects.indexOf( *it ) == -1 )
381 mySelectedObjects.append( *it );
382 status = SS_GlobalChanged;
386 if( updateAll || myUpdateAll )
387 myGLViewer2d->updateAll();
389 myGLViewer2d->activateDrawers( aList, TRUE, TRUE );
395 Sets color of hilighting
396 \param aCol - new color of highlighting
398 void GLViewer_Context::SetHighlightColor( Quantity_NameOfColor aCol )
400 myHighlightColor = aCol;
402 Quantity_Color colorH( aCol );
403 int redH = 255 * (int)colorH.Red();
404 int greenH = 255 * (int)colorH.Green();
405 int blueH = 255 * (int)colorH.Blue();
406 QColor colH = QColor( redH, greenH, blueH );
408 Quantity_Color colorS( mySelectionColor );
409 int redS = 255 * (int)colorS.Red();
410 int greenS = 255 * (int)colorS.Green();
411 int blueS = 255 * (int)colorS.Blue();
412 QColor colS = QColor( redS, greenS, blueS );
414 myGLViewer2d->updateColors( colH, colS);
418 Sets color of selection
419 \param aCol - new color of selection
421 void GLViewer_Context::SetSelectionColor( Quantity_NameOfColor aCol )
423 mySelectionColor = aCol;
425 Quantity_Color colorH( myHighlightColor );
426 int redH = 255 * (int)colorH.Red();
427 int greenH = 255 * (int)colorH.Green();
428 int blueH = 255 * (int)colorH.Blue();
429 QColor colH = QColor( redH, greenH, blueH );
431 Quantity_Color colorS( aCol );
432 int redS = 255 * (int)colorS.Red();
433 int greenS = 255 * (int)colorS.Green();
434 int blueS = 255 * (int)colorS.Blue();
435 QColor colS = QColor( redS, greenS, blueS );
437 myGLViewer2d->updateColors( colH, colS);
441 \return number of selected objects
443 int GLViewer_Context::NbSelected()
445 return mySelectedObjects.count();
449 Inits iteration through selected objects
451 void GLViewer_Context::InitSelected()
457 Checks if iteration through selected objects may be continued
459 bool GLViewer_Context::MoreSelected()
461 return ( mySelCurIndex < NbSelected() );
465 Iterates to next selected object
467 bool GLViewer_Context::NextSelected()
469 if ( mySelCurIndex >= 0 && mySelCurIndex < NbSelected() )
479 \return current selected object (must be used only in cycle as "for( InitSelected(); MoreSelected(); NextSelected() ) {...}" )
481 GLViewer_Object* GLViewer_Context::SelectedObject()
483 return mySelectedObjects[ mySelCurIndex ];
487 \return true if object is selected
488 \param theObj - object to be checked
490 bool GLViewer_Context::isSelected( GLViewer_Object* theObj )
492 return mySelectedObjects.contains( theObj );
495 /*! Inserts new object in context
496 \param theObject - object to be inserted
497 \param display - true if needs display object immediatly after inserting, else false
498 \param isActive - true if needs inserting object in active list
500 int GLViewer_Context::insertObject( GLViewer_Object* object, bool display, bool isActive )
502 // cout << "GLViewer_Context::insertObject" << endl;
509 myActiveObjects.append( object );
512 //QRect* rect = object->getRect()->toQRect();
513 //myGLViewer2d->updateBorders( *rect );
514 myGLViewer2d->activateDrawer( object, FALSE );
518 myInactiveObjects.append( object );
520 return myActiveObjects.count() + myInactiveObjects.count();
524 Replaces object in context
525 \param oldObject - object to be replaced
526 \param newObject - object for replacing
528 bool GLViewer_Context::replaceObject( GLViewer_Object* oldObject, GLViewer_Object* newObject )
530 if( !oldObject || !newObject )
533 if( myActiveObjects.contains( oldObject ) )
535 myActiveObjects.removeAll( oldObject );
536 myActiveObjects.append( newObject );
540 if( myInactiveObjects.contains( oldObject ) )
542 myInactiveObjects.removeAll( oldObject );
543 myInactiveObjects.append( newObject );
551 Updates scales of all objects in context
553 void GLViewer_Context::updateScales( GLfloat scX, GLfloat scY )
555 if( scX <= 0 || scY <= 0 )
558 ObjList::iterator it, itEnd;
560 for( it = myActiveObjects.begin(), itEnd = myActiveObjects.end(); it != itEnd; ++it )
561 (*it)->setScale( scX, scY );
563 for( it = myInactiveObjects.begin(), itEnd = myInactiveObjects.end(); it != itEnd; ++it )
564 (*it)->setScale( scX, scY );
568 Clears hilighting of objects
569 \param updateViewer - if it is true, viewer must be updated
571 void GLViewer_Context::clearHighlighted( bool updateViewer )
573 if( myHFlag && myLastPicked )
575 myLastPicked->unhighlight();
579 myGLViewer2d->updateAll();
584 Clears selection of objects
585 \param updateViewer - if it is true, viewer must be updated
587 void GLViewer_Context::clearSelected( bool updateViewer )
592 ObjList::Iterator it, itEnd;
595 for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end(); it != itEnd; ++it )
602 myGLViewer2d->activateDrawers( aList, TRUE );
603 mySelectedObjects.clear();
607 Selects object, other selected objects are left as selected
608 \param updateViewer - if it is true, viewer must be updated
610 void GLViewer_Context::setSelected( GLViewer_Object* object, bool updateViewer )
615 if( myActiveObjects.contains( object ) && !mySelectedObjects.contains( object ) )
617 object->setSelected( TRUE );
618 mySelectedObjects.append( object );
622 myGLViewer2d->activateDrawer( object, TRUE, TRUE );
626 Unselects object, other selected objects are left as selected
627 \param updateViewer - if it is true, viewer must be updated
629 void GLViewer_Context::remSelected( GLViewer_Object* object, bool updateViewer )
631 if( !object || !mySelectedObjects.contains( object ) )
634 mySelectedObjects.removeAll( object );
638 myGLViewer2d->activateDrawer( object, TRUE, TRUE );
642 Erases object in viewer
643 \param theUpdateViewer - if it is true, viewer must be updated
645 void GLViewer_Context::eraseObject( GLViewer_Object* theObject, bool theUpdateViewer )
647 if( !theObject || !myActiveObjects.contains( theObject ) )
650 theObject->unhighlight();
651 theObject->unselect();
652 theObject->setVisible( false );
654 if( theUpdateViewer )
655 myGLViewer2d->updateAll();
660 \param updateViewer - if it is true, viewer must be updated
662 void GLViewer_Context::deleteObject( GLViewer_Object* theObject, bool updateViewer )
665 ( !myActiveObjects.contains( theObject ) && !myInactiveObjects.contains( theObject ) ) )
668 if( myActiveObjects.contains( theObject ) )
669 myActiveObjects.removeAll( theObject );
670 else if( myInactiveObjects.contains( theObject ) )
671 myInactiveObjects.removeAll( theObject );
675 if( mySelectedObjects.contains( theObject ) )
676 mySelectedObjects.removeAll( theObject );
678 GLViewer_Group* aGroup = theObject->getGroup();
680 aGroup->removeObject( theObject );
682 if( myLastPicked == theObject )
686 myGLViewer2d->updateAll();
690 Installs active status to object
693 bool GLViewer_Context::setActive( GLViewer_Object* theObject )
695 if( !theObject || !myInactiveObjects.contains( theObject ) )
698 myInactiveObjects.removeAll( theObject );
699 myActiveObjects.append( theObject );
704 Installs inactive status to object
707 bool GLViewer_Context::setInactive( GLViewer_Object* theObject )
709 if( !theObject || !myActiveObjects.contains( theObject ) )
712 myActiveObjects.removeAll( theObject );
713 myInactiveObjects.append( theObject );