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