1 // Copyright (C) 2023 CEA, EDF
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "SPV3D_ViewWindow.h"
22 #include "SPV3D_ViewModel.h"
29 #include <QSignalMapper>
30 #include <QXmlStreamWriter>
31 #include <QXmlStreamReader>
32 #include <QXmlStreamAttributes>
36 #include "QtxAction.h"
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"
50 #include <pqCameraReaction.h>
51 #include <pqParaViewBehaviors.h>
52 #include <pqRenderView.h>
54 #include "SALOME_ListIO.hxx"
55 #include "SPV3D_Prs.h"
59 // Use workaround for rendering transparent object over MESA
60 #define USE_WORKAROUND_FOR_MESA
65 SPV3D_ViewWindow::SPV3D_ViewWindow(SUIT_Desktop* theDesktop, SPV3D_ViewModel* theModel):
66 PV3DViewer_ViewWindow(theDesktop, theModel),
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>
81 #include "SPV3D_CADSelection.h"
83 void SPV3D_ViewWindow::init()
85 pqView *view(myModel->getView());
86 pqRenderView *renderView(qobject_cast<pqRenderView *>(view));
87 QWidget *wid = view->widget();
88 wid->setParent( this );
89 setCentralWidget( wid );
92 myToolBar = toolMgr()->createToolBar( tr("LBL_TOOLBAR_LABEL"), // title (language-dependant)
93 QString( "PV3DViewerViewOperations" ), // name (language-independant)
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);
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);
109 QObject::connect(selectionReaction,
110 QOverload<int, int, int, int>::of(&pqRenderViewSelectionReaction::selectedCustomBox), this,
111 &SPV3D_ViewWindow::pickCenterOfRotation);
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);
119 void SPV3D_ViewWindow::goSelect(bool val)
123 pqView* activeView(myModel->getView());
128 for(const auto& elt : myPrs)
130 pqPipelineSource *geometrySource = elt.second->GetSourceProducer();
133 vtkSMProxy* repr = activeView->getViewProxy()->FindRepresentation(
134 geometrySource->getSourceProxy(), 0);
135 repr->InvokeCommand("Reset");
138 activeView->forceRender();
139 activeView->render();
140 activeView->resetDisplay();
142 mySelection->actionTriggered(val);
145 //-----------------------------------------------------------------------------
146 void SPV3D_ViewWindow::pickCenterOfRotation(int posx, int posy)
148 pqView *view(myModel->getView());
149 pqRenderView *renderView(qobject_cast<pqRenderView *>(view));
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;
161 vtkSMRenderViewProxy* renderViewProxy = renderView->getRenderViewProxy();
162 renderViewProxy->SelectSurfaceCells(region, representations, sources, false);
164 // If a point has been selected
165 if (representations->GetNumberOfItems() > 0 && sources->GetNumberOfItems() > 0)
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));
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 };
179 vtkRenderer* renderer = renderViewProxy->GetRenderer();
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++)
187 nearLinePoint[i] = world[i] / world[3];
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++)
196 farLinePoint[i] = world[i] / world[3];
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");
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);
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();
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();
226 void SPV3D_ViewWindow::showCenterAxes(bool show_axes)
230 pqRenderView* renderView = qobject_cast<pqRenderView*>(myModel->getView());
233 renderView->setCenterAxesVisibility(show_axes);
234 renderView->render();
237 SPV3D_Prs *SPV3D_ViewWindow::findOrCreatePrs( const char* entry )
239 std::string entryCpp( entry );
240 SPV3D_Prs *prsOut( new SPV3D_Prs( entry, this ) );
241 for(auto& prs : myPrs)
243 if(entryCpp == prs.first)
245 prsOut->SetPVRenderInfo( prs.second.get() );
249 std::unique_ptr<SPV3D_EXPORTSPV3DData> data(new SPV3D_EXPORTSPV3DData);
250 prsOut->SetPVRenderInfo( data.get() );
251 std::pair<std::string, std::unique_ptr<SPV3D_EXPORTSPV3DData> > p(entryCpp,std::move(data));
252 myPrs.emplace_back( std::move(p) );
256 SPV3D_EXPORTSPV3DData *SPV3D_ViewWindow::isEntryAlreadyExist( const char* entry ) const
258 std::string entryCpp( entry );
259 for(const auto& prs : myPrs)
261 if(entryCpp == prs.first)
262 return prs.second.get();
270 SPV3D_ViewWindow::~SPV3D_ViewWindow()
274 bool SPV3D_ViewWindow::isVisible(const Handle(SALOME_InteractiveObject)& theIObject)
276 std::string entryCpp( theIObject->getEntry() );
277 for(auto& prs : myPrs)
279 if(entryCpp == prs.first )
280 return prs.second->IsVisible();
287 \param theIO - object
288 \param theImmediatly - update viewer
290 void SPV3D_ViewWindow::Display(const Handle(SALOME_InteractiveObject)& /*theIO*/,
291 bool /*theImmediatly*/)
297 \param theIO - object
298 \param theImmediatly - update viewer
300 void SPV3D_ViewWindow::Erase(const Handle(SALOME_InteractiveObject)& /*theIO*/,
301 bool /*theImmediatly*/)
306 Display only passed object
307 \param theIO - object
309 void SPV3D_ViewWindow::DisplayOnly(const Handle(SALOME_InteractiveObject)& /*theIO*/)
315 Display all objects in view
317 void SPV3D_ViewWindow::DisplayAll()
322 Erase all objects in view
324 void SPV3D_ViewWindow::EraseAll()
326 for(auto& prs : myPrs)
335 Updates current viewer
337 void SPV3D_ViewWindow::Repaint(bool )//(bool theUpdateTrihedron)
344 Enables/disables selection.
345 \param theEnable if true - selection will be enabled
347 void SPV3D_ViewWindow::SetSelectionEnabled( bool /*theEnable*/ )
354 void SPV3D_ViewWindow::onKeyPressed(QKeyEvent* event)
356 emit keyPressed( this, event );
362 void SPV3D_ViewWindow::onKeyReleased(QKeyEvent* event)
364 emit keyReleased( this, event );
370 void SPV3D_ViewWindow::onMousePressed(QMouseEvent* event)
372 emit mousePressed(this, event);
378 void SPV3D_ViewWindow::onMouseReleased(QMouseEvent* event)
380 emit mouseReleased( this, event );
386 void SPV3D_ViewWindow::onMouseMoving(QMouseEvent* event)
388 emit mouseMoving( this, event );
392 Emits mouse double clicked
394 void SPV3D_ViewWindow::onMouseDoubleClicked( QMouseEvent* event )
396 emit mouseDoubleClicked( this, event );
400 Custom show event handler
402 void SPV3D_ViewWindow::showEvent( QShowEvent * theEvent )
404 emit Show( theEvent );
408 Custom hide event handler
410 void SPV3D_ViewWindow::hideEvent( QHideEvent * theEvent )
412 emit Hide( theEvent );