Salome HOME
updated copyright message
[modules/gui.git] / src / SPV3D / SPV3D_ViewModel.cxx
1 // Copyright (C) 2023  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 <QMenu>
21 #include <QColorDialog>
22 #include <QToolBar>
23 #include <QTimer>
24
25 #include <vtkActorCollection.h>
26
27 #include "SPV3D_ViewModel.h"
28 #include "SPV3D_ViewWindow.h"
29 #include "SPV3D_Prs.h"
30 #include "PVViewer_Core.h"
31
32 #include <pqActiveObjects.h>
33 #include <pqApplicationCore.h>
34 #include <pqObjectBuilder.h>
35 #include <pqPipelineSource.h>
36 #include <pqRenderView.h>
37
38 #include <vtkSMPropertyHelper.h>
39 #include <vtkSMParaViewPipelineControllerWithRendering.h>
40 #include <vtkSMRenderViewProxy.h>
41 #include <vtkSMRepresentationProxy.h>
42 #include <vtkSMSourceProxy.h>
43 #include <vtkSMPVRepresentationProxy.h>
44
45 #include "SUIT_ViewModel.h"
46 #include "SUIT_ViewManager.h"
47
48 #include "SALOME_InteractiveObject.hxx"
49
50 #include "QtxActionToolMgr.h"
51 #include "QtxBackgroundTool.h"
52
53 #include <pqObjectBuilder.h>
54 #include <pqApplicationCore.h>
55 #include <pqServerManagerModel.h>
56 #include <pqServerResource.h>
57 #include <pqView.h>
58 #include <pqPVApplicationCore.h>
59 #include <pqParaViewBehaviors.h>
60
61 #include <QApplication>
62
63 // VSR: Uncomment below line to allow texture background support in PV3D viewer
64 #define PV3D_ENABLE_TEXTURED_BACKGROUND
65
66 /*!
67   Constructor
68 */
69 SPV3D_ViewModel::SPV3D_ViewModel()
70 {
71   mySelectionEnabled = true;
72 }
73
74 /*!
75   Destructor
76 */
77 SPV3D_ViewModel::~SPV3D_ViewModel() 
78 {
79 }
80
81
82 void SPV3D_ViewModel::initialize()
83 {
84 }
85
86 void SPV3D_ViewModel::render() const
87 {
88   if( _view )
89     _view->render();
90 }
91
92 /*!Create new instance of view window on desktop \a theDesktop.
93  *\retval SUIT_ViewWindow* - created view window pointer.
94  */
95 SUIT_ViewWindow* SPV3D_ViewModel::createView( SUIT_Desktop* theDesktop )
96 {
97   SPV3D_ViewWindow* aViewWindow = new SPV3D_ViewWindow(theDesktop, this);
98
99   aViewWindow->SetSelectionEnabled( isSelectionEnabled() );
100   PVViewer_Core::ParaviewInitApp();
101   QApplication::instance()->installEventFilter( PVViewer_Core::GetPVAppCore() );
102   new pqParaViewBehaviors(aViewWindow,aViewWindow);
103   pqObjectBuilder *builder(pqApplicationCore::instance()->getObjectBuilder());
104   QObject::connect(builder, &pqObjectBuilder::sourceCreated, this, &SPV3D_ViewModel::onSourceCreated);
105   pqServer *serv(pqApplicationCore::instance()->getServerManagerModel()->findServer(pqServerResource("builtin:")));
106   pqView *view=builder->createView(QString("RenderView"),serv);
107   setView(view);
108   
109   aViewWindow->init();
110   
111   return aViewWindow;
112 }
113
114 /*!
115   Sets new view manager
116   \param theViewManager - new view manager
117 */
118 void SPV3D_ViewModel::setViewManager(SUIT_ViewManager* theViewManager)
119 {
120   SUIT_ViewModel::setViewManager(theViewManager);
121
122   if ( !theViewManager )
123     return;
124
125   connect(theViewManager, SIGNAL(mousePress(SUIT_ViewWindow*, QMouseEvent*)), 
126           this, SLOT(onMousePress(SUIT_ViewWindow*, QMouseEvent*)));
127   
128   connect(theViewManager, SIGNAL(mouseMove(SUIT_ViewWindow*, QMouseEvent*)), 
129           this, SLOT(onMouseMove(SUIT_ViewWindow*, QMouseEvent*)));
130   
131   connect(theViewManager, SIGNAL(mouseRelease(SUIT_ViewWindow*, QMouseEvent*)), 
132           this, SLOT(onMouseRelease(SUIT_ViewWindow*, QMouseEvent*)));
133
134   connect(theViewManager, SIGNAL(viewCreated(SUIT_ViewWindow*)), 
135           this, SLOT(onViewCreated(SUIT_ViewWindow*)));
136 }
137
138 /*!
139   Builds popup for vtk viewer
140 */
141 void SPV3D_ViewModel::contextMenuPopup( QMenu */*thePopup*/ )
142 {
143   // NYI
144 }
145
146 /*!
147   SLOT: called on mouse button press, empty implementation
148 */
149 void SPV3D_ViewModel::onMousePress(SUIT_ViewWindow* /*vw*/, QMouseEvent* /*event*/)
150 {}
151
152 /*!
153   SLOT: called on mouse move, empty implementation
154 */
155 void SPV3D_ViewModel::onMouseMove(SUIT_ViewWindow* /*vw*/, QMouseEvent* /*event*/)
156 {}
157
158 /*!
159   SLOT: called on mouse button release, empty implementation
160 */
161 void SPV3D_ViewModel::onMouseRelease(SUIT_ViewWindow* /*vw*/, QMouseEvent* /*event*/)
162 {}
163
164 /*!
165   Enables/disables selection
166   \param isEnabled - new state
167 */
168 void SPV3D_ViewModel::enableSelection(bool isEnabled)
169 {
170   mySelectionEnabled = isEnabled;
171   //!! To be done for view windows
172   if (SUIT_ViewManager* aViewManager = getViewManager()) {
173     QVector<SUIT_ViewWindow*> aViews = aViewManager->getViews();
174     for ( int i = 0; i < aViews.count(); i++ )
175     {
176       if ( SPV3D_ViewWindow* aView = dynamic_cast<SPV3D_ViewWindow*>(aViews.at( i )) )
177         aView->SetSelectionEnabled( isEnabled );
178     }
179   }
180
181   if(!isEnabled) {
182     //clear current selection in the viewer
183     bool blocked = blockSignals( true );
184     /*if ( SUIT_ViewManager* aViewMgr = getViewManager() ) {
185       if( SPV3D_ViewWindow* aViewWindow = dynamic_cast<SPV3D_ViewWindow*>( aViewMgr->getActiveView() ) ){
186         //NYI
187       }
188     }*/
189     blockSignals( blocked );  
190   }
191
192 }
193
194 pqView *SPV3D_ViewModel::getView() const
195 {
196   return _view;
197 }
198
199 /*!
200   Display presentation
201   \param prs - presentation
202 */
203 void SPV3D_ViewModel::Display( const SALOME_PV3DPrs* prs )
204 {
205   if(const SPV3D_Prs* aPrs = dynamic_cast<const SPV3D_Prs*>( prs ))
206   {
207     if( !aPrs->GetRepresentation() )
208     {
209       pqObjectBuilder *builder(pqApplicationCore::instance()->getObjectBuilder());
210       pqActiveObjects::instance().setActiveView(getView());
211       pqPipelineSource *mySourceProducer = aPrs->GetSourceProducer();
212       aPrs->SetSourceProducer( mySourceProducer );
213       pqDataRepresentation* myRepr(builder->createDataRepresentation(mySourceProducer->getOutputPort(0),getView(),"CADRepresentation"));//"GeometryRepresentation"
214       vtkSMViewProxy::RepresentationVisibilityChanged(myRepr->getViewProxy(), myRepr->getProxy(), true);
215       aPrs->SetRepresentation(myRepr);
216     }
217     pqDataRepresentation* myRepr = aPrs->GetRepresentation();
218     myRepr->setVisible(1);
219     vtkSMPVRepresentationProxy* proxy(dynamic_cast<vtkSMPVRepresentationProxy*>(myRepr->getProxy()));
220     if(proxy)
221     {
222       vtkSMPropertyHelper inputHelper(proxy, "Input");
223       vtkSMSourceProxy* input = vtkSMSourceProxy::SafeDownCast(inputHelper.GetAsProxy());
224       input->UpdatePipeline();
225     }
226     getView()->resetDisplay();
227     getView()->render();
228   }
229 }
230
231 /*!
232   Erase presentation
233   \param prs - presentation
234   \param forced - removes object from view
235 */
236 void SPV3D_ViewModel::Erase( const SALOME_PV3DPrs* prs, const bool /*forced*/ )
237 {
238   // NYI - hide a source
239   if(const SPV3D_Prs* aPrs = dynamic_cast<const SPV3D_Prs*>( prs )){
240     if(aPrs->IsNull())
241       return;
242     aPrs->GetRepresentation()->setVisible(0);
243     getView()->render();
244     //pqObjectBuilder* builder = pqApplicationCore::instance()->getObjectBuilder();
245     //pqServer* activeServer = pqActiveObjects::instance().activeServer();
246     //builder->destroySources(activeServer);
247   }
248 }
249
250 /*!
251   Erase all presentations
252   \param forced - removes all objects from view
253 */
254 void SPV3D_ViewModel::EraseAll( SALOME_Displayer* d, const bool forced )
255 {
256   SALOME_View::EraseAll( d, forced );
257   if(SPV3D_ViewWindow* aViewWindow = dynamic_cast<SPV3D_ViewWindow*>(getViewManager()->getActiveView()))
258     aViewWindow->EraseAll();
259   Repaint();
260 }
261
262 /*!
263   Create presentation corresponding to the entry
264   \param entry - entry
265 */
266 SALOME_Prs* SPV3D_ViewModel::CreatePrs( const char* entry )
267 {
268   if(SPV3D_ViewWindow* aViewWindow = dynamic_cast<SPV3D_ViewWindow*>(getViewManager()->getActiveView()))
269   {
270     return aViewWindow->findOrCreatePrs( entry );
271   }
272   return nullptr;
273 }
274
275 /*!
276   \return true if object is displayed in viewer
277   \param obj - object to be checked
278 */
279 bool SPV3D_ViewModel::isVisible( const Handle(SALOME_InteractiveObject)& io )
280 {
281   if(SPV3D_ViewWindow* aViewWindow = dynamic_cast<SPV3D_ViewWindow*>(getViewManager()->getActiveView()))
282     return aViewWindow->isVisible( io );
283   return false;
284 }
285
286 /*!
287   \Collect objects visible in viewer
288   \param theList - visible objects collection
289 */
290 void SPV3D_ViewModel::GetVisible( SALOME_ListIO &/*theList*/ )
291 {
292   // NYI
293 }
294
295 /*!
296   Updates current viewer
297 */
298 void SPV3D_ViewModel::Repaint()
299 {
300   // NYI
301 }
302
303
304 void SPV3D_ViewModel::onViewCreated( SUIT_ViewWindow */*view*/) {
305 #ifdef VGL_WORKAROUND
306   if ( SPV3D_ViewWindow* svw = dynamic_cast<SPV3D_ViewWindow*>( view ) )
307     QTimer::singleShot(500, [svw] () { svw->Repaint(); } );
308 #endif
309 }
310
311 //-----------------------------------------------------------------------------
312 void SPV3D_ViewModel::onSourceCreated(pqPipelineSource* source)
313 {
314   std::string sourceXMLName(source->getSourceProxy()->GetXMLName());
315   pqObjectBuilder* builder = pqApplicationCore::instance()->getObjectBuilder();
316   if (sourceXMLName == "XMLPolyDataReader" || sourceXMLName == "GeometryGenerator" || sourceXMLName == "ShapeSource" || sourceXMLName == "CubeSource")
317   {
318     if (this->GeometrySource)
319     {
320       if (this->GeometrySource == source) {
321       }
322       else
323         builder->destroy(this->GeometrySource);
324     }
325     this->GeometrySource = source;
326   }
327   else
328   {
329     qWarning("Unsupported Source");
330     return;
331   }
332   this->showSelectedMode();
333 }
334
335 //-----------------------------------------------------------------------------
336 void SPV3D_ViewModel::showSelectedMode()
337 {
338   vtkNew<vtkSMParaViewPipelineControllerWithRendering> controller;
339   pqView* activeView = pqActiveObjects::instance().activeView();
340   if (activeView)
341   {
342     if (this->GeometrySource)
343     {
344 #if PARAVIEW_VERSION_MINOR <= 10
345       this->GeometrySource->updatePipeline();
346       this->GeometrySource->setModifiedState(pqProxy::UNMODIFIED);
347 #endif
348
349       vtkSMSourceProxy *sourceProxy = this->GeometrySource->getSourceProxy();
350       vtkSMViewProxy *viewProxy = activeView->getViewProxy();
351       //const char *representationType = "CADRepresentation";
352       controller->Show(sourceProxy, 0, viewProxy);//, representationType);
353
354     }
355   }
356   activeView->render();
357   activeView->resetDisplay();
358 }