1 // File: GLViewer_Context.cxx
2 // Created: November, 2004
4 // Copyright (C) CEA 2004
6 /****************************************************************************
7 ** Class: GLViewer_Context
8 ** Descr: OpenGL Context
10 ** Created: UI team, 20.09.02
11 *****************************************************************************/
13 #include "GLViewer_Context.h"
15 #include "GLViewer_Object.h"
16 #include "GLViewer_Viewer2d.h"
17 #include "GLViewer_ViewPort2d.h"
19 #include <TColStd_SequenceOfInteger.hxx>
23 GLViewer_Context::GLViewer_Context( GLViewer_Viewer2d* v ) :
25 myHighlightColor( Quantity_NOC_CYAN1 ),
26 mySelectionColor( Quantity_NOC_RED ),
27 myTolerance( TOLERANCE ),
31 isLastPickedChanged = false;
37 GLViewer_Context::~GLViewer_Context()
41 int GLViewer_Context::MoveTo( int xi, int yi, bool byCircle )
43 GLfloat x = (GLfloat)xi;
44 GLfloat y = (GLfloat)yi;
45 myGLViewer2d->transPoint( x, y );
46 //cout << "GLViewer_Context::MoveTo " << x << " " << y << endl;
48 QValueList<GLViewer_Object*> anUpdatedObjects;
50 ObjectMap::Iterator it;
60 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )myGLViewer2d->getActiveView()->getViewPort();
61 vp->getScale( aXScale, aYScale );
63 //bool onlyUpdate = true;
64 GLboolean update = GL_FALSE;
65 GLboolean isHigh = GL_FALSE;
66 GLboolean onObject = GL_FALSE;
68 GLViewer_Object* aPrevLastPicked = myLastPicked;
69 GLViewer_Object* lastPicked = NULL;
75 region.setLeft( (int)(x - myTolerance) );
76 region.setRight( (int)(x + myTolerance) );
77 region.setTop( (int)(y - myTolerance) );
78 region.setBottom( (int)(y + myTolerance) );
80 for( it = myObjects.begin(); it != myObjects.end(); ++it )
82 it.key()->setScale( aXScale, aYScale );
83 rect = it.key()->getUpdateRect()->toQRect();
84 obj = QRegion( *rect );
86 if( !byCircle && rect->intersects( region ) )
88 // cout << "object : " << it.data() << endl;
89 update = it.key()->highlight( x, y, myTolerance, GL_FALSE );
90 isHigh = it.key()->isHighlighted();
93 // cout << "update" << endl;
95 // cout << "highlight" << endl;
100 QRegion circle( (int)(x - myTolerance), (int)(y - myTolerance),
101 (int)(2 * myTolerance), (int)(2 * myTolerance), QRegion::Ellipse );
102 intersection = obj.intersect( circle );
103 if( !intersection.isEmpty() )
105 update = it.key()->highlight( x, y, myTolerance, GL_TRUE );
106 isHigh = it.key()->isHighlighted();
113 lastPicked = it.key();
120 myLastPicked = lastPicked; //we need this information everytime
126 for( it = myObjects.begin(); it != myObjects.end(); ++it )
127 if( it.key()->unhighlight() )
128 anUpdatedObjects.append( it.key() );
131 isLastPickedChanged = aPrevLastPicked != myLastPicked;
133 if( isLastPickedChanged )
134 myGLViewer2d->updateAll();
139 if( !myLastPicked && isHigh )
141 //cout << "1" << endl;
142 myLastPicked = lastPicked;
143 myHNumber = myObjects[ lastPicked ];
144 anUpdatedObjects.append( myLastPicked );
146 else if( myLastPicked && !isHigh )
148 //cout << "2" << endl;
150 myLastPicked->unhighlight();
151 anUpdatedObjects.append( myLastPicked );
152 //eraseObject( myLastPicked, true );
156 else if( myLastPicked && isHigh )
158 //cout << "3" << endl;
159 //cout << "HNumber" << myHNumber << endl;
161 myLastPicked->highlight( x, y, myTolerance, byCircle );
162 if( !myLastPicked->isHighlighted() )
164 myLastPicked->unhighlight();
165 anUpdatedObjects.append( myLastPicked );
166 myLastPicked = lastPicked;
167 myHNumber = myObjects[ lastPicked ];
169 anUpdatedObjects.append( myLastPicked );
172 isLastPickedChanged = ( aPrevLastPicked != myLastPicked );
174 if( isLastPickedChanged/*!onlyUpdate*/ )
176 myGLViewer2d->updateAll();
177 //myGLViewer2d->activateAllDrawers( true );
180 myGLViewer2d->activateDrawers( anUpdatedObjects, TRUE, TRUE );
185 int GLViewer_Context::Select( bool Append, bool byCircle )
187 //cout << "GLViewer_Context::Select " << (int)Append << endl;
188 QValueList<int>::Iterator it;
189 ObjectMap::Iterator oit;
190 SelectionStatus status = SS_Invalid;
192 bool onlyUpdate = false;
194 QValueList<GLViewer_Object*> aList;
197 return status;//invalid
199 if( myHFlag && myLastPicked )
201 if( mySelNumbers.count() == 1 && mySelNumbers.first() == myHNumber )
202 status = SS_LocalChanged;
206 for( it = mySelNumbers.begin(); it != mySelNumbers.end(); ++it )
207 for( oit = myObjects.begin(); oit != myObjects.end(); ++oit )
208 if( *it == myObjects[ oit.key() ] )
209 if ( myLastPicked != oit.key() )
211 onlyUpdate = oit.key()->unselect();
212 aList.append( oit.key() );
216 myGLViewer2d->updateAll();
218 myGLViewer2d->activateDrawers( aList, TRUE, TRUE );
220 if( mySelNumbers.count() != 0 && status == SS_Invalid )
221 status = SS_GlobalChanged;
222 mySelNumbers.clear();
225 if ( myLastPicked->select( myXhigh, myYhigh, myTolerance, GLViewer_Rect(), false, byCircle, Append )
226 && mySelNumbers.findIndex( myHNumber ) == -1 )
227 /*if ( myLastPicked->select( myXhigh, myYhigh, myTolerance, byCircle, Append ) )
228 //&&( mySelNumbers.findIndex( myHNumber ) == -1 ) )*/
230 mySelNumbers.append( myHNumber );
231 //cout << "context::select object #" << myHNumber << endl;
232 myGLViewer2d->activateDrawer( myLastPicked, TRUE, TRUE );
234 if( status == SS_Invalid )
235 status = SS_GlobalChanged;
237 // status = SS_GlobalChanged;
239 else if( status == SS_LocalChanged )
240 status = SS_GlobalChanged;
245 if( myHFlag && !myLastPicked )
249 for( it = mySelNumbers.begin(); it != mySelNumbers.end(); ++it )
250 for( oit = myObjects.begin(); oit != myObjects.end(); ++oit )
251 if( *it == myObjects[ oit.key() ] )
253 onlyUpdate = oit.key()->unselect();
254 //list.Append( *it );
255 aList.append( oit.key() );
259 myGLViewer2d->updateAll();
261 myGLViewer2d->activateDrawers( aList, TRUE, TRUE );
263 if( mySelNumbers.count() != 0 )
264 status = SS_GlobalChanged;
266 mySelNumbers.clear();
267 //cout << " myHFlag && !myLastPicked " << endl;
274 // GLViewer_Object* lastPicked = NULL;
275 // GLboolean update = FALSE;
276 // GLboolean isSel = GL_FALSE;
277 // list = new int[2];
279 // float xa, xb, ya, yb;
282 // ObjectMap::Iterator it;
283 // for( it = myObjects.begin(); it != myObjects.end(); ++it )
285 // rect = it.key()->getRect();
286 // xa = rect->left();
287 // xb = rect->right();
289 // yb = rect->bottom();
291 // if( myXhigh >= xa && myXhigh <= xb && myYhigh >= ya && myYhigh <= yb )
293 // update = it.key()->select( myXhigh, myYhigh, myTolerance, byCircle, Append );
294 // isSel = it.key()->isSelected();
297 // myLastPicked = it.key();
298 // number = myObjects[ lastPicked ];
305 // for( it = mySelNumbers.begin(); it != mySelNumbers.end(); ++it )
306 // for( it1 = myObjects.begin(); it1 != myObjects.end(); ++it1 )
307 // if( *it == myObjects[ it1.key() ] )
309 // it1.key()->unselect();
310 // myGLViewer2d->initDrawer( it1.key(), it.data() );
311 // list.Append( *it );
313 // myGLViewer2d->activateDrawers( list, TRUE );
314 // mySelNumbers.clear();
316 // if ( mySelNumbers.findIndex( myObjects[lastPicked] ) == -1)
317 // mySelNumbers.append( myObjects[lastPicked] );
319 // number = mySelNumbers.count();
320 // list = new int[number + 1];
323 // for( it = mySelNumbers.begin(), i = 1; it != mySelNumbers.end(); ++it, i++ )
326 // myGLViewer2d->initDrawer( myLastPicked, myHNumber );
327 // myGLViewer2d->activateDrawers( list, TRUE );
335 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )myGLViewer2d->getActiveView()->getViewPort();
336 vp->getScale( aXScale, aYScale );
342 region.setLeft( ( int )( myXhigh - myTolerance ) );
343 region.setRight( ( int )( myXhigh + myTolerance ) );
344 region.setTop( ( int )( myYhigh - myTolerance ) );
345 region.setBottom( ( int )( myYhigh + myTolerance ) );
347 QRegion circle( ( int )( myXhigh - myTolerance ), ( int )( myYhigh - myTolerance ),
348 2 * myTolerance, 2 * myTolerance, QRegion::Ellipse );
352 for( it = mySelNumbers.begin(); it != mySelNumbers.end(); ++it )
353 for( oit = myObjects.begin(); oit != myObjects.end(); ++oit )
354 if( *it == myObjects[ oit.key() ] )
356 onlyUpdate |= (bool)oit.key()->unselect();
357 aList.append( oit.key() );
361 myGLViewer2d->updateAll();
363 myGLViewer2d->activateDrawers( aList, TRUE, TRUE );
365 if( mySelNumbers.count() != 0 )
366 status = SS_GlobalChanged;
368 mySelNumbers.clear();
371 for( oit = myObjects.begin(); oit != myObjects.end(); ++oit )
373 oit.key()->setScale( aXScale, aYScale );
374 rect = oit.key()->getUpdateRect()->toQRect();
375 obj = QRegion( *rect );
377 if( !byCircle && rect->intersects( region ) )
379 oit.key()->select( myXhigh, myYhigh, myTolerance, GLViewer_Rect(), false, byCircle, Append );
380 isSel = oit.key()->isSelected();
383 if( byCircle && !obj.intersect( circle ).isEmpty() )
385 oit.key()->select( myXhigh, myYhigh, myTolerance, GLViewer_Rect(), false, byCircle, Append );
386 isSel = oit.key()->isSelected();
390 myLastPicked = oit.key();
391 mySelNumbers.append( myObjects[ myLastPicked ] );
392 myGLViewer2d->activateDrawer( myLastPicked, TRUE, TRUE );
393 status = SS_GlobalChanged;
402 int GLViewer_Context::SelectByRect( const QRect& theRect, bool Append )
406 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )myGLViewer2d->getActiveView()->getViewPort();
407 vp->getScale( aXScale, aYScale );
409 SelectionStatus status = SS_NoChanged;
411 QValueList<int>::Iterator it;
412 ObjectMap::Iterator oit;
414 QValueList<GLViewer_Object*> aList;
416 if ( !mySFlag || myObjList.empty() )
419 bool updateAll = false;
422 if( mySelNumbers.count() != 0 )
423 status = SS_GlobalChanged;
425 for( it = mySelNumbers.begin(); it != mySelNumbers.end(); ++it )
426 for( oit = myObjects.begin(); oit != myObjects.end(); ++oit )
427 if( *it == myObjects[ oit.key() ] )
429 updateAll |= (bool)oit.key()->unselect();
430 aList.append( oit.key() );
432 mySelNumbers.clear();
435 for( oit = myObjects.begin(); oit != myObjects.end(); ++oit )
438 oit.key()->setScale( aXScale, aYScale );
439 QRect rect = //myGLViewer2d->getWinObjectRect( oit.key() ); //->getUpdateRect()->toQRect();
440 myGLViewer2d->getQRect( *(oit.key()->getRect()) );
442 if( rect.intersects( theRect ) )
444 GLViewer_Rect aRect = myGLViewer2d->getGLVRect( theRect );
445 oit.key()->select( myXhigh, myYhigh, myTolerance, aRect, false, false, Append );
446 isSel = oit.key()->isSelected();
449 if( isSel && mySelNumbers.findIndex( oit.data() ) == -1 )
451 aList.append( oit.key() );
452 mySelNumbers.append( oit.data() );
453 status = SS_GlobalChanged;
457 if( updateAll ) //i.e only update
459 //cout << "Unhilight.ALL" << endl;
460 myGLViewer2d->updateAll();
463 myGLViewer2d->activateDrawers( aList, TRUE, TRUE );
468 void GLViewer_Context::SetHighlightColor( Quantity_NameOfColor aCol )
470 myHighlightColor = aCol;
472 Quantity_Color colorH( aCol );
473 int redH = 255 * (int)colorH.Red();
474 int greenH = 255 * (int)colorH.Green();
475 int blueH = 255 * (int)colorH.Blue();
476 QColor colH = QColor( redH, greenH, blueH );
478 Quantity_Color colorS( mySelectionColor );
479 int redS = 255 * (int)colorS.Red();
480 int greenS = 255 * (int)colorS.Green();
481 int blueS = 255 * (int)colorS.Blue();
482 QColor colS = QColor( redS, greenS, blueS );
484 myGLViewer2d->updateColors( colH, colS);
487 void GLViewer_Context::SetSelectionColor( Quantity_NameOfColor aCol )
489 mySelectionColor = aCol;
491 Quantity_Color colorH( myHighlightColor );
492 int redH = 255 * (int)colorH.Red();
493 int greenH = 255 * (int)colorH.Green();
494 int blueH = 255 * (int)colorH.Blue();
495 QColor colH = QColor( redH, greenH, blueH );
497 Quantity_Color colorS( aCol );
498 int redS = 255 * (int)colorS.Red();
499 int greenS = 255 * (int)colorS.Green();
500 int blueS = 255 * (int)colorS.Blue();
501 QColor colS = QColor( redS, greenS, blueS );
503 myGLViewer2d->updateColors( colH, colS);
506 int GLViewer_Context::NbSelected()
508 return mySelNumbers.count();
511 void GLViewer_Context::InitSelected()
516 bool GLViewer_Context::MoreSelected()
518 return ( mySelCurIndex < NbSelected() );
521 bool GLViewer_Context::NextSelected()
523 if ( mySelCurIndex >= 0 && mySelCurIndex < NbSelected() )
532 GLViewer_Object* GLViewer_Context::SelectedObject()
534 ObjectMap::Iterator it;
535 for( it = myObjects.begin(); it != myObjects.end(); ++it )
536 if( mySelNumbers[mySelCurIndex] == it.data() )
542 bool GLViewer_Context::isSelected( GLViewer_Object* theObj )
544 for( InitSelected(); MoreSelected(); NextSelected() )
545 if( SelectedObject() == theObj )
551 int GLViewer_Context::insertObject( GLViewer_Object* object, bool display )
553 // cout << "GLViewer_Context::insertObject" << endl;
555 myObjects.insert( object, myNumber++ );
556 myObjList.append( object );
560 //QRect* rect = object->getRect()->toQRect();
561 //myGLViewer2d->updateBorders( *rect );
562 myGLViewer2d->activateDrawer( object, FALSE );
568 bool GLViewer_Context::replaceObject( GLViewer_Object* oldObject, GLViewer_Object* newObject )
570 if( myObjects.contains( oldObject ) )
572 int index = myObjects[ oldObject ];
573 myObjects.remove( oldObject );
574 myObjects.insert( newObject, index );
581 void GLViewer_Context::updateScales( GLfloat scX, GLfloat scY )
584 for ( ObjectMap::Iterator it = myObjects.begin(); it != myObjects.end(); ++it )
585 it.key()->setScale( scX, scY );
588 void GLViewer_Context::clearSelected( bool updateViewer )
590 QValueList<int>::Iterator it;
591 ObjectMap::Iterator oit;
593 TColStd_SequenceOfInteger list;
598 for( it = mySelNumbers.begin(); it != mySelNumbers.end(); ++it )
599 for( oit = myObjects.begin(); oit != myObjects.end(); ++oit )
600 if( *it == myObjects[ oit.key() ] )
602 oit.key()->unselect();
603 //myGLViewer2d->initDrawer( oit.key(), oit.data() );
604 ///myGLViewer2d->initDrawer( oit.key() );
609 myGLViewer2d->activateDrawers( list, TRUE );
610 mySelNumbers.clear();
613 void GLViewer_Context::setSelected( GLViewer_Object* object, bool updateViewer )
616 if ( myObjects.contains( object ) )
617 index = myObjects[object];
619 if( index == -1 || mySelNumbers.findIndex( index ) != -1 )
622 mySelNumbers.append( index );
623 object->setSelected( TRUE );
626 myGLViewer2d->activateDrawer( object, TRUE, TRUE );
629 void GLViewer_Context::remSelected( GLViewer_Object* object, bool updateViewer )
632 if ( myObjects.contains( object ) )
633 index = myObjects[object];
635 if( index == -1 || mySelNumbers.findIndex( index ) == -1 )
638 mySelNumbers.remove( index );
642 myGLViewer2d->activateDrawer( object, TRUE, TRUE );
645 void GLViewer_Context::eraseObject( GLViewer_Object* theObject, bool theUpdateViewer )
650 theObject->unhighlight();
651 theObject->unselect();
652 theObject->setVisible( false );
654 if( theUpdateViewer )
655 myGLViewer2d->updateAll();
656 //myGLViewer2d->activateAllDrawers( true );
659 void GLViewer_Context::deleteObject( GLViewer_Object* theObject, bool updateViewer )
661 if( !theObject || !myObjects.contains(theObject) )
664 int anIndex = myObjects[theObject];
665 myObjects.remove( theObject );
666 myObjList.remove( theObject );
668 if( myLastPicked == theObject )
674 QValueList<int>::Iterator anIt= mySelNumbers.find( anIndex );
675 if( anIt != mySelNumbers.end() )
676 mySelNumbers.remove( anIt );
678 if( mySelCurIndex == anIndex )
682 myGLViewer2d->updateAll();