1 // Copyright (C) 2007-2014 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, 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( rect->contains( GLViewer_Pnt( x, y ) ) )
114 object->highlight( x, y, myTolerance, GL_FALSE );
115 isHigh = object->isHighlighted();
130 myLastPicked = lastPicked;
137 it = myActiveObjects.begin();
138 itEnd = myActiveObjects.end();
140 for( ; it != itEnd; ++it )
141 (*it)->unhighlight();
143 anUpdatedObjects.append( (*it) );
146 myLastPickedChanged = aPrevLastPicked != myLastPicked;
148 if( myLastPickedChanged )
149 myGLViewer2d->updateAll();
154 if( !myLastPicked && isHigh )
157 myLastPicked = lastPicked;
158 anUpdatedObjects.append( myLastPicked );
160 else if( myLastPicked && !isHigh )
163 myLastPicked->unhighlight();
164 anUpdatedObjects.append( myLastPicked );
167 else if( myLastPicked && isHigh )
170 myLastPicked->highlight( x, y, myTolerance, byCircle );
171 anUpdatedObjects.append( myLastPicked );
172 if( myLastPicked != lastPicked )
174 myLastPicked->unhighlight();
175 myLastPicked = lastPicked;
176 anUpdatedObjects.append( myLastPicked );
180 myLastPickedChanged = ( aPrevLastPicked != myLastPicked );
182 if( myLastPickedChanged || myUpdateAll )
183 myGLViewer2d->updateAll();
185 myGLViewer2d->activateDrawers( anUpdatedObjects, TRUE, TRUE );
190 /*! Selects already highlighting object by calling object method select
191 \param Append - true if new selection will be append to existing selection, false - another
192 \param byCircle - true if needs round selection area in complex object
194 int GLViewer_Context::Select( bool Append, bool byCircle )
196 ObjList::Iterator it, itEnd, oit, oitEnd;
197 SelectionStatus status = SS_Invalid;
199 bool updateAll = false;
204 return status;//invalid
206 if( myHFlag && myLastPicked )
208 if( mySelectedObjects.count() == 1 && mySelectedObjects.first() == myLastPicked )
209 status = SS_LocalChanged;
213 for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end() ; it != itEnd; ++it )
214 if( myLastPicked != *it )
216 updateAll = (*it)->unselect() || updateAll;
220 if( updateAll || myUpdateAll )
221 myGLViewer2d->updateAll();
223 myGLViewer2d->activateDrawers( aList, TRUE, TRUE );
225 if( mySelectedObjects.count() != 0 && status == SS_Invalid )
226 status = SS_GlobalChanged;
227 mySelectedObjects.clear();
229 else if( myLastPicked->isSelected() && status != SS_LocalChanged )
231 mySelectedObjects.removeAll( myLastPicked );
232 myLastPicked->unselect();
233 myGLViewer2d->updateAll();
235 if( mySelectedObjects.count() != 0 && status == SS_Invalid )
236 status = SS_GlobalChanged;
241 if ( myLastPicked->select( myXhigh, myYhigh, myTolerance, GLViewer_Rect(), false, byCircle, Append )
242 && mySelectedObjects.indexOf( myLastPicked ) == -1 )
244 mySelectedObjects.append( myLastPicked );
245 myGLViewer2d->activateDrawer( myLastPicked, TRUE, TRUE );
247 if( status == SS_Invalid )
248 status = SS_GlobalChanged;
250 else if( status == SS_LocalChanged )
251 status = SS_GlobalChanged;
256 if( myHFlag && !myLastPicked )
260 for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end() ; it != itEnd; ++it )
261 if ( myLastPicked != *it )
263 updateAll = (*it)->unselect() || updateAll;
267 if( updateAll || myUpdateAll )
268 myGLViewer2d->updateAll();
270 myGLViewer2d->activateDrawers( aList, TRUE, TRUE );
272 if( mySelectedObjects.count() != 0 )
273 status = SS_GlobalChanged;
275 mySelectedObjects.clear();
285 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )myGLViewer2d->getActiveView()->getViewPort();
286 vp->getScale( aXScale, aYScale );
290 for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end() ; it != itEnd; ++it )
291 if( myLastPicked != *it )
293 updateAll = (*it)->unselect() || updateAll;
297 if( updateAll || myUpdateAll )
298 myGLViewer2d->updateAll();
300 myGLViewer2d->activateDrawers( aList, TRUE, TRUE );
302 if( mySelectedObjects.count() != 0 )
303 status = SS_GlobalChanged;
305 mySelectedObjects.clear();
308 for( oit = myActiveObjects.begin(), oitEnd = myActiveObjects.end(); oit != oitEnd; ++oit )
310 (*oit)->setScale( aXScale, aYScale );
311 GLViewer_Rect* rect = (*oit)->getUpdateRect();
313 if( rect->contains( GLViewer_Pnt( myXhigh, myXhigh ) ) )
315 (*oit)->select( myXhigh, myYhigh, myTolerance, GLViewer_Rect(), false, byCircle, Append );
316 isSel = (*oit)->isSelected();
321 mySelectedObjects.append( myLastPicked );
322 myGLViewer2d->activateDrawer( myLastPicked, TRUE, TRUE );
323 status = SS_GlobalChanged;
332 /*! Selects objects on scene by rectangle
333 \param theRect - rectangle of selection
334 \param Append - true if new selection will be append to existing selection, false - another
335 function search object rectangle which intersect with theRect and call object select method
337 int GLViewer_Context::SelectByRect( const QRect& theRect, bool Append )
341 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )myGLViewer2d->getActiveView()->getViewPort();
342 vp->getScale( aXScale, aYScale );
344 SelectionStatus status = SS_NoChanged;
347 ObjList::Iterator it, itEnd;
349 if ( !mySFlag || myActiveObjects.empty() )
352 bool updateAll = false;
355 if( mySelectedObjects.count() != 0 )
356 status = SS_GlobalChanged;
358 for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end(); it != itEnd; ++it )
360 updateAll = (*it)->unselect() || updateAll;
363 mySelectedObjects.clear();
366 for( it = myActiveObjects.begin(), itEnd = myActiveObjects.end(); it != itEnd; ++it )
369 (*it)->setScale( aXScale, aYScale );
370 QRect rect = myGLViewer2d->getQRect( *( (*it)->getRect() ) );
372 if( rect.intersects( theRect ) )
374 GLViewer_Rect aRect = myGLViewer2d->getGLVRect( theRect );
375 (*it)->select( myXhigh, myYhigh, myTolerance, aRect, false, false, Append );
376 isSel = (*it)->isSelected();
379 if( isSel && mySelectedObjects.indexOf( *it ) == -1 )
382 mySelectedObjects.append( *it );
383 status = SS_GlobalChanged;
387 if( updateAll || myUpdateAll )
388 myGLViewer2d->updateAll();
390 myGLViewer2d->activateDrawers( aList, TRUE, TRUE );
396 Sets color of hilighting
397 \param aCol - new color of highlighting
399 void GLViewer_Context::SetHighlightColor( Quantity_NameOfColor aCol )
401 myHighlightColor = aCol;
403 Quantity_Color colorH( aCol );
404 int redH = 255 * (int)colorH.Red();
405 int greenH = 255 * (int)colorH.Green();
406 int blueH = 255 * (int)colorH.Blue();
407 QColor colH = QColor( redH, greenH, blueH );
409 Quantity_Color colorS( mySelectionColor );
410 int redS = 255 * (int)colorS.Red();
411 int greenS = 255 * (int)colorS.Green();
412 int blueS = 255 * (int)colorS.Blue();
413 QColor colS = QColor( redS, greenS, blueS );
415 myGLViewer2d->updateColors( colH, colS);
419 Sets color of selection
420 \param aCol - new color of selection
422 void GLViewer_Context::SetSelectionColor( Quantity_NameOfColor aCol )
424 mySelectionColor = aCol;
426 Quantity_Color colorH( myHighlightColor );
427 int redH = 255 * (int)colorH.Red();
428 int greenH = 255 * (int)colorH.Green();
429 int blueH = 255 * (int)colorH.Blue();
430 QColor colH = QColor( redH, greenH, blueH );
432 Quantity_Color colorS( aCol );
433 int redS = 255 * (int)colorS.Red();
434 int greenS = 255 * (int)colorS.Green();
435 int blueS = 255 * (int)colorS.Blue();
436 QColor colS = QColor( redS, greenS, blueS );
438 myGLViewer2d->updateColors( colH, colS);
442 \return number of selected objects
444 int GLViewer_Context::NbSelected()
446 return mySelectedObjects.count();
450 Inits iteration through selected objects
452 void GLViewer_Context::InitSelected()
458 Checks if iteration through selected objects may be continued
460 bool GLViewer_Context::MoreSelected()
462 return ( mySelCurIndex < NbSelected() );
466 Iterates to next selected object
468 bool GLViewer_Context::NextSelected()
470 if ( mySelCurIndex >= 0 && mySelCurIndex < NbSelected() )
480 \return current selected object (must be used only in cycle as "for( InitSelected(); MoreSelected(); NextSelected() ) {...}" )
482 GLViewer_Object* GLViewer_Context::SelectedObject()
484 return mySelectedObjects[ mySelCurIndex ];
488 \return true if object is selected
489 \param theObj - object to be checked
491 bool GLViewer_Context::isSelected( GLViewer_Object* theObj )
493 return mySelectedObjects.contains( theObj );
496 /*! Inserts new object in context
497 \param theObject - object to be inserted
498 \param display - true if needs display object immediatly after inserting, else false
499 \param isActive - true if needs inserting object in active list
501 int GLViewer_Context::insertObject( GLViewer_Object* object, bool display, bool isActive )
503 // cout << "GLViewer_Context::insertObject" << endl;
510 myActiveObjects.append( object );
513 //QRect* rect = object->getRect()->toQRect();
514 //myGLViewer2d->updateBorders( *rect );
515 myGLViewer2d->activateDrawer( object, FALSE );
519 myInactiveObjects.append( object );
521 return myActiveObjects.count() + myInactiveObjects.count();
525 Replaces object in context
526 \param oldObject - object to be replaced
527 \param newObject - object for replacing
529 bool GLViewer_Context::replaceObject( GLViewer_Object* oldObject, GLViewer_Object* newObject )
531 if( !oldObject || !newObject )
534 if( myActiveObjects.contains( oldObject ) )
536 myActiveObjects.removeAll( oldObject );
537 myActiveObjects.append( newObject );
541 if( myInactiveObjects.contains( oldObject ) )
543 myInactiveObjects.removeAll( oldObject );
544 myInactiveObjects.append( newObject );
552 Updates scales of all objects in context
554 void GLViewer_Context::updateScales( GLfloat scX, GLfloat scY )
556 if( scX <= 0 || scY <= 0 )
559 ObjList::iterator it, itEnd;
561 for( it = myActiveObjects.begin(), itEnd = myActiveObjects.end(); it != itEnd; ++it )
562 (*it)->setScale( scX, scY );
564 for( it = myInactiveObjects.begin(), itEnd = myInactiveObjects.end(); it != itEnd; ++it )
565 (*it)->setScale( scX, scY );
569 Clears hilighting of objects
570 \param updateViewer - if it is true, viewer must be updated
572 void GLViewer_Context::clearHighlighted( bool updateViewer )
574 if( myHFlag && myLastPicked )
576 myLastPicked->unhighlight();
580 myGLViewer2d->updateAll();
585 Clears selection of objects
586 \param updateViewer - if it is true, viewer must be updated
588 void GLViewer_Context::clearSelected( bool updateViewer )
593 ObjList::Iterator it, itEnd;
596 for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end(); it != itEnd; ++it )
603 myGLViewer2d->activateDrawers( aList, TRUE );
604 mySelectedObjects.clear();
608 Selects object, other selected objects are left as selected
609 \param updateViewer - if it is true, viewer must be updated
611 void GLViewer_Context::setSelected( GLViewer_Object* object, bool updateViewer )
616 if( myActiveObjects.contains( object ) && !mySelectedObjects.contains( object ) )
618 object->setSelected( TRUE );
619 mySelectedObjects.append( object );
623 myGLViewer2d->activateDrawer( object, TRUE, TRUE );
627 Unselects object, other selected objects are left as selected
628 \param updateViewer - if it is true, viewer must be updated
630 void GLViewer_Context::remSelected( GLViewer_Object* object, bool updateViewer )
632 if( !object || !mySelectedObjects.contains( object ) )
635 mySelectedObjects.removeAll( object );
639 myGLViewer2d->activateDrawer( object, TRUE, TRUE );
643 Erases object in viewer
644 \param theUpdateViewer - if it is true, viewer must be updated
646 void GLViewer_Context::eraseObject( GLViewer_Object* theObject, bool theUpdateViewer )
648 if( !theObject || !myActiveObjects.contains( theObject ) )
651 theObject->unhighlight();
652 theObject->unselect();
653 theObject->setVisible( false );
655 if( theUpdateViewer )
656 myGLViewer2d->updateAll();
661 \param updateViewer - if it is true, viewer must be updated
663 void GLViewer_Context::deleteObject( GLViewer_Object* theObject, bool updateViewer )
666 ( !myActiveObjects.contains( theObject ) && !myInactiveObjects.contains( theObject ) ) )
669 if( myActiveObjects.contains( theObject ) )
670 myActiveObjects.removeAll( theObject );
671 else if( myInactiveObjects.contains( theObject ) )
672 myInactiveObjects.removeAll( theObject );
676 if( mySelectedObjects.contains( theObject ) )
677 mySelectedObjects.removeAll( theObject );
679 GLViewer_Group* aGroup = theObject->getGroup();
681 aGroup->removeObject( theObject );
683 if( myLastPicked == theObject )
687 myGLViewer2d->updateAll();
691 Installs active status to object
694 bool GLViewer_Context::setActive( GLViewer_Object* theObject )
696 if( !theObject || !myInactiveObjects.contains( theObject ) )
699 myInactiveObjects.removeAll( theObject );
700 myActiveObjects.append( theObject );
705 Installs inactive status to object
708 bool GLViewer_Context::setInactive( GLViewer_Object* theObject )
710 if( !theObject || !myActiveObjects.contains( theObject ) )
713 myActiveObjects.removeAll( theObject );
714 myInactiveObjects.append( theObject );