]> SALOME platform Git repositories - modules/gui.git/blob - src/SPV3D/SPV3D_ViewWindow.cxx
Salome HOME
[bos #42871] Clipping plane remains applied after being deleted
[modules/gui.git] / src / SPV3D / SPV3D_ViewWindow.cxx
1 // Copyright (C) 2023-2024  CEA, EDF
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "SPV3D_ViewWindow.h"
21
22 #include "SPV3D_ViewModel.h"
23
24 #include <QMenu>
25 #include <QToolBar>
26 #include <QTimer>
27 #include <QEvent>
28 #include <QFileInfo>
29 #include <QSignalMapper>
30 #include <QXmlStreamWriter>
31 #include <QXmlStreamReader>
32 #include <QXmlStreamAttributes>
33
34 #include <pqView.h>
35
36 #include "QtxAction.h"
37
38 #include "SUIT_Session.h"
39 #include "SUIT_MessageBox.h"
40 #include "SUIT_Accel.h"
41 #include "SUIT_Tools.h"
42 #include "SUIT_ResourceMgr.h"
43 #include "SUIT_Accel.h"
44 #include "SUIT_OverrideCursor.h"
45 #include "SUIT_ViewManager.h"
46 #include "QtxActionToolMgr.h"
47 #include "QtxMultiAction.h"
48 #include "QtxActionGroup.h"
49
50 #include <pqCameraReaction.h>
51 #include <pqParaViewBehaviors.h>
52 #include <pqRenderView.h>
53
54 #include "SALOME_ListIO.hxx"
55 #include "SPV3D_Prs.h"
56
57 #include <QToolBar>
58
59 // Use workaround for rendering transparent object over MESA
60 #define USE_WORKAROUND_FOR_MESA
61
62 /*!
63   Constructor
64 */
65 SPV3D_ViewWindow::SPV3D_ViewWindow(SUIT_Desktop* theDesktop, SPV3D_ViewModel* theModel):
66   PV3DViewer_ViewWindow(theDesktop, theModel),
67   myModel(theModel)
68 {
69 }
70
71 #include <pqRenderViewSelectionReaction.h>
72 #include <pqPipelineSource.h>
73 #include <vtkSMRenderViewProxy.h>
74 #include <vtkCollection.h>
75 #include <vtkSMRepresentationProxy.h>
76 #include <vtkSMPropertyHelper.h>
77 #include <vtkSMProxyManager.h>
78 #include <vtkRenderer.h>
79 #include <vtkSMSessionProxyManager.h>
80
81 #include "SPV3D_CADSelection.h"
82
83 void SPV3D_ViewWindow::init()
84 {
85   pqView *view(myModel->getView());
86   pqRenderView *renderView(qobject_cast<pqRenderView *>(view));
87   QWidget *wid = view->widget();
88   wid->setParent( this );
89   setCentralWidget( wid );
90   //
91   this->
92   myToolBar = toolMgr()->createToolBar( tr("LBL_TOOLBAR_LABEL"),                       // title (language-dependant)
93                                         QString( "PV3DViewerViewOperations" ),          // name (language-independant)
94                                         false );
95   QAction* resetCenterAction =
96     toolMgr()->toolBar(myToolBar)->addAction(QIcon(":/pqWidgets/Icons/pqResetCamera.svg"), tr( "MNU_FITALL" ) );
97   new pqCameraReaction(resetCenterAction, pqCameraReaction::RESET_CAMERA);
98   QAction *showCenterAction =
99     toolMgr()->toolBar(myToolBar)->addAction(QIcon(":/pqWidgets/Icons/pqShowCenterAxes.svg"), tr( "DSC_SHOW_TRIHEDRON" ) );
100   showCenterAction->setCheckable(true);
101   QObject::connect(showCenterAction, &QAction::toggled, this, &SPV3D_ViewWindow::showCenterAxes);
102   
103   // Pick a new center of rotation on the surface of the mesh
104   QAction* pickCenterAction = toolMgr()->toolBar(myToolBar)->addAction(QIcon(":/pqWidgets/Icons/pqPickCenter.svg"), tr( "MNU_CHANGINGROTATIONPOINT_VIEW" ) );
105   pickCenterAction->setCheckable(true);
106   pqRenderViewSelectionReaction* selectionReaction = new pqRenderViewSelectionReaction(
107     pickCenterAction, renderView, pqRenderViewSelectionReaction::SELECT_CUSTOM_BOX);
108
109   QObject::connect(selectionReaction,
110     QOverload<int, int, int, int>::of(&pqRenderViewSelectionReaction::selectedCustomBox), this,
111     &SPV3D_ViewWindow::pickCenterOfRotation);
112   //
113   mySelection = new SPV3D_CADSelection(this,renderView,SPV3D_CADSelection::SELECT_SOLIDS);
114   QAction *selectionAction =  toolMgr()->toolBar(myToolBar)->addAction(SUIT_Session::session()->resourceMgr()->loadPixmap( "VTKViewer", tr( "ICON_SVTK_PRESELECTION_STANDARD" ) ), tr( "MNU_SVTK_PRESELECTION_STANDARD" ) );
115   selectionAction->setCheckable(true);
116   QObject::connect(selectionAction, &QAction::toggled, this, &SPV3D_ViewWindow::goSelect);
117   
118   SPV3D_EXPORTSPV3DData* rawPtr = new SPV3D_EXPORTSPV3DData();
119   myPrs.reset(rawPtr);
120 }
121
122 void SPV3D_ViewWindow::goSelect(bool val)
123 {
124   if(val)
125     {
126       pqView* activeView(myModel->getView());
127       if (!activeView)
128       {
129         return;
130       }
131       pqPipelineSource *geometrySource = myPrs->GetSourceProducer();
132       if(geometrySource)
133       {
134         vtkSMProxy* repr = activeView->getViewProxy()->FindRepresentation(
135           geometrySource->getSourceProxy(), 0);
136         repr->InvokeCommand("Reset");
137       }
138       activeView->forceRender();
139       activeView->render();
140       activeView->resetDisplay();
141     }
142   mySelection->actionTriggered(val);
143 }
144
145 //-----------------------------------------------------------------------------
146 void SPV3D_ViewWindow::pickCenterOfRotation(int posx, int posy)
147 {
148   pqView *view(myModel->getView());
149   pqRenderView *renderView(qobject_cast<pqRenderView *>(view));
150   if (!renderView)
151     return;
152
153   // Taken from vtkSMRenderViewProxy::ConvertDisplayToPointOnSurface
154   // TODO : we can use this function directly if we make a simple correction in ParaView :
155   // replace the vtkSMPVRepresentationProxy::SafeDownCast(...) by
156   // vtkSMRepresentationProxy::SafeDownCast(...), like done bellow
157   int region[4] = { posx, posy, posx, posy };
158   vtkNew<vtkCollection> representations;
159   vtkNew<vtkCollection> sources;
160
161   vtkSMRenderViewProxy* renderViewProxy = renderView->getRenderViewProxy();
162   renderViewProxy->SelectSurfaceCells(region, representations, sources, false);
163
164   // If a point has been selected
165   if (representations->GetNumberOfItems() > 0 && sources->GetNumberOfItems() > 0)
166   {
167     vtkSMRepresentationProxy* rep =
168       vtkSMRepresentationProxy::SafeDownCast(representations->GetItemAsObject(0));
169     vtkSMProxy* input = vtkSMPropertyHelper(rep, "Input").GetAsProxy(0);
170     vtkSMSourceProxy* selection = vtkSMSourceProxy::SafeDownCast(sources->GetItemAsObject(0));
171
172     // Setup a ray that starts at the center of the camera and ends
173     // at the end of the scene
174     double nearDisplayPoint[3] = { (double)posx, (double)posy, 0.0 };
175     double farDisplayPoint[3] = { (double)posx, (double)posy, 1.0 };
176     double farLinePoint[3] = { 0.0, 0.0, 0.0 };
177     double nearLinePoint[3] = { 0.0, 0.0, 0.0 };
178
179     vtkRenderer* renderer = renderViewProxy->GetRenderer();
180
181     // Compute the near ray point
182     renderer->SetDisplayPoint(nearDisplayPoint);
183     renderer->DisplayToWorld();
184     const double* world = renderer->GetWorldPoint();
185     for (int i = 0; i < 3; i++)
186     {
187       nearLinePoint[i] = world[i] / world[3];
188     }
189
190     // Compute the far ray point
191     renderer->SetDisplayPoint(farDisplayPoint);
192     renderer->DisplayToWorld();
193     world = renderer->GetWorldPoint();
194     for (int i = 0; i < 3; i++)
195     {
196       farLinePoint[i] = world[i] / world[3];
197     }
198
199     // Compute the intersection of the ray with the mesh
200     vtkSMProxyManager* proxyManager = vtkSMProxyManager::GetProxyManager();
201     vtkSMSessionProxyManager* sessionProxyManager = proxyManager->GetActiveSessionProxyManager();
202     vtkSMProxy* pickingHelper = sessionProxyManager->NewProxy("misc", "PickingHelper");
203
204     vtkSMPropertyHelper(pickingHelper, "Input").Set(input);
205     vtkSMPropertyHelper(pickingHelper, "Selection").Set(selection);
206     vtkSMPropertyHelper(pickingHelper, "PointA").Set(nearLinePoint, 3);
207     vtkSMPropertyHelper(pickingHelper, "PointB").Set(farLinePoint, 3);
208     vtkSMPropertyHelper(pickingHelper, "SnapOnMeshPoint").Set(false);
209     pickingHelper->UpdateVTKObjects();
210     pickingHelper->UpdateProperty("Update", 1);
211
212     double center[3] = { 0.0, 0.0, 0.0 };
213     vtkSMPropertyHelper(pickingHelper, "Intersection").UpdateValueFromServer();
214     vtkSMPropertyHelper(pickingHelper, "Intersection").Get(center, 3);
215     pickingHelper->Delete();
216
217     // Update the camera
218     vtkSMRenderViewProxy* renderViewProxy = renderView->getRenderViewProxy();
219     vtkSMPropertyHelper(renderViewProxy, "CenterOfRotation").Set(center, 3);
220     vtkSMPropertyHelper(renderViewProxy, "CameraFocalPoint").Set(center, 3);
221     renderViewProxy->UpdateVTKObjects();
222     renderView->render();
223   }
224 }
225
226 void SPV3D_ViewWindow::showCenterAxes(bool show_axes)
227 {
228   if(!myModel)
229     return;
230   pqRenderView* renderView = qobject_cast<pqRenderView*>(myModel->getView());
231   if (!renderView)
232     return;
233   renderView->setCenterAxesVisibility(show_axes);
234   renderView->render();
235 }
236
237
238 SPV3D_Prs *SPV3D_ViewWindow::findOrCreatePrs( const char* entry )
239 {//en cours
240   SPV3D_Prs *prsOut( new SPV3D_Prs( entry, this ) );
241   prsOut->SetPVRenderInfo( myPrs.get() );
242   return prsOut;
243 }
244
245 unsigned int SPV3D_ViewWindow::isEntryAlreadyExist( const char* entry ) const
246 {
247   unsigned int id;
248   if(myPrs->havePrs(entry, id))
249     return id;
250   else
251     return -1;
252 }
253
254 void SPV3D_ViewWindow::ExportToSPV3D(vtkPolyData* ds, const char* entry)
255 {
256   myPrs->SetPrs(ds, entry);
257 }
258
259 /*!
260   Destructor
261 */
262 SPV3D_ViewWindow::~SPV3D_ViewWindow()
263 {
264 }
265
266 bool SPV3D_ViewWindow::isVisible(const Handle(SALOME_InteractiveObject)& theIObject)
267 {
268   auto entry =  theIObject->getEntry();
269   unsigned int id;
270   if (myPrs->havePrs(entry, id))
271   {
272     return true;
273   }
274   return false;
275 }
276
277 /*!
278   Display object
279   \param theIO - object
280   \param theImmediatly - update viewer
281 */
282 void SPV3D_ViewWindow::Display(const Handle(SALOME_InteractiveObject)& /*theIO*/,
283                               bool /*theImmediatly*/) 
284 {
285 }
286
287 /*!
288   Erase object
289   \param theIO - object
290   \param theImmediatly - update viewer
291 */
292 void SPV3D_ViewWindow::Erase(const Handle(SALOME_InteractiveObject)& /*theIO*/,
293                             bool /*theImmediatly*/)
294 {
295 }
296
297 /*!
298   Display only passed object
299   \param theIO - object
300 */
301 void SPV3D_ViewWindow::DisplayOnly(const Handle(SALOME_InteractiveObject)& /*theIO*/)
302 {
303 }
304
305
306 /*!
307   Display all objects in view
308 */
309 void SPV3D_ViewWindow::DisplayAll() 
310 {
311 }
312
313 /*!
314   Erase all objects in view
315 */
316 void SPV3D_ViewWindow::EraseAll() 
317 {
318   myPrs->Hide();
319   if(myModel)
320     myModel->render();
321 }
322
323 /*!
324   Updates current viewer
325 */
326 void SPV3D_ViewWindow::Repaint(bool )//(bool theUpdateTrihedron)
327 {
328   if(myModel)
329     myModel->render();
330 }
331
332 /*!
333   Enables/disables selection.
334   \param theEnable if true - selection will be enabled
335 */
336 void SPV3D_ViewWindow::SetSelectionEnabled( bool /*theEnable*/ )
337 {
338 }
339
340 /*!
341   Emits key pressed
342 */
343 void SPV3D_ViewWindow::onKeyPressed(QKeyEvent* event)
344 {
345   emit keyPressed( this, event );
346 }
347
348 /*!
349   Emits key released
350 */
351 void SPV3D_ViewWindow::onKeyReleased(QKeyEvent* event)
352 {
353   emit keyReleased( this, event );
354 }
355
356 /*!
357   Emits mouse pressed
358 */
359 void SPV3D_ViewWindow::onMousePressed(QMouseEvent* event)
360 {
361   emit mousePressed(this, event);
362 }
363
364 /*!
365   Emits mouse released
366 */
367 void SPV3D_ViewWindow::onMouseReleased(QMouseEvent* event)
368 {
369   emit mouseReleased( this, event );
370 }
371
372 /*!
373   Emits mouse moving
374 */
375 void SPV3D_ViewWindow::onMouseMoving(QMouseEvent* event)
376 {
377   emit mouseMoving( this, event );
378 }
379
380 /*!
381   Emits mouse double clicked
382 */
383 void SPV3D_ViewWindow::onMouseDoubleClicked( QMouseEvent* event )
384 {
385   emit mouseDoubleClicked( this, event );
386 }
387
388 /*!
389   Custom show event handler
390 */
391 void SPV3D_ViewWindow::showEvent( QShowEvent * theEvent ) 
392 {
393   emit Show( theEvent );
394 }
395
396 /*!
397   Custom hide event handler
398 */
399 void SPV3D_ViewWindow::hideEvent( QHideEvent * theEvent ) 
400 {
401   emit Hide( theEvent );
402 }