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 <vtkCellDataToPointData.h>
37 #include <vtkGeometryFilter.h>
38 #include <vtkContourFilter.h>
39 #include <vtkWarpScalar.h>
40 #include <vtkOutlineFilter.h>
43 //----------------------------------------------------------------------------
44 vtkStandardNewMacro(VISU_Plot3DPL);
47 //----------------------------------------------------------------------------
50 myCellDataToPointData(vtkCellDataToPointData::New()),
51 myAppendPolyData(vtkAppendPolyData::New()),
52 myGeometryFilter(vtkGeometryFilter::New()),
53 myContourFilter(vtkContourFilter::New()),
54 myWarpScalar(vtkWarpScalar::New()),
55 myOrientation(VISU_CutPlanesPL::YZ),
62 SetIsShrinkable(false);
63 SetIsFeatureEdgesAllowed(false);
65 myCellDataToPointData->Delete();
66 myAppendPolyData->Delete();
67 myGeometryFilter->Delete();
68 myContourFilter->Delete();
69 myWarpScalar->Delete();
71 myAngle[0] = myAngle[1] = myAngle[2] = 0.0;
73 SetNumberOfContours(32);
77 //----------------------------------------------------------------------------
83 //----------------------------------------------------------------------------
88 unsigned long int aTime = Superclass::GetMTime();
90 aTime = std::max(aTime, myCellDataToPointData->GetMTime());
91 aTime = std::max(aTime, myAppendPolyData->GetMTime());
92 aTime = std::max(aTime, myGeometryFilter->GetMTime());
93 aTime = std::max(aTime, myContourFilter->GetMTime());
94 aTime = std::max(aTime, myWarpScalar->GetMTime());
100 //----------------------------------------------------------------------------
103 ::DoShallowCopy(VISU_PipeLine *thePipeLine,
106 Superclass::DoShallowCopy(thePipeLine, theIsCopyInput);
108 if(VISU_Plot3DPL *aPipeLine = dynamic_cast<VISU_Plot3DPL*>(thePipeLine)){
109 SetOrientation (aPipeLine->GetPlaneOrientation(),
110 aPipeLine->GetRotateX(), aPipeLine->GetRotateY());
111 SetPlanePosition (aPipeLine->GetPlanePosition(),
112 aPipeLine->IsPositionRelative() );
113 SetScaleFactor( aPipeLine->GetScaleFactor() );
114 SetContourPrs( aPipeLine->GetIsContourPrs() );
115 SetNumberOfContours( aPipeLine->GetNumberOfContours() );
120 //----------------------------------------------------------------------------
121 VISU_CutPlanesPL::PlaneOrientation
123 ::GetOrientation(vtkDataSet* theDataSet)
125 theDataSet->Update();
127 vtkFloatingPointType aBounds[6];
128 theDataSet->GetBounds(aBounds);
129 vtkFloatingPointType aDelta[3] = {aBounds[1] - aBounds[0], aBounds[3] - aBounds[2], aBounds[5] - aBounds[4]};
131 if(aDelta[0] >= aDelta[1] && aDelta[0] >= aDelta[2])
132 if(aDelta[1] >= aDelta[2])
133 return VISU_CutPlanesPL::XY;
135 return VISU_CutPlanesPL::ZX;
137 if(aDelta[1] >= aDelta[0] && aDelta[1] >= aDelta[2])
138 if(aDelta[0] >= aDelta[2])
139 return VISU_CutPlanesPL::XY;
141 return VISU_CutPlanesPL::YZ;
143 if(aDelta[2] >= aDelta[0] && aDelta[2] >= aDelta[1])
144 if(aDelta[0] >= aDelta[1])
145 return VISU_CutPlanesPL::ZX;
147 return VISU_CutPlanesPL::YZ;
149 return VISU_CutPlanesPL::XY;
153 //----------------------------------------------------------------------------
156 ::GetScaleFactor( VISU_ColoredPL* theColoredPL,
157 vtkDataSet* theDataSet )
159 theDataSet->Update();
160 vtkFloatingPointType aLength = theDataSet->GetLength(); // diagonal length
162 vtkFloatingPointType aScalarRange[2];
163 theColoredPL->GetSourceRange(aScalarRange);
165 static vtkFloatingPointType EPS = 0.3;
166 vtkFloatingPointType aRange = aScalarRange[1];
168 return aLength / aRange * EPS;
174 //----------------------------------------------------------------------------
181 myOrientation = GetOrientation(GetMergedInput());
182 SetScaleFactor( GetScaleFactor( this, GetMergedInput() ) );
186 //----------------------------------------------------------------------------
191 return myAppendPolyData->GetOutput();
195 //----------------------------------------------------------------------------
200 vtkDataSet* aMergedInput = GetMergedInput();
201 if(VISU::IsQuadraticData(aMergedInput)) // Bug 0020123, note 0005343
202 throw std::runtime_error("Impossible to build presentation");
204 vtkFloatingPointType aPlaneNormal[3];
205 vtkFloatingPointType anOrigin[3];
206 GetBasePlane( anOrigin, aPlaneNormal );
208 vtkPolyData* aPolyData = 0;
209 vtkCutter *aCutPlane = 0;
211 if ( !IsPlanarInput() )
213 aCutPlane = vtkCutter::New();
214 aCutPlane->SetInput(aMergedInput);
216 vtkPlane *aPlane = vtkPlane::New();
217 aPlane->SetOrigin(anOrigin);
218 aPlane->SetNormal(aPlaneNormal);
220 aCutPlane->SetCutFunction(aPlane);
223 aPolyData = aCutPlane->GetOutput();
227 if ( !aPolyData || aPolyData->GetNumberOfCells() == 0 ) {
228 myGeometryFilter->SetInput(aMergedInput);
229 aPolyData = myGeometryFilter->GetOutput();
232 if ( !myIsContour ) // surface prs
234 if(VISU::IsDataOnCells(aPolyData)) {
235 myCellDataToPointData->SetInput(aPolyData);
236 myCellDataToPointData->PassCellDataOn();
237 myWarpScalar->SetInput(myCellDataToPointData->GetPolyDataOutput());
239 myWarpScalar->SetInput(aPolyData);
243 if(VISU::IsDataOnCells(aPolyData)) {
244 myCellDataToPointData->SetInput(aPolyData);
245 myCellDataToPointData->PassCellDataOn();
246 myContourFilter->SetInput(myCellDataToPointData->GetOutput());
248 myContourFilter->SetInput(aPolyData);
250 vtkFloatingPointType aScalarRange[2];
251 GetSourceRange(aScalarRange);
253 myContourFilter->GenerateValues(GetNumberOfContours(),aScalarRange);
254 myWarpScalar->SetInput(myContourFilter->GetOutput());
257 VISU_CutPlanesPL::ClearAppendPolyData(myAppendPolyData.GetPointer());
258 myAppendPolyData->AddInput(myWarpScalar->GetPolyDataOutput());
263 myWarpScalar->SetNormal(aPlaneNormal);
265 Superclass::Update();
269 //----------------------------------------------------------------------------
274 unsigned long int aSize = Superclass::GetMemorySize();
276 if(vtkDataObject* aDataObject = myGeometryFilter->GetInput())
277 aSize += aDataObject->GetActualMemorySize() * 1024;
279 if(myCellDataToPointData->GetInput())
280 if(vtkDataSet* aDataSet = myCellDataToPointData->GetOutput())
281 aSize += aDataSet->GetActualMemorySize() * 1024;
283 if(vtkDataObject* aDataObject = myContourFilter->GetInput())
284 aSize += aDataObject->GetActualMemorySize() * 1024;
286 if(vtkDataObject* aDataObject = myWarpScalar->GetInput())
287 aSize += aDataObject->GetActualMemorySize() * 1024;
289 int anEnd = myAppendPolyData->GetNumberOfInputConnections(0);
290 for(int anId = 0; anId < anEnd; anId++){
291 if(vtkDataObject* aDataObject = myAppendPolyData->GetInput(anId))
292 aSize += aDataObject->GetActualMemorySize() * 1024;
299 //----------------------------------------------------------------------------
302 ::SetNumberOfContours(int theNumber)
304 myContourFilter->SetNumberOfContours(theNumber);
308 //----------------------------------------------------------------------------
311 ::GetNumberOfContours()
313 return myContourFilter->GetNumberOfContours();
317 //----------------------------------------------------------------------------
320 ::SetScaleFactor(vtkFloatingPointType theScaleFactor)
322 myScaleFactor = theScaleFactor;
323 myWarpScalar->SetScaleFactor(theScaleFactor*myMapScaleFactor);
327 //----------------------------------------------------------------------------
332 return myScaleFactor;
336 //----------------------------------------------------------------------------
339 SetContourPrs(bool theIsContourPrs )
341 if(myIsContour == theIsContourPrs)
344 myIsContour = theIsContourPrs;
349 //----------------------------------------------------------------------------
358 //----------------------------------------------------------------------------
361 ::SetPlanePosition(vtkFloatingPointType thePosition,
364 bool anIsSameValue = VISU::CheckIsSameValue(myIsRelative, theIsRelative);
365 anIsSameValue &= (myPosition == thePosition);
369 myIsRelative = theIsRelative;
370 myPosition = thePosition;
375 //----------------------------------------------------------------------------
378 ::IsPositionRelative()
384 //----------------------------------------------------------------------------
385 VISU_CutPlanesPL::PlaneOrientation
387 ::GetPlaneOrientation()
389 return myOrientation;
393 //----------------------------------------------------------------------------
398 switch(myOrientation){
399 case VISU_CutPlanesPL::XY: return myAngle[0];
400 case VISU_CutPlanesPL::YZ: return myAngle[1];
401 case VISU_CutPlanesPL::ZX: return myAngle[2];
407 //----------------------------------------------------------------------------
411 switch(myOrientation){
412 case VISU_CutPlanesPL::XY: return myAngle[1];
413 case VISU_CutPlanesPL::YZ: return myAngle[2];
414 case VISU_CutPlanesPL::ZX: return myAngle[0];
420 //----------------------------------------------------------------------------
423 SetOrientation(VISU_CutPlanesPL::PlaneOrientation theOrientation,
424 vtkFloatingPointType theXAngle,
425 vtkFloatingPointType theYAngle)
427 bool anIsSameValue = VISU::CheckIsSameValue(GetRotateX(), theXAngle);
428 anIsSameValue &= VISU::CheckIsSameValue(GetRotateY(), theYAngle);
429 anIsSameValue &= (myOrientation == theOrientation);
433 switch(theOrientation){
434 case VISU_CutPlanesPL::XY: myAngle[0] = theXAngle; break;
435 case VISU_CutPlanesPL::YZ: myAngle[1] = theXAngle; break;
436 case VISU_CutPlanesPL::ZX: myAngle[2] = theXAngle; break;
439 switch(theOrientation){
440 case VISU_CutPlanesPL::XY: myAngle[1] = theYAngle; break;
441 case VISU_CutPlanesPL::YZ: myAngle[2] = theYAngle; break;
442 case VISU_CutPlanesPL::ZX: myAngle[0] = theYAngle; break;
445 myOrientation = theOrientation;
450 //----------------------------------------------------------------------------
458 //=======================================================================
459 //function : GetBasePlane
461 //=======================================================================
464 ::GetBasePlane(vtkFloatingPointType theOrigin[3],
465 vtkFloatingPointType theNormal[3],
466 bool theCenterOrigine )
468 VISU_CutPlanesPL::GetDir(theNormal,myAngle,myOrientation);
470 vtkFloatingPointType aPosition = myPosition;
471 vtkFloatingPointType aBounds[6], aBoundPrj[3];
474 GetInput()->GetBounds(aBounds);
475 VISU_CutPlanesPL::GetBoundProject(aBoundPrj,aBounds,theNormal);
476 aPosition = aBoundPrj[0] + aBoundPrj[2]*myPosition;
478 VISU::Mul(theNormal,aPosition,theOrigin);
480 if ( theCenterOrigine ) {
481 // move theOrigin to the center of aBounds projections to the plane
482 GetMergedInput()->GetBounds(aBounds);
483 vtkFloatingPointType boundPoints[8][3] = {
484 {aBounds[0],aBounds[2],aBounds[4]},
485 {aBounds[1],aBounds[2],aBounds[4]},
486 {aBounds[0],aBounds[3],aBounds[4]},
487 {aBounds[1],aBounds[3],aBounds[4]},
488 {aBounds[0],aBounds[2],aBounds[5]},
489 {aBounds[1],aBounds[2],aBounds[5]},
490 {aBounds[0],aBounds[3],aBounds[5]},
491 {aBounds[1],aBounds[3],aBounds[5]}};
492 vtkFloatingPointType newOrigin[3] = { 0,0,0 };
493 for(int i = 0; i < 8; i++) {
494 vtkFloatingPointType proj[3];
495 vtkPlane::ProjectPoint( boundPoints[i], theOrigin, theNormal, proj );
496 newOrigin[0] += proj[0];
497 newOrigin[1] += proj[1];
498 newOrigin[2] += proj[2];
500 theOrigin[0] = newOrigin[0] / 8.;
501 theOrigin[1] = newOrigin[1] / 8.;
502 theOrigin[2] = newOrigin[2] / 8.;
506 //=======================================================================
507 //function : GetMinMaxPosition
508 //purpose : return absolute position range
509 //=======================================================================
512 ::GetMinMaxPosition( vtkFloatingPointType& minPos,
513 vtkFloatingPointType& maxPos )
515 vtkFloatingPointType aBounds[6], aBoundPrj[3], aNormal[3];
516 VISU_CutPlanesPL::GetDir(aNormal,myAngle,myOrientation);
517 GetInput()->GetBounds(aBounds);
518 VISU_CutPlanesPL::GetBoundProject(aBoundPrj,aBounds,aNormal);
519 minPos = aBoundPrj[0];
520 maxPos = aBoundPrj[1];
523 //=======================================================================
524 //function : SetMapScale
526 //=======================================================================
530 ::SetMapScale(vtkFloatingPointType theMapScale)
532 myMapScaleFactor = theMapScale;
533 Superclass::SetMapScale(theMapScale);
536 vtkFloatingPointType aRange[2];
537 GetSourceRange(aRange);
538 vtkFloatingPointType aNewRange[] = { aRange[1] - theMapScale*(aRange[1]-aRange[0]), aRange[1] };
539 myContourFilter->GenerateValues(GetNumberOfContours(),aNewRange);
541 myWarpScalar->SetScaleFactor(myScaleFactor*theMapScale);