]> SALOME platform Git repositories - modules/gui.git/blob - src/GLViewer/GLViewer_Context.cxx
Salome HOME
*** empty log message ***
[modules/gui.git] / src / GLViewer / GLViewer_Context.cxx
1 // File:      GLViewer_Context.cxx
2 // Created:   November, 2004
3 // Author:    OCC team
4 // Copyright (C) CEA 2004
5
6 /****************************************************************************
7 **  Class:   GLViewer_Context 
8 **  Descr:   OpenGL Context
9 **  Module:  GLViewer
10 **  Created: UI team, 20.09.02
11 *****************************************************************************/
12
13 //#include <GLViewerAfx.h>
14
15 #include "GLViewer_Context.h"
16
17 #include "GLViewer_Group.h"
18 #include "GLViewer_Object.h"
19 #include "GLViewer_Viewer2d.h"
20 #include "GLViewer_ViewPort2d.h"
21
22 #include <TColStd_SequenceOfInteger.hxx>
23
24 #define TOLERANCE  12
25
26 GLViewer_Context::GLViewer_Context( GLViewer_Viewer2d* v ) :
27        myGLViewer2d( v ),
28        myHighlightColor( Quantity_NOC_CYAN1 ),
29        mySelectionColor( Quantity_NOC_RED ),
30        myTolerance( TOLERANCE )
31 {
32   myUpdateAll = true;
33
34   myLastPicked = 0;
35   myLastPickedChanged = false;
36
37   myHFlag = GL_TRUE;
38   mySFlag = GL_TRUE;
39
40   mySelCurIndex = 0;
41 }
42
43 GLViewer_Context::~GLViewer_Context()
44 {
45     myActiveObjects.clear();
46     myInactiveObjects.clear();
47     mySelectedObjects.clear();
48 }
49
50 int GLViewer_Context::MoveTo( int xi, int yi, bool byCircle )
51 {
52     GLfloat x = (GLfloat)xi;
53     GLfloat y = (GLfloat)yi;
54     myGLViewer2d->transPoint( x, y );
55
56     myXhigh = x;
57     myYhigh = y;  
58
59     GLboolean isHigh = GL_FALSE;
60     GLboolean onObject = GL_FALSE;
61
62     GLViewer_Object* aPrevLastPicked = myLastPicked;
63     GLViewer_Object* lastPicked = 0;
64
65     ObjList anUpdatedObjects;
66   
67     if( myActiveObjects.isEmpty() )
68         return -1;
69
70     ObjList::iterator it = myActiveObjects.end();
71     ObjList::iterator itEnd = myActiveObjects.begin();
72     for( it--; ; --it )
73     {
74         GLViewer_Object* object = *it;
75
76         GLViewer_Rect* rect = object->getUpdateRect();
77         if( rect->contains( GLViewer_Pnt( x, y ) ) )
78         {
79             onObject = GL_TRUE;
80             object->highlight( x, y, myTolerance, GL_FALSE );
81             isHigh = object->isHighlighted();
82         }
83
84         if( isHigh )
85         {
86             lastPicked = object;
87             break;
88         }
89
90         if( it == itEnd )
91             break;
92     }
93
94     if( !myHFlag )
95     {
96         myLastPicked = lastPicked;
97         return -1;
98     }
99
100     if ( !onObject )
101     {
102         //cout << 0 << endl;
103         it = myActiveObjects.begin();
104         itEnd = myActiveObjects.end();
105
106         for( ; it != itEnd; ++it )
107             (*it)->unhighlight();
108
109         anUpdatedObjects.append( (*it) );
110
111         myLastPicked = 0;
112         myLastPickedChanged = aPrevLastPicked != myLastPicked;
113
114         if( myLastPickedChanged )
115             myGLViewer2d->updateAll();  
116
117         return 0;
118     }
119
120     if( !myLastPicked && isHigh )
121     {
122         //cout << 1 << endl;
123         myLastPicked = lastPicked;
124         anUpdatedObjects.append( myLastPicked );
125     }
126     else if( myLastPicked && !isHigh )
127     {
128         //cout << 2 << endl;
129         myLastPicked->unhighlight();
130         anUpdatedObjects.append( myLastPicked );
131         myLastPicked = 0;
132     }
133     else if( myLastPicked && isHigh )
134     {
135         //cout << 3 << endl;
136         //myLastPicked->highlight( x, y, myTolerance, byCircle );
137         if( myLastPicked != lastPicked )
138         {
139             myLastPicked->unhighlight();
140             if( myLastPicked != lastPicked )
141             {
142                 myLastPicked = lastPicked;
143                 anUpdatedObjects.append( myLastPicked );
144             }
145         }
146     }
147
148     myLastPickedChanged = ( aPrevLastPicked != myLastPicked );
149
150     if( myLastPickedChanged || myUpdateAll )
151         myGLViewer2d->updateAll();
152     else
153         myGLViewer2d->activateDrawers( anUpdatedObjects, TRUE, TRUE );
154
155     return 0;
156 }
157
158 int GLViewer_Context::Select( bool Append, bool byCircle )
159 {
160     ObjList::Iterator it, itEnd, oit, oitEnd;
161     SelectionStatus status = SS_Invalid;
162
163     bool updateAll = false;
164
165     ObjList aList;
166
167     if ( !mySFlag )
168         return status;//invalid
169
170     if( myHFlag && myLastPicked )
171     {
172         if( mySelectedObjects.count() == 1 && mySelectedObjects.first() == myLastPicked )
173             status = SS_LocalChanged;
174
175         if ( !Append )
176         {
177             for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end() ; it != itEnd; ++it )
178                     if( myLastPicked != *it )
179                 {
180                         updateAll = (*it)->unselect() || updateAll;
181                         aList.append( *it );
182                 }
183
184             if( updateAll || myUpdateAll )
185                 myGLViewer2d->updateAll();
186             else
187                 myGLViewer2d->activateDrawers( aList, TRUE, TRUE );
188
189             if( mySelectedObjects.count() != 0 && status == SS_Invalid )
190                 status = SS_GlobalChanged;
191             mySelectedObjects.clear();
192         } 
193
194         if ( myLastPicked->select( myXhigh, myYhigh, myTolerance, GLViewer_Rect(), false, byCircle, Append )
195              && mySelectedObjects.findIndex( myLastPicked ) == -1 )
196         {
197             mySelectedObjects.append( myLastPicked );
198             myGLViewer2d->activateDrawer( myLastPicked, TRUE, TRUE );
199
200             if( status == SS_Invalid )
201                 status = SS_GlobalChanged;
202         }
203         else if( status = SS_LocalChanged )
204             status = SS_GlobalChanged;
205
206         return status;
207     }
208
209     if( myHFlag && !myLastPicked )
210     {
211         if ( !Append )
212         {
213             for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end() ; it != itEnd; ++it )
214                     if ( myLastPicked != *it )
215                 {
216                         updateAll = (*it)->unselect() || updateAll;
217                         aList.append( *it );
218                 }
219
220             if( updateAll || myUpdateAll )
221                 myGLViewer2d->updateAll();
222             else
223                 myGLViewer2d->activateDrawers( aList, TRUE, TRUE );
224
225             if( mySelectedObjects.count() != 0 )
226                 status = SS_GlobalChanged;
227
228             mySelectedObjects.clear();
229         }
230         return status;
231     }
232
233     if( !myHFlag )
234     {
235         bool isSel = false;
236         GLfloat aXScale;
237         GLfloat aYScale;
238         GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )myGLViewer2d->getActiveView()->getViewPort();
239         vp->getScale( aXScale, aYScale );
240
241         if ( !Append )
242         {
243             for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end() ; it != itEnd; ++it )
244                 if( myLastPicked != *it )
245                 {
246                     updateAll = (*it)->unselect() || updateAll;
247                     aList.append( *it );
248                 }
249
250             if( updateAll || myUpdateAll )
251                 myGLViewer2d->updateAll();
252             else
253                 myGLViewer2d->activateDrawers( aList, TRUE, TRUE );
254
255             if( mySelectedObjects.count() != 0 )
256                 status = SS_GlobalChanged;
257
258             mySelectedObjects.clear();
259         }        
260
261         for( oit = myActiveObjects.begin(), oitEnd = myActiveObjects.end(); oit != oitEnd; ++oit )
262         {
263             (*oit)->setScale( aXScale, aYScale );
264             GLViewer_Rect* rect = (*oit)->getUpdateRect();
265
266             if( rect->contains( GLViewer_Pnt( myXhigh, myXhigh ) ) )
267             {
268                 (*oit)->select( myXhigh, myYhigh, myTolerance, GLViewer_Rect(), false, byCircle, Append );
269                 isSel = (*oit)->isSelected();
270             }
271             if( isSel )
272             {
273                 myLastPicked = *oit;
274                 mySelectedObjects.append( myLastPicked );
275                 myGLViewer2d->activateDrawer( myLastPicked, TRUE, TRUE );
276                 status = SS_GlobalChanged;
277                 return status;
278             }
279         }
280     }
281         
282     return SS_NoChanged;
283 }
284
285 int GLViewer_Context::SelectByRect( const QRect& theRect, bool Append )
286 {
287     GLfloat aXScale;
288     GLfloat aYScale;
289     GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )myGLViewer2d->getActiveView()->getViewPort();
290     vp->getScale( aXScale, aYScale );
291
292     SelectionStatus status = SS_NoChanged;
293
294     ObjList aList;
295     ObjList::Iterator it, itEnd;
296
297     if ( !mySFlag || myActiveObjects.empty() )
298         return SS_Invalid;
299
300     bool updateAll = false;
301     if( !Append )
302     {
303         if( mySelectedObjects.count() != 0 )
304             status = SS_GlobalChanged;
305
306         for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end(); it != itEnd; ++it )
307         {
308             updateAll = (*it)->unselect() || updateAll;
309             aList.append( *it );
310         }
311         mySelectedObjects.clear();
312     }
313
314     for( it = myActiveObjects.begin(), itEnd = myActiveObjects.end(); it != itEnd; ++it )
315     {
316         bool isSel = false;
317         (*it)->setScale( aXScale, aYScale );
318         QRect rect = myGLViewer2d->getQRect( *( (*it)->getRect() ) );
319
320         if( rect.intersects( theRect ) )
321         {
322             GLViewer_Rect aRect = myGLViewer2d->getGLVRect( theRect );
323             (*it)->select( myXhigh, myYhigh, myTolerance, aRect, false, false, Append );
324             isSel = (*it)->isSelected();
325         }
326
327         if( isSel && mySelectedObjects.findIndex( *it ) == -1 )
328         {
329             aList.append( *it );
330             mySelectedObjects.append( *it );
331             status = SS_GlobalChanged;
332         }
333     }
334
335     if( updateAll || myUpdateAll )
336         myGLViewer2d->updateAll();
337     else
338         myGLViewer2d->activateDrawers( aList, TRUE, TRUE );
339
340     return status;
341 }
342
343 void GLViewer_Context::SetHighlightColor( Quantity_NameOfColor aCol )
344 {
345   myHighlightColor = aCol;
346   
347   Quantity_Color colorH( aCol );
348   int redH = 255 * (int)colorH.Red();
349   int greenH = 255 * (int)colorH.Green();
350   int blueH = 255 * (int)colorH.Blue();
351   QColor colH = QColor( redH, greenH, blueH );
352
353   Quantity_Color colorS( mySelectionColor );
354   int redS = 255 * (int)colorS.Red();
355   int greenS = 255 * (int)colorS.Green();
356   int blueS = 255 * (int)colorS.Blue();
357   QColor colS = QColor( redS, greenS, blueS );
358
359   myGLViewer2d->updateColors( colH, colS);
360 }
361
362 void GLViewer_Context::SetSelectionColor( Quantity_NameOfColor aCol )
363 {
364   mySelectionColor = aCol;
365   
366   Quantity_Color colorH( myHighlightColor );
367   int redH = 255 * (int)colorH.Red();
368   int greenH = 255 * (int)colorH.Green();
369   int blueH = 255 * (int)colorH.Blue();
370   QColor colH = QColor( redH, greenH, blueH );
371
372   Quantity_Color colorS( aCol );
373   int redS = 255 * (int)colorS.Red();
374   int greenS = 255 * (int)colorS.Green();
375   int blueS = 255 * (int)colorS.Blue();
376   QColor colS = QColor( redS, greenS, blueS );
377
378   myGLViewer2d->updateColors( colH, colS);
379 }
380
381 int GLViewer_Context::NbSelected()
382 {
383   return mySelectedObjects.count();
384 }
385
386 void GLViewer_Context::InitSelected()
387 {
388   mySelCurIndex = 0;
389 }
390
391 bool GLViewer_Context::MoreSelected()
392 {
393   return ( mySelCurIndex < NbSelected() );
394 }
395
396 bool GLViewer_Context::NextSelected()
397 {
398   if ( mySelCurIndex >= 0 && mySelCurIndex < NbSelected() )
399   {
400     mySelCurIndex++;
401     return TRUE;
402   }
403
404   return FALSE;
405 }
406
407 GLViewer_Object* GLViewer_Context::SelectedObject()
408 {
409     return mySelectedObjects[ mySelCurIndex ];
410 }
411
412 bool  GLViewer_Context::isSelected( GLViewer_Object* theObj )
413 {
414     return mySelectedObjects.contains( theObj );
415 }
416
417 int GLViewer_Context::insertObject( GLViewer_Object* object, bool display, bool isActive )
418 {
419 //  cout << "GLViewer_Context::insertObject" << endl;
420
421     if( !object )
422         return -1;
423
424     if( isActive )
425     {
426         myActiveObjects.append( object );
427         if( display )
428         {
429             //QRect* rect = object->getRect()->toQRect();
430             //myGLViewer2d->updateBorders( *rect );
431             myGLViewer2d->activateDrawer( object, FALSE );
432         }
433     }
434     else
435         myInactiveObjects.append( object );
436
437     return myActiveObjects.count() + myInactiveObjects.count();
438 }
439
440 bool GLViewer_Context::replaceObject( GLViewer_Object* oldObject, GLViewer_Object* newObject )
441 {
442     if( !oldObject || !newObject )
443         return false;
444
445   if( myActiveObjects.contains( oldObject ) )
446   {
447     myActiveObjects.remove( oldObject );
448     myActiveObjects.append( newObject );
449     return true;
450   }
451
452   if( myInactiveObjects.contains( oldObject ) )
453   {
454     myInactiveObjects.remove( oldObject );
455     myInactiveObjects.append( newObject );
456     return true;
457   }
458
459   return false;
460 }
461
462 void GLViewer_Context::updateScales( GLfloat scX, GLfloat scY )
463 {
464   if( scX <= 0 || scY <= 0 )
465       return;
466
467   ObjList::iterator it, itEnd;
468
469   for( it = myActiveObjects.begin(), itEnd = myActiveObjects.end(); it != itEnd; ++it )
470       (*it)->setScale( scX, scY );
471
472   for( it = myInactiveObjects.begin(), itEnd = myInactiveObjects.end(); it != itEnd; ++it )
473       (*it)->setScale( scX, scY );
474 }
475
476 void GLViewer_Context::clearHighlighted()
477 {
478   if( myHFlag && myLastPicked )
479   {
480       myLastPicked->unhighlight();
481       myLastPicked = 0;
482
483       myGLViewer2d->updateAll();
484   }
485 }
486
487 void GLViewer_Context::clearSelected( bool updateViewer )
488 {
489   if( !mySFlag )
490     return;
491
492   ObjList::Iterator it, itEnd;
493   ObjList aList;
494
495   for( it = mySelectedObjects.begin(), itEnd = mySelectedObjects.end(); it != itEnd; ++it )
496   {
497     (*it)->unselect();
498     aList.append( *it );
499   }          
500         
501   if( updateViewer )
502     myGLViewer2d->activateDrawers( aList, TRUE );
503   mySelectedObjects.clear();    
504 }
505
506 void GLViewer_Context::setSelected( GLViewer_Object* object, bool updateViewer )
507 {
508   if( !object )
509     return;
510
511   if( myActiveObjects.contains( object ) && !mySelectedObjects.contains( object ) )
512   {
513     object->setSelected( TRUE );
514     mySelectedObjects.append( object );
515   }
516      
517   if( updateViewer )
518     myGLViewer2d->activateDrawer( object, TRUE, TRUE );
519 }
520
521 void GLViewer_Context::remSelected( GLViewer_Object* object, bool updateViewer )
522 {
523   if( !object || !mySelectedObjects.contains( object ) )
524     return;
525   
526   mySelectedObjects.remove( object );
527   object->unselect();
528   
529   if( updateViewer )
530     myGLViewer2d->activateDrawer( object, TRUE, TRUE );
531 }
532
533 void GLViewer_Context::eraseObject( GLViewer_Object* theObject, bool theUpdateViewer )
534 {
535     if( !theObject || !myActiveObjects.contains( theObject ) )
536         return;
537
538     theObject->unhighlight();
539     theObject->unselect();
540     theObject->setVisible( false );
541
542     if( theUpdateViewer )
543         myGLViewer2d->updateAll();
544 }
545
546 void GLViewer_Context::deleteObject( GLViewer_Object* theObject, bool updateViewer )
547 {
548     if( !theObject ||
549         ( !myActiveObjects.contains( theObject ) && !myInactiveObjects.contains( theObject ) ) )
550         return;
551
552     if( myActiveObjects.contains( theObject ) )      
553         myActiveObjects.remove( theObject );
554     else if( myInactiveObjects.contains( theObject ) )
555         myInactiveObjects.remove( theObject );
556     else 
557         return;
558      
559     if( mySelectedObjects.contains( theObject ) )
560         mySelectedObjects.remove( theObject );
561
562     GLViewer_Group* aGroup = theObject->getGroup();
563     if( aGroup )
564         aGroup->removeObject( theObject );
565
566     if( myLastPicked == theObject )
567         myLastPicked = 0;
568
569     myGLViewer2d->updateAll();
570 }
571
572 bool GLViewer_Context::setActive( GLViewer_Object* theObject )
573 {
574   if( !theObject || !myInactiveObjects.contains( theObject ) )
575     return false;
576
577   myInactiveObjects.remove( theObject );
578   myActiveObjects.append( theObject );
579   return true;
580 }
581
582 bool GLViewer_Context::setInactive( GLViewer_Object* theObject )
583 {
584   if( !theObject || !myActiveObjects.contains( theObject ) )
585     return false;
586
587   myActiveObjects.remove( theObject );
588   myInactiveObjects.append( theObject );
589   return true;
590 }