1 // Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // VISU OBJECT : interactive object for VISU entities implementation
24 // File: VISU_PipeLine.cxx
25 // Author: Alexey PETROV
28 #include "VISU_Plot3DPL.hxx"
29 #include "VISU_CutPlanesPL.hxx"
30 #include "VISU_PipeLineUtils.hxx"
32 #include <vtkAppendPolyData.h>
33 #include <vtkCutter.h>
36 #include <vtkGeometryFilter.h>
37 #include <vtkContourFilter.h>
38 #include <vtkWarpScalar.h>
39 #include <vtkOutlineFilter.h>
42 //----------------------------------------------------------------------------
43 vtkStandardNewMacro(VISU_Plot3DPL);
46 //----------------------------------------------------------------------------
49 myCellDataToPointData(VISU_CellDataToPointData::New()),
50 myAppendPolyData(vtkAppendPolyData::New()),
51 myGeometryFilter(vtkGeometryFilter::New()),
52 myContourFilter(vtkContourFilter::New()),
53 myWarpScalar(vtkWarpScalar::New()),
54 myOrientation(VISU_CutPlanesPL::YZ),
61 SetIsShrinkable(false);
62 SetIsFeatureEdgesAllowed(false);
64 myCellDataToPointData->Delete();
65 myAppendPolyData->Delete();
66 myGeometryFilter->Delete();
67 myContourFilter->Delete();
68 myWarpScalar->Delete();
70 myAngle[0] = myAngle[1] = myAngle[2] = 0.0;
72 SetNumberOfContours(32);
76 //----------------------------------------------------------------------------
82 //----------------------------------------------------------------------------
87 unsigned long int aTime = Superclass::GetMTime();
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());
99 //----------------------------------------------------------------------------
102 ::DoShallowCopy(VISU_PipeLine *thePipeLine,
105 Superclass::DoShallowCopy(thePipeLine, theIsCopyInput);
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() );
119 //----------------------------------------------------------------------------
120 VISU_CutPlanesPL::PlaneOrientation
122 ::GetOrientation(vtkDataSet* theDataSet)
124 theDataSet->Update();
126 vtkFloatingPointType aBounds[6];
127 theDataSet->GetBounds(aBounds);
128 vtkFloatingPointType aDelta[3] = {aBounds[1] - aBounds[0], aBounds[3] - aBounds[2], aBounds[5] - aBounds[4]};
130 if(aDelta[0] >= aDelta[1] && aDelta[0] >= aDelta[2])
131 if(aDelta[1] >= aDelta[2])
132 return VISU_CutPlanesPL::XY;
134 return VISU_CutPlanesPL::ZX;
136 if(aDelta[1] >= aDelta[0] && aDelta[1] >= aDelta[2])
137 if(aDelta[0] >= aDelta[2])
138 return VISU_CutPlanesPL::XY;
140 return VISU_CutPlanesPL::YZ;
142 if(aDelta[2] >= aDelta[0] && aDelta[2] >= aDelta[1])
143 if(aDelta[0] >= aDelta[1])
144 return VISU_CutPlanesPL::ZX;
146 return VISU_CutPlanesPL::YZ;
148 return VISU_CutPlanesPL::XY;
152 //----------------------------------------------------------------------------
155 ::GetScaleFactor( VISU_ColoredPL* theColoredPL,
156 vtkDataSet* theDataSet )
158 theDataSet->Update();
159 vtkFloatingPointType aLength = theDataSet->GetLength(); // diagonal length
161 vtkFloatingPointType aScalarRange[2];
162 theColoredPL->GetSourceRange(aScalarRange);
164 static vtkFloatingPointType EPS = 0.3;
165 vtkFloatingPointType aRange = aScalarRange[1];
167 return aLength / aRange * EPS;
173 //----------------------------------------------------------------------------
180 myOrientation = GetOrientation(GetMergedInput());
181 SetScaleFactor( GetScaleFactor( this, GetMergedInput() ) );
185 //----------------------------------------------------------------------------
190 return myAppendPolyData->GetOutput();
194 //----------------------------------------------------------------------------
199 vtkDataSet* aMergedInput = GetMergedInput();
200 if(VISU::IsQuadraticData(aMergedInput)) // Bug 0020123, note 0005343
201 throw std::runtime_error("Impossible to build presentation");
203 vtkFloatingPointType aPlaneNormal[3];
204 vtkFloatingPointType anOrigin[3];
205 GetBasePlane( anOrigin, aPlaneNormal );
207 vtkPolyData* aPolyData = 0;
208 vtkCutter *aCutPlane = 0;
210 if ( !IsPlanarInput() )
212 aCutPlane = vtkCutter::New();
213 aCutPlane->SetInput(aMergedInput);
215 vtkPlane *aPlane = vtkPlane::New();
216 aPlane->SetOrigin(anOrigin);
217 aPlane->SetNormal(aPlaneNormal);
219 aCutPlane->SetCutFunction(aPlane);
222 aPolyData = aCutPlane->GetOutput();
226 if ( !aPolyData || aPolyData->GetNumberOfCells() == 0 ) {
227 myGeometryFilter->SetInput(aMergedInput);
228 aPolyData = myGeometryFilter->GetOutput();
231 if ( !myIsContour ) // surface prs
233 if(VISU::IsDataOnCells(aPolyData)) {
234 myCellDataToPointData->SetInput(aPolyData);
235 myCellDataToPointData->PassCellDataOn();
236 myWarpScalar->SetInput(myCellDataToPointData->GetPolyDataOutput());
238 myWarpScalar->SetInput(aPolyData);
242 if(VISU::IsDataOnCells(aPolyData)) {
243 myCellDataToPointData->SetInput(aPolyData);
244 myCellDataToPointData->PassCellDataOn();
245 myContourFilter->SetInput(myCellDataToPointData->GetOutput());
247 myContourFilter->SetInput(aPolyData);
249 vtkFloatingPointType aScalarRange[2];
250 GetSourceRange(aScalarRange);
252 myContourFilter->GenerateValues(GetNumberOfContours(),aScalarRange);
253 myWarpScalar->SetInput(myContourFilter->GetOutput());
256 VISU_CutPlanesPL::ClearAppendPolyData(myAppendPolyData.GetPointer());
257 myAppendPolyData->AddInput(myWarpScalar->GetPolyDataOutput());
262 myWarpScalar->SetNormal(aPlaneNormal);
264 Superclass::Update();
268 //----------------------------------------------------------------------------
273 unsigned long int aSize = Superclass::GetMemorySize();
275 if(vtkDataObject* aDataObject = myGeometryFilter->GetInput())
276 aSize += aDataObject->GetActualMemorySize() * 1024;
278 if(myCellDataToPointData->GetInput())
279 if(vtkDataSet* aDataSet = myCellDataToPointData->GetOutput())
280 aSize += aDataSet->GetActualMemorySize() * 1024;
282 if(vtkDataObject* aDataObject = myContourFilter->GetInput())
283 aSize += aDataObject->GetActualMemorySize() * 1024;
285 if(vtkDataObject* aDataObject = myWarpScalar->GetInput())
286 aSize += aDataObject->GetActualMemorySize() * 1024;
288 int anEnd = myAppendPolyData->GetNumberOfInputConnections(0);
289 for(int anId = 0; anId < anEnd; anId++){
290 if(vtkDataObject* aDataObject = myAppendPolyData->GetInput(anId))
291 aSize += aDataObject->GetActualMemorySize() * 1024;
298 //----------------------------------------------------------------------------
301 ::SetNumberOfContours(int theNumber)
303 myContourFilter->SetNumberOfContours(theNumber);
307 //----------------------------------------------------------------------------
310 ::GetNumberOfContours()
312 return myContourFilter->GetNumberOfContours();
316 //----------------------------------------------------------------------------
319 ::SetScaleFactor(vtkFloatingPointType theScaleFactor)
321 myScaleFactor = theScaleFactor;
322 myWarpScalar->SetScaleFactor(theScaleFactor*myMapScaleFactor);
326 //----------------------------------------------------------------------------
331 return myScaleFactor;
335 //----------------------------------------------------------------------------
338 SetContourPrs(bool theIsContourPrs )
340 if(myIsContour == theIsContourPrs)
343 myIsContour = theIsContourPrs;
348 //----------------------------------------------------------------------------
357 //----------------------------------------------------------------------------
360 ::SetPlanePosition(vtkFloatingPointType thePosition,
363 bool anIsSameValue = VISU::CheckIsSameValue(myIsRelative, theIsRelative);
364 anIsSameValue &= (myPosition == thePosition);
368 myIsRelative = theIsRelative;
369 myPosition = thePosition;
374 //----------------------------------------------------------------------------
377 ::IsPositionRelative()
383 //----------------------------------------------------------------------------
384 VISU_CutPlanesPL::PlaneOrientation
386 ::GetPlaneOrientation()
388 return myOrientation;
392 //----------------------------------------------------------------------------
397 switch(myOrientation){
398 case VISU_CutPlanesPL::XY: return myAngle[0];
399 case VISU_CutPlanesPL::YZ: return myAngle[1];
400 case VISU_CutPlanesPL::ZX: return myAngle[2];
406 //----------------------------------------------------------------------------
410 switch(myOrientation){
411 case VISU_CutPlanesPL::XY: return myAngle[1];
412 case VISU_CutPlanesPL::YZ: return myAngle[2];
413 case VISU_CutPlanesPL::ZX: return myAngle[0];
419 //----------------------------------------------------------------------------
422 SetOrientation(VISU_CutPlanesPL::PlaneOrientation theOrientation,
423 vtkFloatingPointType theXAngle,
424 vtkFloatingPointType theYAngle)
426 bool anIsSameValue = VISU::CheckIsSameValue(GetRotateX(), theXAngle);
427 anIsSameValue &= VISU::CheckIsSameValue(GetRotateY(), theYAngle);
428 anIsSameValue &= (myOrientation == theOrientation);
432 switch(theOrientation){
433 case VISU_CutPlanesPL::XY: myAngle[0] = theXAngle; break;
434 case VISU_CutPlanesPL::YZ: myAngle[1] = theXAngle; break;
435 case VISU_CutPlanesPL::ZX: myAngle[2] = theXAngle; break;
438 switch(theOrientation){
439 case VISU_CutPlanesPL::XY: myAngle[1] = theYAngle; break;
440 case VISU_CutPlanesPL::YZ: myAngle[2] = theYAngle; break;
441 case VISU_CutPlanesPL::ZX: myAngle[0] = theYAngle; break;
444 myOrientation = theOrientation;
449 //----------------------------------------------------------------------------
457 //=======================================================================
458 //function : GetBasePlane
460 //=======================================================================
463 ::GetBasePlane(vtkFloatingPointType theOrigin[3],
464 vtkFloatingPointType theNormal[3],
465 bool theCenterOrigine )
467 VISU_CutPlanesPL::GetDir(theNormal,myAngle,myOrientation);
469 vtkFloatingPointType aPosition = myPosition;
470 vtkFloatingPointType aBounds[6], aBoundPrj[3];
473 GetInput()->GetBounds(aBounds);
474 VISU_CutPlanesPL::GetBoundProject(aBoundPrj,aBounds,theNormal);
475 aPosition = aBoundPrj[0] + aBoundPrj[2]*myPosition;
477 VISU::Mul(theNormal,aPosition,theOrigin);
479 if ( theCenterOrigine ) {
480 // move theOrigin to the center of aBounds projections to the plane
481 GetMergedInput()->GetBounds(aBounds);
482 vtkFloatingPointType boundPoints[8][3] = {
483 {aBounds[0],aBounds[2],aBounds[4]},
484 {aBounds[1],aBounds[2],aBounds[4]},
485 {aBounds[0],aBounds[3],aBounds[4]},
486 {aBounds[1],aBounds[3],aBounds[4]},
487 {aBounds[0],aBounds[2],aBounds[5]},
488 {aBounds[1],aBounds[2],aBounds[5]},
489 {aBounds[0],aBounds[3],aBounds[5]},
490 {aBounds[1],aBounds[3],aBounds[5]}};
491 vtkFloatingPointType newOrigin[3] = { 0,0,0 };
492 for(int i = 0; i < 8; i++) {
493 vtkFloatingPointType proj[3];
494 vtkPlane::ProjectPoint( boundPoints[i], theOrigin, theNormal, proj );
495 newOrigin[0] += proj[0];
496 newOrigin[1] += proj[1];
497 newOrigin[2] += proj[2];
499 theOrigin[0] = newOrigin[0] / 8.;
500 theOrigin[1] = newOrigin[1] / 8.;
501 theOrigin[2] = newOrigin[2] / 8.;
505 //=======================================================================
506 //function : GetMinMaxPosition
507 //purpose : return absolute position range
508 //=======================================================================
511 ::GetMinMaxPosition( vtkFloatingPointType& minPos,
512 vtkFloatingPointType& maxPos )
514 vtkFloatingPointType aBounds[6], aBoundPrj[3], aNormal[3];
515 VISU_CutPlanesPL::GetDir(aNormal,myAngle,myOrientation);
516 GetInput()->GetBounds(aBounds);
517 VISU_CutPlanesPL::GetBoundProject(aBoundPrj,aBounds,aNormal);
518 minPos = aBoundPrj[0];
519 maxPos = aBoundPrj[1];
522 //=======================================================================
523 //function : SetMapScale
525 //=======================================================================
529 ::SetMapScale(vtkFloatingPointType theMapScale)
531 myMapScaleFactor = theMapScale;
532 Superclass::SetMapScale(theMapScale);
535 vtkFloatingPointType aRange[2];
536 GetSourceRange(aRange);
537 vtkFloatingPointType aNewRange[] = { aRange[1] - theMapScale*(aRange[1]-aRange[0]), aRange[1] };
538 myContourFilter->GenerateValues(GetNumberOfContours(),aNewRange);
540 myWarpScalar->SetScaleFactor(myScaleFactor*theMapScale);