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