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