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 QRegion circle( (int)(x - myTolerance), (int)(y - myTolerance),
81 (int)(2 * myTolerance), (int)(2 * myTolerance), QRegion::Ellipse );
83 for( it = myObjects.begin(); it != myObjects.end(); ++it )
85 it.key()->setScale( aXScale, aYScale );
86 rect = it.key()->getUpdateRect()->toQRect();
87 obj = QRegion( *rect );
88 intersection = obj.intersect( circle );
90 if( !byCircle && rect->intersects( region ) )
92 // cout << "object : " << it.data() << endl;
93 update = it.key()->highlight( x, y, myTolerance, GL_FALSE );
94 isHigh = it.key()->isHighlighted();
97 // cout << "update" << endl;
99 // cout << "highlight" << endl;
102 if( byCircle && !intersection.isEmpty() )
104 update = it.key()->highlight( x, y, myTolerance, GL_TRUE );
105 isHigh = it.key()->isHighlighted();
111 lastPicked = it.key();
118 myLastPicked = lastPicked; //we need this information everytime
124 for( it = myObjects.begin(); it != myObjects.end(); ++it )
125 if( it.key()->unhighlight() )
126 anUpdatedObjects.append( it.key() );
129 isLastPickedChanged = aPrevLastPicked != myLastPicked;
131 if( isLastPickedChanged )
132 myGLViewer2d->updateAll();
137 if( !myLastPicked && isHigh )
139 //cout << "1" << endl;
140 myLastPicked = lastPicked;
141 myHNumber = myObjects[ lastPicked ];
142 anUpdatedObjects.append( myLastPicked );
144 else if( myLastPicked && !isHigh )
146 //cout << "2" << endl;
148 myLastPicked->unhighlight();
149 anUpdatedObjects.append( myLastPicked );
150 //eraseObject( myLastPicked, true );
154 else if( myLastPicked && isHigh )
156 //cout << "3" << endl;
157 //cout << "HNumber" << myHNumber << endl;
159 myLastPicked->highlight( x, y, myTolerance, byCircle );
160 if( !myLastPicked->isHighlighted() )
162 myLastPicked->unhighlight();
163 anUpdatedObjects.append( myLastPicked );
164 myLastPicked = lastPicked;
165 myHNumber = myObjects[ lastPicked ];
167 anUpdatedObjects.append( myLastPicked );
170 isLastPickedChanged = ( aPrevLastPicked != myLastPicked );
172 if( isLastPickedChanged/*!onlyUpdate*/ )
174 myGLViewer2d->updateAll();
175 //myGLViewer2d->activateAllDrawers( true );
178 myGLViewer2d->activateDrawers( anUpdatedObjects, TRUE, TRUE );
183 int GLViewer_Context::Select( bool Append, bool byCircle )
185 //cout << "GLViewer_Context::Select " << (int)Append << endl;
186 QValueList<int>::Iterator it;
187 ObjectMap::Iterator oit;
188 SelectionStatus status = SS_Invalid;
190 bool onlyUpdate = false;
192 QValueList<GLViewer_Object*> aList;
195 return status;//invalid
197 if( myHFlag && myLastPicked )
199 if( mySelNumbers.count() == 1 && mySelNumbers.first() == myHNumber )
200 status = SS_LocalChanged;
204 for( it = mySelNumbers.begin(); it != mySelNumbers.end(); ++it )
205 for( oit = myObjects.begin(); oit != myObjects.end(); ++oit )
206 if( *it == myObjects[ oit.key() ] )
207 if ( myLastPicked != oit.key() )
209 onlyUpdate = oit.key()->unselect();
210 aList.append( oit.key() );
214 myGLViewer2d->updateAll();
216 myGLViewer2d->activateDrawers( aList, TRUE, TRUE );
218 if( mySelNumbers.count() != 0 && status == SS_Invalid )
219 status = SS_GlobalChanged;
220 mySelNumbers.clear();
223 if ( myLastPicked->select( myXhigh, myYhigh, myTolerance, GLViewer_Rect(), false, byCircle, Append )
224 && mySelNumbers.findIndex( myHNumber ) == -1 )
225 /*if ( myLastPicked->select( myXhigh, myYhigh, myTolerance, byCircle, Append ) )
226 //&&( mySelNumbers.findIndex( myHNumber ) == -1 ) )*/
228 mySelNumbers.append( myHNumber );
229 //cout << "context::select object #" << myHNumber << endl;
230 myGLViewer2d->activateDrawer( myLastPicked, TRUE, TRUE );
232 if( status == SS_Invalid )
233 status = SS_GlobalChanged;
235 // status = SS_GlobalChanged;
237 else if( status == SS_LocalChanged )
238 status = SS_GlobalChanged;
243 if( myHFlag && !myLastPicked )
247 for( it = mySelNumbers.begin(); it != mySelNumbers.end(); ++it )
248 for( oit = myObjects.begin(); oit != myObjects.end(); ++oit )
249 if( *it == myObjects[ oit.key() ] )
251 onlyUpdate = oit.key()->unselect();
252 //list.Append( *it );
253 aList.append( oit.key() );
257 myGLViewer2d->updateAll();
259 myGLViewer2d->activateDrawers( aList, TRUE, TRUE );
261 if( mySelNumbers.count() != 0 )
262 status = SS_GlobalChanged;
264 mySelNumbers.clear();
265 //cout << " myHFlag && !myLastPicked " << endl;
272 // GLViewer_Object* lastPicked = NULL;
273 // GLboolean update = FALSE;
274 // GLboolean isSel = GL_FALSE;
275 // list = new int[2];
277 // float xa, xb, ya, yb;
280 // ObjectMap::Iterator it;
281 // for( it = myObjects.begin(); it != myObjects.end(); ++it )
283 // rect = it.key()->getRect();
284 // xa = rect->left();
285 // xb = rect->right();
287 // yb = rect->bottom();
289 // if( myXhigh >= xa && myXhigh <= xb && myYhigh >= ya && myYhigh <= yb )
291 // update = it.key()->select( myXhigh, myYhigh, myTolerance, byCircle, Append );
292 // isSel = it.key()->isSelected();
295 // myLastPicked = it.key();
296 // number = myObjects[ lastPicked ];
303 // for( it = mySelNumbers.begin(); it != mySelNumbers.end(); ++it )
304 // for( it1 = myObjects.begin(); it1 != myObjects.end(); ++it1 )
305 // if( *it == myObjects[ it1.key() ] )
307 // it1.key()->unselect();
308 // myGLViewer2d->initDrawer( it1.key(), it.data() );
309 // list.Append( *it );
311 // myGLViewer2d->activateDrawers( list, TRUE );
312 // mySelNumbers.clear();
314 // if ( mySelNumbers.findIndex( myObjects[lastPicked] ) == -1)
315 // mySelNumbers.append( myObjects[lastPicked] );
317 // number = mySelNumbers.count();
318 // list = new int[number + 1];
321 // for( it = mySelNumbers.begin(), i = 1; it != mySelNumbers.end(); ++it, i++ )
324 // myGLViewer2d->initDrawer( myLastPicked, myHNumber );
325 // myGLViewer2d->activateDrawers( list, TRUE );
333 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )myGLViewer2d->getActiveView()->getViewPort();
334 vp->getScale( aXScale, aYScale );
340 region.setLeft( ( int )( myXhigh - myTolerance ) );
341 region.setRight( ( int )( myXhigh + myTolerance ) );
342 region.setTop( ( int )( myYhigh - myTolerance ) );
343 region.setBottom( ( int )( myYhigh + myTolerance ) );
345 QRegion circle( ( int )( myXhigh - myTolerance ), ( int )( myYhigh - myTolerance ),
346 2 * myTolerance, 2 * myTolerance, QRegion::Ellipse );
350 for( it = mySelNumbers.begin(); it != mySelNumbers.end(); ++it )
351 for( oit = myObjects.begin(); oit != myObjects.end(); ++oit )
352 if( *it == myObjects[ oit.key() ] )
354 onlyUpdate |= (bool)oit.key()->unselect();
355 aList.append( oit.key() );
359 myGLViewer2d->updateAll();
361 myGLViewer2d->activateDrawers( aList, TRUE, TRUE );
363 if( mySelNumbers.count() != 0 )
364 status = SS_GlobalChanged;
366 mySelNumbers.clear();
369 for( oit = myObjects.begin(); oit != myObjects.end(); ++oit )
371 oit.key()->setScale( aXScale, aYScale );
372 rect = oit.key()->getUpdateRect()->toQRect();
373 obj = QRegion( *rect );
375 if( !byCircle && rect->intersects( region ) )
377 oit.key()->select( myXhigh, myYhigh, myTolerance, GLViewer_Rect(), false, byCircle, Append );
378 isSel = oit.key()->isSelected();
381 if( byCircle && !obj.intersect( circle ).isEmpty() )
383 oit.key()->select( myXhigh, myYhigh, myTolerance, GLViewer_Rect(), false, byCircle, Append );
384 isSel = oit.key()->isSelected();
388 myLastPicked = oit.key();
389 mySelNumbers.append( myObjects[ myLastPicked ] );
390 myGLViewer2d->activateDrawer( myLastPicked, TRUE, TRUE );
391 status = SS_GlobalChanged;
400 int GLViewer_Context::SelectByRect( const QRect& theRect, bool Append )
404 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )myGLViewer2d->getActiveView()->getViewPort();
405 vp->getScale( aXScale, aYScale );
407 SelectionStatus status = SS_NoChanged;
409 QValueList<int>::Iterator it;
410 ObjectMap::Iterator oit;
412 QValueList<GLViewer_Object*> aList;
414 if ( !mySFlag || myObjList.empty() )
417 bool updateAll = false;
420 if( mySelNumbers.count() != 0 )
421 status = SS_GlobalChanged;
423 for( it = mySelNumbers.begin(); it != mySelNumbers.end(); ++it )
424 for( oit = myObjects.begin(); oit != myObjects.end(); ++oit )
425 if( *it == myObjects[ oit.key() ] )
427 updateAll |= (bool)oit.key()->unselect();
428 aList.append( oit.key() );
430 mySelNumbers.clear();
433 for( oit = myObjects.begin(); oit != myObjects.end(); ++oit )
436 oit.key()->setScale( aXScale, aYScale );
437 QRect rect = //myGLViewer2d->getWinObjectRect( oit.key() ); //->getUpdateRect()->toQRect();
438 myGLViewer2d->getQRect( *(oit.key()->getRect()) );
440 if( rect.intersects( theRect ) )
442 GLViewer_Rect aRect = myGLViewer2d->getGLVRect( theRect );
443 oit.key()->select( myXhigh, myYhigh, myTolerance, aRect, false, false, Append );
444 isSel = oit.key()->isSelected();
447 if( isSel && mySelNumbers.findIndex( oit.data() ) == -1 )
449 aList.append( oit.key() );
450 mySelNumbers.append( oit.data() );
451 status = SS_GlobalChanged;
455 if( updateAll ) //i.e only update
457 //cout << "Unhilight.ALL" << endl;
458 myGLViewer2d->updateAll();
461 myGLViewer2d->activateDrawers( aList, TRUE, TRUE );
466 void GLViewer_Context::SetHighlightColor( Quantity_NameOfColor aCol )
468 myHighlightColor = aCol;
470 Quantity_Color colorH( aCol );
471 int redH = 255 * (int)colorH.Red();
472 int greenH = 255 * (int)colorH.Green();
473 int blueH = 255 * (int)colorH.Blue();
474 QColor colH = QColor( redH, greenH, blueH );
476 Quantity_Color colorS( mySelectionColor );
477 int redS = 255 * (int)colorS.Red();
478 int greenS = 255 * (int)colorS.Green();
479 int blueS = 255 * (int)colorS.Blue();
480 QColor colS = QColor( redS, greenS, blueS );
482 myGLViewer2d->updateColors( colH, colS);
485 void GLViewer_Context::SetSelectionColor( Quantity_NameOfColor aCol )
487 mySelectionColor = aCol;
489 Quantity_Color colorH( myHighlightColor );
490 int redH = 255 * (int)colorH.Red();
491 int greenH = 255 * (int)colorH.Green();
492 int blueH = 255 * (int)colorH.Blue();
493 QColor colH = QColor( redH, greenH, blueH );
495 Quantity_Color colorS( aCol );
496 int redS = 255 * (int)colorS.Red();
497 int greenS = 255 * (int)colorS.Green();
498 int blueS = 255 * (int)colorS.Blue();
499 QColor colS = QColor( redS, greenS, blueS );
501 myGLViewer2d->updateColors( colH, colS);
504 int GLViewer_Context::NbSelected()
506 return mySelNumbers.count();
509 void GLViewer_Context::InitSelected()
514 bool GLViewer_Context::MoreSelected()
516 return ( mySelCurIndex < NbSelected() );
519 bool GLViewer_Context::NextSelected()
521 if ( mySelCurIndex >= 0 && mySelCurIndex < NbSelected() )
530 GLViewer_Object* GLViewer_Context::SelectedObject()
532 ObjectMap::Iterator it;
533 for( it = myObjects.begin(); it != myObjects.end(); ++it )
534 if( mySelNumbers[mySelCurIndex] == it.data() )
540 bool GLViewer_Context::isSelected( GLViewer_Object* theObj )
542 for( InitSelected(); MoreSelected(); NextSelected() )
543 if( SelectedObject() == theObj )
549 int GLViewer_Context::insertObject( GLViewer_Object* object, bool display )
551 // cout << "GLViewer_Context::insertObject" << endl;
553 myObjects.insert( object, myNumber++ );
554 myObjList.append( object );
558 //QRect* rect = object->getRect()->toQRect();
559 //myGLViewer2d->updateBorders( *rect );
560 myGLViewer2d->activateDrawer( object, FALSE );
566 bool GLViewer_Context::replaceObject( GLViewer_Object* oldObject, GLViewer_Object* newObject )
568 if( myObjects.contains( oldObject ) )
570 int index = myObjects[ oldObject ];
571 myObjects.remove( oldObject );
572 myObjects.insert( newObject, index );
579 void GLViewer_Context::updateScales( GLfloat scX, GLfloat scY )
582 for ( ObjectMap::Iterator it = myObjects.begin(); it != myObjects.end(); ++it )
583 it.key()->setScale( scX, scY );
586 void GLViewer_Context::clearSelected( bool updateViewer )
588 QValueList<int>::Iterator it;
589 ObjectMap::Iterator oit;
591 TColStd_SequenceOfInteger list;
596 for( it = mySelNumbers.begin(); it != mySelNumbers.end(); ++it )
597 for( oit = myObjects.begin(); oit != myObjects.end(); ++oit )
598 if( *it == myObjects[ oit.key() ] )
600 oit.key()->unselect();
601 //myGLViewer2d->initDrawer( oit.key(), oit.data() );
602 ///myGLViewer2d->initDrawer( oit.key() );
607 myGLViewer2d->activateDrawers( list, TRUE );
608 mySelNumbers.clear();
611 void GLViewer_Context::setSelected( GLViewer_Object* object, bool updateViewer )
614 if ( myObjects.contains( object ) )
615 index = myObjects[object];
617 if( index == -1 || mySelNumbers.findIndex( index ) != -1 )
620 mySelNumbers.append( index );
621 object->setSelected( TRUE );
624 myGLViewer2d->activateDrawer( object, TRUE, TRUE );
627 void GLViewer_Context::remSelected( GLViewer_Object* object, bool updateViewer )
630 if ( myObjects.contains( object ) )
631 index = myObjects[object];
633 if( index == -1 || mySelNumbers.findIndex( index ) == -1 )
636 mySelNumbers.remove( index );
640 myGLViewer2d->activateDrawer( object, TRUE, TRUE );
643 void GLViewer_Context::eraseObject( GLViewer_Object* theObject, bool theUpdateViewer )
648 theObject->unhighlight();
649 theObject->unselect();
650 theObject->setVisible( false );
652 if( theUpdateViewer )
653 myGLViewer2d->updateAll();
654 //myGLViewer2d->activateAllDrawers( true );
657 void GLViewer_Context::deleteObject( GLViewer_Object* theObject, bool updateViewer )
659 if( !theObject || !myObjects.contains(theObject) )
662 int anIndex = myObjects[theObject];
663 myObjects.remove( theObject );
664 myObjList.remove( theObject );
666 if( myLastPicked == theObject )
672 QValueList<int>::Iterator anIt= mySelNumbers.find( anIndex );
673 if( anIt != mySelNumbers.end() )
674 mySelNumbers.remove( anIt );
676 if( mySelCurIndex == anIndex )
680 myGLViewer2d->updateAll();