Salome HOME
porting to sketcher in GEOM
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_Displayer.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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.
10 //
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.
15 //
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
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "HYDROGUI_Displayer.h"
24
25 #include "HYDROGUI_DataModel.h"
26 #include "HYDROGUI_Module.h"
27 #include "HYDROGUI_Prs.h"
28 #include "HYDROGUI_PrsImageDriver.h"
29 #include "HYDROGUI_PrsPolylineDriver.h"
30 #include "HYDROGUI_PrsZoneDriver.h"
31 #include "HYDROGUI_Tool.h"
32
33 #include <CurveCreator_Utils.hxx>
34
35 #include <LightApp_Application.h>
36 #include <SVTK_ViewWindow.h>
37 #include <OCCViewer_ViewWindow.h>
38 #include <OCCViewer_ViewPort3d.h>
39 #include <SUIT_ViewManager.h>
40
41 #include <vtkRenderWindowInteractor.h>
42 #include <vtkRenderer.h>
43 #include <vtkWorldPointPicker.h>
44 #include <vtkCamera.h>
45
46 #include <GraphicsView_Viewer.h>
47 #include <GraphicsView_ViewPort.h>
48
49 const double LOCAL_SELECTION_TOLERANCE = 0.0001;
50
51 HYDROGUI_Displayer::HYDROGUI_Displayer( HYDROGUI_Module* theModule )
52 : HYDROGUI_AbstractDisplayer( theModule ),
53   myXPosition( -1 ), myYPosition( -1 ), myIsPositionSaved( false )
54 {
55 }
56
57 HYDROGUI_Displayer::~HYDROGUI_Displayer()
58 {
59 }
60
61 void HYDROGUI_Displayer::SetToUpdate( const HYDROData_SequenceOfObjects& theObjs,
62                                       const int theViewerId )
63 {
64   GraphicsView_Viewer* aViewer = module()->getViewer( theViewerId );
65   if( !aViewer )
66     return;
67
68   GraphicsView_ViewPort* aViewPort = aViewer->getActiveViewPort();
69   if( !aViewPort )
70     return;
71
72   GraphicsView_ObjectList anObjectList = aViewPort->getObjects();
73   for( int i = 1, n = theObjs.Length(); i <= n; i++ )
74   {
75     Handle(HYDROData_Entity) anObj = theObjs.Value( i );
76     if( anObj.IsNull() )
77       continue;
78
79     if( HYDROGUI_Prs* aPrs = HYDROGUI_Tool::GetPresentation( anObj, anObjectList ) )
80       aPrs->setIsToUpdate( true );
81   }
82 }
83
84 void HYDROGUI_Displayer::EraseAll( const int theViewerId )
85 {
86   GraphicsView_Viewer* aViewer = module()->getViewer( theViewerId );
87   if( !aViewer )
88     return;
89
90   GraphicsView_ViewPort* aViewPort = aViewer->getActiveViewPort();
91   if( !aViewPort )
92     return;
93
94   GraphicsView_ObjectListIterator anIter( HYDROGUI_Tool::GetPrsList( aViewPort ) );
95   while( anIter.hasNext() )
96   {
97     if( GraphicsView_Object* anObject = anIter.next() )
98     {
99       aViewPort->removeItem( anObject );
100       delete anObject;
101     }
102   }
103 }
104
105 void HYDROGUI_Displayer::Erase( const HYDROData_SequenceOfObjects& theObjs,
106                                 const int theViewerId )
107 {
108   GraphicsView_Viewer* aViewer = module()->getViewer( theViewerId );
109   if( !aViewer )
110     return;
111
112   GraphicsView_ViewPort* aViewPort = aViewer->getActiveViewPort();
113   if( !aViewPort )
114     return;
115
116   HYDROGUI_DataModel* aModel = (HYDROGUI_DataModel*)module()->dataModel();
117   if( aModel ) 
118   {
119     GraphicsView_ObjectList anObjectList = HYDROGUI_Tool::GetPrsList( aViewPort );
120     for( int i = 1, n = theObjs.Length(); i <= n; i++ )
121     {
122       // the object may be null or dead
123       const Handle(HYDROData_Entity)& anObj = theObjs.Value( i );
124       if( HYDROGUI_Prs* aPrs = HYDROGUI_Tool::GetPresentation( anObj, anObjectList ) )
125       {
126         aViewPort->removeItem( aPrs );
127         anObjectList.removeAll( aPrs );
128         delete aPrs;
129       }
130     }
131   }
132 }
133
134 void HYDROGUI_Displayer::Display( const HYDROData_SequenceOfObjects& theObjs,
135                                   const int theViewerId,
136                                   const bool theIsForced,
137                                   const bool theDoFitAll)
138 {
139   GraphicsView_Viewer* aViewer = module()->getViewer( theViewerId );
140   if( !aViewer )
141     return;
142
143   GraphicsView_ViewPort* aViewPort = aViewer->getActiveViewPort();
144   if( !aViewPort )
145     return;
146
147   bool anIsDisplayed = false;
148   GraphicsView_ObjectList anObjectList = aViewPort->getObjects();
149   for( int i = 1, n = theObjs.Length(); i <= n; i++ )
150   {
151     Handle(HYDROData_Entity) anObj = theObjs.Value( i );
152     if( anObj.IsNull() )
153       continue;
154
155     HYDROGUI_Prs* aPrs = HYDROGUI_Tool::GetPresentation( anObj, anObjectList );
156
157     bool anIsInserted = ( aPrs != 0 );
158     if( !aPrs || aPrs->getIsToUpdate() || theIsForced )
159     {
160       if( HYDROGUI_PrsDriver* aDriver = getDriver( anObj ) )
161       {
162         if( aDriver->Update( anObj, aPrs ) && aPrs && !anIsInserted )
163           aViewPort->addItem( aPrs );
164       }
165     }
166
167     if( aPrs )
168     {
169       bool anIsVisible = module()->isObjectVisible( (size_t)aViewer, anObj );
170       aPrs->setVisible( anIsVisible );
171     }
172   }
173
174   aViewPort->onBoundingRectChanged(); // specific of HYDRO module
175   if ( theDoFitAll )
176   {
177     aViewPort->fitAll();
178   }
179 }
180
181 void HYDROGUI_Displayer::purgeObjects( const int theViewerId )
182 {
183   GraphicsView_Viewer* aViewer = module()->getViewer( theViewerId );
184   if( !aViewer )
185     return;
186
187   GraphicsView_ViewPort* aViewPort = aViewer->getActiveViewPort();
188   if( !aViewPort )
189     return;
190
191   GraphicsView_ObjectListIterator anIter( HYDROGUI_Tool::GetPrsList( aViewPort ) );
192   while( anIter.hasNext() )
193   {
194     if( HYDROGUI_Prs* aPrs = dynamic_cast<HYDROGUI_Prs*>( anIter.next() ) )
195     {
196       Handle(HYDROData_Entity) anObject = aPrs->getObject();
197       if( !anObject.IsNull() && anObject->IsRemoved() )
198       {
199         aViewPort->removeItem( aPrs );
200         delete aPrs;
201       }
202     }
203   }
204 }
205
206 HYDROGUI_PrsDriver* HYDROGUI_Displayer::getDriver( const Handle(HYDROData_Entity)& theObj )
207 {
208   HYDROGUI_PrsDriver* aDriver = NULL;
209   ObjectKind aKind = theObj->GetKind();
210   PrsDriversMap::iterator anIter = myPrsDriversMap.find( aKind );
211   if( anIter != myPrsDriversMap.end() )
212     aDriver = anIter.value();
213   else 
214   {
215     switch( aKind )
216     {
217       case KIND_IMAGE:
218         aDriver = new HYDROGUI_PrsImageDriver();
219         break;
220       case KIND_POLYLINEXY:
221         aDriver = new HYDROGUI_PrsPolylineDriver();
222         break;
223       case KIND_ZONE:
224         aDriver = new HYDROGUI_PrsZoneDriver();
225         break;
226       default:
227         break;
228     }
229
230     if ( aDriver )
231       myPrsDriversMap[ aKind ] = aDriver;
232   }
233
234   return aDriver;
235 }
236
237 QString HYDROGUI_Displayer::GetType() const
238 {
239   return GraphicsView_Viewer::Type();
240 }
241
242 void HYDROGUI_Displayer::SaveCursorViewPosition( SUIT_ViewWindow* theViewWindow )
243 {
244   myIsPositionSaved = false;
245   myXPosition = 0;
246   myYPosition = 0;
247
248   SUIT_ViewWindow* aViewWindow = theViewWindow;
249   if ( !theViewWindow ) {
250     SUIT_ViewManager* aViewMgr = module()->getApp()->activeViewManager();
251     aViewWindow = aViewMgr ? aViewMgr->getActiveView() : 0;
252     if ( !aViewWindow )
253       return;
254   }
255   
256   OCCViewer_ViewWindow* anOCCViewWindow = 
257     dynamic_cast<OCCViewer_ViewWindow*>( aViewWindow );
258   if ( anOCCViewWindow ) {
259     // Get the selected point coordinates
260     OCCViewer_ViewPort3d* aViewPort = anOCCViewWindow->getViewPort();
261     if ( aViewPort ) {
262       QPoint aViewPos = aViewPort->mapFromGlobal( QCursor::pos() );
263       myXPosition = aViewPos.x();
264       myYPosition = aViewPos.y();
265       myIsPositionSaved = true;
266     }
267   }
268   else {
269     SVTK_ViewWindow* aVTKViewWindow = 
270       dynamic_cast<SVTK_ViewWindow*>(aViewWindow);
271     if ( aVTKViewWindow ) {
272       vtkRenderer* aRen = aVTKViewWindow->getRenderer();
273       if ( aRen )
274       {
275         vtkCamera* aCamera = aRen->GetActiveCamera();
276         double* aNormal = aCamera->GetViewPlaneNormal();
277         vtkRenderWindowInteractor* anInteractor = aVTKViewWindow->getInteractor();
278         if ( anInteractor )
279         {
280           anInteractor->GetLastEventPosition( myXPosition, myYPosition );
281           myIsPositionSaved = true;
282         }
283       }
284     }
285   }
286   if (!myIsPositionSaved)
287     int aValue = 0;
288 }
289
290 bool HYDROGUI_Displayer::GetCursorViewCoordinates( SUIT_ViewWindow* theViewWindow,
291                                                    double& theXCoordinate,
292                                                    double& theYCoordinate,
293                                                    double& theZCoordinate )
294 {
295   theXCoordinate = 0;
296   theYCoordinate = 0;
297   theZCoordinate = 0;
298   bool doShow = false;
299   if ( !theViewWindow || !myIsPositionSaved )
300     return doShow;
301   
302   OCCViewer_ViewWindow* anOCCViewWindow = 
303     dynamic_cast<OCCViewer_ViewWindow*>(theViewWindow);
304   if ( anOCCViewWindow ) {
305     // Get the selected point coordinates
306     OCCViewer_ViewPort3d* aViewPort = anOCCViewWindow->getViewPort();
307     if ( !aViewPort ) {
308       return doShow;
309     }
310     gp_Pnt aPnt = CurveCreator_Utils::ConvertClickToPoint( myXPosition, myYPosition,
311                                                            aViewPort->getView() );
312     theXCoordinate = aPnt.X();
313     theYCoordinate = aPnt.Y();
314     doShow = true;
315   } 
316   else
317   {
318     SVTK_ViewWindow* aVTKViewWindow = 
319       dynamic_cast<SVTK_ViewWindow*>(theViewWindow);
320     if ( aVTKViewWindow ) {
321       vtkRenderer* aRen = aVTKViewWindow->getRenderer();
322       if ( aRen )
323       {
324         vtkCamera* aCamera = aRen->GetActiveCamera();
325         double* aNormal = aCamera->GetViewPlaneNormal();
326         myPicker->Pick( myXPosition, myYPosition, 0, aRen );
327         double* aCoords = myPicker->GetPickPosition();
328         /////////////////////// Use the same algorithm as for OCC
329         double X, Y, Z;
330         double aXp, aYp, aZp;
331         double Vx, Vy, Vz;
332         X = aCoords[0];
333         Y = aCoords[1];
334         Z = aCoords[2];
335         Vx = aNormal[0];
336         Vy = aNormal[1];
337         Vz = aNormal[2];
338         Standard_Real aPrec = LOCAL_SELECTION_TOLERANCE;
339         if ( fabs( Vz ) > aPrec ) {
340           double aT = -Z/Vz;
341           aXp = X + aT*Vx;
342           aYp = Y + aT*Vy;
343           aZp = Z + aT*Vz;
344         }
345         else { // Vz = 0 - the eyed plane is orthogonal to Z plane - XOZ, or YOZ
346           aXp = aYp = aZp = 0;
347           if ( fabs( Vy ) < aPrec ) // Vy = 0 - the YOZ plane
348             aYp = Y;
349           else if ( fabs( Vx ) < aPrec ) // Vx = 0 - the XOZ plane
350             aXp = X;
351         }
352         /////////////////////////
353         theXCoordinate = aXp;
354         theYCoordinate = aYp;
355         doShow = true;
356       }
357     } 
358   }
359   return doShow;
360 }