1 // Copyright (C) 2005 OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
19 // Author : OPEN CASCADE
22 // File: GLViewer_Context.cxx
23 // Created: November, 2004
26 \class GLViewer_AspectLine
27 \brief Class for manage of presentations in GLViewer
30 #include "GLViewer_Context.h"
32 #include "GLViewer_Group.h"
33 #include "GLViewer_Object.h"
34 #include "GLViewer_Viewer2d.h"
35 #include "GLViewer_ViewPort2d.h"
37 #include <TColStd_SequenceOfInteger.hxx>
44 GLViewer_Context::GLViewer_Context( GLViewer_Viewer2d* v ) :
46 myHighlightColor( Quantity_NOC_CYAN1 ),
47 mySelectionColor( Quantity_NOC_RED ),
48 myTolerance( TOLERANCE )
53 myLastPickedChanged = false;
64 GLViewer_Context::~GLViewer_Context()
66 myActiveObjects.clear();
67 myInactiveObjects.clear();
68 mySelectedObjects.clear();
72 Hiilights objects under cursor
73 \param x - X coord of mouse cursor
74 \param y - Y coord of mouse cursor
75 \param byCircle - true if needs round sensitive area around mouse cursor, else rectangle
76 function search object rectangle which intersect with sensitive area and call object highlight method
78 int GLViewer_Context::MoveTo( int xi, int yi, bool byCircle )
80 GLfloat x = (GLfloat)xi;
81 GLfloat y = (GLfloat)yi;
82 myGLViewer2d->transPoint( x, y );
87 GLboolean isHigh = GL_FALSE;
88 GLboolean onObject = GL_FALSE;
90 GLViewer_Object* aPrevLastPicked = myLastPicked;
91 GLViewer_Object* lastPicked = 0;
93 ObjList anUpdatedObjects;
95 if( myActiveObjects.isEmpty() )
98 ObjList::iterator it = myActiveObjects.end();
99 ObjList::iterator itEnd = myActiveObjects.begin();
102 GLViewer_Object* object = *it;
104 GLViewer_Rect* rect = object->getUpdateRect();
105 if( rect->contains( GLViewer_Pnt( x, y ) ) )
108 object->highlight( x, y, myTolerance, GL_FALSE );
109 isHigh = object->isHighlighted();
124 myLastPicked = lastPicked;
131 it = myActiveObjects.begin();
132 itEnd = myActiveObjects.end();
134 for( ; it != itEnd; ++it )
135 (*it)->unhighlight();
137 anUpdatedObjects.append( (*it) );
140 myLastPickedChanged = aPrevLastPicked != myLastPicked;
142 if( myLastPickedChanged )
143 myGLViewer2d->updateAll();
148 if( !myLastPicked && isHigh )
151 myLastPicked = lastPicked;
152 anUpdatedObjects.append( myLastPicked );
154 else if( myLastPicked && !isHigh )
157 myLastPicked->unhighlight();
158 anUpdatedObjects.append( myLastPicked );
161 else if( myLastPicked && isHigh )
164 myLastPicked->highlight( x, y, myTolerance, byCircle );
165 anUpdatedObjects.append( myLastPicked );
166 if( myLastPicked != lastPicked )
168 myLastPicked->unhighlight();
169 myLastPicked = lastPicked;
170 anUpdatedObjects.append( myLastPicked );
174 myLastPickedChanged = ( aPrevLastPicked != myLastPicked );
176 if( myLastPickedChanged || myUpdateAll )
177 myGLViewer2d->updateAll();
179 myGLViewer2d->activateDrawers( anUpdatedObjects, TRUE, TRUE );
184 /*! Selects already highlighting object by calling object method select
185 \param Append - true if new selection will be append to existing selection, false - another
186 \param byCircle - true if needs round selection area in complex object
188 int GLViewer_Context::Select( bool Append, bool byCircle )
190 ObjList::Iterator it, itEnd, oit, oitEnd;
191 SelectionStatus status = SS_Invalid;
193 bool updateAll = false;
198 return status;//invalid
200 if( myHFlag && myLastPicked )
202 if( mySelectedObjects.count() == 1 && mySelectedObjects.first() == myLastPicked )
203 status = SS_LocalChanged;
207 for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end() ; it != itEnd; ++it )
208 if( myLastPicked != *it )
210 updateAll = (*it)->unselect() || updateAll;
214 if( updateAll || myUpdateAll )
215 myGLViewer2d->updateAll();
217 myGLViewer2d->activateDrawers( aList, TRUE, TRUE );
219 if( mySelectedObjects.count() != 0 && status == SS_Invalid )
220 status = SS_GlobalChanged;
221 mySelectedObjects.clear();
223 else if( myLastPicked->isSelected() && status != SS_LocalChanged )
225 mySelectedObjects.remove( myLastPicked );
226 myLastPicked->unselect();
227 myGLViewer2d->updateAll();
229 if( mySelectedObjects.count() != 0 && status == SS_Invalid )
230 status = SS_GlobalChanged;
235 if ( myLastPicked->select( myXhigh, myYhigh, myTolerance, GLViewer_Rect(), false, byCircle, Append )
236 && mySelectedObjects.findIndex( myLastPicked ) == -1 )
238 mySelectedObjects.append( myLastPicked );
239 myGLViewer2d->activateDrawer( myLastPicked, TRUE, TRUE );
241 if( status == SS_Invalid )
242 status = SS_GlobalChanged;
244 else if( status == SS_LocalChanged )
245 status = SS_GlobalChanged;
250 if( myHFlag && !myLastPicked )
254 for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end() ; it != itEnd; ++it )
255 if ( myLastPicked != *it )
257 updateAll = (*it)->unselect() || updateAll;
261 if( updateAll || myUpdateAll )
262 myGLViewer2d->updateAll();
264 myGLViewer2d->activateDrawers( aList, TRUE, TRUE );
266 if( mySelectedObjects.count() != 0 )
267 status = SS_GlobalChanged;
269 mySelectedObjects.clear();
279 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )myGLViewer2d->getActiveView()->getViewPort();
280 vp->getScale( aXScale, aYScale );
284 for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end() ; it != itEnd; ++it )
285 if( myLastPicked != *it )
287 updateAll = (*it)->unselect() || updateAll;
291 if( updateAll || myUpdateAll )
292 myGLViewer2d->updateAll();
294 myGLViewer2d->activateDrawers( aList, TRUE, TRUE );
296 if( mySelectedObjects.count() != 0 )
297 status = SS_GlobalChanged;
299 mySelectedObjects.clear();
302 for( oit = myActiveObjects.begin(), oitEnd = myActiveObjects.end(); oit != oitEnd; ++oit )
304 (*oit)->setScale( aXScale, aYScale );
305 GLViewer_Rect* rect = (*oit)->getUpdateRect();
307 if( rect->contains( GLViewer_Pnt( myXhigh, myXhigh ) ) )
309 (*oit)->select( myXhigh, myYhigh, myTolerance, GLViewer_Rect(), false, byCircle, Append );
310 isSel = (*oit)->isSelected();
315 mySelectedObjects.append( myLastPicked );
316 myGLViewer2d->activateDrawer( myLastPicked, TRUE, TRUE );
317 status = SS_GlobalChanged;
326 /*! Selects objects on scene by rectangle
327 \param theRect - rectangle of selection
328 \param Append - true if new selection will be append to existing selection, false - another
329 function search object rectangle which intersect with theRect and call object select method
331 int GLViewer_Context::SelectByRect( const QRect& theRect, bool Append )
335 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )myGLViewer2d->getActiveView()->getViewPort();
336 vp->getScale( aXScale, aYScale );
338 SelectionStatus status = SS_NoChanged;
341 ObjList::Iterator it, itEnd;
343 if ( !mySFlag || myActiveObjects.empty() )
346 bool updateAll = false;
349 if( mySelectedObjects.count() != 0 )
350 status = SS_GlobalChanged;
352 for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end(); it != itEnd; ++it )
354 updateAll = (*it)->unselect() || updateAll;
357 mySelectedObjects.clear();
360 for( it = myActiveObjects.begin(), itEnd = myActiveObjects.end(); it != itEnd; ++it )
363 (*it)->setScale( aXScale, aYScale );
364 QRect rect = myGLViewer2d->getQRect( *( (*it)->getRect() ) );
366 if( rect.intersects( theRect ) )
368 GLViewer_Rect aRect = myGLViewer2d->getGLVRect( theRect );
369 (*it)->select( myXhigh, myYhigh, myTolerance, aRect, false, false, Append );
370 isSel = (*it)->isSelected();
373 if( isSel && mySelectedObjects.findIndex( *it ) == -1 )
376 mySelectedObjects.append( *it );
377 status = SS_GlobalChanged;
381 if( updateAll || myUpdateAll )
382 myGLViewer2d->updateAll();
384 myGLViewer2d->activateDrawers( aList, TRUE, TRUE );
390 Sets color of hilighting
391 \param aCol - new color of highlighting
393 void GLViewer_Context::SetHighlightColor( Quantity_NameOfColor aCol )
395 myHighlightColor = aCol;
397 Quantity_Color colorH( aCol );
398 int redH = 255 * (int)colorH.Red();
399 int greenH = 255 * (int)colorH.Green();
400 int blueH = 255 * (int)colorH.Blue();
401 QColor colH = QColor( redH, greenH, blueH );
403 Quantity_Color colorS( mySelectionColor );
404 int redS = 255 * (int)colorS.Red();
405 int greenS = 255 * (int)colorS.Green();
406 int blueS = 255 * (int)colorS.Blue();
407 QColor colS = QColor( redS, greenS, blueS );
409 myGLViewer2d->updateColors( colH, colS);
413 Sets color of selection
414 \param aCol - new color of selection
416 void GLViewer_Context::SetSelectionColor( Quantity_NameOfColor aCol )
418 mySelectionColor = aCol;
420 Quantity_Color colorH( myHighlightColor );
421 int redH = 255 * (int)colorH.Red();
422 int greenH = 255 * (int)colorH.Green();
423 int blueH = 255 * (int)colorH.Blue();
424 QColor colH = QColor( redH, greenH, blueH );
426 Quantity_Color colorS( aCol );
427 int redS = 255 * (int)colorS.Red();
428 int greenS = 255 * (int)colorS.Green();
429 int blueS = 255 * (int)colorS.Blue();
430 QColor colS = QColor( redS, greenS, blueS );
432 myGLViewer2d->updateColors( colH, colS);
436 \return number of selected objects
438 int GLViewer_Context::NbSelected()
440 return mySelectedObjects.count();
444 Inits iteration through selected objects
446 void GLViewer_Context::InitSelected()
452 Checks if iteration through selected objects may be continued
454 bool GLViewer_Context::MoreSelected()
456 return ( mySelCurIndex < NbSelected() );
460 Iterates to next selected object
462 bool GLViewer_Context::NextSelected()
464 if ( mySelCurIndex >= 0 && mySelCurIndex < NbSelected() )
474 \return current selected object (must be used only in cycle as "for( InitSelected(); MoreSelected(); NextSelected() ) {...}" )
476 GLViewer_Object* GLViewer_Context::SelectedObject()
478 return mySelectedObjects[ mySelCurIndex ];
482 \return true if object is selected
483 \param theObj - object to be checked
485 bool GLViewer_Context::isSelected( GLViewer_Object* theObj )
487 return mySelectedObjects.contains( theObj );
490 /*! Inserts new object in context
491 \param theObject - object to be inserted
492 \param display - true if needs display object immediatly after inserting, else false
493 \param isActive - true if needs inserting object in active list
495 int GLViewer_Context::insertObject( GLViewer_Object* object, bool display, bool isActive )
497 // cout << "GLViewer_Context::insertObject" << endl;
504 myActiveObjects.append( object );
507 //QRect* rect = object->getRect()->toQRect();
508 //myGLViewer2d->updateBorders( *rect );
509 myGLViewer2d->activateDrawer( object, FALSE );
513 myInactiveObjects.append( object );
515 return myActiveObjects.count() + myInactiveObjects.count();
519 Replaces object in context
520 \param oldObject - object to be replaced
521 \param newObject - object for replacing
523 bool GLViewer_Context::replaceObject( GLViewer_Object* oldObject, GLViewer_Object* newObject )
525 if( !oldObject || !newObject )
528 if( myActiveObjects.contains( oldObject ) )
530 myActiveObjects.remove( oldObject );
531 myActiveObjects.append( newObject );
535 if( myInactiveObjects.contains( oldObject ) )
537 myInactiveObjects.remove( oldObject );
538 myInactiveObjects.append( newObject );
546 Updates scales of all objects in context
548 void GLViewer_Context::updateScales( GLfloat scX, GLfloat scY )
550 if( scX <= 0 || scY <= 0 )
553 ObjList::iterator it, itEnd;
555 for( it = myActiveObjects.begin(), itEnd = myActiveObjects.end(); it != itEnd; ++it )
556 (*it)->setScale( scX, scY );
558 for( it = myInactiveObjects.begin(), itEnd = myInactiveObjects.end(); it != itEnd; ++it )
559 (*it)->setScale( scX, scY );
563 Clears hilighting of objects
564 \param updateViewer - if it is true, viewer must be updated
566 void GLViewer_Context::clearHighlighted( bool updateViewer )
568 if( myHFlag && myLastPicked )
570 myLastPicked->unhighlight();
574 myGLViewer2d->updateAll();
579 Clears selection of objects
580 \param updateViewer - if it is true, viewer must be updated
582 void GLViewer_Context::clearSelected( bool updateViewer )
587 ObjList::Iterator it, itEnd;
590 for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end(); it != itEnd; ++it )
597 myGLViewer2d->activateDrawers( aList, TRUE );
598 mySelectedObjects.clear();
602 Selects object, other selected objects are left as selected
603 \param updateViewer - if it is true, viewer must be updated
605 void GLViewer_Context::setSelected( GLViewer_Object* object, bool updateViewer )
610 if( myActiveObjects.contains( object ) && !mySelectedObjects.contains( object ) )
612 object->setSelected( TRUE );
613 mySelectedObjects.append( object );
617 myGLViewer2d->activateDrawer( object, TRUE, TRUE );
621 Unselects object, other selected objects are left as selected
622 \param updateViewer - if it is true, viewer must be updated
624 void GLViewer_Context::remSelected( GLViewer_Object* object, bool updateViewer )
626 if( !object || !mySelectedObjects.contains( object ) )
629 mySelectedObjects.remove( object );
633 myGLViewer2d->activateDrawer( object, TRUE, TRUE );
637 Erases object in viewer
638 \param theUpdateViewer - if it is true, viewer must be updated
640 void GLViewer_Context::eraseObject( GLViewer_Object* theObject, bool theUpdateViewer )
642 if( !theObject || !myActiveObjects.contains( theObject ) )
645 theObject->unhighlight();
646 theObject->unselect();
647 theObject->setVisible( false );
649 if( theUpdateViewer )
650 myGLViewer2d->updateAll();
655 \param updateViewer - if it is true, viewer must be updated
657 void GLViewer_Context::deleteObject( GLViewer_Object* theObject, bool updateViewer )
660 ( !myActiveObjects.contains( theObject ) && !myInactiveObjects.contains( theObject ) ) )
663 if( myActiveObjects.contains( theObject ) )
664 myActiveObjects.remove( theObject );
665 else if( myInactiveObjects.contains( theObject ) )
666 myInactiveObjects.remove( theObject );
670 if( mySelectedObjects.contains( theObject ) )
671 mySelectedObjects.remove( theObject );
673 GLViewer_Group* aGroup = theObject->getGroup();
675 aGroup->removeObject( theObject );
677 if( myLastPicked == theObject )
681 myGLViewer2d->updateAll();
685 Installs active status to object
688 bool GLViewer_Context::setActive( GLViewer_Object* theObject )
690 if( !theObject || !myInactiveObjects.contains( theObject ) )
693 myInactiveObjects.remove( theObject );
694 myActiveObjects.append( theObject );
699 Installs inactive status to object
702 bool GLViewer_Context::setInactive( GLViewer_Object* theObject )
704 if( !theObject || !myActiveObjects.contains( theObject ) )
707 myActiveObjects.remove( theObject );
708 myInactiveObjects.append( theObject );