Salome HOME
Issue 0019818: EDF 703 SMESH VISU : Display Mesh Groups names in viewer (as a caption)
[modules/visu.git] / src / PIPELINE / VISU_Plot3DPL.cxx
1 //  Copyright (C) 2007-2008  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 //  VISU OBJECT : interactive object for VISU entities implementation
23 // File:    VISU_PipeLine.cxx
24 // Author:  Alexey PETROV
25 // Module : VISU
26 //
27 #include "VISU_Plot3DPL.hxx"
28 #include "VISU_CutPlanesPL.hxx"
29 #include "VISU_PipeLineUtils.hxx"
30
31 #include <vtkAppendPolyData.h>
32 #include <vtkCutter.h>
33 #include <vtkPlane.h>
34
35 #include <vtkCellDataToPointData.h>
36 #include <vtkGeometryFilter.h>
37 #include <vtkContourFilter.h>
38 #include <vtkWarpScalar.h>
39 #include <vtkOutlineFilter.h>
40
41
42 //----------------------------------------------------------------------------
43 vtkStandardNewMacro(VISU_Plot3DPL);
44
45
46 //----------------------------------------------------------------------------
47 VISU_Plot3DPL
48 ::VISU_Plot3DPL():
49   myCellDataToPointData(vtkCellDataToPointData::New()),
50   myAppendPolyData(vtkAppendPolyData::New()),
51   myGeometryFilter(vtkGeometryFilter::New()),
52   myContourFilter(vtkContourFilter::New()),
53   myWarpScalar(vtkWarpScalar::New()),
54   myOrientation(VISU_CutPlanesPL::YZ),
55   myIsRelative(true),
56   myIsContour(false),
57   myPosition(0.5),
58   myScaleFactor(1.0),
59   myMapScaleFactor(1.0)
60 {
61   SetIsShrinkable(false);
62   SetIsFeatureEdgesAllowed(false);
63
64   myCellDataToPointData->Delete();
65   myAppendPolyData->Delete();
66   myGeometryFilter->Delete();
67   myContourFilter->Delete();
68   myWarpScalar->Delete();
69
70   myAngle[0] = myAngle[1] = myAngle[2] = 0.0;
71
72   SetNumberOfContours(32);
73 }
74
75
76 //----------------------------------------------------------------------------
77 VISU_Plot3DPL
78 ::~VISU_Plot3DPL()
79 {}
80
81
82 //----------------------------------------------------------------------------
83 unsigned long int 
84 VISU_Plot3DPL
85 ::GetMTime()
86 {
87   unsigned long int aTime = Superclass::GetMTime();
88
89   aTime = std::max(aTime, myCellDataToPointData->GetMTime());
90   aTime = std::max(aTime, myAppendPolyData->GetMTime());
91   aTime = std::max(aTime, myGeometryFilter->GetMTime());
92   aTime = std::max(aTime, myContourFilter->GetMTime());
93   aTime = std::max(aTime, myWarpScalar->GetMTime());
94
95   return aTime;
96 }
97
98
99 //----------------------------------------------------------------------------
100 void
101 VISU_Plot3DPL
102 ::DoShallowCopy(VISU_PipeLine *thePipeLine,
103                 bool theIsCopyInput)
104 {
105   Superclass::DoShallowCopy(thePipeLine, theIsCopyInput);
106
107   if(VISU_Plot3DPL *aPipeLine = dynamic_cast<VISU_Plot3DPL*>(thePipeLine)){
108     SetOrientation (aPipeLine->GetPlaneOrientation(),
109                     aPipeLine->GetRotateX(), aPipeLine->GetRotateY());
110     SetPlanePosition (aPipeLine->GetPlanePosition(),
111                       aPipeLine->IsPositionRelative() );
112     SetScaleFactor( aPipeLine->GetScaleFactor() );
113     SetContourPrs( aPipeLine->GetIsContourPrs() );
114     SetNumberOfContours( aPipeLine->GetNumberOfContours() );
115   }
116 }
117
118
119 //----------------------------------------------------------------------------
120 VISU_CutPlanesPL::PlaneOrientation
121 VISU_Plot3DPL
122 ::GetOrientation(vtkDataSet* theDataSet)
123 {
124   theDataSet->Update();
125
126   vtkFloatingPointType aBounds[6];
127   theDataSet->GetBounds(aBounds);
128   vtkFloatingPointType aDelta[3] = {aBounds[1] - aBounds[0], aBounds[3] - aBounds[2], aBounds[5] - aBounds[4]};
129
130   if(aDelta[0] >= aDelta[1] && aDelta[0] >= aDelta[2])
131     if(aDelta[1] >= aDelta[2])
132       return VISU_CutPlanesPL::XY;
133     else
134       return VISU_CutPlanesPL::ZX;
135
136   if(aDelta[1] >= aDelta[0] && aDelta[1] >= aDelta[2])
137     if(aDelta[0] >= aDelta[2])
138       return VISU_CutPlanesPL::XY;
139     else
140       return VISU_CutPlanesPL::YZ;
141
142   if(aDelta[2] >= aDelta[0] && aDelta[2] >= aDelta[1])
143     if(aDelta[0] >= aDelta[1])
144       return VISU_CutPlanesPL::ZX;
145     else
146       return VISU_CutPlanesPL::YZ;
147
148   return VISU_CutPlanesPL::XY;
149 }
150
151
152 //----------------------------------------------------------------------------
153 vtkFloatingPointType
154 VISU_Plot3DPL
155 ::GetScaleFactor( VISU_ColoredPL* theColoredPL,
156                   vtkDataSet* theDataSet )
157 {
158   theDataSet->Update();
159   vtkFloatingPointType aLength = theDataSet->GetLength(); // diagonal length
160
161   vtkFloatingPointType aScalarRange[2];
162   theColoredPL->GetSourceRange(aScalarRange);
163
164   static vtkFloatingPointType EPS = 0.3;
165   vtkFloatingPointType aRange = aScalarRange[1];
166   if(aRange > 0.0)
167     return aLength / aRange * EPS;
168
169   return 0.0;
170 }
171
172
173 //----------------------------------------------------------------------------
174 void
175 VISU_Plot3DPL
176 ::Init()
177 {
178   Superclass::Init();
179
180   myOrientation = GetOrientation(GetMergedInput());
181   SetScaleFactor( GetScaleFactor( this, GetMergedInput() ) );
182 }
183
184
185 //----------------------------------------------------------------------------
186 vtkDataSet*
187 VISU_Plot3DPL
188 ::InsertCustomPL()
189 {
190   return myAppendPolyData->GetOutput();
191 }
192
193
194 //----------------------------------------------------------------------------
195 void
196 VISU_Plot3DPL
197 ::Update()
198 {
199   vtkFloatingPointType aPlaneNormal[3];
200   vtkFloatingPointType anOrigin[3];
201   GetBasePlane( anOrigin, aPlaneNormal );
202
203   vtkPolyData* aPolyData = 0;
204   vtkCutter *aCutPlane = 0;
205   vtkDataSet* aDataSet = GetMergedInput();
206
207   if ( !IsPlanarInput() )
208   {
209     aCutPlane = vtkCutter::New();
210     aCutPlane->SetInput(aDataSet);
211
212     vtkPlane *aPlane = vtkPlane::New();
213     aPlane->SetOrigin(anOrigin);
214     aPlane->SetNormal(aPlaneNormal);
215
216     aCutPlane->SetCutFunction(aPlane);
217     aPlane->Delete();
218
219     aPolyData = aCutPlane->GetOutput();
220     aPolyData->Update();
221   }
222
223   if ( !aPolyData || aPolyData->GetNumberOfCells() == 0 ) {
224     myGeometryFilter->SetInput(aDataSet);
225     aPolyData = myGeometryFilter->GetOutput();
226     aPolyData->Update();
227   }
228   if ( !myIsContour ) // surface prs
229   {
230     if(VISU::IsDataOnCells(aPolyData)) {
231       myCellDataToPointData->SetInput(aPolyData);
232       myCellDataToPointData->PassCellDataOn();
233       myWarpScalar->SetInput(myCellDataToPointData->GetPolyDataOutput());
234     }else
235       myWarpScalar->SetInput(aPolyData);
236   }
237   else // contour prs
238   {
239     if(VISU::IsDataOnCells(aPolyData)) {
240       myCellDataToPointData->SetInput(aPolyData);
241       myCellDataToPointData->PassCellDataOn();
242       myContourFilter->SetInput(myCellDataToPointData->GetOutput());
243     }else
244       myContourFilter->SetInput(aPolyData);
245
246     vtkFloatingPointType aScalarRange[2];
247     GetSourceRange(aScalarRange);
248
249     myContourFilter->GenerateValues(GetNumberOfContours(),aScalarRange);
250     myWarpScalar->SetInput(myContourFilter->GetOutput());
251   }
252
253   VISU_CutPlanesPL::ClearAppendPolyData(myAppendPolyData.GetPointer());
254   myAppendPolyData->AddInput(myWarpScalar->GetPolyDataOutput());
255
256   if ( aCutPlane )
257     aCutPlane->Delete();
258
259   myWarpScalar->SetNormal(aPlaneNormal);
260
261   Superclass::Update();
262 }
263
264
265 //----------------------------------------------------------------------------
266 unsigned long int
267 VISU_Plot3DPL
268 ::GetMemorySize()
269 {
270   unsigned long int aSize = Superclass::GetMemorySize();
271
272   if(vtkDataObject* aDataObject = myGeometryFilter->GetInput())
273     aSize += aDataObject->GetActualMemorySize() * 1024;
274   
275   if(myCellDataToPointData->GetInput())
276     if(vtkDataSet* aDataSet = myCellDataToPointData->GetOutput())
277       aSize += aDataSet->GetActualMemorySize() * 1024;
278
279   if(vtkDataObject* aDataObject = myContourFilter->GetInput())
280     aSize += aDataObject->GetActualMemorySize() * 1024;
281
282   if(vtkDataObject* aDataObject = myWarpScalar->GetInput())
283     aSize += aDataObject->GetActualMemorySize() * 1024;
284
285   int anEnd = myAppendPolyData->GetNumberOfInputConnections(0);
286   for(int anId = 0; anId < anEnd; anId++){
287     if(vtkDataObject* aDataObject = myAppendPolyData->GetInput(anId))
288       aSize += aDataObject->GetActualMemorySize() * 1024;
289   }
290
291   return aSize;
292 }
293
294
295 //----------------------------------------------------------------------------
296 void
297 VISU_Plot3DPL
298 ::SetNumberOfContours(int theNumber)
299 {
300   myContourFilter->SetNumberOfContours(theNumber);
301 }
302
303
304 //----------------------------------------------------------------------------
305 int
306 VISU_Plot3DPL
307 ::GetNumberOfContours()
308 {
309   return myContourFilter->GetNumberOfContours();
310 }
311
312
313 //----------------------------------------------------------------------------
314 void
315 VISU_Plot3DPL
316 ::SetScaleFactor(vtkFloatingPointType theScaleFactor)
317 {
318   myScaleFactor = theScaleFactor;
319   myWarpScalar->SetScaleFactor(theScaleFactor*myMapScaleFactor);
320 }
321
322
323 //----------------------------------------------------------------------------
324 vtkFloatingPointType
325 VISU_Plot3DPL
326 ::GetScaleFactor()
327 {
328   return myScaleFactor;
329 }
330
331
332 //----------------------------------------------------------------------------
333 void
334 VISU_Plot3DPL::
335 SetContourPrs(bool theIsContourPrs )
336 {
337   if(myIsContour == theIsContourPrs)
338     return;
339
340   myIsContour = theIsContourPrs;
341   Modified();
342 }
343
344
345 //----------------------------------------------------------------------------
346 bool
347 VISU_Plot3DPL
348 ::GetIsContourPrs()
349 {
350   return myIsContour;
351 }
352
353
354 //----------------------------------------------------------------------------
355 void
356 VISU_Plot3DPL
357 ::SetPlanePosition(vtkFloatingPointType thePosition,
358                    bool theIsRelative)
359 {
360   bool anIsSameValue = VISU::CheckIsSameValue(myIsRelative, theIsRelative);
361   anIsSameValue &= (myPosition == thePosition);
362   if(anIsSameValue)
363     return;
364
365   myIsRelative = theIsRelative;
366   myPosition = thePosition;
367   Modified();
368 }
369
370
371 //----------------------------------------------------------------------------
372 bool
373 VISU_Plot3DPL
374 ::IsPositionRelative()
375 {
376   return myIsRelative;
377 }
378
379
380 //----------------------------------------------------------------------------
381 VISU_CutPlanesPL::PlaneOrientation
382 VISU_Plot3DPL
383 ::GetPlaneOrientation()
384 {
385   return myOrientation;
386 }
387
388
389 //----------------------------------------------------------------------------
390 vtkFloatingPointType
391 VISU_Plot3DPL::
392 GetRotateX()
393 {
394   switch(myOrientation){
395   case VISU_CutPlanesPL::XY: return myAngle[0];
396   case VISU_CutPlanesPL::YZ: return myAngle[1];
397   case VISU_CutPlanesPL::ZX: return myAngle[2];
398   }
399   return 0;
400 }
401
402
403 //----------------------------------------------------------------------------
404 vtkFloatingPointType
405 VISU_Plot3DPL::
406 GetRotateY(){
407   switch(myOrientation){
408   case VISU_CutPlanesPL::XY: return myAngle[1];
409   case VISU_CutPlanesPL::YZ: return myAngle[2];
410   case VISU_CutPlanesPL::ZX: return myAngle[0];
411   }
412   return 0;
413 }
414
415
416 //----------------------------------------------------------------------------
417 void
418 VISU_Plot3DPL::
419 SetOrientation(VISU_CutPlanesPL::PlaneOrientation theOrientation,
420                vtkFloatingPointType theXAngle,
421                vtkFloatingPointType theYAngle)
422 {
423   bool anIsSameValue = VISU::CheckIsSameValue(GetRotateX(), theXAngle);
424   anIsSameValue &= VISU::CheckIsSameValue(GetRotateY(), theYAngle);
425   anIsSameValue &= (myOrientation == theOrientation);
426   if(anIsSameValue)
427     return;
428
429   switch(theOrientation){
430   case VISU_CutPlanesPL::XY: myAngle[0] = theXAngle; break;
431   case VISU_CutPlanesPL::YZ: myAngle[1] = theXAngle; break;
432   case VISU_CutPlanesPL::ZX: myAngle[2] = theXAngle; break;
433   }
434
435   switch(theOrientation){
436   case VISU_CutPlanesPL::XY: myAngle[1] = theYAngle; break;
437   case VISU_CutPlanesPL::YZ: myAngle[2] = theYAngle; break;
438   case VISU_CutPlanesPL::ZX: myAngle[0] = theYAngle; break;
439   }
440
441   myOrientation = theOrientation;
442   Modified();
443 }
444
445
446 //----------------------------------------------------------------------------
447 vtkFloatingPointType
448 VISU_Plot3DPL
449 ::GetPlanePosition()
450 {
451   return myPosition;
452 }
453
454 //=======================================================================
455 //function : GetBasePlane
456 //purpose  :
457 //=======================================================================
458 void
459 VISU_Plot3DPL
460 ::GetBasePlane(vtkFloatingPointType theOrigin[3],
461                vtkFloatingPointType theNormal[3],
462                bool  theCenterOrigine )
463 {
464   VISU_CutPlanesPL::GetDir(theNormal,myAngle,myOrientation);
465
466   vtkFloatingPointType aPosition = myPosition;
467   vtkFloatingPointType aBounds[6], aBoundPrj[3];
468   if ( myIsRelative )
469   {
470     GetInput()->GetBounds(aBounds);
471     VISU_CutPlanesPL::GetBoundProject(aBoundPrj,aBounds,theNormal);
472     aPosition = aBoundPrj[0] + aBoundPrj[2]*myPosition;
473   }
474   VISU::Mul(theNormal,aPosition,theOrigin);
475
476   if ( theCenterOrigine ) {
477     // move theOrigin to the center of aBounds projections to the plane
478     GetMergedInput()->GetBounds(aBounds);
479     vtkFloatingPointType boundPoints[8][3] = {
480       {aBounds[0],aBounds[2],aBounds[4]},
481       {aBounds[1],aBounds[2],aBounds[4]},
482       {aBounds[0],aBounds[3],aBounds[4]},
483       {aBounds[1],aBounds[3],aBounds[4]},
484       {aBounds[0],aBounds[2],aBounds[5]},
485       {aBounds[1],aBounds[2],aBounds[5]},
486       {aBounds[0],aBounds[3],aBounds[5]},
487       {aBounds[1],aBounds[3],aBounds[5]}};
488     vtkFloatingPointType newOrigin[3] = { 0,0,0 };
489     for(int i = 0; i < 8; i++) {
490       vtkFloatingPointType proj[3];
491       vtkPlane::ProjectPoint( boundPoints[i], theOrigin, theNormal, proj );
492       newOrigin[0] += proj[0];
493       newOrigin[1] += proj[1];
494       newOrigin[2] += proj[2];
495     }
496     theOrigin[0] = newOrigin[0] / 8.;
497     theOrigin[1] = newOrigin[1] / 8.;
498     theOrigin[2] = newOrigin[2] / 8.;
499   }
500 }
501
502 //=======================================================================
503 //function : GetMinMaxPosition
504 //purpose  : return absolute position range
505 //=======================================================================
506 void
507 VISU_Plot3DPL
508 ::GetMinMaxPosition( vtkFloatingPointType& minPos, 
509                      vtkFloatingPointType& maxPos )
510 {
511   vtkFloatingPointType aBounds[6], aBoundPrj[3], aNormal[3];
512   VISU_CutPlanesPL::GetDir(aNormal,myAngle,myOrientation);
513   GetInput()->GetBounds(aBounds);
514   VISU_CutPlanesPL::GetBoundProject(aBoundPrj,aBounds,aNormal);
515   minPos = aBoundPrj[0];
516   maxPos = aBoundPrj[1];
517 }
518
519 //=======================================================================
520 //function : SetMapScale
521 //purpose  :
522 //=======================================================================
523
524 void 
525 VISU_Plot3DPL
526 ::SetMapScale(vtkFloatingPointType theMapScale)
527 {
528   myMapScaleFactor = theMapScale;
529   Superclass::SetMapScale(theMapScale);
530
531   if ( myIsContour ) {
532     vtkFloatingPointType aRange[2];
533     GetSourceRange(aRange);
534     vtkFloatingPointType aNewRange[] = { aRange[1] - theMapScale*(aRange[1]-aRange[0]), aRange[1] };
535     myContourFilter->GenerateValues(GetNumberOfContours(),aNewRange);
536   }
537   myWarpScalar->SetScaleFactor(myScaleFactor*theMapScale);
538
539   Modified();
540 }