Salome HOME
Join modifications from branch OCC_development_for_3_2_0a2
[modules/visu.git] / src / VISU_I / VISU_Prs3d_i.cc
1 //  VISU OBJECT : interactive object for VISU entities implementation
2 //
3 //  Copyright (C) 2003  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
21 //
22 //
23 //  File   : VISU_Prs3d_i.cc
24 //  Author : Alexey PETROV
25 //  Module : VISU
26
27 #include "VISU_PipeLine.hxx"
28 #include "VISU_Prs3d_i.hh"
29
30 #include "VISU_Result_i.hh"
31 #include "VISU_Actor.h"
32
33 #include "SALOME_Event.hxx"
34
35 #include <vtkActorCollection.h>
36 #include <vtkDataSet.h>
37 #include <vtkMapper.h>
38
39 #include <boost/bind.hpp>
40
41 using namespace VISU;
42 using namespace std;
43
44 #ifdef _DEBUG_
45 static int MYDEBUG = 1;
46 #else
47 static int MYDEBUG = 0;
48 #endif
49
50
51 //----------------------------------------------------------------------------
52 VISU::Prs3d_i
53 ::Prs3d_i(Result_i* theResult,
54           SALOMEDS::SObject_ptr theSObject) :
55   PrsObject_i(theResult->GetStudyDocument()),
56   mySObject(SALOMEDS::SObject::_duplicate(theSObject)),
57   myActorCollection(vtkActorCollection::New()),
58   myResult(theResult),
59   myAddToStudy(true),
60   myPipeLine(NULL)
61 {
62   if(MYDEBUG) MESSAGE("Prs3d_i::Prs3d_i - this = "<<this);
63   myOffset[0] = myOffset[1] = myOffset[2] = 0;
64   myActorCollection->Delete();
65   myResult->Register();
66 }
67
68 VISU::Prs3d_i
69 ::Prs3d_i(Result_i* theResult,
70           bool theAddToStudy) :
71   PrsObject_i(theResult->GetStudyDocument()),
72   myActorCollection(vtkActorCollection::New()),
73   mySObject(SALOMEDS::SObject::_nil()),
74   myAddToStudy(theAddToStudy),
75   myResult(theResult),
76   myPipeLine(NULL)
77 {
78   if(MYDEBUG) MESSAGE("Prs3d_i::Prs3d_i - this = "<<this);
79   myOffset[0] = myOffset[1] = myOffset[2] = 0;
80   myActorCollection->Delete();
81   myResult->Register();
82 }
83
84 void
85 VISU::Prs3d_i
86 ::SameAs(const Prs3d_i* theOrigin)
87 {
88   if (Prs3d_i* aOrigin = const_cast<Prs3d_i*>(theOrigin)) {
89     myPipeLine->SameAs(aOrigin->GetPL());
90     aOrigin->GetOffset(myOffset);
91   }
92 }
93
94 VISU::Prs3d_i
95 ::~Prs3d_i() 
96 {
97   if(MYDEBUG) MESSAGE("Prs3d_i::~Prs3d_i - this = "<<this);
98   myRemoveActorsFromRendererSignal();
99   myPipeLine->Delete();
100   myResult->Destroy();
101 }
102
103
104 //----------------------------------------------------------------------------
105 VISU::Storable* 
106 VISU::Prs3d_i
107 ::Restore(const Storable::TRestoringMap& theMap)
108 {
109   myName = VISU::Storable::FindValue(theMap,"myName").latin1();
110   myOffset[0] = VISU::Storable::FindValue(theMap,"myOffset[0]").toFloat();
111   myOffset[1] = VISU::Storable::FindValue(theMap,"myOffset[1]").toFloat();
112   myOffset[2] = VISU::Storable::FindValue(theMap,"myOffset[2]").toFloat();
113   return this;
114 }
115
116 void
117 VISU::Prs3d_i
118 ::ToStream(std::ostringstream& theStr)
119 {
120   Storable::DataToStream( theStr, "myName",   myName.c_str() );
121   Storable::DataToStream( theStr, "myOffset[0]", myOffset[0] );
122   Storable::DataToStream( theStr, "myOffset[1]", myOffset[1] );
123   Storable::DataToStream( theStr, "myOffset[2]", myOffset[2] );
124 }
125
126
127 //----------------------------------------------------------------------------
128 SALOMEDS::SObject_var 
129 VISU::Prs3d_i
130 ::GetSObject()
131 {
132   if(CORBA::is_nil(mySObject.in())){
133     const SALOMEDS::Study_var& aStudy = myResult->GetStudyDocument();
134     CORBA::String_var anIOR = GetID();
135     mySObject = aStudy->FindObjectIOR(anIOR);
136   }
137   return mySObject;
138 }
139
140 Result_i* 
141 VISU::Prs3d_i
142 ::GetResult() const 
143
144   return myResult;
145 }
146
147 const std::string& 
148 VISU::Prs3d_i
149 ::GetMeshName() const 
150
151   return myMeshName; 
152 }
153
154
155 //----------------------------------------------------------------------------
156 void
157 VISU::Prs3d_i
158 ::Update() 
159 {
160   if(MYDEBUG) MESSAGE("Prs3d_i::Update - this = "<<this);
161   try{
162     myPipeLine->Update();
163   }catch(...){
164     throw std::runtime_error("Prs3d_i::Update >> unexpected exception was caught!!!");
165   }
166 }
167
168
169 //----------------------------------------------------------------------------
170 void
171 VISU::Prs3d_i
172 ::CheckDataSet() 
173 {
174   vtkMapper *aMapper = myPipeLine->GetMapper();
175   vtkDataSet *aDataSet = aMapper->GetInput();
176   if (!aDataSet)
177     throw std::runtime_error("There is no input data !!!");
178   aDataSet->Update();
179   static float eps = VTK_LARGE_FLOAT * 0.1 ;
180   if (!aDataSet->GetNumberOfCells())
181     throw std::runtime_error("There are no visible elements");
182   if (aDataSet->GetLength() > eps)
183     throw std::runtime_error("Diagonal of the actor is too large !!!");
184 }
185
186 void
187 VISU::Prs3d_i
188 ::RemoveFromStudy() 
189 {
190   struct TRemoveFromStudy: public SALOME_Event
191   {
192     VISU::Prs3d_i* myRemovable;
193     typedef boost::signal0<void> TRemoveFromStudySignal;
194     const TRemoveFromStudySignal& myRemoveFromStudySignal;
195
196     TRemoveFromStudy(VISU::Prs3d_i* theRemovable,
197                      const TRemoveFromStudySignal& theRemoveFromStudySignal):
198       myRemovable(theRemovable),
199       myRemoveFromStudySignal(theRemoveFromStudySignal)
200     {}
201     
202     virtual
203     void
204     Execute()
205     {
206       myRemoveFromStudySignal();
207       myRemovable->Destroy();
208     }
209   };
210
211   ProcessVoidEvent(new TRemoveFromStudy(this,myRemoveActorsFromRendererSignal));
212 }
213
214
215 //----------------------------------------------------------------------------
216 VISU_PipeLine* 
217 VISU::Prs3d_i
218 ::GetPipeLine()
219 {
220   return GetPL();
221 }
222
223 VISU_PipeLine* 
224 VISU::Prs3d_i
225 ::GetPL()
226 {
227   return myPipeLine;
228 }
229
230 vtkUnstructuredGrid* 
231 VISU::Prs3d_i::
232 GetInput()
233 {
234   return myPipeLine->GetInput();
235 }
236
237
238 //----------------------------------------------------------------------------
239 void
240 VISU::Prs3d_i
241 ::CreateActor(VISU_Actor* theActor, const Handle(SALOME_InteractiveObject)& theIO)
242 {
243   try{
244     Handle(SALOME_InteractiveObject) anIO = theIO;
245     if(anIO.IsNull() && (!mySObject->_is_nil())){
246       anIO = new SALOME_InteractiveObject(mySObject->GetID(),"VISU",GetName());
247       theActor->setIO(anIO);
248     }
249
250     Update();
251     CheckDataSet();
252
253     theActor->SetPrs3d(this);
254     theActor->SetShrinkFactor();
255     theActor->SetPosition(myOffset);
256     theActor->SetPipeLine(GetPipeLine());
257
258     theActor->SetFactory(this);
259     myUpdateActorsSignal.connect(boost::bind(&VISU_Actor::UpdateFromFactory,theActor));
260     myRemoveActorsFromRendererSignal.connect(boost::bind(&VISU_Actor::RemoveFromRender,theActor));
261
262     myActorCollection->AddItem(theActor);
263     theActor->Delete();
264
265   }catch(std::bad_alloc& ex){
266     throw std::runtime_error("CreateActor >> No enough memory");
267     throw ex;
268   } catch(std::exception&){
269     throw;
270   }catch(...) {
271     throw std::runtime_error("CreateActor >> unexpected exception was caught!!!");
272   }
273 }
274
275 void
276 VISU::Prs3d_i
277 ::RemoveActor(VISU_Actor* theActor) 
278 {
279   if(MYDEBUG) MESSAGE("Prs3d_i::RemoveActor - this = "<<this<<"; theActor = "<<theActor);
280   myActorCollection->RemoveItem(theActor);
281 }
282
283 void
284 VISU::Prs3d_i
285 ::RemoveActors()
286 {
287   if(MYDEBUG) MESSAGE("Prs3d_i::RemoveActors - this = "<<this);
288   myRemoveActorsFromRendererSignal();
289   myActorCollection->RemoveAllItems();
290 }
291
292 void
293 VISU::Prs3d_i
294 ::UpdateActor(VISU_Actor* theActor) 
295 {
296   if(MYDEBUG) MESSAGE("Prs3d_i::UpdateActor - this = "<<this<<"; theActor = "<<theActor);
297   theActor->ShallowCopyPL(myPipeLine);
298   theActor->SetPosition(myOffset);
299   theActor->Modified();
300 }
301
302 void
303 VISU::Prs3d_i
304 ::UpdateActors()
305 {
306   if(MYDEBUG) MESSAGE("Prs3d_i::UpdateActors - this = "<<this);
307   Update();
308   CheckDataSet();
309   myUpdateActorsSignal();
310 }
311
312
313 //----------------------------------------------------------------------------
314 // Clipping planes
315 void
316 VISU::Prs3d_i
317 ::RemoveAllClippingPlanes()
318 {
319   myPipeLine->RemoveAllClippingPlanes();
320 }
321
322 bool
323 VISU::Prs3d_i
324 ::AddClippingPlane(vtkPlane* thePlane)
325 {
326   return myPipeLine->AddClippingPlane(thePlane);
327 }
328
329 vtkIdType
330 VISU::Prs3d_i
331 ::GetNumberOfClippingPlanes() const
332 {
333   return myPipeLine->GetNumberOfClippingPlanes();
334 }
335
336 vtkPlane* 
337 VISU::Prs3d_i::
338 GetClippingPlane(vtkIdType theID) const
339 {
340   return myPipeLine->GetClippingPlane(theID);
341 }
342
343 void
344 VISU::Prs3d_i
345 ::SetPlaneParam (float theDir[3], float theDist, vtkPlane* thePlane) 
346 {
347   myPipeLine->SetPlaneParam(theDir, theDist, thePlane);
348 }
349
350
351 //----------------------------------------------------------------------------
352 void
353 VISU::Prs3d_i
354 ::GetBounds(float aBounds[6])
355 {
356   myPipeLine->GetMapper()->GetBounds(aBounds);
357 }
358
359 void 
360 VISU::Prs3d_i
361 ::SetOffset(const float* theOffsets)
362 {
363   myOffset[0] = theOffsets[0];
364   myOffset[1] = theOffsets[1];
365   myOffset[2] = theOffsets[2];
366 }
367
368 void
369 VISU::Prs3d_i
370 ::SetOffset(float theDx, float theDy, float theDz)
371 {
372   myOffset[0] = theDx;
373   myOffset[1] = theDy;
374   myOffset[2] = theDz;
375 }
376
377 void
378 VISU::Prs3d_i
379 ::GetOffset(float* theOffsets)
380 {
381   theOffsets[0] = myOffset[0];
382   theOffsets[1] = myOffset[1];
383   theOffsets[2] = myOffset[2];
384 }
385
386 void 
387 VISU::Prs3d_i
388 ::GetOffset(float& theDx, float& theDy, float& theDz)
389 {
390   theDx = myOffset[0];
391   theDy = myOffset[1];
392   theDz = myOffset[2];
393 }
394
395
396 //----------------------------------------------------------------------------
397 VISU::Result_i* 
398 VISU::GetResult(SALOMEDS::SObject_ptr theSObject)
399 {
400   VISU::Result_var aResult = FindResult(theSObject);
401   if(!aResult->_is_nil())
402     return dynamic_cast<VISU::Result_i*>(VISU::GetServant(aResult.in()).in());
403   return NULL;
404 }
405